aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/tree.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-10-07 20:34:53 -0400
committerJason Merrill <jason@redhat.com>2022-10-12 11:38:05 -0400
commit9bf74082bc93226e1ceb66430706e957e460c841 (patch)
tree43df246d62d87945fb10948b4cdab83734adfe55 /gcc/cp/tree.cc
parentbfcd9f84531fa99e9d00efd8bcfd3c8ac16fa360 (diff)
downloadgcc-9bf74082bc93226e1ceb66430706e957e460c841.zip
gcc-9bf74082bc93226e1ceb66430706e957e460c841.tar.gz
gcc-9bf74082bc93226e1ceb66430706e957e460c841.tar.bz2
c++: defer all consteval in default args [DR2631]
The proposed resolution of CWG2631 extends our current handling of source_location::current to all consteval functions: default arguments are not evaluated until they're used in a call, the same should apply to evaluation of immediate invocations. And similarly for default member initializers. Previously we folded source_location::current in cp_fold_r; now we fold all consteval calls in default arguments/member initializers in bot_replace. DR 2631 gcc/cp/ChangeLog: * cp-tree.h (source_location_current_p): Remove. * name-lookup.h (struct cp_binding_level): Remove immediate_fn_ctx_p. * call.cc (in_immediate_context): All default args and DMI are potentially immediate context. (immediate_invocation_p): Don't treat source_location specially. (struct in_consteval_if_p_temp_override): Move to cp-tree.h. * constexpr.cc (get_nth_callarg): Move to cp-tree.h. * cp-gimplify.cc (cp_fold_r): Don't fold consteval. * name-lookup.cc (begin_scope): Don't set immediate_fn_ctx_p. * parser.cc (cp_parser_lambda_declarator_opt): Likewise. (cp_parser_direct_declarator): Likewise. * pt.cc (tsubst_default_argument): Open sk_function_parms level. * tree.cc (source_location_current_p): Remove. (bot_replace): Fold consteval here. (break_out_target_exprs): Handle errors. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/consteval-defarg3.C: New test.
Diffstat (limited to 'gcc/cp/tree.cc')
-rw-r--r--gcc/cp/tree.cc52
1 files changed, 24 insertions, 28 deletions
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 3532e44..45348c5 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -3125,32 +3125,6 @@ array_type_nelts_total (tree type)
return sz;
}
-/* Return true if FNDECL is std::source_location::current () method. */
-
-bool
-source_location_current_p (tree fndecl)
-{
- gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL
- && DECL_IMMEDIATE_FUNCTION_P (fndecl));
- if (DECL_NAME (fndecl) == NULL_TREE
- || TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != RECORD_TYPE
- || DECL_CONTEXT (fndecl) != TREE_TYPE (TREE_TYPE (fndecl))
- || !id_equal (DECL_NAME (fndecl), "current"))
- return false;
-
- tree source_location = DECL_CONTEXT (fndecl);
- if (TYPE_NAME (source_location) == NULL_TREE
- || TREE_CODE (TYPE_NAME (source_location)) != TYPE_DECL
- || TYPE_IDENTIFIER (source_location) == NULL_TREE
- || !id_equal (TYPE_IDENTIFIER (source_location),
- "source_location")
- || !decl_in_std_namespace_p (TYPE_NAME (source_location)))
- return false;
-
- return true;
-}
-
struct bot_data
{
splay_tree target_remap;
@@ -3298,7 +3272,7 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_)
variables. */
static tree
-bot_replace (tree* t, int* /*walk_subtrees*/, void* data_)
+bot_replace (tree* t, int* walk_subtrees, void* data_)
{
bot_data &data = *(bot_data*)data_;
splay_tree target_remap = data.target_remap;
@@ -3328,6 +3302,27 @@ bot_replace (tree* t, int* /*walk_subtrees*/, void* data_)
/*check_access=*/false, /*nonnull=*/true,
tf_warning_or_error);
}
+ else if (cxx_dialect >= cxx20
+ && (TREE_CODE (*t) == CALL_EXPR
+ || TREE_CODE (*t) == AGGR_INIT_EXPR)
+ && !in_immediate_context ())
+ {
+ /* Expand immediate invocations. */
+ if (tree fndecl = cp_get_callee_fndecl_nofold (*t))
+ if (DECL_IMMEDIATE_FUNCTION_P (fndecl))
+ {
+ /* Make in_immediate_context true within the args. */
+ in_consteval_if_p_temp_override ito;
+ in_consteval_if_p = true;
+ int nargs = call_expr_nargs (*t);
+ for (int i = 0; i < nargs; ++i)
+ cp_walk_tree (&get_nth_callarg (*t, i), bot_replace, data_, NULL);
+ *t = cxx_constant_value (*t);
+ if (*t == error_mark_node)
+ return error_mark_node;
+ *walk_subtrees = 0;
+ }
+ }
return NULL_TREE;
}
@@ -3353,7 +3348,8 @@ break_out_target_exprs (tree t, bool clear_location /* = false */)
bot_data data = { target_remap, clear_location };
if (cp_walk_tree (&t, bot_manip, &data, NULL) == error_mark_node)
t = error_mark_node;
- cp_walk_tree (&t, bot_replace, &data, NULL);
+ if (cp_walk_tree (&t, bot_replace, &data, NULL) == error_mark_node)
+ t = error_mark_node;
if (!--target_remap_count)
{