summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp30
-rw-r--r--clang/test/CXX/class/class.friend/p1.cpp6
2 files changed, 29 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 07bf8567194..7617c92e4e4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -12689,15 +12689,31 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
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;
}
}
diff --git a/clang/test/CXX/class/class.friend/p1.cpp b/clang/test/CXX/class/class.friend/p1.cpp
index 96701b3b05a..b83dfa36cd3 100644
--- a/clang/test/CXX/class/class.friend/p1.cpp
+++ b/clang/test/CXX/class/class.friend/p1.cpp
@@ -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}}
+};
OpenPOWER on IntegriCloud