Skip to content

Commit c048073

Browse files
authored
[Clang][CodeGen] Respect -fwrapv-pointer when emitting struct GEPs (#134269)
This patch turns off inbounds/nuw flags for member accesses when `-fwrapv-pointer` is set. Closes #132449. It is required by #130734.
1 parent 543e5f5 commit c048073

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4915,6 +4915,9 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
49154915
unsigned idx =
49164916
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
49174917

4918+
if (CGF.getLangOpts().PointerOverflowDefined)
4919+
return CGF.Builder.CreateConstGEP2_32(base, 0, idx, field->getName());
4920+
49184921
return CGF.Builder.CreateStructGEP(base, idx, field->getName());
49194922
}
49204923

@@ -4972,9 +4975,13 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
49724975
if (!UseVolatile) {
49734976
if (!IsInPreservedAIRegion &&
49744977
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
4975-
if (Idx != 0)
4978+
if (Idx != 0) {
49764979
// For structs, we GEP to the field that the record layout suggests.
4977-
Addr = Builder.CreateStructGEP(Addr, Idx, field->getName());
4980+
if (getLangOpts().PointerOverflowDefined)
4981+
Addr = Builder.CreateConstGEP2_32(Addr, 0, Idx, field->getName());
4982+
else
4983+
Addr = Builder.CreateStructGEP(Addr, Idx, field->getName());
4984+
}
49784985
} else {
49794986
llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType(
49804987
getContext().getRecordType(rec), rec->getLocation());

clang/test/CodeGen/pointer-overflow.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,24 @@ void test(void) {
1010
// DEFAULT: getelementptr inbounds nuw i32, ptr
1111
// FWRAPV-POINTER: getelementptr i32, ptr
1212
}
13+
14+
struct S {
15+
int a;
16+
int b;
17+
int c: 10;
18+
int d: 10;
19+
};
20+
21+
int test_struct(struct S* s) {
22+
// -fwrapv-pointer should turn off inbounds nuw for struct GEP's
23+
return s->b;
24+
// DEFAULT: getelementptr inbounds nuw %struct.S, ptr
25+
// FWRAPV-POINTER: getelementptr %struct.S, ptr
26+
}
27+
28+
int test_struct_bitfield(struct S* s) {
29+
// -fwrapv-pointer should turn off inbounds nuw for struct GEP's
30+
return s->d;
31+
// DEFAULT: getelementptr inbounds nuw %struct.S, ptr
32+
// FWRAPV-POINTER: getelementptr %struct.S, ptr
33+
}

0 commit comments

Comments
 (0)