Author: dergachev Date: Mon Jul 1 16:02:18 2019 New Revision: 364870 URL: http://llvm.org/viewvc/llvm-project?rev=364870&view=rev Log: [analyzer] Fix invalidation when returning into a ctor initializer.
Due to RVO the target region of a function that returns an object by value isn't necessarily a temporary object region; it may be an arbitrary memory region. In particular, it may be a field of a bigger object. Make sure we don't invalidate the bigger object when said function is evaluated conservatively. Differential Revision: https://reviews.llvm.org/D63968 Added: cfe/trunk/test/Analysis/rvo.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=364870&r1=364869&r2=364870&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Mon Jul 1 16:02:18 2019 @@ -634,12 +634,19 @@ ProgramStateRef ExprEngine::bindReturnVa std::tie(State, Target) = prepareForObjectConstruction(Call.getOriginExpr(), State, LCtx, RTC->getConstructionContext(), CallOpts); - assert(Target.getAsRegion()); - // Invalidate the region so that it didn't look uninitialized. Don't notify - // the checkers. - State = State->invalidateRegions(Target.getAsRegion(), E, Count, LCtx, + const MemRegion *TargetR = Target.getAsRegion(); + assert(TargetR); + // Invalidate the region so that it didn't look uninitialized. If this is + // a field or element constructor, we do not want to invalidate + // the whole structure. Pointer escape is meaningless because + // the structure is a product of conservative evaluation + // and therefore contains nothing interesting at this point. + RegionAndSymbolInvalidationTraits ITraits; + ITraits.setTrait(TargetR, + RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion); + State = State->invalidateRegions(TargetR, E, Count, LCtx, /* CausedByPointerEscape=*/false, nullptr, - &Call, nullptr); + &Call, &ITraits); R = State->getSVal(Target.castAs<Loc>(), E->getType()); } else { Added: cfe/trunk/test/Analysis/rvo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/rvo.cpp?rev=364870&view=auto ============================================================================== --- cfe/trunk/test/Analysis/rvo.cpp (added) +++ cfe/trunk/test/Analysis/rvo.cpp Mon Jul 1 16:02:18 2019 @@ -0,0 +1,25 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker core,cplusplus \ +// RUN: -analyzer-checker debug.ExprInspection -verify %s + +void clang_analyzer_eval(bool); + +struct A { + int x; +}; + +A getA(); + +struct B { + int *p; + A a; + + B(int *p) : p(p), a(getA()) {} +}; + +void foo() { + B b1(nullptr); + clang_analyzer_eval(b1.p == nullptr); // expected-warning{{TRUE}} + B b2(new int); // No leak yet! + clang_analyzer_eval(b2.p == nullptr); // expected-warning{{FALSE}} + // expected-warning@-1{{Potential leak of memory pointed to by 'b2.p'}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits