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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits