diff options
author | Jason Merrill <jason@redhat.com> | 2023-05-09 18:48:11 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-05-10 11:09:56 -0400 |
commit | 688fdde2f18e3318ef7e9889fdb9b239b905dfc7 (patch) | |
tree | bdec6a44678c94b6d22f8ffa400506a32fa64e4c /gcc/cp/constexpr.cc | |
parent | a056a9868e6ecab24b0b7e4e12e846097b8c8fb0 (diff) | |
download | gcc-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.cc | 22 |
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 |