From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 18589385842D; Mon, 15 Nov 2021 07:52:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 18589385842D MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-5256] c++: check constexpr constructor body X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/master X-Git-Oldrev: daa9c6b015a33fa98af0ee7cd6919120248ab5f9 X-Git-Newrev: 37326651b439bac55d96fb5a43f4daf25e401eda Message-Id: <20211115075241.18589385842D@sourceware.org> Date: Mon, 15 Nov 2021 07:52:41 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Nov 2021 07:52:41 -0000 https://gcc.gnu.org/g:37326651b439bac55d96fb5a43f4daf25e401eda commit r12-5256-g37326651b439bac55d96fb5a43f4daf25e401eda Author: Jason Merrill Date: Sat Nov 13 16:59:31 2021 -0500 c++: check constexpr constructor body The implicit constexpr patch revealed that our checks for constexpr constructors that could possibly produce a constant value (which otherwise are IFNDR) was failing to look at most of the function body. Fixing that required some library tweaks. gcc/cp/ChangeLog: * constexpr.c (maybe_save_constexpr_fundef): Also check whether the body of a constructor is potentially constant. libstdc++-v3/ChangeLog: * src/c++17/memory_resource.cc: Add missing constexpr. * include/experimental/internet: Only mark copy constructor as constexpr with __cpp_constexpr_dynamic_alloc. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-89285-2.C: Expect error. * g++.dg/cpp1y/constexpr-89285.C: Adjust error. Diff: --- gcc/cp/constexpr.c | 27 +++++++++++++++++++------- gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C | 2 +- gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C | 2 +- libstdc++-v3/src/c++17/memory_resource.cc | 2 +- libstdc++-v3/include/experimental/internet | 2 ++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 82a597d7bad..c92db5d413c 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -870,7 +870,9 @@ maybe_save_constexpr_fundef (tree fun) || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))) return; - if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun))) + bool complain = !DECL_GENERATED_P (fun); + + if (!is_valid_constexpr_fn (fun, complain)) return; tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun)); @@ -883,15 +885,26 @@ maybe_save_constexpr_fundef (tree fun) } bool potential = potential_rvalue_constant_expression (massaged); - if (!potential && !DECL_GENERATED_P (fun)) + if (!potential && complain) require_potential_rvalue_constant_expression (massaged); - if (DECL_CONSTRUCTOR_P (fun) - && cx_check_missing_mem_inits (DECL_CONTEXT (fun), - massaged, !DECL_GENERATED_P (fun))) - potential = false; + if (DECL_CONSTRUCTOR_P (fun) && potential) + { + if (cx_check_missing_mem_inits (DECL_CONTEXT (fun), + massaged, complain)) + potential = false; + else if (cxx_dialect > cxx11) + { + /* What we got from massage_constexpr_body is pretty much just the + ctor-initializer, also check the body. */ + massaged = DECL_SAVED_TREE (fun); + potential = potential_rvalue_constant_expression (massaged); + if (!potential && complain) + require_potential_rvalue_constant_expression (massaged); + } + } - if (!potential && !DECL_GENERATED_P (fun)) + if (!potential && complain) return; constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE}; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C index 656bc9cb7f1..ea44daa849e 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C @@ -10,7 +10,7 @@ struct B { int *c = &x->a; while (*c) c = reinterpret_cast((reinterpret_cast(c) + *c)); - *c = reinterpret_cast(this) - reinterpret_cast(c); + *c = reinterpret_cast(this) - reinterpret_cast(c); // { dg-error "reinterpret_cast" } } }; struct C : A { diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C index 3809e1f7a9f..26aab9b6a50 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C @@ -17,4 +17,4 @@ struct C : A { B bar {this}; }; -constexpr C foo {}; // { dg-message "expansion of" } +constexpr C foo {}; // { dg-message "" } diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc index 1ba79903f87..9fc3bb754c1 100644 --- a/libstdc++-v3/src/c++17/memory_resource.cc +++ b/libstdc++-v3/src/c++17/memory_resource.cc @@ -603,7 +603,7 @@ namespace pmr void* pointer = nullptr; aligned_size _M_size; - size_t size() const noexcept + constexpr size_t size() const noexcept { if (_M_size.value == size_t(-1)) [[unlikely]] return size_t(-1); diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet index 65c97de07d9..95b8cdc9963 100644 --- a/libstdc++-v3/include/experimental/internet +++ b/libstdc++-v3/include/experimental/internet @@ -460,7 +460,9 @@ namespace ip // constructors: constexpr address() noexcept : _M_v4(), _M_is_v4(true) { } +#if __cpp_constexpr_dynamic_alloc constexpr +#endif address(const address& __a) noexcept : _M_uninit(), _M_is_v4(__a._M_is_v4) { if (_M_is_v4)