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>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163577
91177308-0d34-0410-b5e6-
96231b3b80d8
}
virtual const Expr *getCXXThisExpr() const;
+
+ virtual RuntimeDefinition getRuntimeDefinition() const;
virtual Kind getKind() const { return CE_CXXMember; }
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);
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();
+ }
+}
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}}
+}
+}