diff mbox

C++ PATCH for c++/69203 (ICE with delete[])

Message ID 56DA11D7.6090306@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 4, 2016, 10:53 p.m. UTC
The representation of delete[] causes the constexpr machinery to ICE. 
That's a separate bug worth fixing, but for GCC 6 it's simpler to stop 
when we see the wrapper, and also gives a better diagnostic.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 3cf04bc44a26e84e8c88231572baadb465c70ed3
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 1 09:08:37 2016 -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.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d308175..c9f9c47 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4885,8 +4885,16 @@  potential_constant_expression_1 (tree t, bool want_rval, bool strict,
 	return false;
      return true;
 
+    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 COND_EXPR:
     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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1dc23c..9c7f0cc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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) \
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 43f854c..1ba3c59 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
index 0000000..4a453a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C
@@ -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 "" }