diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index b7ea24790d361c1..2070f3b7bb3a2fa 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -789,9 +789,6 @@ ExprResult Sema::BuildMemberReferenceExpr( ActOnMemberAccessExtraArgs *ExtraArgs) { LookupResult R(*this, NameInfo, LookupMemberName); - if (SS.isInvalid()) - return ExprError(); - // Implicit member accesses. if (!Base) { TypoExpr *TE = nullptr; @@ -826,6 +823,11 @@ ExprResult Sema::BuildMemberReferenceExpr( BaseType = Base->getType(); } + // BuildMemberReferenceExpr expects the nested-name-specifier, if any, to be + // valid. + if (SS.isInvalid()) + return ExprError(); + return BuildMemberReferenceExpr(Base, BaseType, OpLoc, IsArrow, SS, TemplateKWLoc, FirstQualifierInScope, R, TemplateArgs, S, @@ -1745,14 +1747,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXScopeSpec &SS, + tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - Decl *ObjCImpDecl) { - if (SS.isSet() && SS.isInvalid()) - return ExprError(); - + UnqualifiedId &Id, Decl *ObjCImpDecl) { // Warn about the explicit constructor calls Microsoft extension. if (getLangOpts().MicrosoftExt && Id.getKind() == UnqualifiedIdKind::IK_ConstructorName) diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp new file mode 100644 index 000000000000000..ebdae971a929ee0 --- /dev/null +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/basic.lookup.qual.general/p2.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -Wno-unused %s + +struct A { + int y; +}; + +struct B; // expected-note 4{{forward declaration of 'B'}} + +void f(A *a, B *b) { + a->B::x; // expected-error {{incomplete type 'B' named in nested name specifier}} + a->A::x; // expected-error {{no member named 'x' in 'A'}} + a->A::y; + b->B::x; // expected-error {{member access into incomplete type 'B'}} + b->A::x; // expected-error {{member access into incomplete type 'B'}} + b->A::y; // expected-error {{member access into incomplete type 'B'}} +}