[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
Tue Jan 10 10:46:13 PST 2017
dcoughlin updated this revision to Diff 83828.
dcoughlin added a comment.
Updating spacing, as @kromanenkov requested.
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
@@ -77,7 +77,8 @@
namespace testPointerToMemberFunction {
struct A {
virtual int foo() { return 1; }
- int bar() { return 2; }
+ 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.83828.patch
Type: text/x-patch
Size: 2215 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170110/61c71f49/attachment-0001.bin>
More information about the cfe-commits
mailing list