[cfe-commits] r163577 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Core/CallEvent.cpp test/Analysis/dtor.cpp test/Analysis/inline.cpp
Jordan Rose
jordan_rose at apple.com
Mon Sep 10 17:31:03 PDT 2012
Author: jrose
Date: Mon Sep 10 19:31:02 2012
New Revision: 163577
URL: http://llvm.org/viewvc/llvm-project?rev=163577&view=rev
Log:
[analyzer] Member function calls that use qualified names are non-virtual.
C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
id-expression in the class member access expression is a qualified-id,
that function is called. Otherwise, its final overrider in the dynamic type
of the object expression is called.
<rdar://problem/12255556>
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/dtor.cpp
cfe/trunk/test/Analysis/inline.cpp
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=163577&r1=163576&r2=163577&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Mon Sep 10 19:31:02 2012
@@ -549,6 +549,8 @@
}
virtual const Expr *getCXXThisExpr() const;
+
+ virtual RuntimeDefinition getRuntimeDefinition() const;
virtual Kind getKind() const { return CE_CXXMember; }
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=163577&r1=163576&r2=163577&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Mon Sep 10 19:31:02 2012
@@ -496,6 +496,18 @@
return getOriginExpr()->getImplicitObjectArgument();
}
+RuntimeDefinition CXXMemberCall::getRuntimeDefinition() const {
+ // C++11 [expr.call]p1: ...If the selected function is non-virtual, or if the
+ // id-expression in the class member access expression is a qualified-id,
+ // that function is called. Otherwise, its final overrider in the dynamic type
+ // of the object expression is called.
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
+ if (ME->hasQualifier())
+ return AnyFunctionCall::getRuntimeDefinition();
+
+ return CXXInstanceCall::getRuntimeDefinition();
+}
+
const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
return getOriginExpr()->getArg(0);
Modified: cfe/trunk/test/Analysis/dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dtor.cpp?rev=163577&r1=163576&r2=163577&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dtor.cpp (original)
+++ cfe/trunk/test/Analysis/dtor.cpp Mon Sep 10 19:31:02 2012
@@ -281,3 +281,23 @@
SubclassB b;
}
}
+
+namespace ExplicitDestructorCall {
+ class VirtualDtor {
+ public:
+ virtual ~VirtualDtor() {
+ clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+ }
+ };
+
+ class Subclass : public VirtualDtor {
+ public:
+ virtual ~Subclass() {
+ clang_analyzer_checkInlined(false); // no-warning
+ }
+ };
+
+ void destroy(Subclass *obj) {
+ obj->VirtualDtor::~VirtualDtor();
+ }
+}
Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=163577&r1=163576&r2=163577&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Mon Sep 10 19:31:02 2012
@@ -325,3 +325,18 @@
clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
}
}
+
+
+namespace QualifiedCalls {
+ void test(One *object) {
+ // This uses the One class from the top of the file.
+ clang_analyzer_eval(object->getNum() == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(object->One::getNum() == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(object->A::getNum() == 0); // expected-warning{{TRUE}}
+
+ // getZero is non-virtual.
+ clang_analyzer_eval(object->getZero() == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(object->One::getZero() == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(object->A::getZero() == 0); // expected-warning{{TRUE}}
+}
+}
More information about the cfe-commits
mailing list