Skip to content

Commit 824a5e7

Browse files
committed
[Clang][CodeGen] Do not set inbounds in EmitMemberDataPointerAddress when the base pointer is null
1 parent 57a9088 commit 824a5e7

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -872,9 +872,14 @@ llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
872872

873873
CGBuilderTy &Builder = CGF.Builder;
874874

875-
// Apply the offset, which we assume is non-null.
876-
return Builder.CreateInBoundsGEP(CGF.Int8Ty, Base.emitRawPointer(CGF), MemPtr,
877-
"memptr.offset");
875+
// Apply the offset.
876+
// Specially, we don't add inbounds flags if the base pointer is a constant
877+
// null. This is a workaround for old-style container_of macros.
878+
llvm::Value *BaseAddr = Base.emitRawPointer(CGF);
879+
return Builder.CreateGEP(CGF.Int8Ty, BaseAddr, MemPtr, "memptr.offset",
880+
isa<llvm::ConstantPointerNull>(BaseAddr)
881+
? llvm::GEPNoWrapFlags::none()
882+
: llvm::GEPNoWrapFlags::inBounds());
878883
}
879884

880885
// See if it's possible to return a constant signed pointer.

clang/lib/CodeGen/MicrosoftCXXABI.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3265,9 +3265,13 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
32653265
Addr = Base.emitRawPointer(CGF);
32663266
}
32673267

3268-
// Apply the offset, which we assume is non-null.
3269-
return Builder.CreateInBoundsGEP(CGF.Int8Ty, Addr, FieldOffset,
3270-
"memptr.offset");
3268+
// Apply the offset.
3269+
// Specially, we don't add inbounds flags if the base pointer is a constant
3270+
// null. This is a workaround for old-style container_of macros.
3271+
return Builder.CreateGEP(CGF.Int8Ty, Addr, FieldOffset, "memptr.offset",
3272+
isa<llvm::ConstantPointerNull>(Addr)
3273+
? llvm::GEPNoWrapFlags::none()
3274+
: llvm::GEPNoWrapFlags::inBounds());
32713275
}
32723276

32733277
llvm::Value *

clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,3 +964,24 @@ static_assert(sizeof(b::d) == 16, "");
964964
static_assert(sizeof(void (a<int>::*)()) == 16, "");
965965
#endif
966966
}
967+
968+
namespace ContainerOf {
969+
using size_t = unsigned long long;
970+
971+
struct List {
972+
int data;
973+
};
974+
975+
struct Node {
976+
int data;
977+
struct List list1;
978+
struct List list2;
979+
};
980+
981+
// CHECK-LABEL: define{{.*}} ptr @"?getOwner@ContainerOf@@
982+
// CHECK: %memptr.offset = getelementptr i8, ptr null, {{.*}}
983+
Node* getOwner(List *list, List Node::*member) {
984+
size_t offset = reinterpret_cast<size_t>(&((Node*)nullptr->*member));
985+
return reinterpret_cast<Node*>(reinterpret_cast<char*>(list) - offset);
986+
}
987+
}

clang/test/CodeGenCXX/pointers-to-data-members.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,24 @@ namespace PR47864 {
265265
struct D : B { int m; };
266266
auto x = (int B::*)&D::m;
267267
}
268+
269+
namespace ContainerOf {
270+
using size_t = unsigned long long;
271+
272+
struct List {
273+
int data;
274+
};
275+
276+
struct Node {
277+
int data;
278+
struct List list1;
279+
struct List list2;
280+
};
281+
282+
// CHECK-LABEL: define{{.*}} ptr @_ZN11ContainerOf8getOwnerEPNS_4ListEMNS_4NodeES0_
283+
// CHECK: %memptr.offset = getelementptr i8, ptr null, i64 {{.*}}
284+
Node* getOwner(List *list, List Node::*member) {
285+
size_t offset = reinterpret_cast<size_t>(&((Node*)nullptr->*member));
286+
return reinterpret_cast<Node*>(reinterpret_cast<char*>(list) - offset);
287+
}
288+
}

0 commit comments

Comments
 (0)