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.
This commit is contained in:
parent
daa9c6b015
commit
37326651b4
5 changed files with 25 additions and 10 deletions
|
@ -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};
|
||||
|
|
|
@ -10,7 +10,7 @@ struct B {
|
|||
int *c = &x->a;
|
||||
while (*c)
|
||||
c = reinterpret_cast<int *>((reinterpret_cast<char *>(c) + *c));
|
||||
*c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c);
|
||||
*c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" }
|
||||
}
|
||||
};
|
||||
struct C : A {
|
||||
|
|
|
@ -17,4 +17,4 @@ struct C : A {
|
|||
B bar {this};
|
||||
};
|
||||
|
||||
constexpr C foo {}; // { dg-message "expansion of" }
|
||||
constexpr C foo {}; // { dg-message "" }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -603,7 +603,7 @@ namespace pmr
|
|||
void* pointer = nullptr;
|
||||
aligned_size<min> _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);
|
||||
|
|
Loading…
Add table
Reference in a new issue