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.

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

gcc/cp/ChangeLog
2020-04-09  Jason Merrill  <ja...@redhat.com>

        PR c++/94523
        * constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Look at
        ctx->object and ctx->global->values first.
---
 gcc/cp/constexpr.c                             | 13 +++++++++----
 gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C | 10 ++++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-static1.C

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 96497ab85d7..5793430c88d 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 00000000000..f39ed216fae
--- /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);

base-commit: af19e4d0e23e5f61fc15e44a58bfa3b047854b1e
-- 
2.18.1

Reply via email to