changeset 27516:c3e24c82157f

skip constant folding if expression evaluation generates warning * oct-parse.yy (base_parser::make_colon_expression, base_parser::finish_array_list): Skip constant folding if expression evaluation generates a warning. Save and restore last warning message. Move unwind_protect frame inside try-catch block.
author John W. Eaton <jwe@octave.org>
date Wed, 16 Oct 2019 13:35:08 -0400
parents 466e61c5fb4b
children 85ad4689aa05
files libinterp/parse-tree/oct-parse.yy
diffstat 1 files changed, 76 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.yy	Wed Oct 16 12:17:58 2019 -0700
+++ b/libinterp/parse-tree/oct-parse.yy	Wed Oct 16 13:35:08 2019 -0400
@@ -2441,16 +2441,6 @@
   {
     tree_expression *retval = nullptr;
 
-    interpreter& interp = __get_interpreter__ ("finish_colon_expression");
-    error_system& es = interp.get_error_system ();
-
-    unwind_protect frame;
-
-    frame.add_method (es, &error_system::set_discard_warning_messages,
-                      es.discard_warning_messages ());
-
-    es.discard_warning_messages (true);
-
     if (! base || ! limit)
       {
         delete base;
@@ -2463,40 +2453,61 @@
     int l = base->line ();
     int c = base->column ();
 
-    tree_colon_expression *e
+    tree_colon_expression *expr
       = new tree_colon_expression (base, limit, incr, l, c);
 
+    retval = expr;
+
     if (base->is_constant () && limit->is_constant ()
         && (! incr || incr->is_constant ()))
       {
+        interpreter& interp = __get_interpreter__ ("finish_colon_expression");
+
         try
           {
+            // If the evaluation generates a warning message, restore
+            // the previous value of last_warning_message and skip the
+            // conversion to a constant value.
+
+            unwind_protect frame;
+
+            error_system& es = interp.get_error_system ();
+
+            frame.add_method (es, &error_system::set_last_warning_message,
+                              es.last_warning_message (""));
+
+            frame.add_method (es, &error_system::set_discard_warning_messages,
+                              es.discard_warning_messages (true));
+
             tree_evaluator& tw = interp.get_evaluator ();
 
-            octave_value tmp = e->evaluate (tw);
-
-            tree_constant *tc_retval
-              = new tree_constant (tmp, e->line (), e->column ());
-
-            std::ostringstream buf;
-
-            tree_print_code tpc (buf);
-
-            e->accept (tpc);
-
-            tc_retval->stash_original_text (buf.str ());
-
-            delete e;
-
-            retval = tc_retval;
+            octave_value tmp = expr->evaluate (tw);
+
+            std::string msg = es.last_warning_message ();
+
+            if (msg.empty ())
+              {
+                tree_constant *tc_retval
+                  = new tree_constant (tmp, expr->line (), expr->column ());
+
+                std::ostringstream buf;
+
+                tree_print_code tpc (buf);
+
+                expr->accept (tpc);
+
+                tc_retval->stash_original_text (buf.str ());
+
+                delete expr;
+
+                retval = tc_retval;
+              }
           }
         catch (const execution_exception&)
           {
             interp.recover_from_exception ();
           }
       }
-    else
-      retval = e;
 
     return retval;
   }
@@ -4134,39 +4145,50 @@
   {
     tree_expression *retval = array_list;
 
-    interpreter& interp = __get_interpreter__ ("finish_array_list");
-    error_system& es = interp.get_error_system ();
-
-    unwind_protect frame;
-
-    frame.add_method (es, &error_system::set_discard_warning_messages,
-                      es.discard_warning_messages ());
-
-    es.discard_warning_messages (true);
-
     if (array_list->all_elements_are_constant ())
       {
+        interpreter& interp = __get_interpreter__ ("finish_array_list");
+
         try
           {
+            // If the evaluation generates a warning message, restore
+            // the previous value of last_warning_message and skip the
+            // conversion to a constant value.
+
+            unwind_protect frame;
+
+            error_system& es = interp.get_error_system ();
+
+            frame.add_method (es, &error_system::set_last_warning_message,
+                              es.last_warning_message (""));
+
+            frame.add_method (es, &error_system::set_discard_warning_messages,
+                              es.discard_warning_messages (true));
+
             tree_evaluator& tw = interp.get_evaluator ();
 
             octave_value tmp = array_list->evaluate (tw);
 
-            tree_constant *tc_retval
-              = new tree_constant (tmp, array_list->line (),
-                                   array_list->column ());
-
-            std::ostringstream buf;
-
-            tree_print_code tpc (buf);
-
-            array_list->accept (tpc);
-
-            tc_retval->stash_original_text (buf.str ());
-
-            delete array_list;
-
-            retval = tc_retval;
+            std::string msg = es.last_warning_message ();
+
+            if (msg.empty ())
+              {
+                tree_constant *tc_retval
+                  = new tree_constant (tmp, array_list->line (),
+                                       array_list->column ());
+
+                std::ostringstream buf;
+
+                tree_print_code tpc (buf);
+
+                array_list->accept (tpc);
+
+                tc_retval->stash_original_text (buf.str ());
+
+                delete array_list;
+
+                retval = tc_retval;
+              }
           }
         catch (const execution_exception&)
           {