aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-12 10:43:19 +0200
committerMartin Liska <mliska@suse.cz>2022-09-12 10:43:19 +0200
commitfdb97cd0b7d15efa39ba79dca44be93debb0ef12 (patch)
tree65a6d95503fb9897bda29c72a629e57bb773d1c1 /gcc/cp
parent918bc838c2803f08e4d7ccd179396d48cb8ec804 (diff)
parent643ae816f17745a77b62188b6bf169211609a59b (diff)
downloadgcc-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/ChangeLog51
-rw-r--r--gcc/cp/class.cc2
-rw-r--r--gcc/cp/coroutines.cc9
-rw-r--r--gcc/cp/decl.cc41
-rw-r--r--gcc/cp/decl2.cc33
-rw-r--r--gcc/cp/parser.cc10
-rw-r--r--gcc/cp/pt.cc11
-rw-r--r--gcc/cp/semantics.cc75
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: