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<T>()` 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
