aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-11-07 08:24:48 +0100
committerMartin Liska <mliska@suse.cz>2022-11-07 08:24:48 +0100
commit1b09b78ee61bd921ae78ebd0f7905b95b9e1c903 (patch)
tree9c04b59cdd2cd460f0727501d15402d31ffcf5a4 /gcc/cp
parent1eb021edb27e26f95cda63df121f6bc951647599 (diff)
parentc4f8f8afd07680f9e718de1331cd09607bdd9ac8 (diff)
downloadgcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.zip
gcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.tar.gz
gcc-1b09b78ee61bd921ae78ebd0f7905b95b9e1c903.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog120
-rw-r--r--gcc/cp/call.cc19
-rw-r--r--gcc/cp/constraint.cc3
-rw-r--r--gcc/cp/cp-tree.h22
-rw-r--r--gcc/cp/decl.cc30
-rw-r--r--gcc/cp/decl2.cc8
-rw-r--r--gcc/cp/lambda.cc236
-rw-r--r--gcc/cp/mangle.cc8
-rw-r--r--gcc/cp/mapper-client.cc4
-rw-r--r--gcc/cp/module.cc6
-rw-r--r--gcc/cp/parser.cc99
-rw-r--r--gcc/cp/pt.cc51
-rw-r--r--gcc/cp/semantics.cc1
-rw-r--r--gcc/cp/tree.cc20
14 files changed, 430 insertions, 197 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d065fd1..dd7526e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,123 @@
+2022-11-06 Patrick Palka <ppalka@redhat.com>
+
+ * tree.cc (cxx_attribute_table): Include init_priority entry
+ only if SUPPORTS_INIT_PRIORITY.
+ (handle_init_priority_attribute): Add ATTRIBUTE_UNUSED. Assert
+ SUPPORTS_INIT_PRIORITY is true.
+
+2022-11-04 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * mapper-client.cc: Use in-process client when networking is
+ disabled.
+
+2022-11-03 Marek Polacek <polacek@redhat.com>
+
+ PR c++/107488
+ * call.cc (do_warn_dangling_reference): Quash -Wdangling-reference
+ for member operator*.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/107179
+ * constraint.cc (tsubst_requires_expr): Make sure we're not
+ deferring access checks.
+
+2022-11-03 Jason Merrill <jason@redhat.com>
+
+ * parser.cc (cp_parser_template_declaration_after_parameters): Fix
+ concept parsing below C++20.
+
+2022-11-03 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/93413
+ * decl2.cc (mark_used): Don't defer synthesis of virtual
+ functions.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR): New.
+ (struct tree_lambda_expr): Add discriminator_sig bitfield.
+ (recrd_lambda_scope_sig_discriminator): Declare.
+ * lambda.cc (struct lambda_sig_count): New.
+ (lambda_discriminator): Add signature vector.
+ (start_lambda_scope): Adjust.
+ (compare_lambda_template_head, compare_lambda_sig): New.
+ (record_lambda_scope_sig_discriminator): New.
+ * mangle.cc (write_closure_type): Use the scope-sig discriminator for
+ ABI >= 18. Emit abi mangling warning if needed.
+ * module.cc (trees_out::core_vals): Stream the new discriminator.
+ (trees_in::core_vals): Likewise.
+ * parser.cc (cp_parser_lambda_declarator_opt): Call
+ record_lambda_scope_sig_discriminator.
+ * pt.cc (tsubst_lambda_expr): Likewise.
+
+2022-11-01 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (LAMBDA_EXPR_DISCRIMINATOR): Rename to ...
+ (LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR): ... here.
+ (struct tree_lambda_expr): Make default_capture_mode &
+ discriminator_scope bitfields.
+ (record_null_lambda_scope) Delete.
+ (record_lambda_scope_discriminator): Declare.
+ * lambda.cc (struct lambda_discriminator): New struct.
+ (lambda_scope, lambda_scope_stack): Adjust types.
+ (lambda_count): Delete.
+ (struct tree_int): Delete.
+ (start_lambda_scope, finish_lambda_scope): Adjust.
+ (record_lambda_scope): Only record the scope.
+ (record_lambda_scope_discriminator): New.
+ * mangle.cc (write_closure_type_name): Adjust.
+ * module.cc (trees_out::core_vals): Likewise,
+ (trees_in::core_vals): Likewise.
+ * parser.cc (cp_parser_lambda_expression): Call
+ record_lambda_scope_discriminator.
+ * pt.cc (tsubst_lambda_expr): Adjust record_lambda_scope caling. Call
+ record_lambda_scope_discriminator. Commonize control flow on tsubsting
+ the operator function.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * parser.cc (make_call_declarator): Add std_attrs parm.
+ (cp_parser_lambda_declarator_opt): Pass it.
+ (cp_parser_direct_declarator): Pass it.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (finish_function): Set TREE_NOTHROW later in the function.
+
+2022-11-01 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (duplicate_decls): Reformat loop.
+ * parser.cc (cp_parser_member_declaration): Add newline.
+ * semantics.cc: Remove newline.
+
+2022-10-28 Marek Polacek <polacek@redhat.com>
+
+ * call.cc (maybe_warn_dangling_reference): Enable the warning in
+ system headers if the decl isn't in a system header.
+
+2022-10-28 Jason Merrill <jason@redhat.com>
+
+ * decl.cc (grokdeclarator): Call decl_attributes before do_friend.
+
+2022-10-28 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.cc (cp_parser_omp_all_clauses): Allow optional comma
+ before the first clause even in pragma syntax.
+ (cp_parser_omp_allocate, cp_parser_omp_atomic, cp_parser_omp_depobj,
+ cp_parser_omp_flush, cp_parser_omp_scan_loop_body,
+ cp_parser_omp_ordered, cp_parser_omp_assumption_clauses,
+ cp_finish_omp_declare_variant, cp_parser_omp_declare_target,
+ cp_parser_omp_declare_reduction_exprs, cp_parser_omp_requires,
+ cp_parser_omp_error): Likewise.
+
+2022-10-28 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/61469
+ * cp-tree.h (ENUM_FIXED_UNDERLYING_TYPE_P, ENUM_UNDERLYING_TYPE):
+ Remove. Moved to c-common.h.
+
2022-10-27 Jakub Jelinek <jakub@redhat.com>
PR c++/107379
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 951b9fd..2c0fa37 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13467,7 +13467,17 @@ do_warn_dangling_reference (tree expr)
can be e.g.
const int& z = std::min({1, 2, 3, 4, 5, 6, 7});
which doesn't dangle: std::min here returns an int. */
- || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl))))
+ || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl)))
+ /* Don't emit a false positive for:
+ std::vector<int> v = ...;
+ std::vector<int>::const_iterator it = v.begin();
+ const int &r = *it++;
+ because R refers to one of the int elements of V, not to
+ a temporary object. Member operator* may return a reference
+ but probably not to one of its arguments. */
+ || (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
+ && DECL_OVERLOADED_OPERATOR_P (fndecl)
+ && DECL_OVERLOADED_OPERATOR_IS (fndecl, INDIRECT_REF)))
return NULL_TREE;
/* Here we're looking to see if any of the arguments is a temporary
@@ -13539,6 +13549,13 @@ maybe_warn_dangling_reference (const_tree decl, tree init)
return;
if (!TYPE_REF_P (TREE_TYPE (decl)))
return;
+ /* Don't suppress the diagnostic just because the call comes from
+ a system header. If the DECL is not in a system header, or if
+ -Wsystem-headers was provided, warn. */
+ auto wsh
+ = make_temp_override (global_dc->dc_warn_system_headers,
+ (!in_system_header_at (DECL_SOURCE_LOCATION (decl))
+ || global_dc->dc_warn_system_headers));
if (tree call = do_warn_dangling_reference (init))
{
auto_diagnostic_group d;
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 5e6a3bc..f6ef078 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2252,6 +2252,9 @@ tsubst_requires_expr (tree t, tree args, sat_info info)
{
local_specialization_stack stack (lss_copy);
+ /* We need to check access during the substitution. */
+ deferring_access_check_sentinel acs (dk_no_deferred);
+
/* A requires-expression is an unevaluated context. */
cp_unevaluated u;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6d84514..d13bb3d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1500,9 +1500,13 @@ enum cp_lambda_default_capture_mode_type {
#define LAMBDA_EXPR_EXTRA_SCOPE(NODE) \
(((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope)
-/* If EXTRA_SCOPE, this is the number of the lambda within that scope. */
-#define LAMBDA_EXPR_DISCRIMINATOR(NODE) \
- (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator)
+/* Lambdas in the same extra scope might need a discriminating count.
+ For ABI 17, we have single per-scope count, for ABI 18, we have
+ per-scope, per-signature numbering. */
+#define LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_scope)
+#define LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR(NODE) \
+ (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator_sig)
/* During parsing of the lambda, a vector of capture proxies which need
to be pushed once we're done processing a nested lambda. */
@@ -1530,8 +1534,9 @@ struct GTY (()) tree_lambda_expr
tree regen_info;
vec<tree, va_gc> *pending_proxies;
location_t locus;
- enum cp_lambda_default_capture_mode_type default_capture_mode : 8;
- short int discriminator;
+ enum cp_lambda_default_capture_mode_type default_capture_mode : 2;
+ unsigned discriminator_scope : 15; // Per-scope discriminator
+ unsigned discriminator_sig : 15; // Per-scope, per-signature discriminator
};
/* Non-zero if this template specialization has access violations that
@@ -7778,10 +7783,11 @@ extern tree cp_build_vec_convert (tree, location_t, tree,
tsubst_flags_t);
extern tree cp_build_bit_cast (location_t, tree, tree,
tsubst_flags_t);
-extern void start_lambda_scope (tree);
-extern void record_lambda_scope (tree);
-extern void record_null_lambda_scope (tree);
+extern void start_lambda_scope (tree decl);
extern void finish_lambda_scope (void);
+extern void record_lambda_scope (tree lambda);
+extern void record_lambda_scope_discriminator (tree lambda);
+extern void record_lambda_scope_sig_discriminator (tree lambda, tree fn);
extern tree start_lambda_function (tree fn, tree lambda_expr);
extern void finish_lambda_function (tree body);
extern bool regenerated_lambda_fn_p (tree);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index bc085f8..6e98ea3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2343,12 +2343,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
if (DECL_FUNCTION_TEMPLATE_P (newdecl))
{
- tree parm;
- DECL_ARGUMENTS (old_result)
- = DECL_ARGUMENTS (new_result);
- for (parm = DECL_ARGUMENTS (old_result); parm;
- parm = DECL_CHAIN (parm))
- DECL_CONTEXT (parm) = old_result;
+ DECL_ARGUMENTS (old_result) = DECL_ARGUMENTS (new_result);
+ for (tree p = DECL_ARGUMENTS (old_result); p; p = DECL_CHAIN (p))
+ DECL_CONTEXT (p) = old_result;
if (tree fc = DECL_FRIEND_CONTEXT (new_result))
SET_DECL_FRIEND_CONTEXT (old_result, fc);
@@ -14206,13 +14203,16 @@ grokdeclarator (const cp_declarator *declarator,
else if (decl && DECL_NAME (decl))
{
set_originating_module (decl, true);
-
+
if (initialized)
/* Kludge: We need funcdef_flag to be true in do_friend for
in-class defaulted functions, but that breaks grokfndecl.
So set it here. */
funcdef_flag = true;
+ cplus_decl_attributes (&decl, *attrlist, 0);
+ *attrlist = NULL_TREE;
+
decl = do_friend (ctype, unqualified_id, decl,
flags, funcdef_flag);
return decl;
@@ -17867,14 +17867,6 @@ finish_function (bool inline_p)
finish_fname_decls ();
- /* If this function can't throw any exceptions, remember that. */
- if (!processing_template_decl
- && !cp_function_chain->can_throw
- && !flag_non_call_exceptions
- && !decl_replaceable_p (fndecl,
- opt_for_fn (fndecl, flag_semantic_interposition)))
- TREE_NOTHROW (fndecl) = 1;
-
/* This must come after expand_function_end because cleanups might
have declarations (from inline functions) that need to go into
this function's blocks. */
@@ -18099,6 +18091,14 @@ finish_function (bool inline_p)
&& !DECL_OMP_DECLARE_REDUCTION_P (fndecl))
cp_genericize (fndecl);
+ /* If this function can't throw any exceptions, remember that. */
+ if (!processing_template_decl
+ && !cp_function_chain->can_throw
+ && !flag_non_call_exceptions
+ && !decl_replaceable_p (fndecl,
+ opt_for_fn (fndecl, flag_semantic_interposition)))
+ TREE_NOTHROW (fndecl) = 1;
+
/* Emit the resumer and destroyer functions now, providing that we have
not encountered some fatal error. */
if (coro_emit_helpers)
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index e677926..eeb59ea 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -5788,14 +5788,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = tf_warning_or_error */)
&& !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
&& ! DECL_INITIAL (decl))
{
- /* Defer virtual destructors so that thunks get the right
- linkage. */
- if (DECL_VIRTUAL_P (decl) && !at_eof)
- {
- note_vague_linkage_fn (decl);
- return true;
- }
-
/* Remember the current location for a function we will end up
synthesizing. Then we can inform the user where it was
required in the case of error. */
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index e9d5d4d..c7a9268 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -1444,79 +1444,223 @@ is_lambda_ignored_entity (tree val)
return false;
}
-/* Lambdas that appear in variable initializer or default argument scope
- get that in their mangling, so we need to record it. We might as well
- use the count for function and namespace scopes as well. */
-static GTY(()) tree lambda_scope;
-static GTY(()) int lambda_count;
-struct GTY(()) tree_int
+/* Lambdas that appear in variable initializer or default argument
+ scope get that in their mangling, so we need to record it. Also,
+ multiple lambdas in the same scope may need a mangling
+ discriminator. In ABI <= 17, there is a single per-scope sequence
+ number. In ABI >= 18, there are per-scope per-signature sequence
+ numbers. */
+struct GTY(()) lambda_sig_count
{
- tree t;
- int i;
+ tree fn; // The lambda fn whose sig this is.
+ unsigned count;
+};
+struct GTY(()) lambda_discriminator
+{
+ tree scope;
+ unsigned nesting; // Inside a function, VAR_DECLs get the function
+ // as scope. This counts that nesting.
+ unsigned count; // The per-scope counter.
+ vec<lambda_sig_count, va_gc> *discriminators; // Per-signature counters
};
-static GTY(()) vec<tree_int, va_gc> *lambda_scope_stack;
+// The current scope.
+static GTY(()) lambda_discriminator lambda_scope;
+// Stack of previous scopes.
+static GTY(()) vec<lambda_discriminator, va_gc> *lambda_scope_stack;
+
+// Push DECL as lambda extra scope, also new discriminator counters.
void
start_lambda_scope (tree decl)
{
- tree_int ti;
- gcc_assert (decl);
- /* Once we're inside a function, we ignore variable scope and just push
- the function again so that popping works properly. */
+ gcc_checking_assert (decl);
if (current_function_decl && TREE_CODE (decl) == VAR_DECL)
- decl = current_function_decl;
- ti.t = lambda_scope;
- ti.i = lambda_count;
- vec_safe_push (lambda_scope_stack, ti);
- if (lambda_scope != decl)
+ // If we're inside a function, we ignore variable scope. Don't push.
+ lambda_scope.nesting++;
+ else
+ {
+ vec_safe_push (lambda_scope_stack, lambda_scope);
+ lambda_scope.scope = decl;
+ lambda_scope.nesting = 0;
+ lambda_scope.count = 0;
+ lambda_scope.discriminators = nullptr;
+ }
+}
+
+// Pop from the current lambda extra scope.
+
+void
+finish_lambda_scope (void)
+{
+ if (!lambda_scope.nesting--)
{
- /* Don't reset the count if we're still in the same function. */
- lambda_scope = decl;
- lambda_count = 0;
+ lambda_scope = lambda_scope_stack->last ();
+ lambda_scope_stack->pop ();
}
}
+// Record the current lambda scope into LAMBDA
+
void
record_lambda_scope (tree lambda)
{
- LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope;
- LAMBDA_EXPR_DISCRIMINATOR (lambda) = lambda_count++;
- if (lambda_scope)
+ LAMBDA_EXPR_EXTRA_SCOPE (lambda) = lambda_scope.scope;
+ if (lambda_scope.scope)
{
tree closure = LAMBDA_EXPR_CLOSURE (lambda);
gcc_checking_assert (closure);
- maybe_key_decl (lambda_scope, TYPE_NAME (closure));
+ maybe_key_decl (lambda_scope.scope, TYPE_NAME (closure));
}
}
-/* This lambda is an instantiation of a lambda in a template default argument
- that got no LAMBDA_EXPR_EXTRA_SCOPE, so this shouldn't either. But we do
- need to use and increment the global count to avoid collisions. */
+// Compare lambda template heads TMPL_A and TMPL_B, used for both
+// templated lambdas, and template template parameters of said lambda.
-void
-record_null_lambda_scope (tree lambda)
+static bool
+compare_lambda_template_head (tree tmpl_a, tree tmpl_b)
{
- if (vec_safe_is_empty (lambda_scope_stack))
- record_lambda_scope (lambda);
- else
+ // We only need one level of template parms
+ tree inner_a = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_a));
+ tree inner_b = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl_b));
+
+ // We only compare explicit template parms, ignoring trailing
+ // synthetic ones.
+ int len_a = TREE_VEC_LENGTH (inner_a);
+ int len_b = TREE_VEC_LENGTH (inner_b);
+
+ for (int ix = 0, len = MAX (len_a, len_b); ix != len; ix++)
{
- tree_int *p = lambda_scope_stack->begin();
- LAMBDA_EXPR_EXTRA_SCOPE (lambda) = p->t;
- LAMBDA_EXPR_DISCRIMINATOR (lambda) = p->i++;
+ tree parm_a = NULL_TREE;
+ if (ix < len_a)
+ {
+ parm_a = TREE_VEC_ELT (inner_a, ix);
+ if (parm_a == error_mark_node)
+ return false;
+ parm_a = TREE_VALUE (parm_a);
+ if (DECL_VIRTUAL_P (parm_a))
+ parm_a = NULL_TREE;
+ }
+
+ tree parm_b = NULL_TREE;
+ if (ix < len_b)
+ {
+ parm_b = TREE_VEC_ELT (inner_b, ix);
+ if (parm_b == error_mark_node)
+ return false;
+ parm_b = TREE_VALUE (parm_b);
+ if (DECL_VIRTUAL_P (parm_b))
+ parm_b = NULL_TREE;
+ }
+
+ if (!parm_a && !parm_b)
+ // we're done
+ break;
+
+ if (!(parm_a && parm_b))
+ return false;
+
+ if (TREE_CODE (parm_a) != TREE_CODE (parm_b))
+ return false;
+
+ if (TREE_CODE (parm_a) == PARM_DECL)
+ {
+ if (TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_a))
+ != TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm_b)))
+ return false;
+
+ if (!same_type_p (TREE_TYPE (parm_a), TREE_TYPE (parm_b)))
+ return false;
+ }
+ else
+ {
+ if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_a))
+ != TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parm_b)))
+ return false;
+
+ if (TREE_CODE (parm_a) != TEMPLATE_DECL)
+ gcc_checking_assert (TREE_CODE (parm_a) == TYPE_DECL);
+ else if (!compare_lambda_template_head (parm_a, parm_b))
+ return false;
+ }
}
- gcc_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == NULL_TREE);
+
+ return true;
}
-void
-finish_lambda_scope (void)
+// Compare lambda signatures FN_A and FN_B, they may be TEMPLATE_DECLs too.
+
+static bool
+compare_lambda_sig (tree fn_a, tree fn_b)
{
- tree_int *p = &lambda_scope_stack->last ();
- if (lambda_scope != p->t)
+ if (TREE_CODE (fn_a) == TEMPLATE_DECL
+ && TREE_CODE (fn_b) == TEMPLATE_DECL)
+ {
+ if (!compare_lambda_template_head (fn_a, fn_b))
+ return false;
+ fn_a = DECL_TEMPLATE_RESULT (fn_a);
+ fn_b = DECL_TEMPLATE_RESULT (fn_b);
+ }
+ else if (TREE_CODE (fn_a) == TEMPLATE_DECL
+ || TREE_CODE (fn_b) == TEMPLATE_DECL)
+ return false;
+
+ if (fn_a == error_mark_node
+ || fn_b == error_mark_node)
+ return false;
+
+ for (tree args_a = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_a))),
+ args_b = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn_b)));
+ args_a || args_b;
+ args_a = TREE_CHAIN (args_a), args_b = TREE_CHAIN (args_b))
{
- lambda_scope = p->t;
- lambda_count = p->i;
+ if (!args_a || !args_b)
+ return false;
+ // This check also deals with differing varadicness
+ if (!same_type_p (TREE_VALUE (args_a), TREE_VALUE (args_b)))
+ return false;
}
- lambda_scope_stack->pop ();
+
+ return true;
+}
+
+// Record the per-scope discriminator of LAMBDA. If the extra scope
+// is empty, we must use the empty scope counter, which might not be
+// the live one.
+
+void
+record_lambda_scope_discriminator (tree lambda)
+{
+ auto *slot = (vec_safe_is_empty (lambda_scope_stack)
+ || LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+ ? &lambda_scope : lambda_scope_stack->begin ());
+ LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda) = slot->count++;
+}
+
+// Record the per-scope per-signature discriminator of LAMBDA. If the
+// extra scope is empty, we must use the empty scope counter, which
+// might not be the live one.
+
+void
+record_lambda_scope_sig_discriminator (tree lambda, tree fn)
+{
+ auto *slot = (vec_safe_is_empty (lambda_scope_stack)
+ || LAMBDA_EXPR_EXTRA_SCOPE (lambda)
+ ? &lambda_scope : lambda_scope_stack->begin ());
+ gcc_checking_assert (LAMBDA_EXPR_EXTRA_SCOPE (lambda) == slot->scope);
+
+ // A linear search, we're not expecting this to be a big list, and
+ // this avoids needing a signature hash function.
+ lambda_sig_count *sig;
+ if (unsigned ix = vec_safe_length (slot->discriminators))
+ for (sig = slot->discriminators->begin (); ix--; sig++)
+ if (compare_lambda_sig (fn, sig->fn))
+ goto found;
+ {
+ lambda_sig_count init = {fn, 0};
+ sig = vec_safe_push (slot->discriminators, init);
+ }
+ found:
+ LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda) = sig->count++;
}
tree
@@ -1648,6 +1792,10 @@ prune_lambda_captures (tree body)
}
}
+// Record the per-scope per-signature discriminator of LAMBDA. If the
+// extra scope is empty, we must use the empty scope counter, which
+// might not be the live one.
+
void
finish_lambda_function (tree body)
{
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index e396218..e97428e 100644
--- a/gcc/cp/mangle.cc
+++ b/gcc/cp/mangle.cc
@@ -1810,7 +1810,13 @@ write_closure_type_name (const tree type)
write_method_parms (parms, /*method_p=*/1, fn);
write_char ('E');
- write_compact_number (LAMBDA_EXPR_DISCRIMINATOR (lambda));
+ if ((LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+ != LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda))
+ && abi_warn_or_compat_version_crosses (18))
+ G.need_abi_warning = true;
+ write_compact_number (abi_version_at_least (18)
+ ? LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda)
+ : LAMBDA_EXPR_SCOPE_ONLY_DISCRIMINATOR (lambda));
}
/* Convert NUMBER to ascii using base BASE and generating at least
diff --git a/gcc/cp/mapper-client.cc b/gcc/cp/mapper-client.cc
index fe9544b..8e331c0 100644
--- a/gcc/cp/mapper-client.cc
+++ b/gcc/cp/mapper-client.cc
@@ -227,6 +227,8 @@ module_client::open_module_client (location_t loc, const char *o,
int fd = -1;
#if CODY_NETWORKING
fd = Cody::OpenLocal (&errmsg, name.c_str () + 1);
+#else
+ errmsg = "disabled";
#endif
if (fd >= 0)
c = new module_client (fd, fd);
@@ -254,6 +256,8 @@ module_client::open_module_client (location_t loc, const char *o,
int fd = -1;
#if CODY_NETWORKING
fd = Cody::OpenInet6 (&errmsg, name.c_str (), port);
+#else
+ errmsg = "disabled";
#endif
name[colon] = ':';
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 9957df5..0e9af31 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -6327,7 +6327,8 @@ trees_out::core_vals (tree t)
if (streaming_p ())
{
WU (((lang_tree_node *)t)->lambda_expression.default_capture_mode);
- WU (((lang_tree_node *)t)->lambda_expression.discriminator);
+ WU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+ WU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
}
break;
@@ -6819,7 +6820,8 @@ trees_in::core_vals (tree t)
= state->read_location (*this);
RUC (cp_lambda_default_capture_mode_type,
((lang_tree_node *)t)->lambda_expression.default_capture_mode);
- RU (((lang_tree_node *)t)->lambda_expression.discriminator);
+ RU (((lang_tree_node *)t)->lambda_expression.discriminator_scope);
+ RU (((lang_tree_node *)t)->lambda_expression.discriminator_sig);
break;
case OVERLOAD:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e685f19..9523f73 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -1607,7 +1607,7 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
static cp_declarator *make_call_declarator
(cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier,
- tree, tree, tree, tree, location_t);
+ tree, tree, tree, tree, tree, location_t);
static cp_declarator *make_array_declarator
(cp_declarator *, tree);
static cp_declarator *make_pointer_declarator
@@ -1780,7 +1780,8 @@ make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
/* Make a declarator for the function given by TARGET, with the
indicated PARMS. The CV_QUALIFIERS apply to the function, as in
"const"-qualified member function. The EXCEPTION_SPECIFICATION
- indicates what exceptions can be thrown. */
+ indicates what exceptions can be thrown. STD_ATTRS contains
+ attributes that appertain to the function type. */
cp_declarator *
make_call_declarator (cp_declarator *target,
@@ -1792,6 +1793,7 @@ make_call_declarator (cp_declarator *target,
tree exception_specification,
tree late_return_type,
tree requires_clause,
+ tree std_attrs,
location_t parens_loc)
{
cp_declarator *declarator;
@@ -1816,6 +1818,8 @@ make_call_declarator (cp_declarator *target,
else
declarator->parameter_pack_p = false;
+ declarator->std_attributes = std_attrs;
+
return declarator;
}
@@ -11031,6 +11035,7 @@ cp_parser_lambda_expression (cp_parser* parser)
return error_mark_node;
record_lambda_scope (lambda_expr);
+ record_lambda_scope_discriminator (lambda_expr);
/* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
determine_visibility (TYPE_NAME (type));
@@ -11081,9 +11086,7 @@ cp_parser_lambda_expression (cp_parser* parser)
ok = false;
if (ok)
- {
- cp_parser_lambda_body (parser, lambda_expr);
- }
+ cp_parser_lambda_body (parser, lambda_expr);
else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
{
if (cp_parser_skip_to_closing_brace (parser))
@@ -11684,8 +11687,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
exception_spec,
return_type,
trailing_requires_clause,
+ std_attrs,
UNKNOWN_LOCATION);
- declarator->std_attributes = std_attrs;
fco = grokmethod (&return_type_specs,
declarator,
@@ -11709,6 +11712,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
fco = finish_fully_implicit_template (parser, fco);
finish_member_declaration (fco);
+ record_lambda_scope_sig_discriminator (lambda_expr, fco);
obstack_free (&declarator_obstack, p);
@@ -23264,8 +23268,8 @@ cp_parser_direct_declarator (cp_parser* parser,
exception_specification,
late_return,
requires_clause,
+ attrs,
parens_loc);
- declarator->std_attributes = attrs;
declarator->attributes = gnu_attrs;
/* Any subsequent parameter lists are to do with
return type, so are not those of the declared
@@ -27522,6 +27526,7 @@ cp_parser_member_declaration (cp_parser* parser)
decl = grokfield (declarator, &decl_specifiers,
initializer, /*init_const_expr_p=*/true,
asm_specification, attributes);
+
if (parser->fully_implicit_function_template_p)
{
if (friend_p)
@@ -31445,10 +31450,11 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
else if (cxx_dialect >= cxx11
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
decl = cp_parser_alias_declaration (parser);
- else if (cxx_dialect >= cxx20 /* Implies flag_concept. */
+ else if (flag_concepts
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
- && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_BOOL))
- /* Allow 'concept bool' to be handled as per the TS. */
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ /* -fconcept-ts 'concept bool' syntax is handled below, in
+ cp_parser_single_declaration. */
decl = cp_parser_concept_definition (parser);
else
{
@@ -40443,12 +40449,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
if (nested && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
break;
- if (!first
- /* OpenMP 5.1 allows optional comma in between directive-name and
- clauses everywhere, but as we aren't done with OpenMP 5.0
- implementation yet, let's allow it for now only in C++11
- attributes. */
- || (parser->lexer->in_omp_attribute_pragma && nested != 2))
+ if (!first || nested != 2)
{
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
@@ -40881,9 +40882,7 @@ cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
location_t loc = pragma_tok->location;
tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
@@ -41004,7 +41003,6 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
bool structured_block = false;
- bool first = true;
tree clauses = NULL_TREE;
bool capture = false;
bool compare = false;
@@ -41015,14 +41013,10 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if ((!first || parser->lexer->in_omp_attribute_pragma)
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
- first = false;
-
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -41976,11 +41970,9 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
tree clause = NULL_TREE;
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
- location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
+ location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -42063,9 +42055,7 @@ static void
cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
{
enum memmodel mo = MEMMODEL_LAST;
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -42790,8 +42780,7 @@ cp_parser_omp_scan_loop_body (cp_parser *parser)
cp_lexer_consume_token (parser->lexer);
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
@@ -43593,9 +43582,7 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
location_t loc = pragma_tok->location;
int n = 1;
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
n = 2;
if (cp_lexer_nth_token_is (parser->lexer, n, CPP_NAME))
@@ -45949,7 +45936,6 @@ static void
cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
bool is_assume)
{
- bool first = true;
bool no_openmp = false;
bool no_openmp_routines = false;
bool no_parallelism = false;
@@ -45965,14 +45951,10 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if ((!first || parser->lexer->in_omp_attribute_pragma)
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
- first = false;
-
if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
break;
@@ -46209,9 +46191,7 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
location_t finish_loc = get_finish (varid.get_location ());
location_t varid_loc = make_location (caret_loc, start_loc, finish_loc);
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
@@ -46287,11 +46267,6 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
cp_lexer_consume_token (parser->lexer);
if (strcmp (kind, "simd") == 0)
{
- /* For now only in C++ attributes, do it always for OpenMP 5.1.
- if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
- && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
- cp_lexer_consume_token (parser->lexer); */
-
cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
"#pragma omp declare simd",
pragma_tok);
@@ -46549,9 +46524,7 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
int device_type = 0;
bool only_device_type = true;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- || (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ || (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)))
clauses
= cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
@@ -46801,9 +46774,7 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
return false;
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if (parser->lexer->in_omp_attribute_pragma
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
@@ -47235,20 +47206,15 @@ cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
static bool
cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
{
- bool first = true;
enum omp_requires new_req = (enum omp_requires) 0;
location_t loc = pragma_tok->location;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if ((!first || parser->lexer->in_omp_attribute_pragma)
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
- first = false;
-
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -47402,20 +47368,15 @@ cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok,
int at_compilation = -1;
int severity_fatal = -1;
tree message = NULL_TREE;
- bool first = true;
bool bad = false;
location_t loc = pragma_tok->location;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
- /* For now only in C++ attributes, do it always for OpenMP 5.1. */
- if ((!first || parser->lexer->in_omp_attribute_pragma)
- && cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
- first = false;
-
if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
break;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 51bfbbc..c3fc56a 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -19866,21 +19866,13 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (type == error_mark_node)
return error_mark_node;
- if (LAMBDA_EXPR_EXTRA_SCOPE (t) == NULL_TREE)
- {
- /* A lambda in a default argument outside a class gets no
- LAMBDA_EXPR_EXTRA_SCOPE, as specified by the ABI. But
- tsubst_default_argument calls start_lambda_scope, so we need to
- specifically ignore it here, and use the global scope. */
- record_null_lambda_scope (r);
-
- /* If we're pushed into another scope (PR105652), fix it. */
- if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
- TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
- = TYPE_CONTEXT (TREE_TYPE (t));
- }
- else
+ if (LAMBDA_EXPR_EXTRA_SCOPE (t))
record_lambda_scope (r);
+ else if (TYPE_NAMESPACE_SCOPE_P (TREE_TYPE (t)))
+ /* If we're pushed into another scope (PR105652), fix it. */
+ TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_NAME (type))
+ = TYPE_CONTEXT (TREE_TYPE (t));
+ record_lambda_scope_discriminator (r);
/* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
determine_visibility (TYPE_NAME (type));
@@ -19911,29 +19903,18 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
fntype = build_memfn_type (fntype, type,
type_memfn_quals (fntype),
type_memfn_rqual (fntype));
- tree fn, tmpl;
- if (oldtmpl)
+ tree inst = (oldtmpl
+ ? tsubst_template_decl (oldtmpl, args, complain, fntype)
+ : tsubst_function_decl (oldfn, args, complain, fntype));
+ if (inst == error_mark_node)
{
- tmpl = tsubst_template_decl (oldtmpl, args, complain, fntype);
- if (tmpl == error_mark_node)
- {
- r = error_mark_node;
- goto out;
- }
- fn = DECL_TEMPLATE_RESULT (tmpl);
- finish_member_declaration (tmpl);
- }
- else
- {
- tmpl = NULL_TREE;
- fn = tsubst_function_decl (oldfn, args, complain, fntype);
- if (fn == error_mark_node)
- {
- r = error_mark_node;
- goto out;
- }
- finish_member_declaration (fn);
+ r = error_mark_node;
+ goto out;
}
+ finish_member_declaration (inst);
+ record_lambda_scope_sig_discriminator (r, inst);
+
+ tree fn = oldtmpl ? DECL_TEMPLATE_RESULT (inst) : inst;
/* Let finish_function set this. */
DECL_DECLARED_CONSTEXPR_P (fn) = false;
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 36aa9c4..7c5f90b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -731,7 +731,6 @@ end_maybe_infinite_loop (tree cond)
}
}
-
/* Begin a conditional that might contain a declaration. When generating
normal code, we want the declaration to appear before the statement
containing the conditional. When generating template code, we want the
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 45348c5..c30bbeb 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -5010,8 +5010,10 @@ const struct attribute_spec cxx_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req,
affects_type_identity, handler, exclude } */
+#if SUPPORTS_INIT_PRIORITY
{ "init_priority", 1, 1, true, false, false, false,
handle_init_priority_attribute, NULL },
+#endif
{ "abi_tag", 1, -1, false, false, false, true,
handle_abi_tag_attribute, NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
@@ -5039,7 +5041,7 @@ const struct attribute_spec std_attribute_table[] =
/* Handle an "init_priority" attribute; arguments as in
struct attribute_spec.handler. */
-static tree
+ATTRIBUTE_UNUSED static tree
handle_init_priority_attribute (tree* node,
tree name,
tree args,
@@ -5103,18 +5105,10 @@ handle_init_priority_attribute (tree* node,
pri);
}
- if (SUPPORTS_INIT_PRIORITY)
- {
- SET_DECL_INIT_PRIORITY (decl, pri);
- DECL_HAS_INIT_PRIORITY_P (decl) = 1;
- return NULL_TREE;
- }
- else
- {
- error ("%qE attribute is not supported on this platform", name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ gcc_assert (SUPPORTS_INIT_PRIORITY);
+ SET_DECL_INIT_PRIORITY (decl, pri);
+ DECL_HAS_INIT_PRIORITY_P (decl) = 1;
+ return NULL_TREE;
}
/* DECL is being redeclared; the old declaration had the abi tags in OLD,