[clang] [clang][bytecode] Fix pseudo dtor calls on non-pointers (PR #153970)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Aug 16 11:36:52 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
The isGLValue() check made us ignore expressions we shouldn't ignore.
---
Full diff: https://github.com/llvm/llvm-project/pull/153970.diff
2 Files Affected:
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+2-1)
- (modified) clang/test/AST/ByteCode/builtin-functions.cpp (+43)
``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 8e651cf060620..4c3fb78260a7b 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5146,7 +5146,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
if (!this->emitCheckPseudoDtor(E))
return false;
const Expr *Base = PD->getBase();
- if (!Base->isGLValue())
+ // E.g. `using T = int; 0.~T();`.
+ if (OptPrimType BaseT = classify(Base); !BaseT || BaseT != PT_Ptr)
return this->discard(Base);
if (!this->visit(Base))
return false;
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp
index 1223cf8bdc74f..878c0d1a40f26 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -21,6 +21,27 @@
#error "huh?"
#endif
+
+inline constexpr void* operator new(__SIZE_TYPE__, void* p) noexcept { return p; }
+namespace std {
+ using size_t = decltype(sizeof(0));
+ template<typename T> struct allocator {
+ constexpr T *allocate(size_t N) {
+ return (T*)__builtin_operator_new(sizeof(T) * N); // #alloc
+ }
+ constexpr void deallocate(void *p, __SIZE_TYPE__) {
+ __builtin_operator_delete(p);
+ }
+ };
+template<typename T, typename... Args>
+constexpr T* construct_at(T* p, Args&&... args) { return ::new((void*)p) T(static_cast<Args&&>(args)...); }
+
+ template<typename T>
+ constexpr void destroy_at(T* p) {
+ p->~T();
+ }
+}
+
extern "C" {
typedef decltype(sizeof(int)) size_t;
extern size_t wcslen(const wchar_t *p);
@@ -1767,6 +1788,28 @@ namespace WithinLifetime {
}
} xstd; // both-error {{is not a constant expression}} \
// both-note {{in call to}}
+
+ consteval bool test_dynamic(bool read_after_deallocate) {
+ std::allocator<int> a;
+ int* p = a.allocate(1);
+ // a.allocate starts the lifetime of an array,
+ // the complete object of *p has started its lifetime
+ if (__builtin_is_within_lifetime(p))
+ return false;
+ std::construct_at(p);
+ if (!__builtin_is_within_lifetime(p))
+ return false;
+ std::destroy_at(p);
+ if (__builtin_is_within_lifetime(p))
+ return false;
+ a.deallocate(p, 1);
+ if (read_after_deallocate)
+ __builtin_is_within_lifetime(p); // both-note {{read of heap allocated object that has been deleted}}
+ return true;
+ }
+ static_assert(test_dynamic(false));
+ static_assert(test_dynamic(true)); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
}
#ifdef __SIZEOF_INT128__
``````````
</details>
https://github.com/llvm/llvm-project/pull/153970
More information about the cfe-commits
mailing list