[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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248953 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2015-09-30 22:07:43 +00:00
parent cb96b824e6
commit 20061ec162
2 changed files with 29 additions and 7 deletions

View File

@ -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;
}
}

View File

@ -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}}
};