OK.
On Tue, Feb 14, 2017 at 11:40 AM, Marek Polacek <pola...@redhat.com> wrote: > 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