re PR c++/83993 (ICE: constant not recomputed when ADDR_EXPR changed)
authorJason Merrill <jason@redhat.com>
Wed, 31 Jan 2018 20:46:36 +0000 (21:46 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 31 Jan 2018 20:46:36 +0000 (21:46 +0100)
PR c++/83993
* constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR
around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT
on ADDR_EXPR.

* g++.dg/init/pr83993-2.C: New test.

From-SVN: r257265

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/pr83993-2.C [new file with mode: 0644]

index c8df8f12f14cc27eb625270defe3425ca04c6676..6eb7f27883fe5a7dbc715f5337fb574cde7b14e2 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-31  Jason Merrill  <jason@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/83993
+       * constexpr.c (cxx_eval_outermost_constant_expr): Build NOP_EXPR
+       around non-constant ADDR_EXPRs rather than clearing TREE_CONSTANT
+       on ADDR_EXPR.
+
 2018-01-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/83993
index 087d8d8f4a3d157f726f276effc89bd81ae4f9ef..1390405c416c1013fb0ea346e2430c8dc18c095e 100644 (file)
@@ -4840,8 +4840,12 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (r))
     {
-      /* This isn't actually constant, so unset TREE_CONSTANT.  */
-      if (EXPR_P (r))
+      /* This isn't actually constant, so unset TREE_CONSTANT.
+        Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
+        it to be set if it is invariant address, even when it is not
+        a valid C++ constant expression.  Wrap it with a NOP_EXPR
+        instead.  */
+      if (EXPR_P (r) && TREE_CODE (r) != ADDR_EXPR)
        r = copy_node (r);
       else if (TREE_CODE (r) == CONSTRUCTOR)
        r = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (r), r);
index 5feda0b90cfa7ead1b64d912ab279836ac27aaf3..3f110a9bf0bd11cdc043b0a422690429c3504d66 100644 (file)
@@ -1,5 +1,8 @@
 2018-01-31  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/83993
+       * g++.dg/init/pr83993-2.C: New test.
+
        PR c++/83993
        * g++.dg/init/pr83993-1.C: New test.
        * g++.dg/cpp0x/pr83993.C: New test.
diff --git a/gcc/testsuite/g++.dg/init/pr83993-2.C b/gcc/testsuite/g++.dg/init/pr83993-2.C
new file mode 100644 (file)
index 0000000..19f5408
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/83993
+// { dg-do compile }
+// { dg-options "-w" }
+
+int a[5];
+extern int b[];
+int *const c = &a[6];
+int *const d = &b[1];
+
+int
+foo ()
+{
+  return c[-4] + d[-1];
+}