c++: Fix ICE with inline variable in template [PR97975]
In this test, we have
static inline const int c = b;
in a class template, and we call store_init_value as usual. There, the
value is
IMPLICIT_CONV_EXPR<const float>(b)
which is is_nondependent_static_init_expression but isn't
is_nondependent_constant_expression (they only differ in STRICT).
We call fold_non_dependent_expr, but that just returns the expression
because it only instantiates is_nondependent_constant_expression
expressions. Since we're not checking the initializer of a constexpr
variable, we go on to call maybe_constant_init, whereupon we crash
because it tries to evaluate all is_nondependent_static_init_expression
expressions, which our value is, but it still contains a template code.
I think the fix is to call fold_non_dependent_init instead of
maybe_constant_init, and only call fold_non_dependent_expr on the
"this is a constexpr variable" path so as to avoid instantiating twice
in a row. Outside a template this should also avoid evaluating the
value twice.
gcc/cp/ChangeLog:
PR c++/97975
* constexpr.c (fold_non_dependent_init): Add a tree parameter.
Use it.
* cp-tree.h (fold_non_dependent_init): Add a tree parameter with
a default value.
* typeck2.c (store_init_value): Call fold_non_dependent_expr
only when checking the initializer for constexpr variables.
Call fold_non_dependent_init instead of maybe_constant_init.
gcc/testsuite/ChangeLog:
PR c++/97975
* g++.dg/cpp1z/inline-var8.C: New test.