[cfe-commits] r161278 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp lib/StaticAnalyzer/Core/CallEvent.cpp test/Analysis/method-call-path-notes.cpp test/Analysis/misc-ps-cxx0x.cpp
Jordan Rose
jordan_rose at apple.com
Fri Aug 3 16:08:49 PDT 2012
Author: jrose
Date: Fri Aug 3 18:08:49 2012
New Revision: 161278
URL: http://llvm.org/viewvc/llvm-project?rev=161278&view=rev
Log:
[analyzer] Track null/uninitialized C++ objects used in method calls.
Added:
cfe/trunk/test/Analysis/method-call-path-notes.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h?rev=161278&r1=161277&r2=161278&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h Fri Aug 3 18:08:49 2012
@@ -232,7 +232,6 @@
const Stmt *GetDerefExpr(const ExplodedNode *N);
const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetCalleeExpr(const ExplodedNode *N);
const Stmt *GetRetValExpr(const ExplodedNode *N);
} // end namespace clang
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=161278&r1=161277&r2=161278&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Fri Aug 3 18:08:49 2012
@@ -420,8 +420,17 @@
CXXInstanceCall(const CXXInstanceCall &Other) : SimpleCall(Other) {}
public:
+ /// \brief Returns the expression representing the implicit 'this' object.
+ virtual const Expr *getCXXThisExpr() const = 0;
+
/// \brief Returns the value of the implicit 'this' object.
- virtual SVal getCXXThisVal() const = 0;
+ SVal getCXXThisVal() const {
+ const Expr *Base = getCXXThisExpr();
+ // FIXME: This doesn't handle an overloaded ->* operator.
+ if (!Base)
+ return UnknownVal();
+ return getSVal(Base);
+ }
virtual const Decl *getRuntimeDefinition() const;
@@ -453,7 +462,7 @@
return cast<CXXMemberCallExpr>(SimpleCall::getOriginExpr());
}
- virtual SVal getCXXThisVal() const;
+ virtual const Expr *getCXXThisExpr() const;
virtual Kind getKind() const { return CE_CXXMember; }
@@ -492,7 +501,7 @@
return getOriginExpr()->getArg(Index + 1);
}
- virtual SVal getCXXThisVal() const;
+ virtual const Expr *getCXXThisExpr() const;
virtual Kind getKind() const { return CE_CXXMemberOperator; }
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=161278&r1=161277&r2=161278&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Fri Aug 3 18:08:49 2012
@@ -51,7 +51,7 @@
bool IsFirstArgument, bool checkUninitFields,
const CallEvent &Call, OwningPtr<BugType> &BT);
- static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
+ static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
ExplodedNode *N) const;
@@ -66,15 +66,17 @@
};
} // end anonymous namespace
-void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
- const CallExpr *CE) {
+void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
+ const Expr *BadE) {
ExplodedNode *N = C.generateSink();
if (!N)
return;
BugReport *R = new BugReport(*BT, BT->getName(), N);
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
- bugreporter::GetCalleeExpr(N), R));
+ if (BadE) {
+ R->addRange(BadE->getSourceRange());
+ R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, BadE, R));
+ }
C.EmitReport(R);
}
@@ -227,7 +229,7 @@
if (!BT_call_undef)
BT_call_undef.reset(new BuiltinBug("Called function pointer is an "
"uninitalized pointer value"));
- EmitBadCall(BT_call_undef.get(), C, CE);
+ emitBadCall(BT_call_undef.get(), C, Callee);
return;
}
@@ -235,7 +237,7 @@
if (!BT_call_null)
BT_call_null.reset(
new BuiltinBug("Called function pointer is null (null dereference)"));
- EmitBadCall(BT_call_null.get(), C, CE);
+ emitBadCall(BT_call_null.get(), C, Callee);
}
}
@@ -243,22 +245,20 @@
CheckerContext &C) const {
// If this is a call to a C++ method, check if the callee is null or
// undefined.
- // FIXME: Generalize this to CXXInstanceCall once it supports
- // getCXXThisVal().
- if (const CXXMemberCall *CC = dyn_cast<CXXMemberCall>(&Call)) {
+ if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
SVal V = CC->getCXXThisVal();
if (V.isUndef()) {
if (!BT_cxx_call_undef)
BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
"uninitialized"));
- EmitBadCall(BT_cxx_call_undef.get(), C, CC->getOriginExpr());
+ emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
return;
}
if (V.isZeroConstant()) {
if (!BT_cxx_call_null)
BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
"is null"));
- EmitBadCall(BT_cxx_call_null.get(), C, CC->getOriginExpr());
+ emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
return;
}
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=161278&r1=161277&r2=161278&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Fri Aug 3 18:08:49 2012
@@ -419,21 +419,13 @@
-SVal CXXMemberCall::getCXXThisVal() const {
- const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
-
- // FIXME: Will eventually need to cope with member pointers. This is
- // a limitation in getImplicitObjectArgument().
- if (!Base)
- return UnknownVal();
-
- return getSVal(Base);
+const Expr *CXXMemberCall::getCXXThisExpr() const {
+ return getOriginExpr()->getImplicitObjectArgument();
}
-SVal CXXMemberOperatorCall::getCXXThisVal() const {
- const Expr *Base = getOriginExpr()->getArg(0);
- return getSVal(Base);
+const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
+ return getOriginExpr()->getArg(0);
}
Added: cfe/trunk/test/Analysis/method-call-path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/method-call-path-notes.cpp?rev=161278&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/method-call-path-notes.cpp (added)
+++ cfe/trunk/test/Analysis/method-call-path-notes.cpp Fri Aug 3 18:08:49 2012
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=text -verify %s
+
+// Test warning about null or uninitialized pointer values used as instance member
+// calls.
+class TestInstanceCall {
+public:
+ void foo() {}
+};
+
+void test_ic() {
+ TestInstanceCall *p; // expected-note {{Variable 'p' declared without an initial value}}
+ p->foo(); // expected-warning {{Called C++ object pointer is uninitialized}} expected-note {{Called C++ object pointer is uninitialized}}
+}
+
+void test_ic_null() {
+ TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}}
+ p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
+void test_ic_set_to_null() {
+ TestInstanceCall *p;
+ p = 0; // expected-note {{Null pointer value stored to 'p'}}
+ p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
+void test_ic_null(TestInstanceCall *p) {
+ if (!p) // expected-note {{Taking true branch}}
+ p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
+}
+
+void test_ic_member_ptr() {
+ TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}}
+ typedef void (TestInstanceCall::*IC_Ptr)();
+ IC_Ptr bar = &TestInstanceCall::foo;
+ (p->*bar)(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
+}
Modified: cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp?rev=161278&r1=161277&r2=161278&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp (original)
+++ cfe/trunk/test/Analysis/misc-ps-cxx0x.cpp Fri Aug 3 18:08:49 2012
@@ -87,32 +87,3 @@
operator=(dynamic_cast<const rdar11817693_BaseBase&>(src));
}
-// Test warning about null or uninitialized pointer values used as instance member
-// calls.
-class TestInstanceCall {
-public:
- void foo() {}
-};
-
-void test_ic() {
- TestInstanceCall *p;
- p->foo(); // expected-warning {{Called C++ object pointer is uninitialized}}
-}
-
-void test_ic_null() {
- TestInstanceCall *p = 0;
- p->foo(); // expected-warning {{Called C++ object pointer is null}}
-}
-
-void test_ic_null(TestInstanceCall *p) {
- if (!p)
- p->foo(); // expected-warning {{Called C++ object pointer is null}}
-}
-
-void test_ic_member_ptr() {
- TestInstanceCall *p = 0;
- typedef void (TestInstanceCall::*IC_Ptr)();
- IC_Ptr bar = &TestInstanceCall::foo;
- (p->*bar)(); // expected-warning {{Called C++ object pointer is null}}
-}
-
More information about the cfe-commits
mailing list