From d5bcd6d4d7be1017d9f2c416ecb0fd635d281de1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 4 Mar 2016 17:53:29 -0500 Subject: [PATCH] re PR c++/69203 (ICE in potential_constant_expression_1, at cp/constexpr.c:4754) 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 | 7 +++++++ gcc/cp/constexpr.c | 10 +++++++++- gcc/cp/cp-tree.h | 4 ++++ gcc/cp/init.c | 1 + gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C | 12 ++++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5951567..f4c8744 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-03-04 Jason Merrill + + 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 * decl.c (start_preparsed_function): Don't emit start clobber at the 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 IF_STMT: case COND_EXPR: + if (COND_EXPR_IS_VEC_DELETE (t)) + { + if (flags & tf_error) + error_at (location_of (t), + "% 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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7de0a55..a08c59b 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 43f854c4..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 "" } -- 2.7.4