aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Stmt.h3
-rw-r--r--lib/AST/DeclGroup.cpp1
-rw-r--r--lib/AST/Stmt.cpp8
-rw-r--r--test/Index/c-index-crasher-rdar_7487294.c13
4 files changed, 25 insertions, 0 deletions
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 '}'