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.
+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
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))
{
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)
--- /dev/null
+// 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);