aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-12-17 16:46:40 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-12-17 16:46:40 -0500
commit4f05d85a22351720d860afb788cc5cdaffca92ca (patch)
treef09533c4151488583374ed223b5d904118a1fc44
parent9c7b2b0ba8687f92f7beab2e3615a1107c7063db (diff)
downloadgcc-4f05d85a22351720d860afb788cc5cdaffca92ca.zip
gcc-4f05d85a22351720d860afb788cc5cdaffca92ca.tar.gz
gcc-4f05d85a22351720d860afb788cc5cdaffca92ca.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/constexpr.c27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C12
3 files changed, 39 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e5824d5..91837d3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
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.
* decl.c (redeclaration_error_message): Recurse for variable
templates.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index f3f03e7..87d78d2 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C
new file mode 100644
index 0000000..b94cf30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi1.C
@@ -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" }