[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