================
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to