From 00d19ee130200b063c001723b7c5d074b925a175 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 23 Dec 2009 08:56:00 +0000 Subject: [PATCH] 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 . llvm-svn: 91990 --- clang/include/clang/AST/Stmt.h | 3 +++ clang/lib/AST/DeclGroup.cpp | 1 + clang/lib/AST/Stmt.cpp | 8 ++++++++ clang/test/Index/c-index-crasher-rdar_7487294.c | 13 +++++++++++++ 4 files changed, 25 insertions(+) create mode 100644 clang/test/Index/c-index-crasher-rdar_7487294.c diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 30a4cf7f580a..b58f30e319bf 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/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/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp index 5bdc88173461..434bf00d354e 100644 --- a/clang/lib/AST/DeclGroup.cpp +++ b/clang/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/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index fad80ec0cf23..14f0c8d744d0 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/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/clang/test/Index/c-index-crasher-rdar_7487294.c b/clang/test/Index/c-index-crasher-rdar_7487294.c new file mode 100644 index 000000000000..b01b942fe1d5 --- /dev/null +++ b/clang/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 '}'