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.

llvm-svn: 97463
This commit is contained in:
Douglas Gregor 2010-03-01 18:27:54 +00:00
parent 8bc2a70dfe
commit 604c30299d
5 changed files with 66 additions and 6 deletions

View 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,

View 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 ')'

View 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;
}

View 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;

View File

@ -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);
}
};
}
}