From: Ted Kremenek Date: Wed, 23 Dec 2009 08:56:00 +0000 (+0000) Subject: Add 'DeclStmt::DoDestroy()' which doesn't actually recurse over its child expressions... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7809d49413febf078d0503753987fe9f6061a68;p=clang Add 'DeclStmt::DoDestroy()' which doesn't actually recurse over its child expressions (via StmtIterator), as those expressions are owned by the Decls and Types (which are destroyed elsewhere). This fixes a crasher reported in . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91990 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 30a4cf7f58..b58f30e319 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -294,6 +294,9 @@ class DeclStmt : public Stmt { DeclGroupRef DG; SourceLocation StartLoc, EndLoc; +protected: + virtual void DoDestroy(ASTContext &Ctx); + public: DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp index 5bdc881734..434bf00d35 100644 --- a/lib/AST/DeclGroup.cpp +++ b/lib/AST/DeclGroup.cpp @@ -32,6 +32,7 @@ DeclGroup::DeclGroup(unsigned numdecls, Decl** decls) : NumDecls(numdecls) { } void DeclGroup::Destroy(ASTContext& C) { + // Decls are destroyed by the DeclContext. this->~DeclGroup(); C.Deallocate((void*) this); } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index fad80ec0cf..14f0c8d744 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -426,6 +426,14 @@ Stmt::child_iterator DeclStmt::child_end() { return StmtIterator(DG.end(), DG.end()); } +void DeclStmt::DoDestroy(ASTContext &C) { + // Don't use StmtIterator to iterate over the Decls, as that can recurse + // into VLA size expressions (which are owned by the VLA). Further, Decls + // are owned by the DeclContext, and will be destroyed with them. + if (DG.isDeclGroup()) + DG.getDeclGroup().Destroy(C); +} + // NullStmt Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); } Stmt::child_iterator NullStmt::child_end() { return child_iterator(); } diff --git a/test/Index/c-index-crasher-rdar_7487294.c b/test/Index/c-index-crasher-rdar_7487294.c new file mode 100644 index 0000000000..b01b942fe1 --- /dev/null +++ b/test/Index/c-index-crasher-rdar_7487294.c @@ -0,0 +1,13 @@ +// RUN: c-index-test -test-load-source local %s 2>&1 | FileCheck %s + +// This is invalid source. Previously a double-free caused this +// example to crash c-index-test. + +int foo(int x) { + int y[x * 3]; + help +}; + +// CHECK: 8:3: error: use of undeclared identifier 'help' +// CHECK: help +// CHECK: 12:102: error: expected '}'