[PATCH] D48460: [analyzer] Fix invalidation on C++ const methods.

Phabricator via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 25 16:48:30 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rC335555: [analyzer] Fix invalidation on C++ const methods with arrow syntax. (authored by dergachev, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D48460?vs=152391&id=152805#toc

Repository:
  rC Clang

https://reviews.llvm.org/D48460

Files:
  lib/StaticAnalyzer/Core/CallEvent.cpp
  test/Analysis/const-method-call.cpp


Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -534,9 +534,14 @@
     // Get the record decl for the class of 'This'. D->getParent() may return a
     // base class decl, rather than the class of the instance which needs to be
     // checked for mutable fields.
+    // TODO: We might as well look at the dynamic type of the object.
     const Expr *Ex = getCXXThisExpr()->ignoreParenBaseCasts();
-    const CXXRecordDecl *ParentRecord = Ex->getType()->getAsCXXRecordDecl();
-    if (!ParentRecord || ParentRecord->hasMutableFields())
+    QualType T = Ex->getType();
+    if (T->isPointerType()) // Arrow or implicit-this syntax?
+      T = T->getPointeeType();
+    const CXXRecordDecl *ParentRecord = T->getAsCXXRecordDecl();
+    assert(ParentRecord);
+    if (ParentRecord->hasMutableFields())
       return;
     // Preserve CXXThis.
     const MemRegion *ThisRegion = ThisVal.getAsRegion();
Index: test/Analysis/const-method-call.cpp
===================================================================
--- test/Analysis/const-method-call.cpp
+++ test/Analysis/const-method-call.cpp
@@ -6,6 +6,14 @@
   int x;
   void foo() const;
   void bar();
+
+  void testImplicitThisSyntax() {
+    x = 3;
+    foo();
+    clang_analyzer_eval(x == 3); // expected-warning{{TRUE}}
+    bar();
+    clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
+  }
 };
 
 struct B {
@@ -108,6 +116,22 @@
   clang_analyzer_eval(t.in.x == 2); // expected-warning{{TRUE}}
 }
 
+void checkPointerTypedThisExpression(A *a) {
+  a->x = 3;
+  a->foo();
+  clang_analyzer_eval(a->x == 3); // expected-warning{{TRUE}}
+  a->bar();
+  clang_analyzer_eval(a->x == 3); // expected-warning{{UNKNOWN}}
+}
+
+void checkReferenceTypedThisExpression(A &a) {
+  a.x = 3;
+  a.foo();
+  clang_analyzer_eval(a.x == 3); // expected-warning{{TRUE}}
+  a.bar();
+  clang_analyzer_eval(a.x == 3); // expected-warning{{UNKNOWN}}
+}
+
 // --- Versions of the above tests where the const method is inherited --- //
 
 struct B1 {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48460.152805.patch
Type: text/x-patch
Size: 2149 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180625/c10fe2f6/attachment.bin>


More information about the cfe-commits mailing list