changeset 25482:0d7a89bec20e stable

improve warnings for global/local variable conflicts (bug #54052) * pt-eval.cc (tree_evaluator::visit_decl_elt): Correct warning for case of creating new global variable when there is an existing local variable. Also warn when an existing global value overrides existing local value. Rename warning ID to Octave:global-local-conflict from Octave:global-from-local. * global.tst: New test.
author John W. Eaton <jwe@octave.org>
date Tue, 19 Jun 2018 09:05:48 -0400
parents a06983fe83a5
children 37dbf79c2297 fbc270aeb55d
files libinterp/parse-tree/pt-eval.cc test/global.tst
diffstat 2 files changed, 30 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc	Fri Jun 15 15:35:45 2018 -0400
+++ b/libinterp/parse-tree/pt-eval.cc	Tue Jun 19 09:05:48 2018 -0400
@@ -749,10 +749,10 @@
 
                 if (local_val_is_defined)
                   {
-                    warning_with_id ("Octave:global-from-local",
+                    warning_with_id ("Octave:global-local-conflict",
                                      "global: '%s' is defined in the current scope",
                                      name.c_str ());
-                    warning_with_id ("Octave:global-from-local",
+                    warning_with_id ("Octave:global-local-conflict",
                                      "global: in a future version, global variables must be declared before use");
 
                     // If the symbol is defined in the local but not the
@@ -761,10 +761,15 @@
                     // initializer in the global statement.
                     octave_value global_val = global_scope.varval (name);
 
-                    if (! global_val.is_defined ())
+                    if (global_val.is_defined ())
                       {
-                        warning_with_id ("Octave:global-from-local",
-                                         "global: global value overrides local value");
+                        warning_with_id ("Octave:global-local-conflict",
+                                         "global: global value overrides existing local value");
+                      }
+                    else
+                      {
+                        warning_with_id ("Octave:global-local-conflict",
+                                         "global: existing local value used to initialize global variable");
 
                         global_scope.assign (name, val);
                       }
--- a/test/global.tst	Fri Jun 15 15:35:45 2018 -0400
+++ b/test/global.tst	Tue Jun 19 09:05:48 2018 -0400
@@ -87,16 +87,16 @@
 %!  r = x;
 %!endfunction
 %!test
-%! warning ("off", "Octave:global-from-local", "local");
-%! clear global x
+%! warning ("off", "Octave:global-local-conflict", "local");
+%! clear global x      ## clears global and local value
 %! global x
 %! x = 0;
 %! assert (f (), 0);
 %! global x
 %! assert (x, 0);
 %!test
-%! warning ("off", "Octave:global-from-local", "local");
-%! clear global x
+%! warning ("off", "Octave:global-local-conflict", "local");
+%! clear global x      ## clears global and local value
 %! assert (f (), 1);
 %! global x
 %! assert (x, 1);
@@ -107,16 +107,29 @@
 %!  r = x;
 %!endfunction
 %!test
-%! warning ("off", "Octave:global-from-local", "local");
-%! clear global x
+%! warning ("off", "Octave:global-local-conflict", "local");
+%! clear global x      ## clears global and local value
 %! global x
 %! x = 0;
 %! assert (f (), 0);
 %! global x
 %! assert (x, 0);
 %!test
-%! warning ("off", "Octave:global-from-local", "local");
+%! warning ("off", "Octave:global-local-conflict", "local");
 %! clear global x
 %! assert (f (), 1);
 %! global x
 %! assert (x, 1);
+
+%!test
+%! warning ("off", "Octave:global-local-conflict", "local");
+%! clear global x      ## clears global and local value
+%! x = 42;             ## local value
+%! global x            ## link to undefined global, global gets local value
+%! assert (x, 42);
+%! clear x             ## clears local; global still defined
+%! x = 13;             ## new local value
+%! global x;           ## link to existing global, local gets global value
+%! assert (x, 42);
+%! clear global x      ## clears global and local value
+%! assert (exist ("x"), 0);