[clang] [Clang] Fix offsetof sign-extending unsigned array indices >= 128 (PR #204139)
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 2 20:55:30 PDT 2026
================
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter
+
+// Test that offsetof correctly zero-extends unsigned array indices >= 128.
+// Previously, Clang would sign-extend uint8_t indices >= 128, producing
+// a large bogus offset value instead of the correct one.
+// Also tests that negative indices and oversized __uint128_t indices are rejected.
+// https://github.com/llvm/llvm-project/issues/199319
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long long uint64_t;
+
+struct MyStruct {
+ void *ptrs[256];
+};
+
+// Unsigned indices that were previously sign-extended must be zero-extended.
+_Static_assert(__builtin_offsetof(struct MyStruct, ptrs[(uint8_t)127]) == 127 * sizeof(void *),
+ "offsetof with uint8_t index 127 should be correct");
+
+_Static_assert(__builtin_offsetof(struct MyStruct, ptrs[(uint8_t)128]) == 128 * sizeof(void *),
+ "offsetof with uint8_t index 128 should be correctly zero-extended, not sign-extended");
+
+_Static_assert(__builtin_offsetof(struct MyStruct, ptrs[(uint8_t)255]) == 255 * sizeof(void *),
+ "offsetof with uint8_t index 255 should be correctly zero-extended, not sign-extended");
+
+// uint16_t index: values >= 32768 were also affected by sign-extension.
+struct BigStruct { char data[65536]; };
+_Static_assert(__builtin_offsetof(struct BigStruct, data[(uint16_t)32768]) == 32768,
+ "offsetof with uint16_t index 32768 should be correctly zero-extended");
+
+// Negative indices must be rejected.
+struct NegIdxStruct { int a; int x[1]; };
+_Static_assert(__builtin_offsetof(struct NegIdxStruct, x[-1]) == 0, ""); // expected-error {{not an integral constant expression}}
+
+// __uint128_t indices >= 0x8000000000000000 must be rejected.
----------------
shafik wrote:
So the comment should note what is special about `0x8000000000000000` this is signed int 128 min but why is that special?
https://github.com/llvm/llvm-project/pull/204139
More information about the cfe-commits
mailing list