diff options
author | Martin Liska <mliska@suse.cz> | 2022-09-12 10:43:19 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-09-12 10:43:19 +0200 |
commit | fdb97cd0b7d15efa39ba79dca44be93debb0ef12 (patch) | |
tree | 65a6d95503fb9897bda29c72a629e57bb773d1c1 /gcc/cp | |
parent | 918bc838c2803f08e4d7ccd179396d48cb8ec804 (diff) | |
parent | 643ae816f17745a77b62188b6bf169211609a59b (diff) | |
download | gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.zip gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.tar.gz gcc-fdb97cd0b7d15efa39ba79dca44be93debb0ef12.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 51 | ||||
-rw-r--r-- | gcc/cp/class.cc | 2 | ||||
-rw-r--r-- | gcc/cp/coroutines.cc | 9 | ||||
-rw-r--r-- | gcc/cp/decl.cc | 41 | ||||
-rw-r--r-- | gcc/cp/decl2.cc | 33 | ||||
-rw-r--r-- | gcc/cp/parser.cc | 10 | ||||
-rw-r--r-- | gcc/cp/pt.cc | 11 | ||||
-rw-r--r-- | gcc/cp/semantics.cc | 75 |
8 files changed, 165 insertions, 67 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a11675e..0f37423 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,54 @@ +2022-09-08 Jonathan Wakely <jwakely@redhat.com> + + PR c++/106838 + * class.cc (type_has_virtual_destructor): Return false for + union types. + * semantics.cc (check_trait_type): Add KIND parameter to support + different sets of requirements. + (finish_trait_expr): Pass KIND argument for relevant traits. + +2022-09-08 Patrick Palka <ppalka@redhat.com> + + PR c++/99130 + * decl2.cc (maybe_instantiate_decl): Adjust function comment. + Check VAR_OR_FUNCTION_DECL_P. Pull out the disjunction into ... + (mark_used): ... here, removing the decl_maybe_constant_var_p + part of it. + +2022-09-07 Jason Merrill <jason@redhat.com> + + PR c++/106793 + * decl.cc (grokdeclarator): Improve placeholder diagnostics. + * parser.cc (cp_parser_type_id_1): Add fixit. + +2022-09-07 Arsen Arsenović <arsen@aarsen.me> + + PR c++/106188 + PR c++/106713 + * coroutines.cc (coro_rewrite_function_body): Ensure we have a + BIND_EXPR wrapping the function body. + +2022-09-07 Jakub Jelinek <jakub@redhat.com> + + PR c++/106829 + * semantics.cc (finish_omp_target_clauses): If current_function_decl + isn't a nonstatic member function, don't set data.current_object to + non-NULL. + +2022-09-06 Jason Merrill <jason@redhat.com> + + * decl.cc (grok_op_properties): Return sooner for C++23 op[]. + +2022-09-06 Jakub Jelinek <jakub@redhat.com> + + * parser.cc (cp_parser_omp_clause_doacross_sink): Don't verify val + in omp_cur_iteration - 1 has integer_type_node type. + +2022-09-06 Jakub Jelinek <jakub@redhat.com> + + * pt.cc (tsubst_expr) <case OMP_ORDERED>: If OMP_BODY was NULL, keep + it NULL after instantiation too. + 2022-09-03 Jakub Jelinek <jakub@redhat.com> * parser.cc (cp_parser_omp_clause_name): Handle doacross. diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index a12d367..b84f422 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -5620,7 +5620,7 @@ type_has_virtual_destructor (tree type) { tree dtor; - if (!CLASS_TYPE_P (type)) + if (!NON_UNION_CLASS_TYPE_P (type)) return false; gcc_assert (COMPLETE_TYPE_P (type)); diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index edb3b70..eca01ab 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4095,6 +4095,15 @@ coro_rewrite_function_body (location_t fn_start, tree fnbody, tree orig, BLOCK_SUPERCONTEXT (replace_blk) = top_block; BLOCK_SUBBLOCKS (top_block) = replace_blk; } + else + { + /* We are missing a top level BIND_EXPR. We need one to ensure that we + don't shuffle around the coroutine frame and corrupt it. */ + tree bind_wrap = build3_loc (fn_start, BIND_EXPR, void_type_node, + NULL, NULL, NULL); + BIND_EXPR_BODY (bind_wrap) = fnbody; + fnbody = bind_wrap; + } /* Wrap the function body in a try {} catch (...) {} block, if exceptions are enabled. */ diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index b72b2a8..4665a29 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -12407,14 +12407,20 @@ grokdeclarator (const cp_declarator *declarator, if (cxx_dialect >= cxx17 && type && is_auto (type) && innermost_code != cdk_function + /* Placeholder in parm gets a better error below. */ + && !(decl_context == PARM || decl_context == CATCHPARM) && id_declarator && declarator != id_declarator) if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (type)) - { - error_at (typespec_loc, "template placeholder type %qT must be followed " - "by a simple declarator-id", type); - inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); - type = error_mark_node; - } + { + auto_diagnostic_group g; + gcc_rich_location richloc (typespec_loc); + richloc.add_fixit_insert_after ("<>"); + error_at (&richloc, "missing template argument list after %qE; " + "for deduction, template placeholder must be followed " + "by a simple declarator-id", tmpl); + inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); + type = error_mark_node; + } staticp = 0; inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline); @@ -12892,6 +12898,7 @@ grokdeclarator (const cp_declarator *declarator, { if (!funcdecl_p || !dguide_name_p (unqualified_id)) { + auto_diagnostic_group g; error_at (typespec_loc, "deduced class " "type %qD in function return type", DECL_NAME (tmpl)); @@ -13837,12 +13844,15 @@ grokdeclarator (const cp_declarator *declarator, else if (tree c = CLASS_PLACEHOLDER_TEMPLATE (auto_node)) { auto_diagnostic_group g; - error_at (typespec_loc, - "class template placeholder %qE not permitted " - "in this context", c); + gcc_rich_location richloc (typespec_loc); + richloc.add_fixit_insert_after ("<>"); + error_at (&richloc, + "missing template argument list after %qE; template " + "placeholder not permitted in parameter", c); if (decl_context == PARM && cxx_dialect >= cxx20) - inform (typespec_loc, "use %<auto%> for an " + inform (typespec_loc, "or use %<auto%> for an " "abbreviated function template"); + inform (DECL_SOURCE_LOCATION (c), "%qD declared here", c); } else error_at (typespec_loc, @@ -15331,6 +15341,11 @@ grok_op_properties (tree decl, bool complain) "operator ()". */ return true; + /* C++23 allows an arbitrary number of parameters and default arguments for + operator[], and none of the other checks below apply. */ + if (operator_code == ARRAY_REF && cxx_dialect >= cxx23) + return true; + if (operator_code == COND_EXPR) { /* 13.4.0.3 */ @@ -15344,10 +15359,6 @@ grok_op_properties (tree decl, bool complain) { if (!arg) { - /* Variadic. */ - if (operator_code == ARRAY_REF && cxx_dialect >= cxx23) - break; - error_at (loc, "%qD must not have variable number of arguments", decl); return false; @@ -15408,8 +15419,6 @@ grok_op_properties (tree decl, bool complain) case OVL_OP_FLAG_BINARY: if (arity != 2) { - if (operator_code == ARRAY_REF && cxx_dialect >= cxx23) - break; error_at (loc, methodp ? G_("%qD must have exactly one argument") diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 89ab254..cd18881 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -5381,24 +5381,15 @@ possibly_inlined_p (tree decl) return true; } -/* Normally, we can wait until instantiation-time to synthesize DECL. - However, if DECL is a static data member initialized with a constant - or a constexpr function, we need it right now because a reference to - such a data member or a call to such function is not value-dependent. - For a function that uses auto in the return type, we need to instantiate - it to find out its type. For OpenMP user defined reductions, we need - them instantiated for reduction clauses which inline them by hand - directly. */ +/* If DECL is a function or variable template specialization, instantiate + its definition now. */ void maybe_instantiate_decl (tree decl) { - if (DECL_LANG_SPECIFIC (decl) + if (VAR_OR_FUNCTION_DECL_P (decl) + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) - && (decl_maybe_constant_var_p (decl) - || (TREE_CODE (decl) == FUNCTION_DECL - && DECL_OMP_DECLARE_REDUCTION_P (decl)) - || undeduced_auto_decl (decl)) && !DECL_DECLARED_CONCEPT_P (decl) && !uses_template_parms (DECL_TI_ARGS (decl))) { @@ -5700,15 +5691,13 @@ mark_used (tree decl, tsubst_flags_t complain) return false; } - /* Normally, we can wait until instantiation-time to synthesize DECL. - However, if DECL is a static data member initialized with a constant - or a constexpr function, we need it right now because a reference to - such a data member or a call to such function is not value-dependent. - For a function that uses auto in the return type, we need to instantiate - it to find out its type. For OpenMP user defined reductions, we need - them instantiated for reduction clauses which inline them by hand - directly. */ - maybe_instantiate_decl (decl); + /* If DECL has a deduced return type, we need to instantiate it now to + find out its type. For OpenMP user defined reductions, we need them + instantiated for reduction clauses which inline them by hand directly. */ + if (undeduced_auto_decl (decl) + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_OMP_DECLARE_REDUCTION_P (decl))) + maybe_instantiate_decl (decl); if (processing_template_decl || in_template_function ()) return true; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 076ad62..841ba6e 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -24397,8 +24397,11 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags, location_t loc = type_specifier_seq.locations[ds_type_spec]; if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node)) { - error_at (loc, "missing template arguments after %qT", - auto_node); + auto_diagnostic_group g; + gcc_rich_location richloc (loc); + richloc.add_fixit_insert_after ("<>"); + error_at (&richloc, "missing template arguments after %qE", + tmpl); inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl); } @@ -39355,8 +39358,7 @@ cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc, && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN)) { tree val = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value; - if (integer_onep (val) - && same_type_p (TREE_TYPE (val), integer_type_node)) + if (integer_onep (val)) { cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index cd0d892..c5fc0f1 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -19526,9 +19526,14 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case OMP_ORDERED: tmp = tsubst_omp_clauses (OMP_ORDERED_CLAUSES (t), C_ORT_OMP, args, complain, in_decl); - stmt = push_stmt_list (); - RECUR (OMP_BODY (t)); - stmt = pop_stmt_list (stmt); + if (OMP_BODY (t)) + { + stmt = push_stmt_list (); + RECUR (OMP_BODY (t)); + stmt = pop_stmt_list (stmt); + } + else + stmt = NULL_TREE; t = copy_node (t); OMP_BODY (t) = stmt; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 7b2c495..6bda30e 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -9555,16 +9555,15 @@ finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr) { omp_target_walk_data data; data.this_expr_accessed = false; + data.current_object = NULL_TREE; - tree ct = current_nonlambda_class_type (); - if (ct) - { - tree object = maybe_dummy_object (ct, NULL); - object = maybe_resolve_dummy (object, true); - data.current_object = object; - } - else - data.current_object = NULL_TREE; + if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr) + if (tree ct = current_nonlambda_class_type ()) + { + tree object = maybe_dummy_object (ct, NULL); + object = maybe_resolve_dummy (object, true); + data.current_object = object; + } if (DECL_LAMBDA_FUNCTION_P (current_function_decl)) { @@ -12029,11 +12028,23 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) } } -/* If TYPE is an array of unknown bound, or (possibly cv-qualified) - void, or a complete type, returns true, otherwise false. */ +/* Returns true if TYPE meets the requirements for the specified KIND, + false otherwise. + + When KIND == 1, TYPE must be an array of unknown bound, + or (possibly cv-qualified) void, or a complete type. + + When KIND == 2, TYPE must be a complete type, or array of complete type, + or (possibly cv-qualified) void. + + When KIND == 3: + If TYPE is a non-union class type, it must be complete. + + When KIND == 4: + If TYPE is a class type, it must be complete. */ static bool -check_trait_type (tree type) +check_trait_type (tree type, int kind = 1) { if (type == NULL_TREE) return true; @@ -12042,8 +12053,14 @@ check_trait_type (tree type) return (check_trait_type (TREE_VALUE (type)) && check_trait_type (TREE_CHAIN (type))); - if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) - return true; + if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + return true; // Array of unknown bound. Don't care about completeness. + + if (kind == 3 && !NON_UNION_CLASS_TYPE_P (type)) + return true; // Not a non-union class type. Don't care about completeness. + + if (kind == 4 && TREE_CODE (type) == ARRAY_TYPE) + return true; // Not a class type. Don't care about completeness. if (VOID_TYPE_P (type)) return true; @@ -12081,23 +12098,39 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_HAS_TRIVIAL_COPY: case CPTK_HAS_TRIVIAL_DESTRUCTOR: case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: - case CPTK_HAS_VIRTUAL_DESTRUCTOR: - case CPTK_IS_ABSTRACT: - case CPTK_IS_AGGREGATE: - case CPTK_IS_EMPTY: - case CPTK_IS_FINAL: + if (!check_trait_type (type1)) + return error_mark_node; + break; + case CPTK_IS_LITERAL_TYPE: case CPTK_IS_POD: - case CPTK_IS_POLYMORPHIC: case CPTK_IS_STD_LAYOUT: case CPTK_IS_TRIVIAL: case CPTK_IS_TRIVIALLY_COPYABLE: - if (!check_trait_type (type1)) + if (!check_trait_type (type1, /* kind = */ 2)) + return error_mark_node; + break; + + case CPTK_IS_EMPTY: + case CPTK_IS_POLYMORPHIC: + case CPTK_IS_ABSTRACT: + case CPTK_HAS_VIRTUAL_DESTRUCTOR: + if (!check_trait_type (type1, /* kind = */ 3)) + return error_mark_node; + break; + + /* N.B. std::is_aggregate is kind=2 but we don't need a complete element + type to know whether an array is an aggregate, so use kind=4 here. */ + case CPTK_IS_AGGREGATE: + case CPTK_IS_FINAL: + if (!check_trait_type (type1, /* kind = */ 4)) return error_mark_node; break; case CPTK_IS_ASSIGNABLE: case CPTK_IS_CONSTRUCTIBLE: + if (!check_trait_type (type1)) + return error_mark_node; break; case CPTK_IS_TRIVIALLY_ASSIGNABLE: |