In both these PRs the problem is the same: we have a non-dependent incomplete
postfix expression in a template, and since r245223 we treat it as dependent
(with a pedwarn), and erase its type.  For OVERLOADs this is bad because we'll 
hit
this in tsubst_copy:
    case OVERLOAD:
      /* An OVERLOAD will always be a non-dependent overload set; an
         overload set from function scope will just be represented with an
         IDENTIFIER_NODE, and from class scope with a BASELINK.  */
      gcc_assert (!uses_template_parms (t)); 

and for VAR_DECLs it's bad because the subsequent code cannot cope with its
null type.  Jason suggested to only clobber EXPR_P trees and said that these
could stay dependent.  But only resetting the type for EXPR_Ps would mean that
we'd print the incomplete type diagnostics twice, so I decided to do this
instead.  It's all invalid code, so it doesn't seem to be a problem to skip the
dependent_p = true; line and resetting the scope.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-02-14  Marek Polacek  <pola...@redhat.com>

        PR c++/79420
        PR c++/79463
        * parser.c (cp_parser_postfix_dot_deref_expression): Avoid
        clobbering if the postfix expression isn't an EXPR_P.

        * g++.dg/cpp1y/pr79463.C: New.
        * g++.dg/template/incomplete10.C: New.
        * g++.dg/template/incomplete9.C: New.

diff --git gcc/cp/parser.c gcc/cp/parser.c
index ce45bba..ccafefd 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -7331,7 +7331,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
                   (scope, current_class_type))))
        {
          scope = complete_type (scope);
-         if (!COMPLETE_TYPE_P (scope))
+         if (!COMPLETE_TYPE_P (scope)
+             /* Avoid clobbering e.g. OVERLOADs or DECLs.  */
+             && EXPR_P (postfix_expression))
            {
              /* In a template, be permissive by treating an object expression
                 of incomplete type as dependent (after a pedwarn).  */
diff --git gcc/testsuite/g++.dg/cpp1y/pr79463.C 
gcc/testsuite/g++.dg/cpp1y/pr79463.C
index e69de29..fdf668b 100644
--- gcc/testsuite/g++.dg/cpp1y/pr79463.C
+++ gcc/testsuite/g++.dg/cpp1y/pr79463.C
@@ -0,0 +1,7 @@
+// PR c++/79463
+// { dg-options "-g" }
+// { dg-do compile { target c++14 } }
+
+struct A;
+extern A a; // { dg-error "'a' has incomplete type" }
+template < int > int f = a.x;
diff --git gcc/testsuite/g++.dg/template/incomplete10.C 
gcc/testsuite/g++.dg/template/incomplete10.C
index e69de29..f0b406d 100644
--- gcc/testsuite/g++.dg/template/incomplete10.C
+++ gcc/testsuite/g++.dg/template/incomplete10.C
@@ -0,0 +1,13 @@
+// PR c++/79420
+
+struct S;
+extern S s; // { dg-error "'s' has incomplete type" }
+template<int> int f ()
+{
+  return s.x;
+}
+
+void g ()
+{
+  f<0> ();
+}
diff --git gcc/testsuite/g++.dg/template/incomplete9.C 
gcc/testsuite/g++.dg/template/incomplete9.C
index e69de29..9e03232 100644
--- gcc/testsuite/g++.dg/template/incomplete9.C
+++ gcc/testsuite/g++.dg/template/incomplete9.C
@@ -0,0 +1,11 @@
+// PR c++/79420
+
+template<int> int f ()
+{
+  return f.x; // { dg-error "overloaded function with no contextual type 
information" }
+}
+
+void g ()
+{
+  f<0> ();
+}

        Marek

Reply via email to