r248953 - [Sema] Don't crash when friending an unqualified templated constructor
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 30 15:07:43 PDT 2015
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!");
+ }
// 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}}
+};
More information about the cfe-commits
mailing list