[analyzer] Do not report use of undef on "return foo();" when the return type is void.

Fixes a false positive found by analyzing LLVM code base.

llvm-svn: 163750
This commit is contained in:
Anna Zaks 2012-09-12 22:57:40 +00:00
parent 75cfbb60a8
commit 5d2964e770
4 changed files with 39 additions and 0 deletions

View File

@ -293,6 +293,9 @@ public:
/// of some kind.
static bool isCallStmt(const Stmt *S);
/// \brief Returns the result type of a function, method declaration.
static QualType getDeclaredResultType(const Decl *D);
// Iterator access to formal parameters and their types.
private:
typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;

View File

@ -16,6 +16,7 @@
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@ -41,6 +42,19 @@ void ReturnUndefChecker::checkPreStmt(const ReturnStmt *RS,
if (!C.getState()->getSVal(RetE, C.getLocationContext()).isUndef())
return;
// "return;" is modeled to evaluate to an UndefinedValue. Allow UndefinedValue
// to be returned in functions returning void to support the following pattern:
// void foo() {
// return;
// }
// void test() {
// return foo();
// }
const StackFrameContext *SFC = C.getStackFrame();
QualType RT = CallEvent::getDeclaredResultType(SFC->getDecl());
if (!RT.isNull() && RT->isSpecificBuiltinType(BuiltinType::Void))
return;
ExplodedNode *N = C.generateSink();
if (!N)

View File

@ -252,6 +252,16 @@ bool CallEvent::isCallStmt(const Stmt *S) {
|| isa<CXXNewExpr>(S);
}
/// \brief Returns the result type, adjusted for references.
QualType CallEvent::getDeclaredResultType(const Decl *D) {
assert(D);
if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
return FD->getResultType();
else if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
return MD->getResultType();
return QualType();
}
static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
CallEvent::BindingsTy &Bindings,
SValBuilder &SVB,

View File

@ -122,3 +122,15 @@ int pr4631_f1_b(void)
return x; // no-warning
}
void foo_radar12278788() { return; }
void test_radar12278788() {
return foo_radar12278788(); // no-warning
}
void foo_radar12278788_fp() { return; }
typedef int (*RetIntFuncType)();
typedef void (*RetVoidFuncType)();
int test_radar12278788_FP() {
RetVoidFuncType f = foo_radar12278788_fp;
return ((RetIntFuncType)f)(); //expected-warning {{Undefined or garbage value returned to caller}}
}