On Wed, Sep 30, 2015 at 3:07 PM, David Majnemer via cfe-commits < cfe-commits@lists.llvm.org> wrote:
> Author: majnemer > Date: Wed Sep 30 17:07:43 2015 > New Revision: 248953 > > URL: http://llvm.org/viewvc/llvm-project?rev=248953&view=rev > Log: > [Sema] Don't crash when friending an unqualified templated constructor > > Unqualified templated constructors cannot be friended and our lack of a > diagnostic led to violated invariants. Instead, raise a diagnostic when > processing the friend declaration. > > This fixes PR20251. > > Modified: > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/test/CXX/class/class.friend/p1.cpp > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=248953&r1=248952&r2=248953&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep 30 17:07:43 2015 > @@ -12689,15 +12689,31 @@ NamedDecl *Sema::ActOnFriendFunctionDecl > DC = CurContext; > assert(isa<CXXRecordDecl>(DC) && "friend declaration not in class?"); > } > - > + > if (!DC->isRecord()) { > + int DiagArg = -1; > + switch (D.getName().getKind()) { > + case UnqualifiedId::IK_ConstructorTemplateId: > + case UnqualifiedId::IK_ConstructorName: > + DiagArg = 0; > + break; > + case UnqualifiedId::IK_DestructorName: > + DiagArg = 1; > + break; > + case UnqualifiedId::IK_ConversionFunctionId: > + DiagArg = 2; > + break; > + case UnqualifiedId::IK_Identifier: > + case UnqualifiedId::IK_ImplicitSelfParam: > + case UnqualifiedId::IK_LiteralOperatorId: > + case UnqualifiedId::IK_OperatorFunctionId: > + case UnqualifiedId::IK_TemplateId: > + break; > + llvm_unreachable("Didn't expect this kind of unqualified-id!"); > Is the break followed by unreachable intentional? -- Sean Silva > + } > // This implies that it has to be an operator or function. > - if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName || > - D.getName().getKind() == UnqualifiedId::IK_DestructorName || > - D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) { > - Diag(Loc, diag::err_introducing_special_friend) << > - (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 : > - D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : > 2); > + if (DiagArg >= 0) { > + Diag(Loc, diag::err_introducing_special_friend) << DiagArg; > return nullptr; > } > } > > Modified: cfe/trunk/test/CXX/class/class.friend/p1.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.friend/p1.cpp?rev=248953&r1=248952&r2=248953&view=diff > > ============================================================================== > --- cfe/trunk/test/CXX/class/class.friend/p1.cpp (original) > +++ cfe/trunk/test/CXX/class/class.friend/p1.cpp Wed Sep 30 17:07:43 2015 > @@ -79,3 +79,9 @@ class PreDeclared; > int myoperation(float f) { > return (int) f; > } > + > +template <typename T> > +class B { > + template <typename U> > + friend B<U>() {} // expected-error {{must use a qualified name when > declaring a constructor as a friend}} > +}; > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits