[PATCH] D28033: [analyzer] Treat pointers to static member functions as function pointers

Devin Coughlin via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 21 14:35:03 PST 2016


dcoughlin created this revision.
dcoughlin added a reviewer: kromanenkov.
dcoughlin added subscribers: cfe-commits, NoQ, zaks.anna.

Sema treats pointers to static member functions as having function pointer
type, so treat treat them as function pointer values in the analyzer as well.
This prevents an assertion failure in SValBuilder::evalBinOp caused by code
that expects function pointers to be Locs (in contrast, PointerToMember values
are nonlocs).

Kirill: does this look alright to you?


https://reviews.llvm.org/D28033

Files:
  lib/StaticAnalyzer/Core/SValBuilder.cpp
  test/Analysis/pointer-to-member.cpp


Index: test/Analysis/pointer-to-member.cpp
===================================================================
--- test/Analysis/pointer-to-member.cpp
+++ test/Analysis/pointer-to-member.cpp
@@ -78,6 +78,7 @@
   struct A {
     virtual int foo() { return 1; }
     int bar() { return 2;  }
+    int static staticMemberFunction(int p) { return p + 1; };
   };
 
   struct B : public A {
@@ -111,11 +112,19 @@
 
     clang_analyzer_eval((APtr->*AFP)() == 3); // expected-warning{{TRUE}}
   }
+
+  void testPointerToStaticMemberCall() {
+    int (*fPtr)(int) = &A::staticMemberFunction;
+    if (fPtr != 0) { // no-crash
+      clang_analyzer_eval(fPtr(2) == 3); // expected-warning{{TRUE}}
+    }
+  }
 } // end of testPointerToMemberFunction namespace
 
 namespace testPointerToMemberData {
   struct A {
     int i;
+    static int j;
   };
 
   void testPointerToMemberData() {
@@ -126,6 +135,13 @@
     a.*AMdPointer += 1;
 
     clang_analyzer_eval(a.i == 43); // expected-warning{{TRUE}}
+
+    int *ptrToStaticField = &A::j;
+    if (ptrToStaticField != 0) {
+      *ptrToStaticField = 7;
+      clang_analyzer_eval(*ptrToStaticField == 7); // expected-warning{{TRUE}}
+      clang_analyzer_eval(A::j == 7); // expected-warning{{TRUE}}
+    }
   }
 } // end of testPointerToMemberData namespace
 
Index: lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -218,6 +218,18 @@
 }
 
 DefinedSVal SValBuilder::getMemberPointer(const DeclaratorDecl* DD) {
+  assert(!DD || isa<CXXMethodDecl>(DD) || isa<FieldDecl>(DD));
+
+  if (auto *MD = dyn_cast_or_null<CXXMethodDecl>(DD)) {
+    // Sema treats pointers to static member functions as have function pointer
+    // type, so return a function pointer for the method.
+    // We don't need to play a similar trick for static member fields
+    // because these are represented as plain VarDecls and not FieldDecls
+    // in the AST.
+    if (MD->isStatic())
+      return getFunctionPointer(MD);
+  }
+
   return nonloc::PointerToMember(DD);
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28033.82274.patch
Type: text/x-patch
Size: 2145 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161221/22959f2e/attachment-0001.bin>


More information about the cfe-commits mailing list