aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-05-09 18:48:11 -0400
committerJason Merrill <jason@redhat.com>2023-05-10 11:09:56 -0400
commit688fdde2f18e3318ef7e9889fdb9b239b905dfc7 (patch)
treebdec6a44678c94b6d22f8ffa400506a32fa64e4c /gcc/cp/constexpr.cc
parenta056a9868e6ecab24b0b7e4e12e846097b8c8fb0 (diff)
downloadgcc-688fdde2f18e3318ef7e9889fdb9b239b905dfc7.zip
gcc-688fdde2f18e3318ef7e9889fdb9b239b905dfc7.tar.gz
gcc-688fdde2f18e3318ef7e9889fdb9b239b905dfc7.tar.bz2
c++: always check consteval address
The restriction on the "permitted result of a constant expression" to not refer to an immediate function applies regardless of context. The previous code tried to only check in cases where we wouldn't get the check in cp_fold_r, but with the next patch I would need to add another case and it shouldn't be a problem to always check. We also shouldn't talk about immediate evaluation when we aren't dealing with one. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): Always check for address of immediate fn. (maybe_constant_init_1): Evaluate PTRMEM_CST. gcc/testsuite/ChangeLog: * g++.dg/DRs/dr2478.C: Handle -fimplicit-constexpr. * g++.dg/cpp23/consteval-if12.C: Adjust diagnostics. * g++.dg/cpp2a/consteval20.C: Likewise. * g++.dg/cpp2a/consteval24.C: Likewise. * g++.dg/cpp2a/srcloc20.C: Likewise.
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc22
1 files changed, 15 insertions, 7 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 987a536..7b80906 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8353,7 +8353,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
non_constant_p = true;
}
- if (!global_ctx.heap_vars.is_empty ())
+ if (!non_constant_p && cxx_dialect >= cxx20
+ && !global_ctx.heap_vars.is_empty ())
{
tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
NULL);
@@ -8384,15 +8385,22 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
/* Check that immediate invocation does not return an expression referencing
any immediate function decls. */
- if (is_consteval || in_immediate_context ())
+ if (!non_constant_p && cxx_dialect >= cxx20)
if (tree immediate_fndecl
= cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
NULL))
{
if (!allow_non_constant && !non_constant_p)
- error_at (cp_expr_loc_or_input_loc (t),
- "immediate evaluation returns address of immediate "
- "function %qD", immediate_fndecl);
+ {
+ if (is_consteval)
+ error_at (cp_expr_loc_or_input_loc (t),
+ "immediate evaluation returns address of immediate "
+ "function %qD", immediate_fndecl);
+ else
+ error_at (cp_expr_loc_or_input_loc (t),
+ "constant evaluation returns address of immediate "
+ "function %qD", immediate_fndecl);
+ }
r = t;
non_constant_p = true;
}
@@ -8795,8 +8803,8 @@ maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
t = TARGET_EXPR_INITIAL (t);
if (!is_nondependent_static_init_expression (t))
/* Don't try to evaluate it. */;
- else if (CONSTANT_CLASS_P (t) && allow_non_constant)
- /* No evaluation needed. */;
+ else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
+ /* No evaluation needed. PTRMEM_CST needs the immediate fn check. */;
else
{
/* [basic.start.static] allows constant-initialization of variables with