diff options
author | Jason Merrill <jason@redhat.com> | 2022-10-07 20:34:53 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-10-12 11:38:05 -0400 |
commit | 9bf74082bc93226e1ceb66430706e957e460c841 (patch) | |
tree | 43df246d62d87945fb10948b4cdab83734adfe55 /gcc/cp/tree.cc | |
parent | bfcd9f84531fa99e9d00efd8bcfd3c8ac16fa360 (diff) | |
download | gcc-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.cc | 52 |
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) { |