aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-04-08 23:59:30 -0400
committerJason Merrill <jason@redhat.com>2020-04-09 17:34:16 -0400
commitef529765234bea7893bd56f3ab3a2da7695f6b21 (patch)
tree8c1d3602bc7bd39287c7329c91ac1bc9790146cb /gcc
parent3fd1c229ad10fda68318882329568f400a38fb6d (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C10
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);