mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 19:32:35 +00:00
[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:
parent
75cfbb60a8
commit
5d2964e770
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user