diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c5e41445d8be057f4069e63e4481b744f4a65a02..0dd1e0a6f4296770dce65877660bbb87058f0d00 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2274,8 +2274,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // name, then the code is ill-formed; this interpretation is // reinforced by the NAD status of core issue 635. TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Next); - if ((DSContext == DSC_top_level || - (DSContext == DSC_class && DS.isFriendSpecified())) && + if ((DSContext == DSC_top_level || DSContext == DSC_class) && TemplateId->Name && Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) { if (isConstructorDeclarator()) { @@ -2325,8 +2324,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // If we're in a context where the identifier could be a class name, // check whether this is a constructor declaration. - if ((DSContext == DSC_top_level || - (DSContext == DSC_class && DS.isFriendSpecified())) && + if ((DSContext == DSC_top_level || DSContext == DSC_class) && Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(), &SS)) { if (isConstructorDeclarator()) @@ -4445,8 +4443,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { else if (D.getCXXScopeSpec().isSet()) AllowConstructorName = (D.getContext() == Declarator::FileContext || - (D.getContext() == Declarator::MemberContext && - D.getDeclSpec().isFriendSpecified())); + D.getContext() == Declarator::MemberContext); else AllowConstructorName = (D.getContext() == Declarator::MemberContext); diff --git a/test/CXX/special/class.ctor/p1.cpp b/test/CXX/special/class.ctor/p1.cpp index 4d821841e47fdf9b812b14c8a597726007265beb..23ceebad3b3daa4bf4cbb1b77d31352097265539 100644 --- a/test/CXX/special/class.ctor/p1.cpp +++ b/test/CXX/special/class.ctor/p1.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// expected-no-diagnostics + struct X0 { struct type { }; @@ -41,3 +41,7 @@ template<typename T> X1<T>::X1() { } template<typename T> (X1<T>::X1)(double) { } template<typename T> X1<T> X1<T>::f1(int) { return 0; } template<typename T> X1<T> (X1<T>::f1)(type) { return 0; } + +class A { + A::A(); // expected-error{{extra qualification on member 'A'}} +}; diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 6b43ea205af3fc31bf615c712d57f2e4da5393dc..449e24b03b68fbd1c29c21c99d2bc6977a16fe1b 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -204,3 +204,7 @@ struct PR11150 { void f() { int __except = 0; } void ::f(); // expected-warning{{extra qualification on member 'f'}} + +class C { + C::C(); // expected-warning{{extra qualification on member 'C'}} +};