diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-09-30 22:07:43 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-09-30 22:07:43 +0000 |
commit | e14d5304973f9513b4cd70659e60efb7986b6040 (patch) | |
tree | 8258dbcdd44e03c784932d61fbbfe2e481c20144 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 2dfd74f758da92d7c2ebd7590722092001d5622e (diff) | |
download | bcm5719-llvm-e14d5304973f9513b4cd70659e60efb7986b6040.tar.gz bcm5719-llvm-e14d5304973f9513b4cd70659e60efb7986b6040.zip |
[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.
llvm-svn: 248953
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 30 |
1 files changed, 23 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; } } |