diff options
author | Jason Merrill <jason@redhat.com> | 2017-03-08 20:01:18 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-03-08 20:01:18 -0500 |
commit | 89262ec6bdb835436ecfa715397bae078035fe9e (patch) | |
tree | d1beabae6e2ca6fc0899e6f2d80f1804a443eade | |
parent | ad807dcbd94c22ce642a7431cb079c198ddeeb4b (diff) | |
download | gcc-89262ec6bdb835436ecfa715397bae078035fe9e.zip gcc-89262ec6bdb835436ecfa715397bae078035fe9e.tar.gz gcc-89262ec6bdb835436ecfa715397bae078035fe9e.tar.bz2 |
PR c++/79797 - ICE with self-reference in array DMI.
* constexpr.c (lookup_placeholder): Split out...
(cxx_eval_constant_expression): ...from here.
From-SVN: r245986
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 59 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C | 12 |
3 files changed, 56 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 47add32..5bd8322 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-03-08 Jason Merrill <jason@redhat.com> + + PR c++/79797 - ICE with self-reference in array DMI. + * constexpr.c (lookup_placeholder): Split out... + (cxx_eval_constant_expression): ...from here. + 2017-03-07 Jakub Jelinek <jakub@redhat.com> PR c/79834 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f114da0..2510e23 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3827,6 +3827,35 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t, return NULL_TREE; } +/* Find the object of TYPE under initialization in CTX. */ + +static tree +lookup_placeholder (const constexpr_ctx *ctx, bool lval, tree type) +{ + if (!ctx || !ctx->ctor || (lval && !ctx->object)) + return NULL_TREE; + + /* We could use ctx->object unconditionally, but using ctx->ctor when we + can is a minor optimization. */ + if (!lval && same_type_p (TREE_TYPE (ctx->ctor), type)) + return ctx->ctor; + + /* Since an object cannot have a field of its own type, we can search outward + from ctx->object to find the unique containing object of TYPE. */ + tree ob = ctx->object; + while (ob) + { + if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type)) + break; + if (handled_component_p (ob)) + ob = TREE_OPERAND (ob, 0); + else + ob = NULL_TREE; + } + + return ob; +} + /* Attempt to reduce the expression T to a constant value. On failure, issue diagnostic and return error_mark_node. */ /* FIXME unify with c_fully_fold */ @@ -4468,27 +4497,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case PLACEHOLDER_EXPR: - if (!ctx || !ctx->ctor || (lval && !ctx->object) - || !(same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (t), TREE_TYPE (ctx->ctor)))) - { - /* A placeholder without a referent. We can get here when - checking whether NSDMIs are noexcept, or in massage_init_elt; - just say it's non-constant for now. */ - gcc_assert (ctx->quiet); - *non_constant_p = true; - break; - } - else - { - /* Use of the value or address of the current object. We could - use ctx->object unconditionally, but using ctx->ctor when we - can is a minor optimization. */ - tree ctor = lval ? ctx->object : ctx->ctor; - return cxx_eval_constant_expression - (ctx, ctor, lval, - non_constant_p, overflow_p); - } + /* Use of the value or address of the current object. */ + if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t))) + return cxx_eval_constant_expression (ctx, ctor, lval, + non_constant_p, overflow_p); + /* A placeholder without a referent. We can get here when + checking whether NSDMIs are noexcept, or in massage_init_elt; + just say it's non-constant for now. */ + gcc_assert (ctx->quiet); + *non_constant_p = true; break; case EXIT_EXPR: diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C new file mode 100644 index 0000000..2134ac9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr7.C @@ -0,0 +1,12 @@ +// PR c++/79797 +// { dg-do compile { target c++14 } } + +struct A +{ + A* x[1]{(A*)this}; +}; + +extern constexpr A a{}; + +#define SA(X) static_assert ((X), #X) +SA (a.x[0] == &a); |