Skip to content

Commit 4177691

Browse files
committed
[Clang][CodeGen] Add more tests.
1 parent 222a681 commit 4177691

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

clang/lib/CodeGen/CGBuilder.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,19 +215,25 @@ class CGBuilderTy : public CGBuilderBaseTy {
215215
///
216216
/// This API assumes that drilling into a struct like this is always an
217217
/// inbounds and nuw operation.
218+
/// Specifically, inbounds flag will not be set if \p IsBaseConstantNull is
219+
/// true.
218220
using CGBuilderBaseTy::CreateStructGEP;
219221
Address CreateStructGEP(Address Addr, unsigned Index,
220-
const llvm::Twine &Name = "") {
222+
const llvm::Twine &Name = "",
223+
bool IsBaseConstantNull = false) {
221224
llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
222225
const llvm::DataLayout &DL = BB->getDataLayout();
223226
const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
224227
auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
225228

226-
return Address(CreateStructGEP(Addr.getElementType(), Addr.getBasePointer(),
227-
Index, Name),
228-
ElTy->getElementType(Index),
229-
Addr.getAlignment().alignmentAtOffset(Offset),
230-
Addr.isKnownNonNull());
229+
llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::noUnsignedWrap();
230+
if (!IsBaseConstantNull)
231+
NWFlags |= llvm::GEPNoWrapFlags::inBounds();
232+
return Address(
233+
CreateConstGEP2_32(Addr.getElementType(), Addr.getBasePointer(), 0,
234+
Index, Name, NWFlags),
235+
ElTy->getElementType(Index),
236+
Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull());
231237
}
232238

233239
/// Given

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4738,6 +4738,9 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
47384738
}
47394739

47404740
Expr *BaseExpr = E->getBase();
4741+
// Check whether the underlying base pointer is a constant null.
4742+
// If so, we do not set inbounds flag for GEP to avoid breaking some old-style
4743+
// offsetof idioms.
47414744
Expr *UnderlyingBaseExpr = BaseExpr;
47424745
while (auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
47434746
UnderlyingBaseExpr = BaseMemberExpr->getBase();
@@ -4876,9 +4879,8 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
48764879
unsigned idx =
48774880
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
48784881

4879-
if (IsBaseConstantNull)
4880-
return CGF.Builder.CreateConstGEP(base, idx, field->getName());
4881-
return CGF.Builder.CreateStructGEP(base, idx, field->getName());
4882+
return CGF.Builder.CreateStructGEP(base, idx, field->getName(),
4883+
IsBaseConstantNull);
48824884
}
48834885

48844886
static Address emitPreserveStructAccess(CodeGenFunction &CGF, LValue base,

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@ uintptr_t get_offset_of_y_naively() {
1616
return ((uintptr_t)(&(((S *)nullptr)->y)));
1717
}
1818

19+
struct Empty {};
20+
21+
struct T {
22+
int a;
23+
S s;
24+
[[no_unique_address]] Empty e1;
25+
int b;
26+
[[no_unique_address]] Empty e2;
27+
};
28+
29+
// CHECK-LABEL: @_Z30get_offset_of_y_naively_nestedv(
30+
// CHECK-NEXT: entry:
31+
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr nuw ([[STRUCT_S:%.*]], ptr getelementptr nuw ([[STRUCT_T:%.*]], ptr null, i32 0, i32 1), i32 0, i32 1) to i64)
32+
//
33+
uintptr_t get_offset_of_y_naively_nested() {
34+
return ((uintptr_t)(&(((T *)nullptr)->s.y)));
35+
}
36+
37+
// CHECK-LABEL: @_Z26get_offset_of_zero_storagev(
38+
// CHECK-NEXT: entry:
39+
// CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr (i8, ptr null, i64 16) to i64)
40+
//
41+
uintptr_t get_offset_of_zero_storage() {
42+
return ((uintptr_t)(&(((T *)nullptr)->e2)));
43+
}
44+
1945
// CHECK-LABEL: @_Z27get_offset_of_y_via_builtinv(
2046
// CHECK-NEXT: entry:
2147
// CHECK-NEXT: ret i64 4

0 commit comments

Comments
 (0)