Skip to content

Commit befe3a6

Browse files
committed
[TBAA] Don't emit pointer-tbaa for void pointers.
While there are no special rules in the standards regarding void pointers and strict aliasing, emitting distinct tags for void pointers break some common idioms and there is no good alternative to re-write the code without strict-aliasing violations. An example is to count the entries in an array of pointers: int count_elements(void * values) { void **seq = values; int count; for (count = 0; seq && seq[count]; count++); return count; } https://clang.godbolt.org/z/8dTv51v8W An example in the wild is from #119099 This patch avoids emitting distinct tags for void pointers, to avoid those idioms causing mis-compiles for now.
1 parent dcdf44a commit befe3a6

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,14 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
226226
PtrDepth++;
227227
Ty = Ty->getPointeeType()->getBaseElementTypeUnsafe();
228228
} while (Ty->isPointerType());
229+
230+
// While there are no special rules in the standards regarding void pointers
231+
// and strict aliasing, emitting distinct tags for void pointers break some
232+
// common idioms and there is no good alternative to re-write the code
233+
// without strict-aliasing violations.
234+
if (Ty->isVoidType())
235+
return AnyPtr;
236+
229237
assert(!isa<VariableArrayType>(Ty));
230238
// When the underlying type is a builtin type, we compute the pointee type
231239
// string recursively, which is implicitly more forgiving than the standards

clang/test/CodeGen/tbaa-pointers.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,9 @@ int void_ptrs(void **ptr) {
208208
// COMMON-LABEL: define i32 @void_ptrs(
209209
// COMMON-SAME: ptr noundef [[PTRA:%.+]])
210210
// COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8
211-
// DISABLE-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
212-
// DISABLE-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
213-
// DISABLE-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]]
214-
// DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID:!.+]]
215-
// DEFAULT-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID]]
216-
// DEFAULT-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[P1VOID:!.+]]
211+
// COMMON-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
212+
// COMMON-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]]
213+
// COMMON-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]]
217214
// COMMON-NEXT: [[BOOL:%.+]] = icmp ne ptr [[L1]], null
218215
// COMMON-NEXT: [[BOOL_EXT:%.+]] = zext i1 [[BOOL]] to i64
219216
// COMMON-NEXT: [[COND:%.+]] = select i1 [[BOOL]], i32 0, i32 1
@@ -254,7 +251,3 @@ int void_ptrs(void **ptr) {
254251
// COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0}
255252
// COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0}
256253
// DEFAULT: [[ANYPTR]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0}
257-
// DEFAULT: [[P2VOID]] = !{[[P2VOID_TY:!.+]], [[P2VOID_TY]], i64 0}
258-
// DEFAULT: [[P2VOID_TY]] = !{!"p2 void", [[ANY_POINTER]], i64 0}
259-
// DEFAULT: [[P1VOID]] = !{[[P1VOID_TY:!.+]], [[P1VOID_TY]], i64 0}
260-
// DEFAULT: [[P1VOID_TY]] = !{!"p1 void", [[ANY_POINTER]], i64 0}

0 commit comments

Comments
 (0)