[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