From 37326651b439bac55d96fb5a43f4daf25e401eda Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 13 Nov 2021 16:59:31 -0500 Subject: 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. --- gcc/cp/constexpr.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'gcc/cp/constexpr.c') diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 82a597d..c92db5d 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}; -- cgit v1.1