================
@@ -2113,37 +2115,97 @@ SVal
RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
return getBindingForFieldOrElementCommon(B, R, R->getElementType());
}
+std::optional<SVal>
+RegionStoreManager::getConstantValFromInitializer(const FieldRegion *R,
+ bool IsMainAnalysis) {
+ SmallVector<const SubRegion *, 4> Path;
+ const MemRegion *Cur = R;
+ while (Cur && !isa<VarRegion>(Cur)) {
+ if (isa<FieldRegion, ElementRegion>(Cur)) {
+ Path.push_back(cast<SubRegion>(Cur));
+ Cur = cast<SubRegion>(Cur)->getSuperRegion();
+ } else {
+ return std::nullopt;
+ }
+ }
+
+ const auto *VR = dyn_cast_or_null<VarRegion>(Cur);
+ if (!VR)
+ return std::nullopt;
+
+ const VarDecl *VD = VR->getDecl();
+ QualType LeafTy = R->getDecl()->getType();
+
+ bool TrustInit =
+ (VD->getType().isConstQualified() || LeafTy.isConstQualified() ||
+ (IsMainAnalysis && VD->hasGlobalStorage()));
+ if (!TrustInit)
+ return std::nullopt;
+
+ const Expr *Init = VD->getAnyInitializer();
+ if (!Init)
+ return std::nullopt;
+
+ const Expr *E = Init;
+ for (const SubRegion *SR : llvm::reverse(Path)) {
+ const auto *ILE = dyn_cast<InitListExpr>(E);
+ if (!ILE)
+ return isa<ImplicitValueInitExpr>(E)
+ ? std::optional<SVal>(svalBuilder.makeZeroVal(LeafTy))
+ : std::nullopt;
----------------
steakhal wrote:
This doesn't explain why is the second condition dependent on the first
condition.
In other words, why isn't this written as this:
```c++
if (isa<ImplicitValueInitExpr>(E))
return svalBuilder.makeZeroVal(LeafTy);
if (const auto *ILE = dyn_cast<InitListExpr>(E)) {
// ...
}
return std::nullopt;
```
Notice that the `isa<ImplicitValueInitExpr>(E)` condition is no longer
dependent on `!ILE`. This makes it easier to reason about when each return path
is hit.
https://github.com/llvm/llvm-project/pull/189361
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits