Skip to content

Commit 02065e8

Browse files
committed
[Clang][CodeGen] Do not set inbounds flag for struct GEP with null base pointers
1 parent 029e102 commit 02065e8

File tree

3 files changed

+12
-7
lines changed

3 files changed

+12
-7
lines changed

clang/lib/CodeGen/CGBuilder.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,16 @@ class CGBuilderTy : public CGBuilderBaseTy {
223223
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
224224
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
225225

226-
return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
227-
Index, Name),
228-
ElTy->getElementType(Index),
229-
Addr.getAlignment().alignmentAtOffset(Offset),
230-
Addr.isKnownNonNull());
226+
// Specially, we don't add inbounds flags if the base pointer is null.
227+
// This is a workaround for old-style offsetof macros.
228+
llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::noUnsignedWrap();
229+
if (!isa<llvm::ConstantPointerNull>(Addr.getBasePointer()))
230+
NWFlags |= llvm::GEPNoWrapFlags::inBounds();
231+
return Address(
232+
CreateConstGEP2_32(Addr.getElementType(), Addr.getBasePointer(), 0,
233+
Index, Name, NWFlags),
234+
ElTy->getElementType(Index),
235+
Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull());
231236
}
232237

233238
/// Given

clang/test/CodeGen/catch-nullptr-and-nonzero-offset-in-offsetof-idiom.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ struct S {
1717

1818
// CHECK-LABEL: @get_offset_of_y_naively(
1919
// CHECK-NEXT: entry:
20-
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr inbounds nuw ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64)
20+
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr nuw ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64)
2121
//
2222
uintptr_t get_offset_of_y_naively(void) {
2323
return ((uintptr_t)(&(((struct S *)0)->y)));

clang/test/CodeGenCXX/catch-nullptr-and-nonzero-offset-in-offsetof-idiom.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct S {
1010

1111
// CHECK-LABEL: @_Z23get_offset_of_y_naivelyv(
1212
// CHECK-NEXT: entry:
13-
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr inbounds nuw ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64)
13+
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr nuw ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64)
1414
//
1515
uintptr_t get_offset_of_y_naively() {
1616
return ((uintptr_t)(&(((S *)nullptr)->y)));

0 commit comments

Comments
 (0)