r364870 - [analyzer] Fix invalidation when returning into a ctor initializer.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 1 16:02:18 PDT 2019
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 at -1{{Potential leak of memory pointed to by 'b2.p'}}
+}
More information about the cfe-commits
mailing list