aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog42
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/cfgexpand.cc49
-rw-r--r--gcc/config/aarch64/aarch64-sve.md37
-rw-r--r--gcc/config/avr/avr.md35
-rw-r--r--gcc/cp/ChangeLog24
-rw-r--r--gcc/cp/coroutines.cc57
-rw-r--r--gcc/cp/coroutines.h4
-rw-r--r--gcc/gcc.cc8
-rw-r--r--gcc/testsuite/ChangeLog37
-rw-r--r--gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C4
-rw-r--r--gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C2
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr104051-0.C (renamed from gcc/testsuite/g++.dg/coroutines/pr104051.C)4
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr104051-1.C23
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr116775.C68
-rw-r--r--gcc/testsuite/gcc.dg/pr119160.c13
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c22
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr120423-1.c29
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c22
-rw-r--r--gcc/testsuite/gcc.target/avr/torture/pr120423-2.c30
20 files changed, 475 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 549505e..0eaaf7c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,45 @@
+2025-06-14 Georg-Johann Lay <avr@gjlay.de>
+
+ Backported from master:
+ 2025-06-14 Georg-Johann Lay <avr@gjlay.de>
+
+ PR rtl-optimization/120423
+ PR rtl-optimization/116389
+ * config/avr/avr.md [-mno-lra]: Add pre-reload split to transform
+ (left shift of) a paradoxical subreg to a (left shift of) zero-extend.
+
+2025-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120629
+ * cfgexpand.cc (expand_split_edge): New function.
+ (expand_gimple_cond, construct_init_block): Use it.
+
+2025-06-13 Spencer Abson <spencer.abson@arm.com>
+
+ PR target/118150
+ * config/aarch64/aarch64-sve.md (*one_cmpl<mode>3_cc): New
+ combiner pattern.
+ (*one_cmpl<mode>3_ptest): Likewise.
+
+2025-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/120629
+ * cfgexpand.cc (construct_init_block): If first_block isn't BB_RTL,
+ has any PHI nodes and false_edge->dest_idx before redirection is
+ different from make_single_succ_edge result's dest_idx, swap the
+ latter with the former last pred edge and their dest_idx members.
+
+2025-06-13 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.cc (driver::set_up_specs): Use gcc_exec_prefix to
+ read the spec file rather than standard_exec_prefix.
+
+2025-06-13 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/120589
+ * config/mcore/mcore.cc (mcore_mark_dllimport): Don't use
+ gen_rtx_MEM.
+
2025-06-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/120638
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index c544224..caed742 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250613
+20250615
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index f288a54..e1cdb71 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -2830,6 +2830,31 @@ expand_remove_edge (edge e)
remove_edge (e);
}
+/* Split edge E during expansion and instead of creating a new
+ bb on that edge, add there BB. FLAGS should be flags on the
+ new edge from BB to former E->dest. */
+
+static void
+expand_split_edge (edge e, basic_block bb, int flags)
+{
+ unsigned int dest_idx = e->dest_idx;
+ basic_block dest = e->dest;
+ redirect_edge_succ (e, bb);
+ e = make_single_succ_edge (bb, dest, flags);
+ if ((dest->flags & BB_RTL) == 0
+ && phi_nodes (dest)
+ && e->dest_idx != dest_idx)
+ {
+ /* If there are any PHI nodes on dest, swap the new succ edge
+ with the one moved into false_edge's former position, so that
+ PHI arguments don't need adjustment. */
+ edge e2 = EDGE_PRED (dest, dest_idx);
+ std::swap (e->dest_idx, e2->dest_idx);
+ std::swap (EDGE_PRED (dest, e->dest_idx),
+ EDGE_PRED (dest, e2->dest_idx));
+ }
+}
+
/* A subroutine of expand_gimple_cond. Given E, a fallthrough edge
of a basic block where we just expanded the conditional at the end,
@@ -3013,8 +3038,7 @@ expand_gimple_cond (basic_block bb, gcond *stmt)
new_bb = create_basic_block (NEXT_INSN (last), get_last_insn (), bb);
dest = false_edge->dest;
- unsigned int dest_idx = false_edge->dest_idx;
- redirect_edge_succ (false_edge, new_bb);
+ expand_split_edge (false_edge, new_bb, 0);
false_edge->flags |= EDGE_FALLTHRU;
new_bb->count = false_edge->count ();
loop_p loop = find_common_loop (bb->loop_father, dest->loop_father);
@@ -3022,19 +3046,6 @@ expand_gimple_cond (basic_block bb, gcond *stmt)
if (loop->latch == bb
&& loop->header == dest)
loop->latch = new_bb;
- edge e = make_single_succ_edge (new_bb, dest, 0);
- if ((dest->flags & BB_RTL) == 0
- && phi_nodes (dest)
- && e->dest_idx != dest_idx)
- {
- /* If there are any PHI nodes on dest, swap the new succ edge
- with the one moved into false_edge's former position, so that
- PHI arguments don't need adjustment. */
- edge e2 = EDGE_PRED (dest, dest_idx);
- std::swap (e->dest_idx, e2->dest_idx);
- std::swap (EDGE_PRED (dest, e->dest_idx),
- EDGE_PRED (dest, e2->dest_idx));
- }
if (BARRIER_P (BB_END (new_bb)))
BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
update_bb_for_insn (new_bb);
@@ -6538,7 +6549,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
static basic_block
construct_init_block (void)
{
- basic_block init_block, first_block;
+ basic_block init_block;
edge e = NULL;
int flags;
@@ -6569,11 +6580,7 @@ construct_init_block (void)
init_block->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
add_bb_to_loop (init_block, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
if (e)
- {
- first_block = e->dest;
- redirect_edge_succ (e, init_block);
- make_single_succ_edge (init_block, first_block, flags);
- }
+ expand_split_edge (e, init_block, flags);
else
make_single_succ_edge (init_block, EXIT_BLOCK_PTR_FOR_FN (cfun),
EDGE_FALLTHRU);
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index c5d3e8c..7cb13e7 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3948,6 +3948,7 @@
;; -------------------------------------------------------------------------
;; Includes:
;; - NOT
+;; - NOTS
;; -------------------------------------------------------------------------
;; Unpredicated predicate inverse.
@@ -3972,6 +3973,42 @@
"not\t%0.b, %1/z, %2.b"
)
+;; Predicated predicate inverse in which the flags are set in the same
+;; way as a PTEST.
+(define_insn "*one_cmpl<mode>3_cc"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upa")
+ (match_operand 3)
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (and:PRED_ALL
+ (not:PRED_ALL
+ (match_operand:PRED_ALL 2 "register_operand" "Upa"))
+ (match_dup 3))]
+ UNSPEC_PTEST))
+ (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
+ (and:PRED_ALL (not:PRED_ALL (match_dup 2)) (match_dup 3)))]
+ "TARGET_SVE"
+ "nots\t%0.b, %1/z, %2.b"
+)
+
+;; Same, where only the flags result is interesting.
+(define_insn "*one_cmpl<mode>3_ptest"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upa")
+ (match_operand 3)
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (and:PRED_ALL
+ (not:PRED_ALL
+ (match_operand:PRED_ALL 2 "register_operand" "Upa"))
+ (match_dup 3))]
+ UNSPEC_PTEST))
+ (clobber (match_scratch:PRED_ALL 0 "=Upa"))]
+ "TARGET_SVE"
+ "nots\t%0.b, %1/z, %2.b"
+)
+
;; =========================================================================
;; == Binary arithmetic
;; =========================================================================
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 01b8e4b..f8bbdc7 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -5273,6 +5273,41 @@
;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
;; arithmetic shift left
+;; Work around PR120423: Transform left shift of a paradoxical subreg
+;; into left shift of the zero-extended entity.
+(define_split ; PR120423
+ [(set (match_operand:HISI 0 "register_operand")
+ (ashift:HISI (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
+ 0)
+ (match_operand:QI 2 "const_int_operand")))]
+ "!reload_completed
+ && !avropt_lra_p
+ && <HISI:SIZE> > <QIPSI:SIZE>"
+ [(set (match_dup 4)
+ (zero_extend:HISI (match_dup 5)))
+ (set (match_dup 0)
+ (ashift:HISI (match_dup 4)
+ (match_dup 2)))]
+ {
+ operands[4] = gen_reg_rtx (<HISI:MODE>mode);
+ operands[5] = force_reg (<QIPSI:MODE>mode, operands[1]);
+ })
+
+;; Similar happens for PR116389.
+(define_split ; PR116389
+ [(set (match_operand:HISI 0 "register_operand")
+ (subreg:HISI (match_operand:QIPSI 1 "nonimmediate_operand")
+ 0))]
+ "!reload_completed
+ && !avropt_lra_p
+ && <HISI:SIZE> > <QIPSI:SIZE>"
+ [(set (match_dup 0)
+ (zero_extend:HISI (match_dup 2)))]
+ {
+ operands[2] = force_reg (<QIPSI:MODE>mode, operands[1]);
+ })
+
+
;; "ashlqi3"
;; "ashlqq3" "ashluqq3"
(define_expand "ashl<mode>3"
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 842f74d..41d68ed 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,27 @@
+2025-06-14 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (build_co_await): Identify diagnostics
+ for initial and final await expressions.
+ (cp_coroutine_transform::wrap_original_function_body): Do
+ not handle initial and final await expressions here ...
+ (cp_coroutine_transform::apply_transforms): ... handle them
+ here and avoid duplicate diagnostics.
+ * coroutines.h: Declare inital and final await expressions
+ in the transform class. Save the function closing brace
+ location.
+
+2025-06-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/116775
+ * coroutines.cc (analyze_expression_awaits): When we see
+ a builtin_constant_p call, and that contains one or more
+ await expressions, then replace the call with its result
+ and discard the unevaluated operand.
+
+2025-06-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * coroutines.cc (build_actor_fn): Set can_throw.
+
2025-06-12 Alfie Richards <alfie.richards@arm.com>
* decl.cc (maybe_version_functions): Change record_function_versions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 97eee6e..4057a07 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1277,8 +1277,14 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind,
if (TREE_CODE (o_type) != RECORD_TYPE)
{
- error_at (loc, "awaitable type %qT is not a structure",
- o_type);
+ if (suspend_kind == FINAL_SUSPEND_POINT)
+ error_at (loc, "%qs awaitable type %qT is not a structure",
+ "final_suspend()", o_type);
+ else if (suspend_kind == INITIAL_SUSPEND_POINT)
+ error_at (loc, "%qs awaitable type %qT is not a structure",
+ "initial_suspend()", o_type);
+ else
+ error_at (loc, "awaitable type %qT is not a structure", o_type);
return error_mark_node;
}
@@ -2406,6 +2412,11 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
bool spf = start_preparsed_function (actor, NULL_TREE, SF_PRE_PARSED);
gcc_checking_assert (spf);
gcc_checking_assert (cfun && current_function_decl && TREE_STATIC (actor));
+ if (flag_exceptions)
+ /* We, unconditionally, add a try/catch and rethrow.
+ TODO: Determine if the combination of initial suspend and the original
+ body cannot throw, and elide these additions. */
+ cp_function_chain->can_throw = true;
tree stmt = begin_function_body ();
tree actor_bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
@@ -3420,7 +3431,8 @@ maybe_promote_temps (tree *stmt, void *d)
return cp_walk_tree (stmt, register_awaits, d, &visited);
}
-/* Lightweight callback to determine two key factors:
+/* Relatively lightweight callback to do initial assessment:
+ 0) Rewrite some await expressions.
1) If the statement/expression contains any await expressions.
2) If the statement/expression potentially requires a re-write to handle
TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
@@ -3437,6 +3449,26 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, void *d)
switch (TREE_CODE (*stmt))
{
default: return NULL_TREE;
+ case CALL_EXPR:
+ {
+ tree fn = cp_get_callee_fndecl_nofold (*stmt);
+ /* Special-cases where we want to re-write await expressions to some
+ other value before they are otherwise processed. */
+ if (fn && DECL_IS_BUILTIN_CONSTANT_P (fn))
+ {
+ gcc_checking_assert (call_expr_nargs (*stmt) == 1);
+ tree expr = CALL_EXPR_ARG (*stmt, 0);
+ if (cp_walk_tree (&expr, find_any_await, nullptr, NULL))
+ {
+ if (TREE_CONSTANT (maybe_constant_value (expr)))
+ *stmt = integer_one_node;
+ else
+ *stmt = integer_zero_node;
+ }
+ *do_subtree = 0;
+ }
+ }
+ break;
case CO_YIELD_EXPR:
/* co_yield is syntactic sugar, re-write it to co_await. */
*stmt = TREE_OPERAND (*stmt, 1);
@@ -4330,7 +4362,6 @@ cp_coroutine_transform::wrap_original_function_body ()
/* Wrap the function body in a try {} catch (...) {} block, if exceptions
are enabled. */
tree var_list = NULL_TREE;
- tree initial_await = build_init_or_final_await (fn_start, false);
/* [stmt.return.coroutine] / 3
If p.return_void() is a valid expression, flowing off the end of a
@@ -4524,7 +4555,8 @@ cp_coroutine_transform::wrap_original_function_body ()
zero_resume = build2_loc (loc, MODIFY_EXPR, act_des_fn_ptr_type,
resume_fn_ptr, zero_resume);
finish_expr_stmt (zero_resume);
- finish_expr_stmt (build_init_or_final_await (fn_start, true));
+ finish_expr_stmt (final_await);
+
BIND_EXPR_BODY (update_body) = pop_stmt_list (BIND_EXPR_BODY (update_body));
BIND_EXPR_VARS (update_body) = nreverse (var_list);
BLOCK_VARS (top_block) = BIND_EXPR_VARS (update_body);
@@ -5181,9 +5213,10 @@ cp_coroutine_transform::cp_coroutine_transform (tree _orig_fn, bool _inl)
}
/* We don't have the locus of the opening brace - it's filled in later (and
- there doesn't really seem to be any easy way to get at it).
- The closing brace is assumed to be input_location. */
+ there doesn't really seem to be any easy way to get at it). */
fn_start = DECL_SOURCE_LOCATION (orig_fn_decl);
+ /* The closing brace is assumed to be input_location. */
+ fn_end = input_location;
/* Build types we need. */
tree fr_name = get_fn_local_identifier (orig_fn_decl, "Frame");
@@ -5262,6 +5295,16 @@ cp_coroutine_transform::apply_transforms ()
= coro_build_actor_or_destroy_function (orig_fn_decl, act_des_fn_type,
frame_ptr_type, false);
+ /* Avoid repeating diagnostics about promise or awaiter fails. */
+ if (!seen_error ())
+ {
+ iloc_sentinel stable_input_loc (fn_start);
+ initial_await = build_init_or_final_await (fn_start, false);
+ input_location = fn_end;
+ if (initial_await && initial_await != error_mark_node)
+ final_await = build_init_or_final_await (fn_end, true);
+ }
+
/* Transform the function body as per [dcl.fct.def.coroutine] / 5. */
wrap_original_function_body ();
diff --git a/gcc/cp/coroutines.h b/gcc/cp/coroutines.h
index 55caa6e..919dc9a 100644
--- a/gcc/cp/coroutines.h
+++ b/gcc/cp/coroutines.h
@@ -102,6 +102,7 @@ private:
tree orig_fn_decl; /* The original function decl. */
tree orig_fn_body = NULL_TREE; /* The original function body. */
location_t fn_start = UNKNOWN_LOCATION;
+ location_t fn_end = UNKNOWN_LOCATION;
tree resumer = error_mark_node;
tree destroyer = error_mark_node;
tree coroutine_body = NULL_TREE;
@@ -126,6 +127,9 @@ private:
bool inline_p = false;
bool valid_coroutine = false;
+ tree initial_await = error_mark_node;
+ tree final_await = error_mark_node;
+
void analyze_fn_parms ();
void wrap_original_function_body ();
bool build_ramp_function ();
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 4e61de2..235fe80 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -8506,11 +8506,13 @@ driver::set_up_specs () const
spec_machine_suffix = just_machine_suffix;
#endif
+ const char *exec_prefix
+ = gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix;
/* We need to check standard_exec_prefix/spec_machine_suffix/specs
for any override of as, ld and libraries. */
- specs_file = (char *) alloca (strlen (standard_exec_prefix)
- + strlen (spec_machine_suffix) + sizeof ("specs"));
- strcpy (specs_file, standard_exec_prefix);
+ specs_file = (char *) alloca (
+ strlen (exec_prefix) + strlen (spec_machine_suffix) + sizeof ("specs"));
+ strcpy (specs_file, exec_prefix);
strcat (specs_file, spec_machine_suffix);
strcat (specs_file, "specs");
if (access (specs_file, R_OK) == 0)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 80cc664..c339beb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,40 @@
+2025-06-14 Georg-Johann Lay <avr@gjlay.de>
+
+ Backported from master:
+ 2025-06-14 Georg-Johann Lay <avr@gjlay.de>
+
+ PR rtl-optimization/120423
+ PR rtl-optimization/116389
+ * gcc.target/avr/torture/pr120423-1.c: New test.
+ * gcc.target/avr/torture/pr120423-2.c: New test.
+ * gcc.target/avr/torture/pr120423-116389.c: New test.
+
+2025-06-14 Iain Sandoe <iain@sandoe.co.uk>
+
+ * g++.dg/coroutines/coro1-missing-await-method.C: Adjust for
+ improved diagnostics.
+ * g++.dg/coroutines/coro-missing-final-suspend.C: Likewise.
+ * g++.dg/coroutines/pr104051.C: Move to...
+ * g++.dg/coroutines/pr104051-0.C: ...here.
+ * g++.dg/coroutines/pr104051-1.C: New test.
+
+2025-06-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/116775
+ * g++.dg/coroutines/pr116775.C: New test.
+
+2025-06-13 Spencer Abson <spencer.abson@arm.com>
+
+ PR target/118150
+ * gcc.target/aarch64/sve/acle/general/not_1.c: New test.
+
+2025-06-13 Konstantinos Eleftheriou <konstantinos.eleftheriou@vrull.eu>
+
+ PR testsuite/119862
+ * gcc.dg/pr119160.c: Added empty definitions for
+ `__cyg_profile_func_enter` and `__cyg_profile_func_exit`
+ functions.
+
2025-06-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/120638
diff --git a/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C b/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C
index 6a0878c..b252231 100644
--- a/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C
+++ b/gcc/testsuite/g++.dg/coroutines/coro-missing-final-suspend.C
@@ -7,10 +7,10 @@
#include "coro1-ret-int-yield-int.h"
coro1
-my_coro () // { dg-error {no member named 'final_suspend' in} }
+my_coro ()
{
co_return 0;
-}
+} // { dg-error {no member named 'final_suspend' in} }
// check we have not messed up continuation of the compilation.
template <class... Args>
diff --git a/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C b/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C
index c1869e0..c6a3188 100644
--- a/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C
+++ b/gcc/testsuite/g++.dg/coroutines/coro1-missing-await-method.C
@@ -7,7 +7,7 @@
#include "coro1-ret-int-yield-int.h"
coro1
-bar0 () // { dg-error {no member named 'await_suspend' in 'coro1::suspend_always_prt'} }
+bar0 ()
{
co_await coro1::suspend_never_prt{}; // { dg-error {no member named 'await_ready' in 'coro1::suspend_never_prt'} }
co_yield 5; // { dg-error {no member named 'await_suspend' in 'coro1::suspend_always_prt'} }
diff --git a/gcc/testsuite/g++.dg/coroutines/pr104051.C b/gcc/testsuite/g++.dg/coroutines/pr104051-0.C
index f77a915..bf878b2 100644
--- a/gcc/testsuite/g++.dg/coroutines/pr104051.C
+++ b/gcc/testsuite/g++.dg/coroutines/pr104051-0.C
@@ -24,7 +24,7 @@ template <typename T> struct task {
std::coroutine_handle<> await_suspend(std::coroutine_handle<>);
T await_resume();
};
-task<std::vector<int>> foo() { // { dg-error {awaitable type 'bool' is not a structure} }
+task<std::vector<int>> foo() {
while ((co_await foo()).empty())
;
-}
+} // { dg-error {'final_suspend\(\)' awaitable type 'bool' is not a structure} }
diff --git a/gcc/testsuite/g++.dg/coroutines/pr104051-1.C b/gcc/testsuite/g++.dg/coroutines/pr104051-1.C
new file mode 100644
index 0000000..35b5e2c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr104051-1.C
@@ -0,0 +1,23 @@
+// { dg-additional-options "-fsyntax-only" }
+// { dg-skip-if "requires hosted libstdc++ for vector" { ! hostedlib } }
+#include <coroutine>
+template <typename>
+struct promise {
+ auto get_return_object() {
+ return std::coroutine_handle<promise>::from_promise(*this);
+ }
+ auto initial_suspend() { return 42.0; }
+ auto final_suspend() noexcept { return true; }
+ void unhandled_exception();
+ void return_void ();
+};
+template <typename T> struct task {
+ using promise_type = promise<T>;
+ task(std::coroutine_handle<promise<T>>);
+ bool await_ready();
+ std::coroutine_handle<> await_suspend(std::coroutine_handle<>);
+ T await_resume();
+};
+task<double> foo() { // { dg-error {'initial_suspend\(\)' awaitable type 'double' is not a structure} }
+ co_return;
+}
diff --git a/gcc/testsuite/g++.dg/coroutines/pr116775.C b/gcc/testsuite/g++.dg/coroutines/pr116775.C
new file mode 100644
index 0000000..981e27a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr116775.C
@@ -0,0 +1,68 @@
+// { dg-additional-options "-fsyntax-only" }
+// PR116775
+#include <coroutine>
+#ifndef OUTPUT
+# define PRINT(X)
+# define PRINTF(...)
+#else
+#include <cstdio>
+# define PRINT(X) puts(X)
+# define PRINTF(...) printf(__VA_ARGS__)
+#endif
+
+struct awaitable {
+ awaitable(int n) : delay{n} {}
+
+ constexpr bool await_ready() const noexcept { return false; }
+ auto await_suspend(std::coroutine_handle<> h) const {
+ __builtin_trap ();
+ return false;
+ }
+ int await_resume() const noexcept {
+ return delay;
+ }
+
+ int delay;
+};
+
+struct Task {
+ struct promise_type {
+ promise_type() = default;
+ Task get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void () {}
+ awaitable yield_value (int v) { return {v}; }
+ };
+};
+
+Task foo() noexcept {
+ if (__builtin_constant_p (true ? 1 : co_await awaitable{10}))
+ PRINT ("const OK");
+ else
+ {
+ PRINT ("failed : should be const");
+ __builtin_abort ();
+ }
+ if (__builtin_constant_p (false ? 1 : co_await awaitable{15}))
+ {
+ PRINT ("failed : should not be const");
+ __builtin_abort ();
+ }
+ else
+ PRINT ("not const, OK");
+ if (__builtin_constant_p (5 == (co_yield 42)))
+ {
+ PRINT ("failed : should not be const");
+ __builtin_abort ();
+ }
+ else
+ PRINT ("not const, OK");
+ co_return;
+}
+
+//call foo
+int main() {
+ foo();
+}
diff --git a/gcc/testsuite/gcc.dg/pr119160.c b/gcc/testsuite/gcc.dg/pr119160.c
index 5743b3b..c3d9b81 100644
--- a/gcc/testsuite/gcc.dg/pr119160.c
+++ b/gcc/testsuite/gcc.dg/pr119160.c
@@ -4,6 +4,19 @@
typedef __attribute__((__vector_size__ (32))) int V;
+/* Add empty implementations of __cyg_profile_func_enter() and
+ __cyg_profile_func_exit() to avoid problems on non-glibc
+ systems. */
+void __attribute__((no_instrument_function))
+__cyg_profile_func_enter(void *this_fn, void *call_site)
+{
+}
+
+void __attribute__((no_instrument_function))
+__cyg_profile_func_exit(void *this_fn, void *call_site)
+{
+}
+
void
foo (V v, V, V, V *r)
{
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
new file mode 100644
index 0000000..875d788
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/not_1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <arm_sve.h>
+
+void
+test1 (svbool_t pg, svbool_t x, int *any, svbool_t *ptr)
+{
+ svbool_t res = svnot_z (pg, x);
+ *any = svptest_last (pg, res);
+ *ptr = res;
+}
+
+int
+test2 (svbool_t pg, svbool_t x)
+{
+ svbool_t res = svnot_z (pg, x);
+ return svptest_first (pg, res);
+}
+
+/* { dg-final { scan-assembler-times {\tnots\t} 2 } } */
+/* { dg-final { scan-assembler-not {\tnot\t} } } */
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c
new file mode 100644
index 0000000..91b4bbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+struct data
+{
+ int a;
+ int b;
+ long c;
+};
+
+unsigned char val;
+unsigned val2;
+
+void func1 (struct data *d)
+{
+ d->a = 0;
+ d->b = 0x100 * val - 1;
+}
+
+void func2 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x10000 * val2 - 1;
+}
+
+void func3 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x1000000 * val - 1;
+}
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c
new file mode 100644
index 0000000..928c135
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-116389.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+struct T { int val; };
+
+void f_int (int);
+char* get_pos (void);
+struct T* get_pT (void);
+
+void func (char i)
+{
+ struct T t = * get_pT ();
+ unsigned diff = get_pos () - &i;
+
+ if (diff)
+ {
+ long val32 = t.val;
+ if (get_pos ())
+ val32 = diff;
+ if (get_pos ())
+ f_int (2 * val32);
+ }
+}
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c
new file mode 100644
index 0000000..56e6141
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/pr120423-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ffixed-18 -ffixed-20 -ffixed-22" } */
+
+struct data
+{
+ int a;
+ int b;
+ long c;
+};
+
+unsigned char val;
+unsigned val2;
+
+void func1 (struct data *d)
+{
+ d->a = 0;
+ d->b = 0x100 * val - 1;
+}
+
+void func2 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x10000 * val2 - 1;
+}
+
+void func3 (struct data *d)
+{
+ d->a = 0;
+ d->c = 0x1000000 * val - 1;
+}