diff options
author | Jason Merrill <jason@redhat.com> | 2020-04-08 23:59:30 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-09 17:34:16 -0400 |
commit | ef529765234bea7893bd56f3ab3a2da7695f6b21 (patch) | |
tree | 8c1d3602bc7bd39287c7329c91ac1bc9790146cb /gcc | |
parent | 3fd1c229ad10fda68318882329568f400a38fb6d (diff) | |
download | gcc-ef529765234bea7893bd56f3ab3a2da7695f6b21.zip gcc-ef529765234bea7893bd56f3ab3a2da7695f6b21.tar.gz gcc-ef529765234bea7893bd56f3ab3a2da7695f6b21.tar.bz2 |
c++: constexpr static data member instantiation [PR94523]
Here due to my recent change to store_init_value we were expanding the
initializer of aw knowing that we were initializing aw. When
cxx_eval_call_expression finished the constructor, it wanted to look up the
value of aw to set TREE_READONLY on it, but we haven't set DECL_INITIAL yet,
so decl_constant_value tried to instantiate the initializer again. And
infinite recursion. Stopped by optimizing the case of asking for the value
of ctx->object, which is ctx->value. It also would have worked to look in
the values hash table, so let's move that up before decl_constant_value as
well.
gcc/cp/ChangeLog
2020-04-09 Jason Merrill <jason@redhat.com>
PR c++/94523
* constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Look at
ctx->object and ctx->global->values first.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C | 10 |
3 files changed, 25 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cdd9b52..49246e8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-04-09 Jason Merrill <jason@redhat.com> + + PR c++/94523 + * constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Look at + ctx->object and ctx->global->values first. + 2020-04-09 Marek Polacek <polacek@redhat.com> PR c++/93790 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 96497ab..5793430 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -5485,6 +5485,15 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, CONST_DECL for aggregate constants. */ if (lval) return t; + else if (t == ctx->object) + return ctx->ctor; + if (VAR_P (t)) + if (tree *p = ctx->global->values.get (t)) + if (*p != NULL_TREE) + { + r = *p; + break; + } if (COMPLETE_TYPE_P (TREE_TYPE (t)) && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false)) { @@ -5499,10 +5508,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, if (TREE_CODE (r) == TARGET_EXPR && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR) r = TARGET_EXPR_INITIAL (r); - if (VAR_P (r)) - if (tree *p = ctx->global->values.get (r)) - if (*p != NULL_TREE) - r = *p; if (DECL_P (r)) { if (!ctx->quiet) diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C new file mode 100644 index 0000000..f39ed21 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C @@ -0,0 +1,10 @@ +// PR c++/94523 +// { dg-do compile { target c++14 } } + +template <bool, typename a> using b = a; +struct d { + char ao; + template <typename ap> constexpr d(ap) : ao{} {} +}; +template <int... au> struct e { static constexpr auto aw = d(au...); }; +template <int c> b<c, d> ax(e<1>::aw); |