================
@@ -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 part looks weird to me.
We dyncast from E to T1. Then if it wasn't a T1, we check if it's T2
where T1: InitListExpr and T2: ImplicitValueInitExpr
I've checked and neither T1 is a subtype of T2, nor the other way around.
This makes me wonder, why does the guarded block depend on the `!ILE` condition?
https://github.com/llvm/llvm-project/pull/189361
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits