[analyzer] Add some convenience accessors to CallEvent, and use them.
These are CallEvent-equivalents of helpers already accessible in
CheckerContext, as part of making it easier for new checkers to be written
using CallEvent rather than raw CallExprs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167338 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 95cc6f2..b0a4bc6 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -105,8 +105,7 @@
if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
// Get the returned value if it's a region.
- SVal Result = C.getSVal(Call.getOriginExpr());
- const MemRegion *RetReg = Result.getAsRegion();
+ const MemRegion *RetReg = Call.getReturnValue().getAsRegion();
if (!RetReg)
return;
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index f83acd9..98d2a85 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -291,13 +291,12 @@
// returns 'self'. So assign the flags, which were set on 'self' to the
// return value.
// EX: self = performMoreInitialization(self)
- const Expr *CallExpr = CE.getOriginExpr();
- if (CallExpr)
- addSelfFlag(state, state->getSVal(CallExpr, C.getLocationContext()),
- prevFlags, C);
+ addSelfFlag(state, CE.getReturnValue(), prevFlags, C);
return;
}
}
+
+ C.addTransition(state);
}
void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index d716f57..cc5cf63 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2783,8 +2783,7 @@
// Consult the summary for the return value.
RetEffect RE = Summ.getRetEffect();
if (RE.getKind() == RetEffect::NoRetHard) {
- SymbolRef Sym = state->getSVal(CallOrMsg.getOriginExpr(),
- C.getLocationContext()).getAsSymbol();
+ SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
if (Sym)
state = removeRefBinding(state, Sym);
}
@@ -2863,8 +2862,7 @@
case RetEffect::OwnedAllocatedSymbol:
case RetEffect::OwnedSymbol: {
- SymbolRef Sym = state->getSVal(CallOrMsg.getOriginExpr(),
- C.getLocationContext()).getAsSymbol();
+ SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
if (!Sym)
break;
@@ -2883,7 +2881,7 @@
case RetEffect::ARCNotOwnedSymbol:
case RetEffect::NotOwnedSymbol: {
const Expr *Ex = CallOrMsg.getOriginExpr();
- SymbolRef Sym = state->getSVal(Ex, C.getLocationContext()).getAsSymbol();
+ SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
if (!Sym)
break;
assert(Ex);
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index b1e2d78..c5cb317 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/AST/ParentMap.h"
#include "llvm/ADT/SmallSet.h"
@@ -99,6 +100,14 @@
return false;
}
+bool CallEvent::isGlobalCFunction(StringRef FunctionName) const {
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(getDecl());
+ if (!FD)
+ return false;
+
+ return CheckerContext::isCLibraryFunction(FD, FunctionName);
+}
+
/// \brief Returns true if a type is a pointer-to-const or reference-to-const
/// with no further indirection.
static bool isPointerToConst(QualType Ty) {
@@ -223,6 +232,13 @@
return ArgE->getSourceRange();
}
+SVal CallEvent::getReturnValue() const {
+ const Expr *E = getOriginExpr();
+ if (!E)
+ return UndefinedVal();
+ return getSVal(E);
+}
+
void CallEvent::dump() const {
dump(llvm::errs());
}
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index 570ebc0..74eeef1 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -43,6 +43,8 @@
// Using a string compare is slow, we might want to switch on BuiltinID here.
unsigned BId = FD->getBuiltinID();
if (BId != 0) {
+ if (Name.empty())
+ return true;
StringRef BName = FD->getASTContext().BuiltinInfo.GetName(BId);
if (BName.find(Name) != StringRef::npos)
return true;
@@ -64,9 +66,14 @@
return false;
// If this function is not externally visible, it is not a C library function.
- if (FD->getLinkage() != ExternalLinkage)
+ // Note that we make an exception for inline functions, which may be
+ // declared in header files without external linkage.
+ if (!FD->isInlined() && FD->getLinkage() != ExternalLinkage)
return false;
+ if (Name.empty())
+ return true;
+
StringRef FName = II->getName();
if (FName.equals(Name))
return true;