Author: marius doerner Date: 2025-03-25T20:39:12+01:00 New Revision: 4067581aea299692d37866183b0a535f561892ad
URL: https://github.com/llvm/llvm-project/commit/4067581aea299692d37866183b0a535f561892ad DIFF: https://github.com/llvm/llvm-project/commit/4067581aea299692d37866183b0a535f561892ad.diff LOG: [clang] Placement new error when modifying consts (#132460) Raise an error when placement new is used to modify a const-qualified variable in a constexpr function. Fixes #131432 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c73f4fd446ac8..04ec2cfef679c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -362,6 +362,8 @@ Bug Fixes to C++ Support - Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892) - Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810) +- Clang now issues an error when placement new is used to modify a const-qualified variable + in a ``constexpr`` function. (#GH131432) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 8b40cdfbd2f1f..95da7b067b459 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10420,7 +10420,16 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { typedef bool result_type; bool failed() { return false; } + bool checkConst(QualType QT) { + if (QT.isConstQualified()) { + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; + return false; + } + return true; + } bool found(APValue &Subobj, QualType SubobjType) { + if (!checkConst(SubobjType)) + return false; // FIXME: Reject the cases where [basic.life]p8 would not permit the // old name of the object to be used to name the new object. unsigned SubobjectSize = 1; diff --git a/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp b/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp index a29fb981cedbf..6f6f9b04aa392 100644 --- a/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp +++ b/clang/test/SemaCXX/cxx2c-constexpr-placement-new.cpp @@ -114,3 +114,42 @@ constexpr bool bleh() { } static_assert(bleh()); // expected-error {{not an integral constant expression}} \ // expected-note {{in call to 'bleh()'}} + +constexpr int modify_const_variable() { + const int a = 10; + new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable()); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} + +typedef const int T0; +typedef T0 T1; +constexpr T1 modify_const_variable_td() { + T1 a = 10; + new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'T1' (aka 'const int') is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_td()); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} + +template<typename T> +constexpr T modify_const_variable_tmpl() { + T a = 10; + new ((int *)&a) int(12); // expected-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}} + return a; +} +static_assert(modify_const_variable_tmpl<const int>()); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} + +namespace ModifyMutableMember { + struct S { + mutable int a {10}; + }; + constexpr int modify_mutable_member() { + const S s; + new ((int *)&s.a) int(12); + return s.a; + } + static_assert(modify_mutable_member() == 12); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits