forked from OSchip/llvm-project
[analyzer] Proactively avoid inlining vararg functions and blocks until we properly support them.
llvm-svn: 150207
This commit is contained in:
parent
29082a5f1d
commit
482080a621
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
Loading…
Reference in New Issue