aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-01 18:27:54 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-01 18:27:54 +0000
commit00225547b51b42f7400eed36475b6672418a1151 (patch)
tree85987be0a714e7b23babb929ca5a5f62c7293232
parent2e0a715595a21adeb7172995df59317741301aa3 (diff)
Robustify instantiation of templates when there are errors in the
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
-rw-r--r--include/clang/Parse/Action.h6
-rw-r--r--lib/Parse/ParseDecl.cpp8
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--test/SemaTemplate/instantiate-invalid.cpp52
5 files changed, 66 insertions, 6 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 469816caa5..f211b5ca3a 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -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,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 4405dcb974..8a32f35b64 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -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 ')'
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 0fe9b7fa21..da192dd887 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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;
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3d9899e112..0f7bae835f 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -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
index 0000000000..b8a59015c0
--- /dev/null
+++ b/test/SemaTemplate/instantiate-invalid.cpp
@@ -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);
+ }
+};
+}
+}