]> granicus.if.org Git - clang/commitdiff
Robustify instantiation of templates when there are errors in the
authorDouglas Gregor <dgregor@apple.com>
Mon, 1 Mar 2010 18:27:54 +0000 (18:27 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 1 Mar 2010 18:27:54 +0000 (18:27 +0000)
template definition. Do this both by being more tolerant of errors in
our asserts and by not dropping a variable declaration completely when
its initializer is ill-formed. Fixes the crash-on-invalid in PR6375,
but not the original issue.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97463 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseDecl.cpp
lib/Sema/Sema.h
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-invalid.cpp [new file with mode: 0644]

index 469816caa5528f3a528c09d562ec8920077b0571..f211b5ca3a69d89474f77dc5c62121e6013355d7 100644 (file)
@@ -503,6 +503,12 @@ public:
     return;
   }
 
+  /// \brief Note that the given declaration had an initializer that could not
+  /// be parsed.
+  virtual void ActOnInitializerError(DeclPtrTy Dcl) {
+    return;
+  }
+  
   /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
   /// gives the actions implementation a chance to process the group as a whole.
   virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec& DS,
index 4405dcb974a8129291892d8e52ee753e6947991c..8a32f35b64b0c3ca354a64fd9f2d21ab449d54a1 100644 (file)
@@ -564,10 +564,10 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
       }
 
       if (Init.isInvalid()) {
-        SkipUntil(tok::semi, true, true);
-        return DeclPtrTy();
-      }
-      Actions.AddInitializerToDecl(ThisDecl, move(Init));
+        SkipUntil(tok::comma, true, true);
+        Actions.ActOnInitializerError(ThisDecl);
+      } else
+        Actions.AddInitializerToDecl(ThisDecl, move(Init));
     }
   } else if (Tok.is(tok::l_paren)) {
     // Parse C++ direct initializer: '(' expression-list ')'
index 0fe9b7fa2187bd9f20d9eb341dd17b6927f8e82a..da192dd887957565a9c7e64a13000cdc2743cea7 100644 (file)
@@ -3413,7 +3413,8 @@ public:
 
     Decl *getInstantiationOf(const Decl *D) {
       Decl *Result = LocalDecls[D];
-      assert(Result && "declaration was not instantiated in this scope!");
+      assert((Result || D->isInvalidDecl()) && 
+             "declaration was not instantiated in this scope!");
       return Result;
     }
 
index 3d9899e112eada1f01719cf1226ba3506754cf9e..0f7bae835fde469d371e8be23b272f123eba904d 100644 (file)
@@ -2323,7 +2323,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
     }
 
     // UsingShadowDecls can instantiate to nothing because of using hiding.
-    assert((Result || isa<UsingShadowDecl>(D))
+    assert((Result || isa<UsingShadowDecl>(D) || D->isInvalidDecl() ||
+            cast<Decl>(ParentDC)->isInvalidDecl())
            && "Unable to find instantiation of declaration!");
 
     D = Result;
diff --git a/test/SemaTemplate/instantiate-invalid.cpp b/test/SemaTemplate/instantiate-invalid.cpp
new file mode 100644 (file)
index 0000000..b8a5901
--- /dev/null
@@ -0,0 +1,52 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+namespace PR6375 {
+  template<class Conv> class rasterizer_sl_clip Conv::xi(x2), Conv::yi(y2));
+namespace agg
+{
+       template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
+       {
+               template<class Scanline> bool sweep_scanline(Scanline& sl)
+               {
+                       unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+                       while(num_cells) { }
+               }
+       }
+    class scanline_u8 {}
+    template<class PixelFormat> class renderer_base { }
+}
+    template<class Rasterizer, class Scanline, class BaseRenderer, class ColorT>
+    void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, const ColorT& color)
+    {
+            while(ras.sweep_scanline(sl))
+            {
+        }
+    };
+namespace agg
+{
+    struct rgba8
+    {
+    };
+    template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+    void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+    {
+        unsigned i;
+            render_scanlines_aa_solid(ras, sl, r, c.color(i));
+        }
+    template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl
+    {
+        const ColorT& color(unsigned i) const { return *m_colors[i]; }
+    }
+class the_application : public agg::platform_support
+{
+    agg::rbox_ctrl<agg::rgba8> m_polygons;
+    virtual void on_init()
+    {
+        typedef agg::renderer_base<pixfmt_type> base_ren_type;
+        base_ren_type ren_base(pf);
+        agg::scanline_u8 sl;
+        agg::rasterizer_scanline_aa<> ras;
+        agg::render_ctrl(ras, sl, ren_base, m_polygons);
+    }
+};
+}
+}