[cfe-commits] r129308 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h lib/StaticAnalyzer/Core/CFRefCount.cpp lib/StaticAnalyzer/Core/ObjCMessage.cpp test/Analysis/misc-ps-region-store.cpp
Ted Kremenek
kremenek at apple.com
Mon Apr 11 15:22:05 PDT 2011
Author: kremenek
Date: Mon Apr 11 17:22:05 2011
New Revision: 129308
URL: http://llvm.org/viewvc/llvm-project?rev=129308&view=rev
Log:
C++ static analysis: also invalidate fields of objects that are the callees in C++ method calls.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
cfe/trunk/test/Analysis/misc-ps-region-store.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h?rev=129308&r1=129307&r2=129308&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h Mon Apr 11 17:22:05 2011
@@ -171,14 +171,23 @@
const CallExpr *CallE;
ObjCMessage Msg;
const GRState *State;
-
public:
CallOrObjCMessage(const CallExpr *callE, const GRState *state)
- : CallE(callE), State(state) { }
+ : CallE(callE), State(state) {}
CallOrObjCMessage(const ObjCMessage &msg, const GRState *state)
- : CallE(0), Msg(msg), State(state) { }
+ : CallE(0), Msg(msg), State(state) {}
QualType getResultType(ASTContext &ctx) const;
+
+ bool isFunctionCall() const {
+ return (bool) CallE;
+ }
+
+ bool isCXXCall() const {
+ return CallE && isa<CXXMemberCallExpr>(CallE);
+ }
+
+ SVal getCXXCallee() const;
unsigned getNumArgs() const {
if (CallE) return CallE->getNumArgs();
@@ -187,7 +196,8 @@
SVal getArgSVal(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return State->getSVal(CallE->getArg(i));
+ if (CallE)
+ return State->getSVal(CallE->getArg(i));
return Msg.getArgSVal(i, State);
}
@@ -195,13 +205,15 @@
const Expr *getArg(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return CallE->getArg(i);
+ if (CallE)
+ return CallE->getArg(i);
return Msg.getArgExpr(i);
}
SourceRange getArgSourceRange(unsigned i) const {
assert(i < getNumArgs());
- if (CallE) return CallE->getArg(i)->getSourceRange();
+ if (CallE)
+ return CallE->getArg(i)->getSourceRange();
return Msg.getArgSourceRange(i);
}
};
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=129308&r1=129307&r2=129308&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Mon Apr 11 17:22:05 2011
@@ -2529,6 +2529,14 @@
RegionsToInvalidate.push_back(region);
}
+ // Invalidate all instance variables for the callee of a C++ method call.
+ // FIXME: We should be able to do better with inter-procedural analysis.
+ // FIXME: we can probably do better for const versus non-const methods.
+ if (callOrMsg.isCXXCall()) {
+ if (const MemRegion *callee = callOrMsg.getCXXCallee().getAsRegion())
+ RegionsToInvalidate.push_back(callee);
+ }
+
for (unsigned idx = 0, e = callOrMsg.getNumArgs(); idx != e; ++idx) {
SVal V = callOrMsg.getArgSValAsScalarOrLoc(idx);
SymbolRef Sym = V.getAsLocSymbol();
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp?rev=129308&r1=129307&r2=129308&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ObjCMessage.cpp Mon Apr 11 17:22:05 2011
@@ -111,7 +111,7 @@
QualType CallOrObjCMessage::getResultType(ASTContext &ctx) const {
QualType resultTy;
bool isLVal = false;
-
+
if (CallE) {
isLVal = CallE->isLValue();
const Expr *Callee = CallE->getCallee();
@@ -140,3 +140,10 @@
return Msg.getArgSVal(i, State);
return UnknownVal();
}
+
+SVal CallOrObjCMessage::getCXXCallee() const {
+ assert(isCXXCall());
+ const Expr *callee =
+ cast<CXXMemberCallExpr>(CallE)->getImplicitObjectArgument();
+ return State->getSVal(callee);
+}
Modified: cfe/trunk/test/Analysis/misc-ps-region-store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.cpp?rev=129308&r1=129307&r2=129308&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.cpp (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.cpp Mon Apr 11 17:22:05 2011
@@ -303,3 +303,36 @@
PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}
void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }
+
+// Invalidate fields during C++ method calls.
+class RDar9267815 {
+ int x;
+ void test();
+ void test_pos();
+ void test2();
+ void invalidate();
+};
+
+void RDar9267815::test_pos() {
+ int *p = 0;
+ if (x == 42)
+ return;
+ *p = 0xDEADBEEF; // expected-warning {{null}}
+}
+void RDar9267815::test() {
+ int *p = 0;
+ if (x == 42)
+ return;
+ if (x == 42)
+ *p = 0xDEADBEEF; // no-warning
+}
+
+void RDar9267815::test2() {
+ int *p = 0;
+ if (x == 42)
+ return;
+ invalidate();
+ if (x == 42)
+ *p = 0xDEADBEEF; // expected-warning {{null}}
+}
+
More information about the cfe-commits
mailing list