[analyzer] Proactively avoid inlining vararg functions and blocks until we properly support them.

llvm-svn: 150207
This commit is contained in:
Ted Kremenek 2012-02-09 21:59:52 +00:00
parent 29082a5f1d
commit 482080a621
2 changed files with 54 additions and 1 deletions

View File

@ -309,6 +309,30 @@ ExprEngine::invalidateArguments(ProgramStateRef State,
}
// For now, skip inlining variadic functions.
// We also don't inline blocks.
static bool shouldInlineCall(const CallExpr *CE, ExprEngine &Eng) {
if (!Eng.getAnalysisManager().shouldInlineCall())
return false;
QualType callee = CE->getCallee()->getType();
const FunctionProtoType *FT = 0;
if (const PointerType *PT = callee->getAs<PointerType>())
FT = dyn_cast<FunctionProtoType>(PT->getPointeeType());
else if (const BlockPointerType *BT = callee->getAs<BlockPointerType>()) {
// FIXME: inline blocks.
// FT = dyn_cast<FunctionProtoType>(BT->getPointeeType());
(void) BT;
return false;
}
// If we have no prototype, assume the function is okay.
if (!FT)
return true;
// Skip inlining of variadic functions.
return !FT->isVariadic();
}
void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
ExplodedNodeSet &dst) {
// Perform the previsit of the CallExpr.
@ -325,7 +349,7 @@ void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
: Eng(eng), CE(ce) {}
virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) {
// Should we inline the call?
if (Eng.getAnalysisManager().shouldInlineCall() &&
if (shouldInlineCall(CE, Eng) &&
Eng.InlineCall(Dst, CE, Pred)) {
return;
}

View File

@ -0,0 +1,29 @@
// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core -analyzer-inline-call -analyzer-store region -verify %s
// For now, don't inline varargs.
void foo(int *x, ...) {
*x = 1;
}
void bar() {
foo(0, 2); // no-warning
}
// For now, don't inline vararg blocks.
void (^baz)(int *x, ...) = ^(int *x, ...) { *x = 1; };
void taz() {
baz(0, 2); // no-warning
}
// For now, don't inline blocks.
void (^qux)(int *p) = ^(int *p) { *p = 1; };
void test_qux() {
qux(0); // no-warning
}
void test_analyzer_is_running() {
int *p = 0;
*p = 0xDEADBEEF; // expected-warning {{null}}
}