GCC Bugzilla – Attachment 53565 Details for
Bug 106651
[C++23] P1169 - static operator()
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
gcc13-pr106651-wip.patch
gcc13-pr106651-wip.patch (text/plain), 11.15 KB, created by
Jakub Jelinek
on 2022-09-12 17:46:50 UTC
(
hide
)
Description:
gcc13-pr106651-wip.patch
Filename:
MIME Type:
Creator:
Jakub Jelinek
Created:
2022-09-12 17:46:50 UTC
Size:
11.15 KB
patch
obsolete
>--- gcc/cp/cp-tree.h.jj 2022-09-12 10:31:27.703547176 +0200 >+++ gcc/cp/cp-tree.h 2022-09-12 15:18:28.591931918 +0200 >@@ -504,6 +504,7 @@ extern GTY(()) tree cp_global_trees[CPTI > OVL_NESTED_P (in OVERLOAD) > DECL_MODULE_EXPORT_P (in _DECL) > PACK_EXPANSION_FORCE_EXTRA_ARGS_P (in *_PACK_EXPANSION) >+ LAMBDA_EXPR_STATIC_P (in LAMBDA_EXPR) > 4: IDENTIFIER_MARKED (IDENTIFIER_NODEs) > TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, > CALL_EXPR, or FIELD_DECL). >@@ -1488,6 +1489,10 @@ enum cp_lambda_default_capture_mode_type > #define LAMBDA_EXPR_CAPTURE_OPTIMIZED(NODE) \ > TREE_LANG_FLAG_2 (LAMBDA_EXPR_CHECK (NODE)) > >+/* Predicate tracking whether the lambda was declared 'static'. */ >+#define LAMBDA_EXPR_STATIC_P(NODE) \ >+ TREE_LANG_FLAG_3 (LAMBDA_EXPR_CHECK (NODE)) >+ > /* True if this TREE_LIST in LAMBDA_EXPR_CAPTURE_LIST is for an explicit > capture. */ > #define LAMBDA_CAPTURE_EXPLICIT_P(NODE) \ >--- gcc/cp/lambda.cc.jj 2022-05-09 18:20:05.069883739 +0200 >+++ gcc/cp/lambda.cc 2022-09-12 18:16:22.026229443 +0200 >@@ -1098,7 +1098,9 @@ maybe_add_lambda_conv_op (tree type) > tree optype = TREE_TYPE (callop); > tree fn_result = TREE_TYPE (optype); > >- tree thisarg = build_int_cst (TREE_TYPE (DECL_ARGUMENTS (callop)), 0); >+ tree thisarg = NULL_TREE; >+ if (TREE_CODE (optype) == METHOD_TYPE) >+ thisarg = build_int_cst (TREE_TYPE (DECL_ARGUMENTS (callop)), 0); > if (generic_lambda_p) > { > ++processing_template_decl; >@@ -1108,18 +1110,22 @@ maybe_add_lambda_conv_op (tree type) > return expression for a deduced return call op to allow for simple > implementation of the conversion operator. */ > >- tree instance = cp_build_fold_indirect_ref (thisarg); > tree objfn = lookup_template_function (DECL_NAME (callop), > DECL_TI_ARGS (callop)); >- objfn = build_min (COMPONENT_REF, NULL_TREE, >- instance, objfn, NULL_TREE); >- int nargs = list_length (DECL_ARGUMENTS (callop)) - 1; >+ int nargs = list_length (DECL_ARGUMENTS (callop)); >+ if (thisarg) >+ { >+ tree instance = cp_build_fold_indirect_ref (thisarg); >+ objfn = build_min (COMPONENT_REF, NULL_TREE, >+ instance, objfn, NULL_TREE); >+ --nargs; >+ call = prepare_op_call (objfn, nargs); >+ } > >- call = prepare_op_call (objfn, nargs); > if (type_uses_auto (fn_result)) > decltype_call = prepare_op_call (objfn, nargs); > } >- else >+ else if (thisarg) > { > direct_argvec = make_tree_vector (); > direct_argvec->quick_push (thisarg); >@@ -1134,9 +1140,13 @@ maybe_add_lambda_conv_op (tree type) > tree fn_args = NULL_TREE; > { > int ix = 0; >- tree src = DECL_CHAIN (DECL_ARGUMENTS (callop)); >+ tree src = DECL_ARGUMENTS (callop); > tree tgt = NULL; > >+ if (thisarg) >+ src = DECL_CHAIN (src); >+ else if (!decltype_call) >+ src = NULL_TREE; > while (src) > { > tree new_node = copy_node (src); >@@ -1159,12 +1169,15 @@ maybe_add_lambda_conv_op (tree type) > if (generic_lambda_p) > { > tree a = tgt; >- if (DECL_PACK_P (tgt)) >+ if (thisarg) > { >- a = make_pack_expansion (a); >- PACK_EXPANSION_LOCAL_P (a) = true; >+ if (DECL_PACK_P (tgt)) >+ { >+ a = make_pack_expansion (a); >+ PACK_EXPANSION_LOCAL_P (a) = true; >+ } >+ CALL_EXPR_ARG (call, ix) = a; > } >- CALL_EXPR_ARG (call, ix) = a; > > if (decltype_call) > { >@@ -1192,7 +1205,7 @@ maybe_add_lambda_conv_op (tree type) > tf_warning_or_error); > } > } >- else >+ else if (thisarg) > { > /* Don't warn on deprecated or unavailable lambda declarations, unless > the lambda is actually called. */ >@@ -1202,14 +1215,18 @@ maybe_add_lambda_conv_op (tree type) > direct_argvec->address ()); > } > >- CALL_FROM_THUNK_P (call) = 1; >- SET_EXPR_LOCATION (call, UNKNOWN_LOCATION); >+ if (thisarg) >+ { >+ CALL_FROM_THUNK_P (call) = 1; >+ SET_EXPR_LOCATION (call, UNKNOWN_LOCATION); >+ } > >- tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop)); >- stattype = (cp_build_type_attribute_variant >- (stattype, TYPE_ATTRIBUTES (optype))); >- if (flag_noexcept_type >- && TYPE_NOTHROW_P (TREE_TYPE (callop))) >+ tree stattype >+ = build_function_type (fn_result, thisarg ? FUNCTION_ARG_CHAIN (callop) >+ : TYPE_ARG_TYPES (optype)); >+ stattype = cp_build_type_attribute_variant (stattype, >+ TYPE_ATTRIBUTES (optype)); >+ if (flag_noexcept_type && TYPE_NOTHROW_P (TREE_TYPE (callop))) > stattype = build_exception_variant (stattype, noexcept_true_spec); > > if (generic_lambda_p) >@@ -1248,6 +1265,41 @@ maybe_add_lambda_conv_op (tree type) > > add_method (type, fn, false); > >+ if (thisarg == NULL_TREE) >+ { >+ /* For static lambda, just return operator(). */ >+ if (nested) >+ push_function_context (); >+ else >+ /* Still increment function_depth so that we don't GC in the >+ middle of an expression. */ >+ ++function_depth; >+ >+ /* Generate the body of the conversion op. */ >+ >+ start_preparsed_function (convfn, NULL_TREE, >+ SF_PRE_PARSED | SF_INCLASS_INLINE); >+ tree body = begin_function_body (); >+ tree compound_stmt = begin_compound_stmt (0); >+ >+ /* decl_needed_p needs to see that it's used. */ >+ TREE_USED (callop) = 1; >+ finish_return_stmt (decay_conversion (callop, tf_warning_or_error)); >+ >+ finish_compound_stmt (compound_stmt); >+ finish_function_body (body); >+ >+ fn = finish_function (/*inline_p=*/true); >+ if (!generic_lambda_p) >+ expand_or_defer_fn (fn); >+ >+ if (nested) >+ pop_function_context (); >+ else >+ --function_depth; >+ return; >+ } >+ > /* Generic thunk code fails for varargs; we'll complain in mark_used if > the conversion op is used. */ > if (varargs_function_p (callop)) >--- gcc/cp/error.cc.jj 2022-05-25 11:06:58.653513126 +0200 >+++ gcc/cp/error.cc 2022-09-12 16:40:10.225858396 +0200 >@@ -1692,7 +1692,13 @@ dump_lambda_function (cxx_pretty_printer > { > /* A lambda's signature is essentially its "type". */ > dump_type (pp, DECL_CONTEXT (fn), flags); >- if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST)) >+ if (TREE_CODE (TREE_TYPE (fn)) == FUNCTION_TYPE) >+ { >+ pp->padding = pp_before; >+ pp_c_ws_string (pp, "static"); >+ } >+ else if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) >+ & TYPE_QUAL_CONST)) > { > pp->padding = pp_before; > pp_c_ws_string (pp, "mutable"); >--- gcc/cp/decl.cc.jj 2022-09-08 13:01:19.472776458 +0200 >+++ gcc/cp/decl.cc 2022-09-12 19:41:32.564685359 +0200 >@@ -15296,8 +15296,25 @@ grok_op_properties (tree decl, bool comp > an enumeration, or a reference to an enumeration. 13.4.0.6 */ > if (! methodp || DECL_STATIC_FUNCTION_P (decl)) > { >+ if (operator_code == CALL_EXPR) >+ { >+ if (! DECL_STATIC_FUNCTION_P (decl)) >+ { >+ error_at (loc, "%qD must be a member function", decl); >+ return false; >+ } >+ if (cxx_dialect < cxx23 >+ /* For lambdas we diagnose static lambda specifier elsewhere. */ >+ && ! LAMBDA_FUNCTION_P (decl) >+ /* For instantiations, we have diagnosed this already. */ >+ && ! DECL_USE_TEMPLATE (decl)) >+ pedwarn (loc, OPT_Wc__23_extensions, "%qD may be a static member " >+ "function only with %<-std=c++23%> or %<-std=gnu++23%>", decl); >+ /* There are no further restrictions on the arguments to an >+ overloaded "operator ()". */ >+ return true; >+ } > if (operator_code == TYPE_EXPR >- || operator_code == CALL_EXPR > || operator_code == COMPONENT_REF > || operator_code == ARRAY_REF > || operator_code == NOP_EXPR) >--- gcc/cp/parser.cc.jj 2022-09-12 10:31:27.832545389 +0200 >+++ gcc/cp/parser.cc 2022-09-12 16:56:13.147727647 +0200 >@@ -1994,7 +1994,7 @@ enum > constexpr. */ > CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8, > /* When parsing a decl-specifier-seq, only allow mutable, constexpr or >- for C++20 consteval. */ >+ for C++20 consteval or for C++23 static. */ > CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10, > /* When parsing a decl-specifier-seq, allow missing typename. */ > CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20, >@@ -11714,13 +11714,26 @@ cp_parser_lambda_declarator_opt (cp_pars > omitted_parms_loc = UNKNOWN_LOCATION; > } > >- if (lambda_specs.storage_class == sc_mutable) >+ if (lambda_specs.storage_class == sc_mutable >+ || lambda_specs.storage_class == sc_static) > { >- LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1; >- quals = TYPE_UNQUALIFIED; >+ if (lambda_specs.storage_class == sc_mutable) >+ { >+ LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1; >+ quals = TYPE_UNQUALIFIED; >+ } >+ else if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE >+ || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)) >+ error_at (lambda_specs.locations[ds_storage_class], >+ "%<static%> lambda specifier with lambda capture"); >+ else >+ { >+ LAMBDA_EXPR_STATIC_P (lambda_expr) = 1; >+ quals = TYPE_UNQUALIFIED; >+ } > if (lambda_specs.conflicting_specifiers_p) > error_at (lambda_specs.locations[ds_storage_class], >- "duplicate %<mutable%>"); >+ "conflicting lambda specifiers"); > } > > tx_qual = cp_parser_tx_qualifier_opt (parser); >@@ -11807,6 +11820,12 @@ cp_parser_lambda_declarator_opt (cp_pars > if (lambda_specs.locations[ds_consteval]) > return_type_specs.locations[ds_consteval] > = lambda_specs.locations[ds_consteval]; >+ if (LAMBDA_EXPR_STATIC_P (lambda_expr)) >+ { >+ return_type_specs.storage_class = sc_static; >+ return_type_specs.locations[ds_storage_class] >+ = lambda_specs.locations[ds_storage_class]; >+ } > > p = obstack_alloc (&declarator_obstack, 0); > >@@ -11830,8 +11849,9 @@ cp_parser_lambda_declarator_opt (cp_pars > { > DECL_INITIALIZED_IN_CLASS_P (fco) = 1; > DECL_ARTIFICIAL (fco) = 1; >- /* Give the object parameter a different name. */ >- DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier; >+ if (!LAMBDA_EXPR_STATIC_P (lambda_expr)) >+ /* Give the object parameter a different name. */ >+ DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier; > DECL_SET_LAMBDA_FUNCTION (fco, true); > } > if (template_param_list) >@@ -16008,8 +16028,15 @@ cp_parser_decl_specifier_seq (cp_parser* > && token->keyword != RID_MUTABLE > && token->keyword != RID_CONSTEXPR > && token->keyword != RID_CONSTEVAL) >- error_at (token->location, "%qD invalid in lambda", >- ridpointers[token->keyword]); >+ { >+ if (token->keyword != RID_STATIC) >+ error_at (token->location, "%qD invalid in lambda", >+ ridpointers[token->keyword]); >+ else if (cxx_dialect < cxx23) >+ pedwarn (token->location, OPT_Wc__23_extensions, >+ "%qD only valid in lambda with %<-std=c++23%> or " >+ "%<-std=gnu++23%>", ridpointers[token->keyword]); >+ } > > if (ds != ds_last) > set_and_check_decl_spec_loc (decl_specs, ds, token); >--- gcc/c-family/c-cppbuiltin.cc.jj 2022-09-12 10:31:27.253553409 +0200 >+++ gcc/c-family/c-cppbuiltin.cc 2022-09-12 18:23:21.461519917 +0200 >@@ -1081,6 +1081,7 @@ c_cpp_builtins (cpp_reader *pfile) > cpp_define (pfile, "__cpp_constexpr=202110L"); > cpp_define (pfile, "__cpp_multidimensional_subscript=202110L"); > cpp_define (pfile, "__cpp_named_character_escapes=202207L"); >+ cpp_define (pfile, "__cpp_static_call_operator=202207L"); > } > if (flag_concepts) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 106651
:
53565
|
53571