Skip to content

Commit 502aaee

Browse files
committed
[CHERI CSA] When inferring the alignment of the first field in a struct, use the alignment of the struct
itself to help infer higher alignment.
1 parent 9a43e01 commit 502aaee

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

clang/lib/StaticAnalyzer/Checkers/PointerAlignmentChecker.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,20 @@ 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>()) {
194+
// If this is the first field of a larger struct, we can use the alignment
195+
// of the containing struct try to increase the assumed alignment.
196+
const RegionOffset &Offset = FR->getAsOffset();
197+
if (!Offset.hasSymbolicOffset() && Offset.getOffset() == 0) {
198+
if (const auto *Base =
199+
FR->getSuperRegion()->getAs<TypedValueRegion>()) {
200+
auto BaseTy = Base->getValueType();
201+
unsigned BaseAlign = ASTCtx.getTypeAlignInChars(BaseTy).getQuantity();
202+
NaturalAlign = std::max(NaturalAlign, BaseAlign);
203+
}
204+
}
205+
}
206+
193207
if (const ElementRegion *ER = R->getAs<ElementRegion>()) {
194208
int ElTyTZ = APSInt::getUnsigned(NaturalAlign).countTrailingZeros();
195209

clang/test/Analysis/pointer-alignment.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,15 @@ void cast_and_assign(void) {
202202
// no duplicate assign warn
203203
*i = 42;
204204
}
205+
206+
// ----
207+
struct __attribute__((aligned(8))) AlignedParentStruct {
208+
int a;
209+
int b;
210+
};
211+
212+
void write_to_first_member(struct AlignedParentStruct *chunk) {
213+
// No warning because alignment of is inferred from the parent struct.
214+
*(long long*)(&chunk->a) = 0;
215+
}
216+

0 commit comments

Comments
 (0)