aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc43
1 files changed, 31 insertions, 12 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 4346b29..f56c5c4 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -307,7 +307,14 @@ is_valid_constexpr_fn (tree fun, bool complain)
{
ret = false;
if (complain)
- error ("%q#T has virtual base classes", DECL_CONTEXT (fun));
+ {
+ if (DECL_CONSTRUCTOR_P (fun))
+ error ("%<constexpr%> constructor in %q#T that has "
+ "virtual base classes", DECL_CONTEXT (fun));
+ else
+ error ("%<constexpr%> destructor in %q#T that has "
+ "virtual base classes", DECL_CONTEXT (fun));
+ }
}
return ret;
@@ -1048,6 +1055,12 @@ explain_invalid_constexpr_fn (tree fun)
{
static hash_set<tree> *diagnosed;
tree body;
+
+ /* Don't try to explain a function we already complained about. */
+ if (function *f = DECL_STRUCT_FUNCTION (fun))
+ if (f->language->erroneous)
+ return;
+
/* In C++23, a function marked 'constexpr' may not actually be a constant
expression. We haven't diagnosed the problem yet: -Winvalid-constexpr
wasn't enabled. The function was called, so diagnose why it cannot be
@@ -3079,6 +3092,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
constexpr_ctx new_ctx = *ctx;
+ ctx = &new_ctx;
if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
&& TREE_CODE (t) == AGGR_INIT_EXPR)
{
@@ -3088,16 +3102,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
CONSTRUCTOR_NO_CLEARING (ctor) = true;
ctx->global->put_value (new_ctx.object, ctor);
- ctx = &new_ctx;
}
/* An immediate invocation is manifestly constant evaluated including the
arguments of the call, so use mce_true even for the argument
evaluation. */
if (DECL_IMMEDIATE_FUNCTION_P (fun))
- {
- new_ctx.manifestly_const_eval = mce_true;
- ctx = &new_ctx;
- }
+ new_ctx.manifestly_const_eval = mce_true;
/* We used to shortcut trivial constructor/op= here, but nowadays
we can only get a trivial function here with -fno-elide-constructors. */
@@ -3185,6 +3195,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
}
+ /* Don't complain about problems evaluating an ill-formed function. */
+ if (function *f = DECL_STRUCT_FUNCTION (fun))
+ if (f->language->erroneous)
+ new_ctx.quiet = true;
+
int depth_ok = push_cx_call_context (t);
/* Remember the object we are constructing or destructing. */
@@ -9254,9 +9269,11 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
if (heap_var)
{
if (!allow_non_constant && !non_constant_p)
- error_at (DECL_SOURCE_LOCATION (heap_var),
- "%qE is not a constant expression because it refers to "
- "a result of %<operator new%>", t);
+ {
+ error ("%qE is not a constant expression because it refers to "
+ "a result of %<operator new%>", t);
+ inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
+ }
r = t;
non_constant_p = true;
}
@@ -9265,9 +9282,11 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
if (DECL_NAME (heap_var) != heap_deleted_identifier)
{
if (!allow_non_constant && !non_constant_p)
- error_at (DECL_SOURCE_LOCATION (heap_var),
- "%qE is not a constant expression because allocated "
- "storage has not been deallocated", t);
+ {
+ error ("%qE is not a constant expression because allocated "
+ "storage has not been deallocated", t);
+ inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
+ }
r = t;
non_constant_p = true;
}