r319055 - [analyzer] pr34404: Fix a crash on modeling pointers to indirect members.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 27 09:31:16 PST 2017
Author: dergachev
Date: Mon Nov 27 09:31:16 2017
New Revision: 319055
URL: http://llvm.org/viewvc/llvm-project?rev=319055&view=rev
Log:
[analyzer] pr34404: Fix a crash on modeling pointers to indirect members.
We were crashing whenever a C++ pointer-to-member was taken, that was pointing
to a member of an anonymous structure field within a class, eg.
struct A {
struct {
int x;
};
};
// ...
&A::x;
Differential Revision: https://reviews.llvm.org/D39800
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/pointer-to-member.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=319055&r1=319054&r2=319055&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Nov 27 09:31:16 2017
@@ -2108,10 +2108,12 @@ void ExprEngine::VisitCommonDeclRefExpr(
ProgramPoint::PostLValueKind);
return;
}
- if (isa<FieldDecl>(D)) {
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
// FIXME: Compute lvalue of field pointers-to-member.
// Right now we just use a non-null void pointer, so that it gives proper
// results in boolean contexts.
+ // FIXME: Maybe delegate this to the surrounding operator&.
+ // Note how this expression is lvalue, however pointer-to-member is NonLoc.
SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
currBldrCtx->blockCount());
state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
Modified: cfe/trunk/test/Analysis/pointer-to-member.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/pointer-to-member.cpp?rev=319055&r1=319054&r2=319055&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/pointer-to-member.cpp (original)
+++ cfe/trunk/test/Analysis/pointer-to-member.cpp Mon Nov 27 09:31:16 2017
@@ -230,3 +230,42 @@ void double_diamond() {
clang_analyzer_eval(d2.*(static_cast<int D2::*>(static_cast<int R2::*>(static_cast<int R1::*>(&B::f)))) == 4); // expected-warning {{TRUE}}
}
} // end of testPointerToMemberDiamond namespace
+
+namespace testAnonymousMember {
+struct A {
+ struct {
+ int x;
+ };
+ struct {
+ struct {
+ int y;
+ };
+ };
+ struct {
+ union {
+ int z;
+ };
+ };
+};
+
+void test() {
+ clang_analyzer_eval(&A::x); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&A::y); // expected-warning{{TRUE}}
+ clang_analyzer_eval(&A::z); // expected-warning{{TRUE}}
+
+ // FIXME: These should be true.
+ int A::*l = &A::x, A::*m = &A::y, A::*n = &A::z;
+ clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(m); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(n); // expected-warning{{UNKNOWN}}
+
+ // FIXME: These should be true as well.
+ A a;
+ a.x = 1;
+ clang_analyzer_eval(a.*l == 1); // expected-warning{{UNKNOWN}}
+ a.y = 2;
+ clang_analyzer_eval(a.*m == 2); // expected-warning{{UNKNOWN}}
+ a.z = 3;
+ clang_analyzer_eval(a.*n == 3); // expected-warning{{UNKNOWN}}
+}
+} // end of testAnonymousMember namespace
More information about the cfe-commits
mailing list