On 02/27/2018 02:13 PM, Marek Polacek wrote:
My recent change introducing cxx_constant_init caused this code
template <class> class A {
static const long b = 0;
static const unsigned c = (b);
};
to be rejected. The reason is that force_paren_expr turns "b" into "*(const
long int &) &b", where the former is not value-dependent but the latter is
value-dependent. So when we get to maybe_constant_init_1:
5147 if (!is_nondependent_static_init_expression (t))
5148 /* Don't try to evaluate it. */;
it's not evaluated and we get the non-constant initialization error.
(Before we'd always evaluated the expression.)
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2018-02-27 Marek Polacek <[email protected]>
PR c++/84582
* semantics.c (force_paren_expr): Avoid creating a static cast
when processing a template.
* g++.dg/cpp1z/static1.C: New test.
* g++.dg/template/static37.C: New test.
diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index 35569d0cb0d..b48de2df4e2 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -1697,7 +1697,7 @@ force_paren_expr (tree expr)
expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
else if (VAR_P (expr) && DECL_HARD_REGISTER (expr))
/* We can't bind a hard register variable to a reference. */;
- else
+ else if (!processing_template_decl)
Hmm, this means that we forget about the parentheses in a template. I'm
surprised that this didn't break anything in the testsuite. In
particular, auto-fn15.C. I've attached an addition to auto-fn15.C to
catch this issue.
Can we use PAREN_EXPR instead of the static_cast in a template?
Jason
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn15.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn15.C
index ba9f3579f62..0db428f7270 100644
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn15.C
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn15.C
@@ -22,6 +22,8 @@ template <class T>
decltype(auto) h5(T t) { return t.i; }
template <class T>
decltype(auto) h6(T t) { return (t.i); }
+template <class T>
+decltype(auto) h7(T t) { return (i); }
int main()
{
@@ -48,4 +50,5 @@ int main()
same_type<decltype(h4()),int&>();
same_type<decltype(h5(a)),int>();
same_type<decltype(h6(a)),int&>();
+ same_type<decltype(h7(a)),int&>();
}