diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-12 16:00:01 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-12 16:00:01 +0000 |
commit | 57265e35292897e383d70bbd1d552209fac37b39 (patch) | |
tree | e43845efefde3cd88483e9e0438d9c4af3a7423b /lib/Sema/SemaTemplate.cpp | |
parent | 7683a3ffbbcb2950584bc85bb27ac921a3e5524e (diff) |
Fix a crash-on-invalid involving name lookup of tag names, where we
ended up finding a function template that we didn't expect. Recover
more gracefully, and fix a similar issue for class templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 285495a41b..d1577a5ab6 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -748,10 +748,12 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, LookupName(Previous, S); } - assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?"); + if (Previous.isAmbiguous()) + return true; + NamedDecl *PrevDecl = 0; if (Previous.begin() != Previous.end()) - PrevDecl = *Previous.begin(); + PrevDecl = (*Previous.begin())->getUnderlyingDecl(); // If there is a previous declaration with the same name, check // whether this is a valid redeclaration. @@ -804,7 +806,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, } } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) PrevDecl = PrevClassTemplate = 0; - + if (PrevClassTemplate) { // Ensure that the template parameter lists are compatible. if (!TemplateParameterListsAreEqual(TemplateParams, @@ -861,9 +863,15 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, TPC_ClassTemplate)) Invalid = true; - // FIXME: If we had a scope specifier, we better have a previous template - // declaration! - + if (SS.isSet()) { + // If the name of the template was qualified, we must be defining the + // template out-of-line. + if (!SS.isInvalid() && !Invalid && !PrevClassTemplate && + !(TUK == TUK_Friend && CurContext->isDependentContext())) + Diag(NameLoc, diag::err_member_def_does_not_match) + << Name << SemanticContext << SS.getRange(); + } + CXXRecordDecl *NewClass = CXXRecordDecl::Create(Context, Kind, SemanticContext, NameLoc, Name, KWLoc, PrevClassTemplate? |