================
@@ -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;
+
+ if (const auto *FR = dyn_cast<FieldRegion>(SR)) {
+ if (ILE->getType()->isUnionType()) {
+ // A union InitListExpr has one init for one member. We can only
+ // resolve if the accessed field matches the initialized member.
+ const FieldDecl *InitField = ILE->getInitializedFieldInUnion();
+ if (InitField && InitField == FR->getDecl()) {
+ if (ILE->getNumInits() > 0)
+ E = ILE->getInit(0);
+ else
+ return svalBuilder.makeZeroVal(LeafTy);
+ } else {
+ return std::nullopt;
+ }
+ } else {
+ unsigned Idx = FR->getDecl()->getFieldIndex();
+ if (Idx < ILE->getNumInits())
+ E = ILE->getInit(Idx);
+ else
+ return std::nullopt;
+ }
+ } else if (const auto *ER = dyn_cast<ElementRegion>(SR)) {
----------------
steakhal wrote:
The problem with large else-ifs and fallthroughs is that one must read the
whole chain.
1) How can I reach my block.
2) What if I fall through from my block, which return I hit? Maybe in some
other handler block or the return at the end of the whole chain?
Because of this, it's generally advised to have disjunct blocks - no fall
throughs.
While it's not actually too bad in this implementation, I can easily see it
getting out of control one or two patches down the line.
https://github.com/llvm/llvm-project/pull/189361
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits