llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: puneeth_aditya_5656 (mugiwaraluffy56)

<details>
<summary>Changes</summary>

## Summary
When dereferencing a pointer that was `reinterpret_cast` to a larger type (e.g. 
`*(int**)""`), the bytecode interpreter would crash with an assertion failure 
because it tried to read more bytes than the allocation contained.

## Changes
- Add a size check in `Pointer::toRValue()` before calling `deref&lt;T&gt;()` 
to ensure the allocation is large enough
- If the allocation is too small, return `std::nullopt` to gracefully fail the 
constant evaluation instead of crashing
- Add regression test

Fixes #<!-- -->179015

---
Full diff: https://github.com/llvm/llvm-project/pull/179030.diff


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Pointer.cpp (+5) 
- (added) clang/test/AST/ByteCode/crash-GH179015.cpp (+14) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index a1ab492e5cb37..6286cbd7e3a62 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -947,6 +947,11 @@ std::optional<APValue> Pointer::toRValue(const Context 
&Ctx,
 
   // Just load primitive types.
   if (OptPrimType T = Ctx.classify(ResultType)) {
+    // Check that the allocation is large enough to read the value.
+    // This might not be the case when we reinterpret_cast a pointer to
+    // a larger type (e.g. *(int**)"").
+    if (Offset + primSize(*T) > BS.Pointee->getDescriptor()->getAllocSize())
+      return std::nullopt;
     TYPE_SWITCH(*T, return this->deref<T>().toAPValue(ASTCtx));
   }
 
diff --git a/clang/test/AST/ByteCode/crash-GH179015.cpp 
b/clang/test/AST/ByteCode/crash-GH179015.cpp
new file mode 100644
index 0000000000000..359554121af1f
--- /dev/null
+++ b/clang/test/AST/ByteCode/crash-GH179015.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++14 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++17 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++20 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++23 %s 
-fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -verify -std=c++2c %s 
-fexperimental-new-constant-interpreter
+
+// https://github.com/llvm/llvm-project/issues/179015
+// Ensure we don't crash when trying to dereference a cast pointer where the
+// target type is larger than the source allocation.
+
+void foo() {
+  *(int **)""; // expected-warning {{expression result unused}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/179030
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to