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