[cfe-commits] r108372 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/deduction-crash.cpp

Douglas Gregor dgregor at apple.com
Wed Jul 14 16:14:13 PDT 2010


Author: dgregor
Date: Wed Jul 14 18:14:12 2010
New Revision: 108372

URL: http://llvm.org/viewvc/llvm-project?rev=108372&view=rev
Log:
When there are extra or missing template parameter lists in a template
definition, we're likely going to end up breaking the invariants of
the template system, e.g., that the depths of template parameter lists
match up with the nesting template of the template. So, make sure we
mark such ill-formed declarations as invalid or don't even build them
at all.


Added:
    cfe/trunk/test/SemaTemplate/deduction-crash.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=108372&r1=108371&r2=108372&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Jul 14 18:14:12 2010
@@ -2956,7 +2956,8 @@
                                           TemplateParameterList **ParamLists,
                                           unsigned NumParamLists,
                                           bool IsFriend,
-                                          bool &IsExplicitSpecialization);
+                                          bool &IsExplicitSpecialization,
+                                          bool &Invalid);
 
   DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                 SourceLocation KWLoc, CXXScopeSpec &SS,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=108372&r1=108371&r2=108372&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Jul 14 18:14:12 2010
@@ -2572,6 +2572,7 @@
   // determine whether we have a template or a template specialization.
   bool isExplicitSpecialization = false;
   unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
+  bool Invalid = false;
   if (TemplateParameterList *TemplateParams
         = MatchTemplateParametersToScopeSpecifier(
                                   D.getDeclSpec().getSourceRange().getBegin(),
@@ -2579,7 +2580,8 @@
                         (TemplateParameterList**)TemplateParamLists.get(),
                                                    TemplateParamLists.size(),
                                                   /*never a friend*/ false,
-                                                  isExplicitSpecialization)) {
+                                                  isExplicitSpecialization,
+                                                  Invalid)) {
     // All but one template parameter lists have been matching.
     --NumMatchedTemplateParamLists;
 
@@ -2606,7 +2608,7 @@
   VarDecl *NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
                                    II, R, TInfo, SC, SCAsWritten);
 
-  if (D.isInvalidType())
+  if (D.isInvalidType() || Invalid)
     NewVD->setInvalidDecl();
 
   SetNestedNameSpecifier(NewVD, D);
@@ -3156,6 +3158,7 @@
   bool isExplicitSpecialization = false;
   bool isFunctionTemplateSpecialization = false;
   unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
+  bool Invalid = false;
   if (TemplateParameterList *TemplateParams
         = MatchTemplateParametersToScopeSpecifier(
                                   D.getDeclSpec().getSourceRange().getBegin(),
@@ -3163,7 +3166,8 @@
                            (TemplateParameterList**)TemplateParamLists.get(),
                                                   TemplateParamLists.size(),
                                                   isFriend,
-                                                  isExplicitSpecialization)) {
+                                                  isExplicitSpecialization,
+                                                  Invalid)) {
     // All but one template parameter lists have been matching.
     --NumMatchedTemplateParamLists;
 
@@ -3214,6 +3218,12 @@
                         (TemplateParameterList**)TemplateParamLists.release());
   }
 
+  if (Invalid) {
+    NewFD->setInvalidDecl();
+    if (FunctionTemplate)
+      FunctionTemplate->setInvalidDecl();
+  }
+  
   // C++ [dcl.fct.spec]p5:
   //   The virtual specifier shall only be used in declarations of
   //   nonstatic class member functions that appear within a
@@ -5037,19 +5047,24 @@
   // FIXME: Check explicit specializations more carefully.
   bool isExplicitSpecialization = false;
   unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
+  bool Invalid = false;
   if (TUK != TUK_Reference) {
     if (TemplateParameterList *TemplateParams
           = MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
                         (TemplateParameterList**)TemplateParameterLists.get(),
                                               TemplateParameterLists.size(),
                                                     TUK == TUK_Friend,
-                                                    isExplicitSpecialization)) {
+                                                    isExplicitSpecialization,
+                                                    Invalid)) {
       // All but one template parameter lists have been matching.
       --NumMatchedTemplateParamLists;
 
       if (TemplateParams->size() > 0) {
         // This is a declaration or definition of a class template (which may
         // be a member of another template).
+        if (Invalid)
+          return DeclPtrTy();
+        
         OwnedDecl = false;
         DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
                                                SS, Name, NameLoc, Attr,
@@ -5069,7 +5084,6 @@
   DeclContext *SearchDC = CurContext;
   DeclContext *DC = CurContext;
   bool isStdBadAlloc = false;
-  bool Invalid = false;
 
   RedeclarationKind Redecl = ForRedeclaration;
   if (TUK == TUK_Friend || TUK == TUK_Reference)

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=108372&r1=108371&r2=108372&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jul 14 18:14:12 2010
@@ -1233,7 +1233,8 @@
                                           TemplateParameterList **ParamLists,
                                               unsigned NumParamLists,
                                               bool IsFriend,
-                                              bool &IsExplicitSpecialization) {
+                                              bool &IsExplicitSpecialization,
+                                              bool &Invalid) {
   IsExplicitSpecialization = false;
   
   // Find the template-ids that occur within the nested-name-specifier. These
@@ -1311,6 +1312,7 @@
              diag::err_template_spec_needs_template_parameters)
           << TemplateId
           << SS.getRange();
+        Invalid = true;
       } else {
         Diag(SS.getRange().getBegin(), diag::err_template_spec_needs_header)
           << SS.getRange()
@@ -1373,7 +1375,13 @@
           << ExplicitSpecializationsInSpecifier.back();
         ExplicitSpecializationsInSpecifier.pop_back();
       }
-        
+
+      // We have a template parameter list with no corresponding scope, which 
+      // means that the resulting template declaration can't be instantiated
+      // properly (we'll end up with dependent nodes when we shouldn't).
+      if (!isExplicitSpecHeader)
+        Invalid = true;
+      
       ++Idx;
     }
   }
@@ -3622,12 +3630,17 @@
   // template.
   // FIXME: We probably shouldn't complain about these headers for
   // friend declarations.
+  bool Invalid = false;
   TemplateParameterList *TemplateParams
     = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, SS,
                         (TemplateParameterList**)TemplateParameterLists.get(),
                                               TemplateParameterLists.size(),
                                               TUK == TUK_Friend,
-                                              isExplicitSpecialization);
+                                              isExplicitSpecialization,
+                                              Invalid);
+  if (Invalid)
+    return true;
+    
   unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
   if (TemplateParams)
     --NumMatchedTemplateParamLists;

Added: cfe/trunk/test/SemaTemplate/deduction-crash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/deduction-crash.cpp?rev=108372&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/deduction-crash.cpp (added)
+++ cfe/trunk/test/SemaTemplate/deduction-crash.cpp Wed Jul 14 18:14:12 2010
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1| FileCheck %s
+
+// PR7511
+
+// Note that the error count below doesn't matter. We just want to
+// make sure that the parser doesn't crash.
+// CHECK: 16 errors
+template<a>
+struct int_;
+
+template<a>
+template<int,typename T1,typename>
+struct ac
+{
+  typedef T1 ae
+};
+
+template<class>struct aaa
+{
+  typedef ac<1,int,int>::ae ae
+};
+
+template<class>
+struct state_machine
+{
+  typedef aaa<int>::ae aaa;
+  int start()
+  {
+    ant(0);
+  }
+  
+  template<class>
+  struct region_processing_helper
+  {
+    template<class,int=0>
+    struct In;
+    
+    template<int my>
+    struct In<a::int_<aaa::a>,my>;
+        
+    template<class Event>
+    int process(Event)
+    {
+      In<a::int_<0> > a;
+    }
+  }
+  template<class Event>
+  int ant(Event)
+  {
+    region_processing_helper<int>* helper;
+    helper->process(0)
+  }
+};
+
+int a()
+{
+  state_machine<int> p;
+  p.ant(0);
+}





More information about the cfe-commits mailing list