diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-07-13 00:10:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-07-13 00:10:04 +0000 |
commit | 669eed8d676458c701f45f7fd686f01de2dee53b (patch) | |
tree | f1207aca112b5472c4f646fd2c9c7ae99403ab68 /lib/Sema/SemaTemplate.cpp | |
parent | dd41ed59cf7aefabd40bf766d8fcc7ebd759c8e5 (diff) |
Provide a special diagnostic for attempts to explicitly specialize
class templates within class scope (which is ill-formed), and recover
by dropping the explicit specialization entirely. Fixes the infinite
loop in PR7622.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108217 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 31823c72ea..7cc4317845 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4549,13 +4549,21 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { } /// \brief Check the scope of an explicit instantiation. -static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, +/// +/// \returns true if a serious error occurs, false otherwise. +static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, SourceLocation InstLoc, bool WasQualifiedName) { DeclContext *ExpectedContext = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext(); DeclContext *CurContext = S.CurContext->getLookupContext(); + if (CurContext->isRecord()) { + S.Diag(InstLoc, diag::err_explicit_instantiation_in_class) + << D; + return true; + } + // C++0x [temp.explicit]p2: // An explicit instantiation shall appear in an enclosing namespace of its // template. @@ -4576,7 +4584,7 @@ static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, : diag::warn_explicit_instantiation_out_of_scope_0x) << D; S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); - return; + return false; } // C++0x [temp.explicit]p2: @@ -4585,10 +4593,10 @@ static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, // its template is declared or, if that namespace is inline (7.3.1), any // namespace from its enclosing namespace set. if (WasQualifiedName) - return; + return false; if (CurContext->Equals(ExpectedContext)) - return; + return false; S.Diag(InstLoc, S.getLangOptions().CPlusPlus0x? @@ -4596,6 +4604,7 @@ static void CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) << D << ExpectedContext; S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); + return false; } /// \brief Determine whether the given scope specifier has a template-id in it. @@ -4698,8 +4707,9 @@ Sema::ActOnExplicitInstantiation(Scope *S, // namespace of its template. [...] // // This is C++ DR 275. - CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc, - SS.isSet()); + if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc, + SS.isSet())) + return true; ClassTemplateSpecializationDecl *Specialization = 0; |