[cfe-commits] r101040 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.decls/temp.mem/p1.cpp test/SemaTemplate/class-template-decl.cpp test/SemaTemplate/friend.cpp
Douglas Gregor
dgregor at apple.com
Mon Apr 12 09:00:02 PDT 2010
Author: dgregor
Date: Mon Apr 12 11:00:01 2010
New Revision: 101040
URL: http://llvm.org/viewvc/llvm-project?rev=101040&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp
cfe/trunk/test/SemaTemplate/class-template-decl.cpp
cfe/trunk/test/SemaTemplate/friend.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 12 11:00:01 2010
@@ -2200,6 +2200,8 @@
"conversion function from %0 to %1 invokes a deleted function">;
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
+def err_missing_qualified_for_redecl : Error<
+ "must qualify the name %0 to declare %q1 in this scope">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
def err_invalid_declarator_global_scope : Error<
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Apr 12 11:00:01 2010
@@ -4948,8 +4948,7 @@
}
if (!Previous.empty()) {
- assert(Previous.isSingleResult());
- NamedDecl *PrevDecl = Previous.getFoundDecl();
+ NamedDecl *PrevDecl = (*Previous.begin())->getUnderlyingDecl();
if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
// If this is a use of a previous tag, or if the tag is already declared
// in the same scope (so that the definition/declaration completes or
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Apr 12 11:00:01 2010
@@ -748,10 +748,12 @@
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 @@
}
} 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 @@
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?
Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p1.cpp Mon Apr 12 11:00:01 2010
@@ -19,17 +19,17 @@
template<typename T>
struct X {
template<typename Y>
- struct Y { };
+ struct Y1 { }; //
};
template<>
struct X<float> {
template<typename Y>
- struct Y { };
+ struct Y1 { };
};
template<typename T, typename U>
- struct Z : public X<T>::template Y<U> { };
+ struct Z : public X<T>::template Y1<U> { };
Z<float, int> z0;
}
Modified: cfe/trunk/test/SemaTemplate/class-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/class-template-decl.cpp?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/class-template-decl.cpp (original)
+++ cfe/trunk/test/SemaTemplate/class-template-decl.cpp Mon Apr 12 11:00:01 2010
@@ -51,3 +51,8 @@
}
template<typename T> class X1 { } var; // expected-error{{declared as a template}}
+
+namespace M {
+}
+
+template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
Modified: cfe/trunk/test/SemaTemplate/friend.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend.cpp?rev=101040&r1=101039&r2=101040&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/friend.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend.cpp Mon Apr 12 11:00:01 2010
@@ -12,3 +12,22 @@
struct C0 {
friend struct A<int>;
};
+
+namespace PR6770 {
+ namespace N {
+ int f1(int);
+ }
+ using namespace N;
+
+ namespace M {
+ float f1(float);
+ }
+ using M::f1;
+
+ template<typename T> void f1(T, T);
+ template <class T>
+ void f() {
+ friend class f; // expected-error{{'friend' used outside of class}}
+ friend class f1; // expected-error{{ 'friend' used outside of class}}
+ }
+}
More information about the cfe-commits
mailing list