tomasz-kaminski-sonarsource updated this revision to Diff 459666.
tomasz-kaminski-sonarsource added a comment.
Ping and reformat.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D132030/new/
https://reviews.llvm.org/D132030
Files:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
clang/lib/StaticAnalyzer/Core/CallEvent.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
clang/test/Analysis/copy-elision.cpp
Index: clang/test/Analysis/copy-elision.cpp
===================================================================
--- clang/test/Analysis/copy-elision.cpp
+++ clang/test/Analysis/copy-elision.cpp
@@ -20,6 +20,7 @@
#endif
void clang_analyzer_eval(bool);
+void clang_analyzer_dump(int);
namespace variable_functional_cast_crash {
@@ -418,3 +419,31 @@
}
} // namespace address_vector_tests
+
+namespace arg_directly_from_return_in_loop {
+
+struct Result {
+ int value;
+};
+
+Result create() {
+ return Result{10};
+}
+
+int accessValue(Result r) {
+ return r.value;
+}
+
+void test() {
+ for (int i = 0; i < 3; ++i) {
+ int v = accessValue(create());
+ if (i == 0) {
+ clang_analyzer_dump(v); // expected-warning {{10 S32b}}
+ } else {
+ clang_analyzer_dump(v); // expected-warning {{10 S32b}}
+ // was {{reg_${{[0-9]+}}<int r.value> }} for C++11
+ }
+ }
+}
+
+} // namespace arg_directly_from_return_in_loop
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -760,9 +760,9 @@
SVal Target;
assert(RTC->getStmt() == Call.getOriginExpr());
EvalCallOptions CallOpts; // FIXME: We won't really need those.
- std::tie(State, Target) =
- handleConstructionContext(Call.getOriginExpr(), State, LCtx,
- RTC->getConstructionContext(), CallOpts);
+ std::tie(State, Target) = handleConstructionContext(
+ Call.getOriginExpr(), State, currBldrCtx, LCtx,
+ RTC->getConstructionContext(), CallOpts);
const MemRegion *TargetR = Target.getAsRegion();
assert(TargetR);
// Invalidate the region so that it didn't look uninitialized. If this is
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -111,9 +111,15 @@
return LValue;
}
+// In case when the prvalue is returned from the function (kind is one of
+// SimpleReturnedValueKind, CXX17ElidedCopyReturnedValueKind), then
+// it's materialization happens in context of the caller.
+// We pass BldrCtx explicitly, as currBldrCtx always refers to callee's context.
SVal ExprEngine::computeObjectUnderConstruction(
- const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
- const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx) {
+ const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
+ const LocationContext *LCtx, const ConstructionContext *CC,
+ EvalCallOptions &CallOpts, unsigned Idx) {
+
SValBuilder &SVB = getSValBuilder();
MemRegionManager &MRMgr = SVB.getRegionManager();
ASTContext &ACtx = SVB.getContext();
@@ -210,8 +216,11 @@
CallerLCtx = CallerLCtx->getParent();
assert(!isa<BlockInvocationContext>(CallerLCtx));
}
+
+ NodeBuilderContext CallerBldrCtx(getCoreEngine(),
+ SFC->getCallSiteBlock(), CallerLCtx);
return computeObjectUnderConstruction(
- cast<Expr>(SFC->getCallSite()), State, CallerLCtx,
+ cast<Expr>(SFC->getCallSite()), State, &CallerBldrCtx, CallerLCtx,
RTC->getConstructionContext(), CallOpts);
} else {
// We are on the top frame of the analysis. We do not know where is the
@@ -251,7 +260,7 @@
EvalCallOptions PreElideCallOpts = CallOpts;
SVal V = computeObjectUnderConstruction(
- TCC->getConstructorAfterElision(), State, LCtx,
+ TCC->getConstructorAfterElision(), State, BldrCtx, LCtx,
TCC->getConstructionContextAfterElision(), CallOpts);
// FIXME: This definition of "copy elision has not failed" is unreliable.
@@ -319,7 +328,7 @@
CallEventManager &CEMgr = getStateManager().getCallEventManager();
auto getArgLoc = [&](CallEventRef<> Caller) -> Optional<SVal> {
const LocationContext *FutureSFC =
- Caller->getCalleeStackFrame(currBldrCtx->blockCount());
+ Caller->getCalleeStackFrame(BldrCtx->blockCount());
// Return early if we are unable to reliably foresee
// the future stack frame.
if (!FutureSFC)
@@ -338,7 +347,7 @@
// because this-argument is implemented as a normal argument in
// operator call expressions but not in operator declarations.
const TypedValueRegion *TVR = Caller->getParameterLocation(
- *Caller->getAdjustedParameterIndex(Idx), currBldrCtx->blockCount());
+ *Caller->getAdjustedParameterIndex(Idx), BldrCtx->blockCount());
if (!TVR)
return None;
@@ -643,8 +652,8 @@
}
// The target region is found from construction context.
- std::tie(State, Target) =
- handleConstructionContext(CE, State, LCtx, CC, CallOpts, Idx);
+ std::tie(State, Target) = handleConstructionContext(
+ CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx);
break;
}
case CXXConstructExpr::CK_VirtualBase: {
Index: clang/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -485,9 +485,9 @@
EvalCallOptions CallOpts;
ExprEngine &Engine = getState()->getStateManager().getOwningEngine();
- SVal RetVal =
- Engine.computeObjectUnderConstruction(getOriginExpr(), getState(),
- getLocationContext(), CC, CallOpts);
+ SVal RetVal = Engine.computeObjectUnderConstruction(
+ getOriginExpr(), getState(), &Engine.getBuilderContext(),
+ getLocationContext(), CC, CallOpts);
return RetVal;
}
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -732,6 +732,7 @@
/// A multi-dimensional array is also a continuous memory location in a
/// row major order, so for arr[0][0] Idx is 0 and for arr[2][2] Idx is 8.
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
+ const NodeBuilderContext *BldrCtx,
const LocationContext *LCtx,
const ConstructionContext *CC,
EvalCallOptions &CallOpts,
@@ -748,13 +749,13 @@
/// A convenient wrapper around computeObjectUnderConstruction
/// and updateObjectsUnderConstruction.
- std::pair<ProgramStateRef, SVal>
- handleConstructionContext(const Expr *E, ProgramStateRef State,
- const LocationContext *LCtx,
- const ConstructionContext *CC,
- EvalCallOptions &CallOpts, unsigned Idx = 0) {
+ std::pair<ProgramStateRef, SVal> handleConstructionContext(
+ const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
+ const LocationContext *LCtx, const ConstructionContext *CC,
+ EvalCallOptions &CallOpts, unsigned Idx = 0) {
- SVal V = computeObjectUnderConstruction(E, State, LCtx, CC, CallOpts, Idx);
+ SVal V = computeObjectUnderConstruction(E, State, BldrCtx, LCtx, CC,
+ CallOpts, Idx);
State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
return std::make_pair(State, V);
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -214,8 +214,14 @@
const CFGBlock *Block;
const LocationContext *LC;
+ NodeBuilderContext(const CoreEngine &E, const CFGBlock *B,
+ const LocationContext *L)
+ : Eng(E), Block(B), LC(L) {
+ assert(B);
+ }
+
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
- : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
+ : NodeBuilderContext(E, B, N->getLocationContext()) {}
/// Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return Block; }
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits