diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-07-01 23:02:18 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-07-01 23:02:18 +0000 |
| commit | ceb639dbeea97c901b2642ebe296eb358d27b2f6 (patch) | |
| tree | a8a86d4fe063869ad50940409ed31bb73f952923 /clang/lib | |
| parent | 512f4838c47c5bab13d8bb0eabc01d64222825ae (diff) | |
| download | bcm5719-llvm-ceb639dbeea97c901b2642ebe296eb358d27b2f6.tar.gz bcm5719-llvm-ceb639dbeea97c901b2642ebe296eb358d27b2f6.zip | |
[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
llvm-svn: 364870
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 3fe06aea63e..e00a08b2162 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -634,12 +634,19 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call, 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 { |

