@@ -190,25 +190,36 @@ int getTrailingZerosCount(const MemRegion *R, ProgramStateRef State,
190190 return -1 ;
191191 unsigned NaturalAlign = ASTCtx.getTypeAlignInChars (PT).getQuantity ();
192192
193- if (const FieldRegion *FR = R->getAs <FieldRegion>()) {
193+ unsigned FullOffsetInChars = 0 ;
194+ for (auto *SubR = R->getAs <SubRegion>(); SubR;
195+ SubR = SubR->getSuperRegion ()->getAs <SubRegion>()) {
194196 // If this is the a field of a larger struct, we can use the alignment
195197 // of the containing struct combined with the offset to try to increase
196198 // the assumed alignment.
197- const RegionOffset &Offset = FR->getAsOffset ();
198- if (!Offset.hasSymbolicOffset ()) {
199- if (const auto *Base =
200- FR->getSuperRegion ()->getAs <TypedValueRegion>()) {
201- auto BaseTy = Base->getValueType ();
202- unsigned BaseAlign = ASTCtx.getTypeAlignInChars (BaseTy).getQuantity ();
203- uint64_t FieldOffsetBits = Offset.getOffset ();
204- unsigned Offset =
205- ASTCtx.toCharUnitsFromBits (FieldOffsetBits).getQuantity ();
206- unsigned OffsetAlign =
207- (Offset == 0 ) ? BaseAlign : (1ULL << llvm::countr_zero (Offset));
208- unsigned InferredAlign = std::min (BaseAlign, OffsetAlign);
209- NaturalAlign = std::max (NaturalAlign, InferredAlign);
210- }
211- }
199+ const auto *FR = SubR->getAs <FieldRegion>();
200+ if (!FR)
201+ break ;
202+
203+ const RegionOffset &LocalOffset = FR->getAsOffset ();
204+ if (LocalOffset.hasSymbolicOffset ())
205+ break ;
206+
207+ const auto *Base = FR->getSuperRegion ()->getAs <TypedValueRegion>();
208+ if (!Base)
209+ break ;
210+
211+ auto BaseTy = Base->getValueType ();
212+ unsigned BaseAlign = ASTCtx.getTypeAlignInChars (BaseTy).getQuantity ();
213+ uint64_t LocalOffsetBits = LocalOffset.getOffset ();
214+ FullOffsetInChars +=
215+ ASTCtx.toCharUnitsFromBits (LocalOffsetBits).getQuantity ();
216+ unsigned FullOffsetAlign =
217+ (FullOffsetInChars == 0 )
218+ ? BaseAlign
219+ : (1ULL << llvm::countr_zero (FullOffsetInChars));
220+
221+ unsigned InferredAlign = std::min (BaseAlign, FullOffsetAlign);
222+ NaturalAlign = std::max (NaturalAlign, InferredAlign);
212223 }
213224
214225 if (const ElementRegion *ER = R->getAs <ElementRegion>()) {
0 commit comments