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  <pola...@redhat.com>

        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&>();
 }

Reply via email to