re PR c++/69203 (ICE in potential_constant_expression_1, at cp/constexpr.c:4754)
authorJason Merrill <jason@redhat.com>
Fri, 4 Mar 2016 22:53:29 +0000 (17:53 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 4 Mar 2016 22:53:29 +0000 (17:53 -0500)
PR c++/69203

* cp-tree.h (COND_EXPR_IS_VEC_DELETE): New.
* init.c (build_vec_delete_1): Set it.
* constexpr.c (potential_constant_expression_1) [COND_EXPR]: Check it.

From-SVN: r233987

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C [new file with mode: 0644]

index 5951567..f4c8744 100644 (file)
@@ -1,3 +1,10 @@
+2016-03-04  Jason Merrill  <jason@redhat.com>
+
+       PR c++/69203
+       * cp-tree.h (COND_EXPR_IS_VEC_DELETE): New.
+       * init.c (build_vec_delete_1): Set it.
+       * constexpr.c (potential_constant_expression_1) [COND_EXPR]: Check it.
+
 2016-03-04  Jakub Jelinek  <jakub@redhat.com>
 
        * decl.c (start_preparsed_function): Don't emit start clobber at the
index d308175..c9f9c47 100644 (file)
@@ -4885,8 +4885,16 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
        return false;
      return true;
 
-    case IF_STMT:
     case COND_EXPR:
+      if (COND_EXPR_IS_VEC_DELETE (t))
+       {
+         if (flags & tf_error)
+           error_at (location_of (t),
+                     "%<delete[]%> is not a constant-expression");
+         return false;
+       }
+      /* Fall through.  */
+    case IF_STMT:
     case VEC_COND_EXPR:
       /* If the condition is a known constant, we know which of the legs we
         care about; otherwise we only require that the condition and
index 7de0a55..a08c59b 100644 (file)
@@ -107,6 +107,7 @@ operator == (const cp_expr &lhs, tree rhs)
 /* Usage of TREE_LANG_FLAG_?:
    0: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
       NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
+      COND_EXPR_IS_VEC_DELETE (in COND_EXPR).
       DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
       COMPOUND_EXPR_OVERLOADED (in COMPOUND_EXPR).
       CLEANUP_P (in TRY_BLOCK)
@@ -404,6 +405,9 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 #define STMT_EXPR_NO_SCOPE(NODE) \
    TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
 
+#define COND_EXPR_IS_VEC_DELETE(NODE) \
+  TREE_LANG_FLAG_0 (COND_EXPR_CHECK (NODE))
+
 /* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual
    sense of `same'.  */
 #define same_type_p(TYPE1, TYPE2) \
index 43f854c..1ba3c59 100644 (file)
@@ -3685,6 +3685,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
   TREE_NO_WARNING (cond) = 1;
   body = build3_loc (input_location, COND_EXPR, void_type_node,
                     cond, body, integer_zero_node);
+  COND_EXPR_IS_VEC_DELETE (body) = true;
   body = build1 (NOP_EXPR, void_type_node, body);
 
   if (controller)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C
new file mode 100644 (file)
index 0000000..4a453a4
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/69203
+// { dg-do compile { target c++11 } }
+
+struct A { ~A(); };
+constexpr int f(int i) { return i; }
+constexpr int g(A* ap)
+{
+  return f((delete[] ap, 42)); // { dg-message "" }
+}
+
+A a;
+constexpr int i = g(&a);       // { dg-error "" }