Mercurial > octave
changeset 25478:a06983fe83a5 stable
maybe preserve local value when declaring variable global (bug #54052)
* pt-eval.cc (tree_evaluator::visit_decl_elt): In global declaration,
if local value is defined but global is not, then preserve global value.
If global value is already defined, override local value with global
value. Either way, warn about variable already being defined.
* test/global.tst: New tests.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 15 Jun 2018 15:35:45 -0400 |
parents | 9771111f04f4 |
children | 594eeec64f14 0d7a89bec20e |
files | libinterp/parse-tree/pt-eval.cc test/global.tst |
diffstat | 2 files changed, 83 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc Wed Jun 13 16:21:58 2018 -0700 +++ b/libinterp/parse-tree/pt-eval.cc Fri Jun 15 15:35:45 2018 -0400 @@ -727,11 +727,51 @@ { if (elt.is_global ()) { + std::string name = id->name (); + symbol_table& symtab = m_interpreter.get_symbol_table (); - symbol_record global_sym = symtab.find_global_symbol (id->name ()); - - id->link_to_global (symtab.global_scope (), global_sym); + symbol_scope global_scope = symtab.global_scope (); + + symbol_record global_sr = global_scope.find_symbol (name); + + // FIXME: Hmmm. Seems like this should happen automatically + // for symbols coming from the global scope... + global_sr.mark_global (); + + symbol_scope scope = symtab.current_scope (); + + if (! scope.is_global (name)) + { + octave_value val = scope.varval (name); + + bool local_val_is_defined = val.is_defined (); + + if (local_val_is_defined) + { + warning_with_id ("Octave:global-from-local", + "global: '%s' is defined in the current scope", + name.c_str ()); + warning_with_id ("Octave:global-from-local", + "global: in a future version, global variables must be declared before use"); + + // If the symbol is defined in the local but not the + // global scope, then use the local value as the + // initial value. This value will also override any + // initializer in the global statement. + octave_value global_val = global_scope.varval (name); + + if (! global_val.is_defined ()) + { + warning_with_id ("Octave:global-from-local", + "global: global value overrides local value"); + + global_scope.assign (name, val); + } + } + + id->link_to_global (global_scope, global_sr); + } } else if (elt.is_persistent ()) id->mark_persistent ();
--- a/test/global.tst Wed Jun 13 16:21:58 2018 -0700 +++ b/test/global.tst Fri Jun 15 15:35:45 2018 -0400 @@ -80,3 +80,43 @@ %! f; %! clear H; %! g; + +%!function r = f () +%! x = 1; +%! global x; +%! r = x; +%!endfunction +%!test +%! warning ("off", "Octave:global-from-local", "local"); +%! clear global x +%! global x +%! x = 0; +%! assert (f (), 0); +%! global x +%! assert (x, 0); +%!test +%! warning ("off", "Octave:global-from-local", "local"); +%! clear global x +%! assert (f (), 1); +%! global x +%! assert (x, 1); + +%!function r = f () +%! x = 1; +%! global x = 3; +%! r = x; +%!endfunction +%!test +%! warning ("off", "Octave:global-from-local", "local"); +%! clear global x +%! global x +%! x = 0; +%! assert (f (), 0); +%! global x +%! assert (x, 0); +%!test +%! warning ("off", "Octave:global-from-local", "local"); +%! clear global x +%! assert (f (), 1); +%! global x +%! assert (x, 1);