aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/Decl.cpp16
-rw-r--r--test/Sema/PR2923.c12
2 files changed, 25 insertions, 3 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 3713776298..dbc92f414f 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -176,16 +176,26 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
return 0;
}
-unsigned FunctionDecl::getNumParams() const {
- const FunctionType *FT = getType()->getAsFunctionType();
+// Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams()
+static unsigned getNumTypeParams(QualType T) {
+ const FunctionType *FT = T->getAsFunctionType();
if (isa<FunctionTypeNoProto>(FT))
return 0;
return cast<FunctionTypeProto>(FT)->getNumArgs();
}
+unsigned FunctionDecl::getNumParams() const {
+ // Can happen if a FunctionDecl is declared using typeof(some_other_func) bar;
+ if (!ParamInfo)
+ return 0;
+
+ return getNumTypeParams(getType());
+}
+
void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
assert(ParamInfo == 0 && "Already has param info!");
- assert(NumParams == getNumParams() && "Parameter count mismatch!");
+ assert(NumParams == getNumTypeParams(getType()) &&
+ "Parameter count mismatch!");
// Zero params -> null pointer.
if (NumParams) {
diff --git a/test/Sema/PR2923.c b/test/Sema/PR2923.c
new file mode 100644
index 0000000000..dac25a2506
--- /dev/null
+++ b/test/Sema/PR2923.c
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify
+
+// Test for absence of crash reported in PR 2923:
+//
+// http://llvm.org/bugs/show_bug.cgi?id=2923
+//
+// Previously we had a crash when deallocating the FunctionDecl for 'bar'
+// because FunctionDecl::getNumParams() just used the type of foo to determine
+// the number of parameters it has. In the case of 'bar' there are no
+// ParmVarDecls.
+int foo(int x, int y) { return x + y; }
+extern typeof(foo) bar;