mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-11 21:03:45 +08:00
PR c++/79592 - missing explanation of invalid constexpr.
We changed months back to use the pre-generic form for constexpr evaluation, but explain_invalid_constexpr_fn was still using DECL_SAVED_TREE. This mostly works, but misses some issues due to folding. So with this patch we save the pre-generic form of constexpr functions even when we know they can't produce a constant result. * constexpr.c (register_constexpr_fundef): Do store the body of a template instantiation that is not potentially constant. (explain_invalid_constexpr_fn): Look it up. (cxx_eval_call_expression): Check fundef->result. From-SVN: r279473
This commit is contained in:
parent
9c7b2b0ba8
commit
4f05d85a22
@ -1,3 +1,11 @@
|
||||
2019-12-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/79592 - missing explanation of invalid constexpr.
|
||||
* constexpr.c (register_constexpr_fundef): Do store the body of a
|
||||
template instantiation that is not potentially constant.
|
||||
(explain_invalid_constexpr_fn): Look it up.
|
||||
(cxx_eval_call_expression): Check fundef->result.
|
||||
|
||||
2019-12-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/92576 - redeclaration of variable template.
|
||||
|
@ -885,16 +885,16 @@ register_constexpr_fundef (tree fun, tree body)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!potential_rvalue_constant_expression (massaged))
|
||||
{
|
||||
if (!DECL_GENERATED_P (fun))
|
||||
require_potential_rvalue_constant_expression (massaged);
|
||||
return NULL;
|
||||
}
|
||||
bool potential = potential_rvalue_constant_expression (massaged);
|
||||
if (!potential && !DECL_GENERATED_P (fun))
|
||||
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 (!potential && !DECL_GENERATED_P (fun))
|
||||
return NULL;
|
||||
|
||||
/* Create the constexpr function table if necessary. */
|
||||
@ -917,6 +917,12 @@ register_constexpr_fundef (tree fun, tree body)
|
||||
if (clear_ctx)
|
||||
DECL_CONTEXT (DECL_RESULT (fun)) = NULL_TREE;
|
||||
|
||||
if (!potential)
|
||||
/* For a template instantiation, we want to remember the pre-generic body
|
||||
for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression
|
||||
that it doesn't need to bother trying to expand the function. */
|
||||
entry.result = error_mark_node;
|
||||
|
||||
gcc_assert (*slot == NULL);
|
||||
*slot = ggc_alloc<constexpr_fundef> ();
|
||||
**slot = entry;
|
||||
@ -962,11 +968,15 @@ explain_invalid_constexpr_fn (tree fun)
|
||||
{
|
||||
/* Then if it's OK, the body. */
|
||||
if (!DECL_DECLARED_CONSTEXPR_P (fun)
|
||||
&& !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)))
|
||||
&& DECL_DEFAULTED_FN (fun))
|
||||
explain_implicit_non_constexpr (fun);
|
||||
else
|
||||
{
|
||||
body = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
|
||||
if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun))
|
||||
body = fd->body;
|
||||
else
|
||||
body = DECL_SAVED_TREE (fun);
|
||||
body = massage_constexpr_body (fun, body);
|
||||
require_potential_rvalue_constant_expression (body);
|
||||
if (DECL_CONSTRUCTOR_P (fun))
|
||||
cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true);
|
||||
@ -1919,6 +1929,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
|
||||
{
|
||||
new_call.fundef = retrieve_constexpr_fundef (fun);
|
||||
if (new_call.fundef == NULL || new_call.fundef->body == NULL
|
||||
|| new_call.fundef->result == error_mark_node
|
||||
|| fun == current_function_decl)
|
||||
{
|
||||
if (!ctx->quiet)
|
||||
|
12
gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C
Normal file
@ -0,0 +1,12 @@
|
||||
// PR c++/79592
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct pthread_mutex {
|
||||
void *m_ptr;
|
||||
};
|
||||
|
||||
struct M {
|
||||
pthread_mutex m = { ((void *) 1LL) }; // { dg-error "reinterpret_cast" }
|
||||
};
|
||||
|
||||
constexpr M m; // { dg-error "M::M" }
|
Loading…
Reference in New Issue
Block a user