================
@@ -3801,8 +3801,17 @@ bool Compiler<Emitter>::VisitOffsetOfExpr(const 
OffsetOfExpr *E) {
 
       if (!this->visit(ArrayIndexExpr))
         return false;
-      // Cast to Sint64.
+      // Cast to Sint64. For unsigned types, cast to Uint64 first to avoid
+      // sign-extending values with the high bit set (e.g. uint8_t >= 128).
+      // AP types cannot be safely narrowed to Sint64; fail constant 
evaluation.
----------------
marlus wrote:

Good point, thanks. The previous fix rejected all AP types (PT_IntAP/PT_IntAPS) 
unconditionally, which was too conservative, small values like (__uint128_t)1 
that fit in int64_t should work.
 
Fixed in Compiler.cpp: for AP types, I now evaluate the constant directly using 
EvaluateAsInt, check that the value is non-negative and fits in a signed 64-bit 
integer (isSignedIntN(64)), and push it directly as Sint64. Values that are 
negative or exceed INT64_MAX are still rejected. Added a test case for a small 
__uint128_t value to cover this path.

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