c++: Error recovery with erroneous DECL_INITIAL [PR94475]
authorPatrick Palka <ppalka@redhat.com>
Wed, 15 Apr 2020 16:47:41 +0000 (12:47 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 16 Apr 2020 12:58:40 +0000 (08:58 -0400)
Here we're ICE'ing in do_narrow during error-recovery, because ocp_convert
returns error_mark_node after it attempts to reduce a const decl to its
erroneous DECL_INITIAL via scalar_constant_value, and we later pass this
error_mark_node to fold_build2 which isn't prepared to handle error_mark_nodes.

We could fix this ICE in do_narrow by checking if ocp_convert returns
error_mark_node, but for the sake of consistency and for better error recovery
it seems it'd be preferable if ocp_convert didn't care that a const decl's
initializer is erroneous and would instead proceed as if the decl was not const,
which is the approach that this patch takes.

gcc/cp/ChangeLog:

PR c++/94475
* cvt.c (ocp_convert): If the result of scalar_constant_value is
erroneous, ignore it and use the original expression.

gcc/testsuite/ChangeLog:

PR c++/94475
* g++.dg/conversion/err-recover2.C: New test.
* g++.dg/diagnostic/pr84138.C: Remove now-bogus warning.
* g++.dg/warn/Wsign-compare-8.C: Remove now-bogus warning.

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/conversion/err-recover2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/pr84138.C
gcc/testsuite/g++.dg/warn/Wsign-compare-8.C

index 3e324056ba75718f208e88cad5b7778409f60cf5..b2acd8927193776c8846e774468c45cfdc8f08b7 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-16  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94475
+       * cvt.c (ocp_convert): If the result of scalar_constant_value is
+       erroneous, ignore it and use the original expression.
+
 2020-04-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/94571
index a3b80968b334882176f7faa55b19e1d8ed711af5..656e7fd3ec089748f8ea4a7a1ed4678f3cbaa633 100644 (file)
@@ -723,7 +723,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
   if (!CLASS_TYPE_P (type))
     {
       e = mark_rvalue_use (e);
-      e = scalar_constant_value (e);
+      tree v = scalar_constant_value (e);
+      if (!error_operand_p (v))
+       e = v;
     }
   if (error_operand_p (e))
     return error_mark_node;
index ed4420487fc0c6069a870e234e202b734378c4d8..756f1d759e6427fe6b20a9a59548ba39f19fa614 100644 (file)
@@ -1,3 +1,10 @@
+2020-04-16  Patrick Palka  <ppalka@redhat.com>
+
+       PR c++/94475
+       * g++.dg/conversion/err-recover2.C: New test.
+       * g++.dg/diagnostic/pr84138.C: Remove now-bogus warning.
+       * g++.dg/warn/Wsign-compare-8.C: Remove now-bogus warning.
+
 2020-04-16  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR rtl-optimization/94605
diff --git a/gcc/testsuite/g++.dg/conversion/err-recover2.C b/gcc/testsuite/g++.dg/conversion/err-recover2.C
new file mode 100644 (file)
index 0000000..437e1a9
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/94475
+// { dg-do compile }
+
+unsigned char
+sr ()
+{
+  const unsigned char xz = EI; // { dg-error "not declared" }
+
+  return xz - (xz >> 1);
+}
index 5c48b9b164a9c0194c0289ff70bc15fa379ed85b..00352306a56e93ca917c3f4298f5e157a6b7a234 100644 (file)
@@ -5,4 +5,4 @@ foo()
 {
   const int i = 0 = 0; // { dg-error "lvalue required as left operand" }
   return 1 ? 0 : (char)i;
-} // { dg-warning "control reaches" }
+}
index 237ba84d5263a6d69788ad2154ffef0309e82b60..4d2688157fcf4a2d079ac1dfc78bb0279cda1197 100644 (file)
@@ -5,4 +5,4 @@ bool foo (char c)
 {
   const int i = 0 = 0; // { dg-error "lvalue" }
   return c = i;
-} // { dg-warning "control reaches" }
+}