diff options
-rw-r--r-- | lib/AST/Decl.cpp | 16 | ||||
-rw-r--r-- | test/Sema/PR2923.c | 12 |
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; |