[gcc r16-2603] Another testcase for PR120687
https://gcc.gnu.org/g:9c48cbb259851873397abc632422f3f44f253db0 commit r16-2603-g9c48cbb259851873397abc632422f3f44f253db0 Author: Richard Biener Date: Tue Jul 29 14:01:46 2025 +0200 Another testcase for PR120687 This shows reassoc is harmful even with len == 3. PR tree-optimization/120687 * gcc.dg/vect/pr120687-3.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/vect/pr120687-3.c | 16 1 file changed, 16 insertions(+) diff --git a/gcc/testsuite/gcc.dg/vect/pr120687-3.c b/gcc/testsuite/gcc.dg/vect/pr120687-3.c new file mode 100644 index ..f20a66a62230 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120687-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ +/* { dg-additional-options "-ffast-math" } */ + +float +frd (float *p, float *lastone) +{ + float sum = 0; + for (; p <= lastone; p += 2) +sum += p[0] + p[1]; + return sum; +} + +/* { dg-final { scan-tree-dump "reduction: detected reduction chain" "vect" } } */ +/* { dg-final { scan-tree-dump-not "SLP discovery of reduction chain failed" "vect" } } */ +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */
[gcc r15-10082] calls: Allow musttail calls to noreturn [PR121159]
https://gcc.gnu.org/g:4af2b713a20153b01c3071015856e60a73d10928 commit r15-10082-g4af2b713a20153b01c3071015856e60a73d10928 Author: Jakub Jelinek Date: Tue Jul 29 09:49:55 2025 +0200 calls: Allow musttail calls to noreturn [PR121159] In the PR119483 r15-9003 change we've allowed musttail calls to noreturn functions, after all the decision not to normally tail call noreturn functions is not because it is not possible to tail call those, but because it screws up backtraces. As the following testcase shows, we've done that only for functions not declared [[noreturn]]/_Noreturn but later on discovered through IPA as noreturn. Functions explicitly declared [[noreturn]] have (for historical reasons) volatile FUNCTION_TYPE and the FUNCTION_DECLs are volatile as well, so in order to support those we shouldn't complain on ECF_NORETURN (we've stopped doing so for musttail in PR119483) but also shouldn't complain about TYPE_VOLATILE on their FUNCTION_TYPE (something that IPA doesn't change, I think it only sets TREE_THIS_VOLATILE on the FUNCTION_DECL). volatile on function type really means noreturn as well, it has no other meaning. 2025-07-29 Jakub Jelinek PR middle-end/121159 * calls.cc (can_implement_as_sibling_call_p): Don't reject declared noreturn functions in musttail calls. * c-c++-common/pr121159.c: New test. * gcc.dg/plugin/must-tail-call-2.c (test_5): Don't expect an error. (cherry picked from commit f4abe216199930adfa110059c3c8e642c585388b) Diff: --- gcc/calls.cc | 3 ++- gcc/testsuite/c-c++-common/pr121159.c | 17 + gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gcc/calls.cc b/gcc/calls.cc index 076e046a8ef1..099a353909e8 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -2580,7 +2580,8 @@ can_implement_as_sibling_call_p (tree exp, return false; } - if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr + if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) + && !CALL_EXPR_MUST_TAIL_CALL (exp)) { maybe_complain_about_tail_call (exp, _("volatile function type")); return false; diff --git a/gcc/testsuite/c-c++-common/pr121159.c b/gcc/testsuite/c-c++-common/pr121159.c new file mode 100644 index ..c8c5d672958e --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr121159.c @@ -0,0 +1,17 @@ +/* PR middle-end/121159 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "foo \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ + +[[noreturn, gnu::noipa]] void +foo (void) +{ + for (;;) +; +} + +void +bar (void) +{ + [[gnu::musttail]] return foo (); +} diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c index d51d15cc0879..6f65f4ab96cb 100644 --- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c +++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c @@ -55,5 +55,5 @@ volatile fn_ptr_t fn_ptr; void test_5 (void) { - fn_ptr (); /* { dg-error "cannot tail-call: " } */ + fn_ptr (); }
[gcc r16-2600] Fix UB in string_slice::operator== (PR 121261)
https://gcc.gnu.org/g:c1102be3b25bde9989561b2610f8ee721a33a8e7 commit r16-2600-gc1102be3b25bde9989561b2610f8ee721a33a8e7 Author: Alfie Richards Date: Mon Jul 28 13:32:45 2025 + Fix UB in string_slice::operator== (PR 121261) This adds a nullptr check to fix a regression where it is possible to call `memcmp (NULL, NULL, 0)` which is UB prior to C26. This fixes the bootstrap-ubsan build. gcc/ChangeLog: PR middle-end/121261 * vec.h: Add null ptr check. Diff: --- gcc/vec.h | 4 1 file changed, 4 insertions(+) diff --git a/gcc/vec.h b/gcc/vec.h index 9604edb1c3cf..0ea7a4957340 100644 --- a/gcc/vec.h +++ b/gcc/vec.h @@ -2514,6 +2514,10 @@ public: return false; if (lhs.size () != rhs.size ()) return false; +/* Case where either is a NULL pointer and therefore, as both are valid, + both are empty slices with length 0. */ +if (lhs.size () == 0) + return true; return memcmp (lhs.begin (), rhs.begin (), lhs.size ()) == 0; }
[gcc(refs/users/meissner/heads/work216-bugs)] Revert changes
https://gcc.gnu.org/g:80673a98b7379b7a1e17f78b60003bee9432d249 commit 80673a98b7379b7a1e17f78b60003bee9432d249 Author: Michael Meissner Date: Tue Jul 29 04:57:20 2025 -0400 Revert changes Diff: --- gcc/config/rs6000/predicates.md | 13 ++-- gcc/config/rs6000/rs6000-protos.h | 24 +-- gcc/config/rs6000/rs6000.cc | 30 +++-- gcc/config/rs6000/rs6000.h| 10 +-- gcc/config/rs6000/rs6000.md | 136 -- 5 files changed, 106 insertions(+), 107 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 9fa1dda4f899..647e89afb6a7 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1460,13 +1460,14 @@ ;; Return 1 if OP is a comparison operator suitable for floating point ;; vector/scalar comparisons that generate a -1/0 mask. -;; -;; Do not match UNEQ, UNLT, UNLE, UNGT, or UNGE since the fpmask -;; instructions can trap on signaling NaNs. -;; -;; Do not match NE, ifcvt.c will handle reversing the results. (define_predicate "fpmask_comparison_operator" - (match_code "eq,lt,le,gt,ge")) + (match_code "eq,gt,ge")) + +;; Return 1 if OP is a comparison operator suitable for vector/scalar +;; comparisons that generate a 0/-1 mask (i.e. the inverse of +;; fpmask_comparison_operator). +(define_predicate "invert_fpmask_comparison_operator" + (match_code "ne,unlt,unle")) ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar ;; comparisons that generate a -1/0 mask. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index d0a59f8006fe..4619142d197b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -114,30 +114,8 @@ extern const char *rs6000_sibcall_template (rtx *, unsigned int); extern const char *rs6000_indirect_call_template (rtx *, unsigned int); extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int); extern const char *rs6000_pltseq_template (rtx *, int); - -/* Whether we can reverse the sense of a comparison. - - If the comparison involves UNEQ, LTGT, UNGT, UNGE, UNLT, and UNLE - comparisons we cannot generate instructions that could generate a trap with - a signaling NaN. These comprisons are created using the floating point - relational tests (like isgreater, isless, etc.), and these comparisons must - not trap on any value like a signaling NaN. The fpmask instructions - (XSCMPEQDP, XSCMPGTQP, etc.) that do the comparison and produce 1's or 0's - to allow the XXSEL instruction to do a conditional move. - - However, if we are not generating fpmask instructions, we have to allow - doing the reversals. We need this reversal to handle condition jumps that - are too far away to jump to directly and we have to reverse the jump, so we - can generate a jump around an unconditional jump. */ - -enum class rev_cond_allowed { - reverse_ok, - no_reverse -}; - extern enum rtx_code rs6000_reverse_condition (machine_mode, - enum rtx_code, - enum rev_cond_allowed); + enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx); extern void rs6000_emit_sCOND (machine_mode, rtx[]); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 0fea81e3243c..f4f0ad80e35e 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -15282,22 +15282,17 @@ rs6000_print_patchable_function_entry (FILE *file, } enum rtx_code -rs6000_reverse_condition (machine_mode mode, - enum rtx_code code, - enum rev_cond_allowed do_reverse) +rs6000_reverse_condition (machine_mode mode, enum rtx_code code) { /* Reversal of FP compares takes care -- an ordered compare - becomes an unordered compare and vice versa. - - Do not allow reversing comparisons if this is an IEEE comparison that must - not trap. We do allow the comparsion to be reversed for explicit jumps - when rev_cond_allowed::reverse_ok is passed. */ - if (mode == CCFPmode) -return (do_reverse == rev_cond_allowed::no_reverse - ? UNKNOWN - : reverse_condition_maybe_unordered (code)); - - return reverse_condition (code); + becomes an unordered compare and vice versa. */ + if (mode == CCFPmode + && (!flag_finite_math_only + || code == UNLT || code == UNLE || code == UNGT || code == UNGE + || code == UNEQ || code == LTGT)) +return reverse_condition_maybe_unordered (code); + else +return reverse_condition (code); } /* Check if C (as 64bit integer) can be rotated to a constant which constains @@ -15907,14 +15902,11 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[]) rtx not_result = gen_reg_rtx (CCEQmode);
[gcc(refs/users/meissner/heads/work216-bugs)] Delete files.
https://gcc.gnu.org/g:c7af002c5fff63bd7266c35e624766585d1383d3 commit c7af002c5fff63bd7266c35e624766585d1383d3 Author: Michael Meissner Date: Tue Jul 29 04:56:35 2025 -0400 Delete files. Diff: --- gcc/testsuite/gcc.target/powerpc/pr118541-1.c | 28 --- gcc/testsuite/gcc.target/powerpc/pr118541-2.c | 26 - gcc/testsuite/gcc.target/powerpc/pr118541-3.c | 26 - gcc/testsuite/gcc.target/powerpc/pr118541-4.c | 26 - 4 files changed, 106 deletions(-) diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-1.c b/gcc/testsuite/gcc.target/powerpc/pr118541-1.c deleted file mode 100644 index 30901cd1e41d.. --- a/gcc/testsuite/gcc.target/powerpc/pr118541-1.c +++ /dev/null @@ -1,28 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify isgreater does not generate xscmpgtdp when NaNs are allowed. */ - -double -ieee_compare (double a, double b, double c, double d) -{ - /* - * fcmpu 0,1,2 - * fmr 1,4 - * bnglr 0 - * fmr 1,3 - * blr - */ - - return __builtin_isgreater (a, b) ? c : d; -} - -/* { dg-final { scan-assembler-not {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler-not {\mxxsel\M} } } */ -/* { dg-final { scan-assembler {\mxscmpudp\M|\mfcmpu\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-2.c b/gcc/testsuite/gcc.target/powerpc/pr118541-2.c deleted file mode 100644 index 17872bf84805.. --- a/gcc/testsuite/gcc.target/powerpc/pr118541-2.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -Ofast" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify isgreater does generate xscmpgtdp when NaNs are not allowed. */ - -double -ieee_compare (double a, double b, double c, double d) -{ - /* - * xscmpgtdp 1,1,2 - * xxsel 1,4,3,1 - * blr - */ - - return __builtin_isgreater (a, b) ? c : d; -} - -/* { dg-final { scan-assembler {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler {\mxxsel\M} } } */ -/* { dg-final { scan-assembler-not {\mxscmpudp\M|\mfcmpu\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-3.c b/gcc/testsuite/gcc.target/powerpc/pr118541-3.c deleted file mode 100644 index 1f36890b775f.. --- a/gcc/testsuite/gcc.target/powerpc/pr118541-3.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify normal > does generate xscmpgtdp when NaNs are allowed. */ - -double -normal_compare (double a, double b, double c, double d) -{ - /* - * xscmpgtdp 1,1,2 - * xxsel 1,4,3,1 - * blr - */ - - return a > b ? c : d; -} - -/* { dg-final { scan-assembler {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler {\mxxsel\M} } } */ -/* { dg-final { scan-assembler-not {\mxscmpudp\M|\mfcmpu\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr118541-4.c b/gcc/testsuite/gcc.target/powerpc/pr118541-4.c deleted file mode 100644 index 563d33be5758.. --- a/gcc/testsuite/gcc.target/powerpc/pr118541-4.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-mdejagnu-cpu=power9 -Ofast" } */ -/* { dg-require-effective-target powerpc_vsx } */ - -/* PR target/118541 says that the IEEE comparison functions like isgreater - should not optimize floating point conditional moves to use - x{s,v}cmp{eq,gt,ge}{dp,qp} and xxsel since that instruction can cause traps - if one of the arguments is a signaling NaN. */ - -/* Verify normal > does generate xscmpgtdp when NaNs are not allowed. */ - -double -normal_compare (double a, double b, double c, double d) -{ - /* - * xscmpgtdp 1,1,2 - * xxsel 1,4,3,1 - * blr - */ - - return a > b ? c : d; -} - -/* { dg-final { scan-assembler {\mxscmpg[te]dp\M} } } */ -/* { dg-final { scan-assembler {\mxxsel\M} } } */ -/* { dg-final { scan-assembler-not {\mxscmpudp\M|
[gcc r16-2597] calls: Allow musttail calls to noreturn [PR121159]
https://gcc.gnu.org/g:f4abe216199930adfa110059c3c8e642c585388b commit r16-2597-gf4abe216199930adfa110059c3c8e642c585388b Author: Jakub Jelinek Date: Tue Jul 29 09:49:55 2025 +0200 calls: Allow musttail calls to noreturn [PR121159] In the PR119483 r15-9003 change we've allowed musttail calls to noreturn functions, after all the decision not to normally tail call noreturn functions is not because it is not possible to tail call those, but because it screws up backtraces. As the following testcase shows, we've done that only for functions not declared [[noreturn]]/_Noreturn but later on discovered through IPA as noreturn. Functions explicitly declared [[noreturn]] have (for historical reasons) volatile FUNCTION_TYPE and the FUNCTION_DECLs are volatile as well, so in order to support those we shouldn't complain on ECF_NORETURN (we've stopped doing so for musttail in PR119483) but also shouldn't complain about TYPE_VOLATILE on their FUNCTION_TYPE (something that IPA doesn't change, I think it only sets TREE_THIS_VOLATILE on the FUNCTION_DECL). volatile on function type really means noreturn as well, it has no other meaning. 2025-07-29 Jakub Jelinek PR middle-end/121159 * calls.cc (can_implement_as_sibling_call_p): Don't reject declared noreturn functions in musttail calls. * c-c++-common/pr121159.c: New test. * gcc.dg/plugin/must-tail-call-2.c (test_5): Don't expect an error. Diff: --- gcc/calls.cc | 3 ++- gcc/testsuite/c-c++-common/pr121159.c | 17 + gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gcc/calls.cc b/gcc/calls.cc index e16190c12a63..2711c4ebe325 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -2589,7 +2589,8 @@ can_implement_as_sibling_call_p (tree exp, return false; } - if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr + if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) + && !CALL_EXPR_MUST_TAIL_CALL (exp)) { maybe_complain_about_tail_call (exp, _("volatile function type")); return false; diff --git a/gcc/testsuite/c-c++-common/pr121159.c b/gcc/testsuite/c-c++-common/pr121159.c new file mode 100644 index ..c8c5d672958e --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr121159.c @@ -0,0 +1,17 @@ +/* PR middle-end/121159 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "foo \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ + +[[noreturn, gnu::noipa]] void +foo (void) +{ + for (;;) +; +} + +void +bar (void) +{ + [[gnu::musttail]] return foo (); +} diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c index d51d15cc0879..6f65f4ab96cb 100644 --- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c +++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c @@ -55,5 +55,5 @@ volatile fn_ptr_t fn_ptr; void test_5 (void) { - fn_ptr (); /* { dg-error "cannot tail-call: " } */ + fn_ptr (); }
[gcc r16-2604] Match: Introduce mul based pattern for unsigned SAT_MUL
https://gcc.gnu.org/g:a481f299b35085bf1b218eb36a77e8a571fb7662 commit r16-2604-ga481f299b35085bf1b218eb36a77e8a571fb7662 Author: Pan Li Date: Sat Jul 26 16:32:08 2025 +0800 Match: Introduce mul based pattern for unsigned SAT_MUL Like widen_mul based pattern, we would like introduce the mul based pattern as well. The pattern is quite simple compares to the widen_mul, thus add new instead of the for loop in match.pd. gcc/ChangeLog: * match.pd: Add mul based unsigned SAT_MUL. Signed-off-by: Pan Li Diff: --- gcc/match.pd | 22 +- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 4903552c82a6..82e6e291ae19 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3595,22 +3595,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) return (T)x; } while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t. */ - (convert@4 (min (widen_mult:c@3 (convert@5 (convert @0)) - (convert@6 (convert @1))) + (convert (min (widen_mult:c@3 (convert@4 (convert @0)) +(convert@5 (convert @1))) INTEGER_CST@2)) - (if (types_match (type, @0, @1) && types_match (type, @4)) + (if (types_match (type, @0, @1)) (with { unsigned prec = TYPE_PRECISION (type); unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3)); + unsigned cvt4_prec = TYPE_PRECISION (TREE_TYPE (@4)); unsigned cvt5_prec = TYPE_PRECISION (TREE_TYPE (@5)); - unsigned cvt6_prec = TYPE_PRECISION (TREE_TYPE (@6)); wide_int c2 = wi::to_wide (@2); wide_int max = wi::mask (prec, false, widen_prec); bool c2_is_max_p = wi::eq_p (c2, max); - bool widen_mult_p = cvt5_prec == cvt6_prec && widen_prec == cvt6_prec * 2; + bool widen_mult_p = cvt4_prec == cvt5_prec && widen_prec == cvt5_prec * 2; } (if (widen_prec > prec && c2_is_max_p && widen_mult_p) + (match (unsigned_integer_sat_mul @0 @1) + (convert (min (mult:c@3 (convert @0) (convert @1)) INTEGER_CST@2)) + (if (types_match (type, @0, @1)) +(with + { + unsigned prec = TYPE_PRECISION (type); + unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3)); + wide_int c2 = wi::to_wide (@2); + wide_int max = wi::mask (prec, false, widen_prec); + bool c2_is_max_p = wi::eq_p (c2, max); + } + (if (widen_prec > prec && c2_is_max_p) ) /* The boundary condition for case 10: IMM = 1:
[gcc r16-2605] RISC-V: Add test cases for mul based unsigned scalar SAT_MUL
https://gcc.gnu.org/g:8166458f19846fb795e31d5cf2475e0bade9f546 commit r16-2605-g8166458f19846fb795e31d5cf2475e0bade9f546 Author: Pan Li Date: Sat Jul 26 16:38:23 2025 +0800 RISC-V: Add test cases for mul based unsigned scalar SAT_MUL Add run and tree-optimized check for mul based unsigned scalar SAT_MUL instead of the widen_mul. gcc/testsuite/ChangeLog: * gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u64.c: Add rv64 target for run. * gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u64.c: Ditto. * gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u64.c: Ditto. * gcc.target/riscv/sat/sat_u_mul-1-u16-from-u32.c: New test. * gcc.target/riscv/sat/sat_u_mul-1-u8-from-u16.c: New test. * gcc.target/riscv/sat/sat_u_mul-1-u8-from-u32.c: New test. * gcc.target/riscv/sat/sat_u_mul-2-u16-from-u64.c: New test. * gcc.target/riscv/sat/sat_u_mul-2-u32-from-u64.c: New test. * gcc.target/riscv/sat/sat_u_mul-2-u8-from-u64.c: New test. * gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u32.c: New test. * gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u16.c: New test. * gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u32.c: New test. Signed-off-by: Pan Li Diff: --- .../gcc.target/riscv/sat/sat_u_mul-1-u16-from-u32.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-1-u8-from-u16.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-1-u8-from-u32.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-2-u16-from-u64.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-2-u32-from-u64.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-2-u8-from-u64.c | 11 +++ .../gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u32.c | 16 .../gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u64.c | 2 +- .../gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u64.c | 2 +- .../gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u16.c | 16 .../gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u32.c | 16 .../gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u64.c | 2 +- 12 files changed, 117 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u32.c new file mode 100644 index ..74092320dc17 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u16-from-u32.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint16_t +#define WT uint32_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u16.c new file mode 100644 index ..ec79e5d77c8c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u16.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint8_t +#define WT uint16_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u32.c new file mode 100644 index ..eb95184d2f25 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-1-u8-from-u32.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint8_t +#define WT uint32_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u16-from-u64.c new file mode 100644 index ..b1d33a940f97 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u16-from-u64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint16_t +#define WT uint64_t + +DEF_SAT_U_MUL_FMT_1_WRAP(NT, WT) + +/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u32-from-u64.c new file mode 100644 index ..af5ffecf6e4d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-2-u32-from-u64.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */ + +#include "sat_arith.h" + +#define NT uint32_t +#de
[gcc/devel/gfortran-test] (238 commits) Merge branch 'master' into devel/gfortran-test
The branch 'devel/gfortran-test' was updated to point to: db57737117c3... Merge branch 'master' into devel/gfortran-test It previously pointed to: 75164bb76981... Revert "fortran: Testing patches for coarray shared memory. Diff: Summary of changes (added commits): --- db57737... Merge branch 'master' into devel/gfortran-test 0f61284... fortran: Consistently use the same assignment reallocation (*) 1800ac2... fortran: Trigger reference saving on pointer dereference [P (*) 5f9f20d... fortran: Bound class container lookup after array descripto (*) a5861d3... RISC-V: Add test case for vaadd.vx combine polluting VXRM (*) f9e8cf8... RISC-V: Add test for vec_duplicate + vaadd.vv combine case (*) 6028940... RISC-V: Add test for vec_duplicate + vaadd.vv combine case (*) b953374... RISC-V: Combine vec_duplicate + vaadd.vv to vaadd.vx on GR2 (*) 62f8a24... RISC-V: Fix another vf FP16 combine run test failures (*) fb9e543... Daily bump. (*) 4a8fd4a... Prevent mixups of IDENTIFIER_TRANSPARENT_ALIAS and IDENTIFI (*) 68ddec9... c++/modules: Stream some missing lang_type flags (*) 11518c8... diagnostics: move diagnostic.c to diagnostics/context.cc: r (*) e48e340... diagnostics: convert diagnostic_t to enum class diagnostics (*) 7ac42d3... RISC-V: riscv-ext.def: Add allocated group IDs and group bi (*) 13516af... Daily bump. (*) bae1f7e... Introduce lazily-created.h (*) 8dac541... diagnostics: avoid using "sink" for things that aren't a di (*) 3568e2f... diagnostics: make context::m_source_printing private (*) 24ffe3e... diagnostics: eliminate ::diagnostic_info typedef (*) 8aa5441... diagnostics: introduce context-options.h (*) 5f88037... diagnostics: move file_cache from input.{cc,h} to diagnosti (*) 14280a1... diagnostics: eliminate some redundant includes (*) 84c4bf5... diagnostics: simplify header files (*) 8d9d951... diagnostics: move diagnostic.c to diagnostics/context.cc (*) 3cc27ed... diagnostics: convert diagnostic_t to enum class diagnostics (*) e8c3961... diagnostics: rename diagnostic_option_id to diagnostics::op (*) a211066... Rename diagnostic-spec.{cc,h} to gcc-diagnostic-spec.{cc,h} (*) c48df0f... diagnostics: move diagnostics::edit_context -> diagnostics: (*) a9c3674... diagnostics: reorganize selftests (*) d67c91a... diagnostics: gcc/diagnostic-url.h -> gcc/diagnostics/url.h (*) 8a1a19f... diagnostics: move gcc/diagnostic-color.{h,cc} to gcc/diagno (*) 1b52954... diagnostics: move gcc/selftest-diagnostic.{h,cc} -> gcc/dia (*) 7830048... diagnostics: move buffering code to its own .cc file (*) 0654c54... diagnostics: move option_classifier to its own files (*) 0661b7b... diagnostics: move diagnostic_context to diagnostics::contex (*) 0c0cb2f... diagnostics: move diagnostic_info to its own header (*) f3157d0... diagnostics: add m_ prefix to fields of diagnostic_info (*) e3565f2... diagnostics: move diagnostic-macro-unwinding.{cc,h} -> diag (*) e31ec9e... diagnostics: introduce diagnostics/source-printing.cc (*) 5ac3308... diagnostics: move/rename output formats to diagnostics as " (*) 5b64ba6... diagnostics: introduce namespace diagnostics::paths (*) c9c996d... diagnostics: move diagnostics_output_spec to diagnostics::o (*) accd28c... diagnostics: rename diagnostic_output_file to diagnostics:: (*) bff1af9... diagnostics: move client data hooks into namespace/dir "dia (*) d38c7fa... diagnostics: move edit_context to namespace/dir "diagnostic (*) e84867c... diagnostics: move diagnostic_diagram to diagnostics::diagra (*) cf7b34b... diagnostics: move diagnostic_metadata to diagnostics::metad (*) 1743dd3... diagnostics: move logical locations into "diagnostics" (*) 6d91526... diagnostics: introduce a "gcc/diagnostics" subdirectory (*) ba5a678... c++: more name lookup for non-dep rewritten cmp ops (*) cebf2a8... Remove now redundant vect_get_vec_defs overload (*) 91eb409... Tidy vect_is_simple_use API for SLP only (*) e38c88d... Fix and simplify vect_model_simple_cost (*) 529ae14... RISC-V: Prepare dynamic LMUL heuristic for SLP. (*) 0c8781c... libstdc++: doc: Rectify referencing of non-existent type (*) fe3069a... Reduce the number of STMT_VINFO_VECTYPE uses (*) c2bb709... Remove unused stmt_vectype (*) a2775fe... c++, coroutines: Handle allocation fail returns [PR121219]. (*) f888d5f... RISC-V: Remove user-level interrupts (*) 22e5711... Remove STMT_VINFO_VEC_STMTS (*) 735b470... Remove load interleaving code (*) fcadd6d... Remove store interleaving support (*) 727276a... Remove vect_get_vec_defs_for_operand (*) 85d081b... Remove VMAT_CONTIGUOUS_PERMUTE (*) fab1cd6... Remove dead code from vectorizable_store (*) 02213d0... gcn: Add "s_nop"s for MI300 (*) 94f896c... Determine CONSTRAINT_LEN at run-time [PR121214] (*) 6cc6bfc... ada: Minor cleanup (*) bf9cb91... ada: ppc-vx6: pthread clocks and headers for decls (*) 09eced2... ada:
[gcc/devel/gfortran-test] Merge branch 'master' into devel/gfortran-test
https://gcc.gnu.org/g:db57737117c3765e379750c977a7d404f2e2d50e commit db57737117c3765e379750c977a7d404f2e2d50e Merge: 75164bb76981 0f61284eae63 Author: Jerry DeLisle Date: Tue Jul 29 10:56:10 2025 -0700 Merge branch 'master' into devel/gfortran-test Diff: ChangeLog |4 + MAINTAINERS|1 + contrib/ChangeLog | 14 + contrib/filter-clang-warnings.py |2 +- contrib/gcc-changelog/git_commit.py|1 + contrib/gcc.doxy |2 +- gcc/ChangeLog | 1916 +++ gcc/DATESTAMP |2 +- gcc/Makefile.in| 53 +- gcc/ada/ChangeLog | 425 + gcc/ada/accessibility.adb | 27 +- gcc/ada/aspects.ads|7 + gcc/ada/doc/gnat_rm/gnat_language_extensions.rst | 68 + ...ard_and_implementation_defined_restrictions.rst |6 +- gcc/ada/einfo.ads | 76 +- gcc/ada/exp_aggr.adb | 178 +- gcc/ada/exp_attr.adb | 404 ++-- gcc/ada/exp_ch3.adb| 67 +- gcc/ada/exp_ch4.adb| 10 +- gcc/ada/exp_ch6.adb| 1435 +- gcc/ada/exp_ch6.ads| 13 + gcc/ada/exp_ch7.adb| 168 +- gcc/ada/exp_ch9.adb| 44 +- gcc/ada/exp_ch9.ads|9 +- gcc/ada/exp_disp.adb | 87 +- gcc/ada/exp_disp.ads |3 - gcc/ada/exp_put_image.adb | 343 ++-- gcc/ada/exp_spark.adb | 24 + gcc/ada/exp_strm.adb | 35 +- gcc/ada/exp_util.adb | 66 +- gcc/ada/exp_util.ads | 10 - gcc/ada/freeze.adb | 48 +- gcc/ada/gcc-interface/misc.cc |4 +- gcc/ada/gcc-interface/trans.cc | 21 +- gcc/ada/gcc-interface/utils.cc | 31 +- gcc/ada/gen_il-fields.ads |7 + gcc/ada/gen_il-gen-gen_entities.adb|9 + gcc/ada/gen_il-gen-gen_nodes.adb |9 +- gcc/ada/gen_il-internals.adb |2 + gcc/ada/gnat_rm.texi | 144 +- gcc/ada/gsocket.h |6 + gcc/ada/inline.adb | 11 + gcc/ada/libgnat/a-calend.adb | 29 +- gcc/ada/libgnat/a-cbhama.adb |2 +- gcc/ada/libgnat/a-cbhama.ads |2 +- gcc/ada/libgnat/g-calend.adb | 21 +- gcc/ada/libgnat/g-socket.adb |9 +- gcc/ada/s-oscons-tmplt.c |6 +- gcc/ada/sem_attr.adb | 42 + gcc/ada/sem_aux.adb| 88 +- gcc/ada/sem_aux.ads| 14 + gcc/ada/sem_ch12.adb | 23 +- gcc/ada/sem_ch13.adb | 162 +- gcc/ada/sem_ch3.adb| 52 +- gcc/ada/sem_ch4.adb| 38 +- gcc/ada/sem_ch5.adb|9 +- gcc/ada/sem_ch6.adb| 877 - gcc/ada/sem_ch6.ads| 160 ++ gcc/ada/sem_ch8.adb| 10 +- gcc/ada/sem_ch9.adb|6 + gcc/ada/sem_disp.adb | 49 + gcc/ada/sem_res.adb|4 +- gcc/ada/sem_util.adb | 101 +- gcc/ada/sem_util.ads | 20 +- gcc/ada/sinfo.ads | 36 +- gcc/ada/snames.ads-tmpl|1 + gcc/ada/styleg.adb |6 +- gcc/ada/sysdep.c |6 + gcc/ada/tbuild.adb |6 +- gcc/analyzer/ChangeLog | 107 ++ gcc/analyzer/access-diagram.cc | 10 +- gcc/analyzer/access-diagram.h |2 +- gcc/analyzer/ana-state-to-diagnostic-state.cc |4 +- gcc/analyzer/ana-state-to-diagnostic-state.h |2 +- gcc/analyzer/analyzer.cc |4 +- gcc/analyzer/bounds-checking.cc| 28 +
[gcc r16-2619] testsuite: Cleanup after auto-profile testcases when auto-profile is not supported [PR121215]
https://gcc.gnu.org/g:688f1947bd5453632a8973d1d5fba68169c9d1a9 commit r16-2619-g688f1947bd5453632a8973d1d5fba68169c9d1a9 Author: Andrew Pinski Date: Tue Jul 29 10:38:58 2025 -0700 testsuite: Cleanup after auto-profile testcases when auto-profile is not supported [PR121215] The problem here is that in tree-prof.exp does not cleanup if requiring auto-profile but it is not supported and the testcase uses dg-additional-sources. Currently additional_sources is not reset to "" and then another testcase comes along and thinks that is the additional source to be added. Committed as obvious after testing: make check-gcc RUNTESTFLAGS="tree-prof.exp=afdo-crossmodule-1.c tree-ssa.exp=pr67891.c" to make sure pr67891.c now no longer uses the additional source. PR testsuite/121215 gcc/testsuite/ChangeLog: * lib/profopt.exp (profopt-execute): Call cleanup-after-saved-dg-test if returning early for the -fauto-profile case failing case. Signed-off-by: Andrew Pinski Diff: --- gcc/testsuite/lib/profopt.exp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/testsuite/lib/profopt.exp b/gcc/testsuite/lib/profopt.exp index b4d244b31320..81d86c632d17 100644 --- a/gcc/testsuite/lib/profopt.exp +++ b/gcc/testsuite/lib/profopt.exp @@ -382,6 +382,7 @@ proc profopt-execute { src } { unsupported "$testcase" unset testname_with_flags verbose "$src not supported on this target, skipping it" 3 + cleanup-after-saved-dg-test return } @@ -458,6 +459,7 @@ proc profopt-execute { src } { unsupported "$testcase -fauto-profile: cannot run create_gcov" unset testname_with_flags set status "fail" + cleanup-after-saved-dg-test return } set status [remote_wait "" 300]
[gcc(refs/users/meissner/heads/work216-bugs)] Revert changes
https://gcc.gnu.org/g:46f796fe2aff30e8509998c0c4c5dcdeeb1f3715 commit 46f796fe2aff30e8509998c0c4c5dcdeeb1f3715 Author: Michael Meissner Date: Tue Jul 29 13:52:47 2025 -0400 Revert changes Diff: --- gcc/config/rs6000/predicates.md | 11 +-- gcc/config/rs6000/rs6000-protos.h | 24 +-- gcc/config/rs6000/rs6000.cc | 44 +++- gcc/config/rs6000/rs6000.h| 10 +-- gcc/config/rs6000/rs6000.md | 98 +++ gcc/testsuite/gcc.target/powerpc/pr118541-1.c | 28 gcc/testsuite/gcc.target/powerpc/pr118541-2.c | 26 --- 7 files changed, 103 insertions(+), 138 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 0c55ba26919f..647e89afb6a7 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1460,14 +1460,15 @@ ;; Return 1 if OP is a comparison operator suitable for floating point ;; vector/scalar comparisons that generate a -1/0 mask. -;; -;; Do not match UNEQ, UNLT, UNLE, UNGT, or UNGE since the fpmask -;; instructions can trap on signaling NaNs. -;; -;; Do not match NE, LT, or LE, ifcvt.c will handle reversing the results. (define_predicate "fpmask_comparison_operator" (match_code "eq,gt,ge")) +;; Return 1 if OP is a comparison operator suitable for vector/scalar +;; comparisons that generate a 0/-1 mask (i.e. the inverse of +;; fpmask_comparison_operator). +(define_predicate "invert_fpmask_comparison_operator" + (match_code "ne,unlt,unle")) + ;; Return 1 if OP is a comparison operation suitable for integer vector/scalar ;; comparisons that generate a -1/0 mask. (define_predicate "vecint_comparison_operator" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index d0a59f8006fe..4619142d197b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -114,30 +114,8 @@ extern const char *rs6000_sibcall_template (rtx *, unsigned int); extern const char *rs6000_indirect_call_template (rtx *, unsigned int); extern const char *rs6000_indirect_sibcall_template (rtx *, unsigned int); extern const char *rs6000_pltseq_template (rtx *, int); - -/* Whether we can reverse the sense of a comparison. - - If the comparison involves UNEQ, LTGT, UNGT, UNGE, UNLT, and UNLE - comparisons we cannot generate instructions that could generate a trap with - a signaling NaN. These comprisons are created using the floating point - relational tests (like isgreater, isless, etc.), and these comparisons must - not trap on any value like a signaling NaN. The fpmask instructions - (XSCMPEQDP, XSCMPGTQP, etc.) that do the comparison and produce 1's or 0's - to allow the XXSEL instruction to do a conditional move. - - However, if we are not generating fpmask instructions, we have to allow - doing the reversals. We need this reversal to handle condition jumps that - are too far away to jump to directly and we have to reverse the jump, so we - can generate a jump around an unconditional jump. */ - -enum class rev_cond_allowed { - reverse_ok, - no_reverse -}; - extern enum rtx_code rs6000_reverse_condition (machine_mode, - enum rtx_code, - enum rev_cond_allowed); + enum rtx_code); extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); extern rtx rs6000_emit_fp_cror (rtx_code, machine_mode, rtx); extern void rs6000_emit_sCOND (machine_mode, rtx[]); diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index ebc1af993b6b..f4f0ad80e35e 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -15282,36 +15282,17 @@ rs6000_print_patchable_function_entry (FILE *file, } enum rtx_code -rs6000_reverse_condition (machine_mode mode, - enum rtx_code code, - enum rev_cond_allowed do_reverse) +rs6000_reverse_condition (machine_mode mode, enum rtx_code code) { /* Reversal of FP compares takes care -- an ordered compare - becomes an unordered compare and vice versa. - - Do not allow reversing comparisons if this is an IEEE comparison that must - not trap. We do allow the comparsion to be reversed for explicit jumps - when rev_cond_allowed::reverse_ok is passed. */ - if (mode == CCFPmode) -{ - /* If NaNs are allowed, don't allow the reversal of floating point -comparisons when the comparison is used in the context of a floating -point conditional move when no_ordered is passed. We do allow the -comparsion to be reversed for explicit jumps when ordered_ok is -passed. */ - if (!flag_finite_math_only) - return (do_reverse == rev_cond_allowed::no_reverse - ? UNKNOWN - : reverse_condition_maybe_unordered (code)); - - /* E
[gcc r16-2618] aarch64: Add support for unpacked SVE FP conditional binary arithmetic
https://gcc.gnu.org/g:241380c6d632eb6d6595c0976663a29a9be47507 commit r16-2618-g241380c6d632eb6d6595c0976663a29a9be47507 Author: Spencer Abson Date: Tue Jul 29 16:37:26 2025 + aarch64: Add support for unpacked SVE FP conditional binary arithmetic This patch extends the expander for conditional smax, smin, add, sub, mul, min, max, and div to support partial SVE FP modes. If exceptions from undefined vector elements must be suppressed, this expansion converts the container-level predicate to an element-level one, and ensures that these elements are inactive for the operation. In practice, this is a predicate AND with the existing mask and a container-size PTRUE. gcc/ChangeLog: * config/aarch64/aarch64-protos.h (aarch64_sve_emit_masked_fp_pred): Declare. * config/aarch64/aarch64-sve.md (and3): Change this to... (@and3): ...this, so that we can use gen_and3. (@cond_): Extend from SVE_FULL_F_B16B16 to SVE_F_B16B16, use aarch64_predicate_operand. (*cond__2_strict): Likewise. (*cond__3_strict): Likewise. (*cond__any_strict): Likwise. (*cond__2_const_strict): Extend from SVE_FULL_F to SVE_F, use aarch64_predicate_operand. (*cond__any_const_strict): Likewise. (*cond_sub_3_const_strict): Likwise. (*cond_sub_const_strict): Likewise. (*vcond_mask_): Use aarch64_predicate_operand, and update the comment here. * config/aarch64/aarch64.cc (aarch64_sve_emit_masked_fp_pred): New function. Helper to mask the predicate in conditional expanders. gcc/testsuite/ChangeLog: * g++.target/aarch64/sve/unpacked_cond_binary_bf16_2.C: New test. * gcc.target/aarch64/sve/unpacked_cond_builtin_fmax_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_builtin_fmin_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fadd_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fdiv_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fmaxnm_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fminnm_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fmul_2.c: Likewise. * gcc.target/aarch64/sve/unpacked_cond_fsubr_2.c: Likewise. Diff: --- gcc/config/aarch64/aarch64-protos.h| 1 + gcc/config/aarch64/aarch64-sve.md | 152 +++-- gcc/config/aarch64/aarch64.cc | 27 .../aarch64/sve/unpacked_cond_binary_bf16_2.C | 18 +++ .../aarch64/sve/unpacked_cond_builtin_fmax_2.c | 24 .../aarch64/sve/unpacked_cond_builtin_fmin_2.c | 24 .../gcc.target/aarch64/sve/unpacked_cond_fadd_2.c | 28 .../gcc.target/aarch64/sve/unpacked_cond_fdiv_2.c | 22 +++ .../aarch64/sve/unpacked_cond_fmaxnm_2.c | 24 .../aarch64/sve/unpacked_cond_fminnm_2.c | 24 .../gcc.target/aarch64/sve/unpacked_cond_fmul_2.c | 22 +++ .../gcc.target/aarch64/sve/unpacked_cond_fsubr_2.c | 26 12 files changed, 319 insertions(+), 73 deletions(-) diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index e946e8da11da..38c307cdc3a6 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -1031,6 +1031,7 @@ rtx aarch64_pfalse_reg (machine_mode); bool aarch64_sve_same_pred_for_ptest_p (rtx *, rtx *); rtx aarch64_sve_packed_pred (machine_mode); rtx aarch64_sve_fp_pred (machine_mode, rtx *); +rtx aarch64_sve_emit_masked_fp_pred (machine_mode, rtx); void aarch64_emit_load_store_through_mode (rtx, rtx, machine_mode); bool aarch64_expand_maskloadstore (rtx *, machine_mode); void aarch64_emit_sve_pred_move (rtx, rtx, rtx); diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index b252eef411c2..fe407f7e77ff 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -5605,18 +5605,21 @@ ;; Predicated floating-point operations with merging. (define_expand "@cond_" - [(set (match_operand:SVE_FULL_F_B16B16 0 "register_operand") - (unspec:SVE_FULL_F_B16B16 + [(set (match_operand:SVE_F_B16B16 0 "register_operand") + (unspec:SVE_F_B16B16 [(match_operand: 1 "register_operand") - (unspec:SVE_FULL_F_B16B16 + (unspec:SVE_F_B16B16 [(match_dup 1) (const_int SVE_STRICT_GP) - (match_operand:SVE_FULL_F_B16B16 2 "") - (match_operand:SVE_FULL_F_B16B16 3 "")] + (match_operand:SVE_F_B16B16 2 "") + (match_operand:SVE_F_B16B16 3 "")] SVE_COND_FP_BINARY) - (match_operand:SVE_FULL_F_B16B16 4 "aarch64_simd_reg_or_zero")] + (match_operand:SVE_F_B16B16 4 "aarch64_simd_reg_or_zero")]
[gcc r15-10110] cobol: Repair some exception processing logic.
https://gcc.gnu.org/g:5915b1a3538dd1dc92863b2e1e6d9817c04a9291 commit r15-10110-g5915b1a3538dd1dc92863b2e1e6d9817c04a9291 Author: Robert Dubner Date: Thu Apr 24 16:26:58 2025 -0400 cobol: Repair some exception processing logic. This patch changes the exception processing logic for the calculation of reference modifications and table subscripts to be more in accordance with ISO specifications. It also adjusts the processing of RETURN-CODE when calling routines that have no CALL ... RETURNING phrase. gcc/cobol * genapi.cc: (initialize_variable_internal): Change TRACE1 formatting. (create_and_call): Repair RETURN-CODE processing. (mh_source_is_group): Repair run-time IF type comparison. (psa_FldLiteralA): Change TRACE1 formatting. (parser_symbol_add): Eliminate unnecessary code. * genutil.cc: Eliminate SET_EXCEPTION_CODE macro. (get_data_offset_dest): Repair set_exception_code logic. (get_data_offset_source): Likewise. (get_binary_value): Likewise. (refer_refmod_length): Likewise. (refer_fill_depends): Likewise. (refer_offset_dest): Likewise. (refer_size_dest): Likewise. (refer_offset_source): Likewise. gcc/testsuite * cobol.dg/group1/declarative_1.cob: Adjust for repaired exception logic. (cherry picked from commit 05b6fc1eb55f30d28c3a23d8a6c2ef0a10856f46) Diff: --- gcc/cobol/genapi.cc | 99 +-- gcc/cobol/genutil.cc| 779 gcc/testsuite/cobol.dg/group1/declarative_1.cob | 6 +- 3 files changed, 295 insertions(+), 589 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index c8911f964d59..e44364a1b482 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -1229,7 +1229,40 @@ initialize_variable_internal( cbl_refer_t refer, } else { - TRACE1_FIELD_VALUE("", parsed_var, "") + // Convert strings of spaces to "" + tree spaces = gg_define_int(0); + if( parsed_var->type == FldGroup + || parsed_var->type == FldAlphanumeric + || parsed_var->type == FldAlphaEdited + || parsed_var->type == FldLiteralA ) +{ +gg_assign(spaces, integer_one_node); +tree counter = gg_define_int(parsed_var->data.capacity); +WHILE(counter, gt_op, integer_zero_node) + { + gg_decrement(counter); + IF( gg_indirect(member(parsed_var->var_decl_node, "data"), counter), + ne_op, + build_int_cst_type(UCHAR, ' ') ) + { + gg_assign(spaces, integer_zero_node); + } + ELSE +{ +} + ENDIF + } + WEND +} + IF(spaces, eq_op, integer_one_node) +{ +TRACE1_TEXT(" ") +} + ELSE +{ +TRACE1_FIELD_VALUE("", parsed_var, "") +} + ENDIF } TRACE1_END } @@ -12341,7 +12374,7 @@ create_and_call(size_t narg, // Because the CALL had a RETURNING clause, RETURN-CODE doesn't return a // value. So, we make sure it is zero -gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); +gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); if( returned_value_type == CHAR_P ) { @@ -12352,7 +12385,7 @@ create_and_call(size_t narg, gg_add( member(returned.field->var_decl_node, "data"), refer_offset_dest(returned))); gg_assign(returned_length, -refer_size_dest(returned)); +gg_cast(TREE_TYPE(returned_length), refer_size_dest(returned))); // The returned value is a string of nbytes, which by specification // has to be at least as long as the returned_length of the target: @@ -12442,28 +12475,9 @@ create_and_call(size_t narg, } else { -// Because no explicit returning value is expected, we switch to -// the IBM default behavior, where the returned INT value is assigned -// to our RETURN-CODE: -returned_value = gg_define_variable(SHORT); - -// Before doing the call, we save the COBOL program_state: -push_program_state(); -gg_assign(returned_value, gg_cast(SHORT, call_expr)); -// And after the call, we restore it: -pop_program_state(); - -// We know that the returned value is a 2-byte little-endian INT: -gg_assign( var_decl_return_code, -returned_value); -TRACE1 - { - TRACE1_HEADER - gg_printf("returned value: %d", -gg_cast(INT, var_decl_return_code), -NULL_TREE); - TRACE1_END - } +// Because no explicit returning value is expected, we just call it. We +// expect COBOL routines to set RETURN-CODE when they think it
[gcc r15-10109] libgcobol: Check for struct tm tm_zone
https://gcc.gnu.org/g:636c0d50988472fa5a5bee2b22ed413ea39d842a commit r15-10109-g636c0d50988472fa5a5bee2b22ed413ea39d842a Author: Rainer Orth Date: Mon Apr 21 15:59:14 2025 +0200 libgcobol: Check for struct tm tm_zone intrinsic.cc doesn't compile on Solaris: /vol/gcc/src/hg/master/cobol/libgcobol/intrinsic.cc: In function ‘void __gg__formatted_current_date(cblc_field_t*, cblc_field_t*, std::size_t, std::size_t)’: /vol/gcc/src/hg/master/cobol/libgcobol/intrinsic.cc:1480:6: error: ‘struct std::tm’ has no member named ‘tm_zone’; did you mean ‘tm_mon’? 1480 | tm.tm_zone = "GMT"; | ^~~ | tm_mon struct tm.tm_zone is new in POSIX.1-2024, thus cannot be assumed to be present universally. This patch checks for its presence and guards the use accordingly. Bootstrapped without regressions on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-solaris2.11. 2025-04-08 Rainer Orth libgcobol: * configure.ac: Check for struct tm.tm_zone. * configure, config.h.in: Regenerate. * intrinsic.cc (__gg__formatted_current_date): Guard tm.tm_zone use with HAVE_STRUCT_TM_TM_ZONE. (cherry picked from commit a619a128c992b2121a862b8470960ae751d25db6) Diff: --- libgcobol/config.h.in | 3 ++ libgcobol/configure| 74 -- libgcobol/configure.ac | 3 ++ libgcobol/intrinsic.cc | 2 ++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in index 6a5327996167..fdf5e3e7dc1c 100644 --- a/libgcobol/config.h.in +++ b/libgcobol/config.h.in @@ -72,6 +72,9 @@ /* Define to 1 if you have the `strtof128' function. */ #undef HAVE_STRTOF128 +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#undef HAVE_STRUCT_TM_TM_ZONE + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/libgcobol/configure b/libgcobol/configure index e83119d48f62..6821591852af 100755 --- a/libgcobol/configure +++ b/libgcobol/configure @@ -2449,6 +2449,63 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func + +# ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES +# -- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_cxx_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_member cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -11693,7 +11750,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11696 "configure" +#line 11753 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11799,7 +11856,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11802 "configure" +#line 11859 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17434,6 +17491,19 @@ $as_echo "#define USE_IEC_60559 1" >>confdefs.h +# struct tm tm_zone is a POSIX.1-2024 addition. +ac_fn_cxx_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include +" +if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_TM_TM_ZONE 1 +_ACEOF + + +fi + + if test "${multilib}" = "yes"; then multilib_arg="--enable-multilib" else diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac index a1e95139299e..4bb690559ad9 100644 --- a/libgcobol/configure.ac +++ b/libgcobol/configure.ac @@ -231,6 +231,9 @@ elif test "${ENABLE_LIBQUADMATH_SUPPORT}" = "
[gcc r15-10112] cobol, v2: Fix up cobol cross-compilation from 32-bit arches [PR119364]
https://gcc.gnu.org/g:adffa5342315cc642e3c0a35304f7d27f7c4f987 commit r15-10112-gadffa5342315cc642e3c0a35304f7d27f7c4f987 Author: Jakub Jelinek Date: Fri May 2 19:09:34 2025 +0200 cobol, v2: Fix up cobol cross-compilation from 32-bit arches [PR119364] Right now it is not possible to even build cross-compilers from 32-bit architectures to e.g. x86_64-linux or aarch64-linux, even from little-endian ones. The following patch attempts to fix that. There were various issues seen e.g. trying to build i686-linux -> x86_64-linux cross-compiler (so still 64-bit libgcobol, but the compiler is 32-bit). 1) warning about >> 32 shift of size_t, on 32-bit arches size_t is 32-bit and so the shift is UB; fixed by doing (new_size>>16)>>16 so that it ors in >> 32 when new_size is 64-bit and 0 when it is 32-bit 2) enum cbl_field_attr_t was using size_t as underlying type, but has various bitmasks which require full 64-bit type; changed this to uint64_t underlying type and using unsigned long long in the structure; various routines which operate with those attributes had to be changed also to work with uint64_t instead of size_t 3) on i686-linux, config.h can #define _FILE_OFFSET_BITS 64 or similar macros; as documented, those macros have to be defined before including first C library header, but some sources included cobol-system.h which includes config.h only after various other headers; this resulted in link failures, as ino_t was sometimes unsigned long and sometines unsigned long long, depending on whether config.h was included first or not, and e.g. cobol_filename uses ino_t argument 4) lots of places used %ld or %lx *printf format specifers with size_t arguments; that works only if size_t is unsigned long, but not when it is unsigned int or unsigned long long or some other type; now while ISO C99 has %zd or %zx to print size_t and C++14 includes C99 (or C11?), while for the C++ headers the C++ compilers typically have full control over it and so support everything in C++14 (e.g. libstdc++ in GCC 5.1+ or libc++ if not too old), for C library we are dependent on the system C library (note, on the host for the compiler side). And not all hosts support C99 in their C libraries; so instead of just changing it to %zd or %zx, I'm changing it to what we use elsewhere in GCC, HOST_SIZE_T_PRINT_{DEC,UNSIGNED,HEX_PURE} or GCC_PRISZ macros in the *printf family format string and casts of the size_t arguments to fmt_size_t. Note, if not using the C library *printf family (e.g. in dbgmsg, sprintf, snprintf, fprintf, etc.) but the GCC diagnostic code (e.g. err_msg, error, warning, yywarn, ...), then %zd/%zu is supported and on the other side HOST_SIZE_T_PRINT_{DEC,UNSIGNED,HEX_PURE} etc. macros shouldn't be used (for two reasons, because it is unnecessary when %zd/%zu is guaranteed to be supported there because GCC has control over that and more importantly because it breaks translations, both extraction of the to be translated strings and we don't want to have different messages, once with %lld, once with %ld, once with just %d or %I64d depending on host, translators couldn't translate it all). 5) see above, there were already tons of %zd/%zu or %3zu etc. format specifers in *printf format strings, this patch changes those too 6) I've noticed dbgmsg wasn't declared with printf attribute, which resulted in bugs where format specifiers didn't match actually passed types of arguments 2025-05-02 Jakub Jelinek PR cobol/119364 libgcobol/ * valconv.cc (__gg__realloc_if_necessary): Use (new_size>>16)>>16; instead of new_size>>32; to avoid warnings on 32-bit hosts. * common-defs.h (enum cbl_field_attr_t): Use uint64_t as underlying type rather than size_t. * gcobolio.h (cblc_field_t): Change attr member type from size_t to unsigned long long. gcc/cobol/ * util.cc (is_numeric_edited): Use HOST_SIZE_T_PRINT_UNSIGNED instead of "%zu" and cast corresponding argument to fmt_size_t. (normalize_picture): Use GCC_PRISZ instead of "z" and pass address of fmt_size_t var to sscanf and copy afterwards. (cbl_refer_t::str): Use HOST_SIZE_T_PRINT_UNSIGNED instead of "%zu" or GCC_PRISZ instead of "z" and cast corresponding argument to fmt_size_t. (struct move_corresponding_field): Likewise. (valid_move): Likewise. (ambiguous_reference): Likewise. (parent_names): Likewise. (find_corresponding::find_corresponding): Likewise. (corresponding_fields): Likewise. (uniqu
[gcc r15-10119] libgcobol: Heed --enable-libgcobol
https://gcc.gnu.org/g:7fdeb675872349d016a344b5f801e90344267dac commit r15-10119-g7fdeb675872349d016a344b5f801e90344267dac Author: Rainer Orth Date: Thu May 8 09:42:42 2025 +0200 libgcobol: Heed --enable-libgcobol If some target isn't listed as supported in configure.tgt, --enable-libgcobol cannot override that. However, that's what should happen just like an explicit --enable-languages=cobol forces the frontend to be built. This patch, shamelessly adapted from libphobos, does just that. Tested on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu. 2025-04-08 Rainer Orth libgcobol: * configure.ac: Handle --enable-libgcobol. Let it override LIBGCOBOL_SUPPORTED. * configure: Regenerate. (cherry picked from commit fdd2374b87bd9d7f4c201c81875d77acaebb38cd) Diff: --- libgcobol/configure| 26 +++--- libgcobol/configure.ac | 15 ++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/libgcobol/configure b/libgcobol/configure index 06e7544822cb..5f319eedf538 100755 --- a/libgcobol/configure +++ b/libgcobol/configure @@ -788,6 +788,7 @@ enable_option_checking enable_multilib enable_maintainer_mode enable_silent_rules +enable_libgcobol enable_version_specific_runtime_libs enable_dependency_tracking enable_shared @@ -1438,6 +1439,7 @@ Optional Features: sometimes confusing) to the casual installer --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") + --enable-libgcobol Enable libgcobol --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory @@ -3723,6 +3725,16 @@ END fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-libgcobol" >&5 +$as_echo_n "checking for --enable-libgcobol... " >&6; } +# Check whether --enable-libgcobol was given. +if test "${enable_libgcobol+set}" = set; then : + enableval=$enable_libgcobol; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libgcobol" >&5 +$as_echo "$enable_libgcobol" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-version-specific-runtime-libs" >&5 $as_echo_n "checking for --enable-version-specific-runtime-libs... " >&6; } # Check whether --enable-version-specific-runtime-libs was given. @@ -11798,7 +11810,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11801 "configure" +#line 11813 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11904,7 +11916,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11907 "configure" +#line 11919 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -16795,6 +16807,14 @@ _ACEOF unset LIBGCOBOL_SUPPORTED . ${srcdir}/configure.tgt +# Decide if it's usable. +case $LIBGCOBOL_SUPPORTED:$enable_libgcobol in +*:no) use_libgcobol=no ;; +*:yes) use_libgcobol=yes ;; +yes:*) use_libgcobol=yes ;; +*:*) use_libgcobol=no ;; +esac + # - # __int128 support # - @@ -16887,7 +16907,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcobol_cv_have_int128" >&5 $as_echo "$libgcobol_cv_have_int128" >&6; } - if test "x$LIBGCOBOL_SUPPORTED" = xyes && test "x$libgcobol_cv_have_int128" = xyes; then + if test "x$use_libgcobol" = xyes && test "x$libgcobol_cv_have_int128" = xyes; then BUILD_LIBGCOBOL_TRUE= BUILD_LIBGCOBOL_FALSE='#' else diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac index e2547637209c..13326960515a 100644 --- a/libgcobol/configure.ac +++ b/libgcobol/configure.ac @@ -40,6 +40,11 @@ AM_MAINTAINER_MODE AM_INIT_AUTOMAKE([1.15.1 no-define foreign no-dist -Wall -Wno-portability]) +AC_MSG_CHECKING([for --enable-libgcobol]) +AC_ARG_ENABLE(libgcobol, + [AS_HELP_STRING([--enable-libgcobol], [Enable libgcobol])]) +AC_MSG_RESULT($enable_libgcobol) + AC_MSG_CHECKING([for --enable-version-specific-runtime-libs]) AC_ARG_ENABLE(version-specific-runtime-libs, AS_HELP_STRING([--enable-version-specific-runtime-libs], @@ -138,6 +143,14 @@ AC_CHECK_SIZEOF([void *]) unset LIBGCOBOL_SUPPORTED . ${srcdir}/configure.tgt +# Decide if it's usable. +case $LIBGCOBOL_SUPPORTED:$enable_libgcobol in +*:no) use_libgcobol=no ;; +*:yes) use_libgcobol=yes ;; +yes:*) use_libgcobol=yes ;; +*:*) use_libgcobol=no ;; +esac + # - # __int128 support # - @@ -164,7 +177,7 @@ AC_CACHE_CHECK([whether __int128 is supported], [libgcobol_cv_have_int128], libgcobol_cv_have_int128=no ])]) -AM_CONDITIONAL(BUILD_LIBGCOBOL, [test "x$LIBGCOBOL_SUPPORTED" = xyes && test "x$libgcobol_cv_have_i
[gcc r15-10115] libgcobol: Fix bootstrap for targets without program_invocation_short_name
https://gcc.gnu.org/g:b61e85f3eb34e3b6403eb02e4004b30e8bd170ae commit r15-10115-gb61e85f3eb34e3b6403eb02e4004b30e8bd170ae Author: Iain Sandoe Date: Tue May 6 09:42:40 2025 +0100 libgcobol: Fix bootstrap for targets without program_invocation_short_name program_invocation_short_name is not widely available, however getprogname() appears to be a suitable replacement. Amend the library configuration to look for both. Use program_invocation_short_name in preference to getprogname() when it is available. If neither is found fall back to a constant string. libgcobol/ChangeLog: * config.h.in: Regenerate. * configure: Regenerate. * configure.ac: Check for program_invocation_short_name and and getprogname(). * libgcobol.cc (default_exception_handler): When the platform has program_invocation_short_name, use it otherwise fall back to using getprogname() or a constant string (if neither interface is available). Signed-off-by: Iain Sandoe (cherry picked from commit 67e79da5a3c0deb93cd6df1557affb6994440357) Diff: --- libgcobol/config.h.in | 10 +++ libgcobol/configure| 81 -- libgcobol/configure.ac | 14 - libgcobol/libgcobol.cc | 15 -- 4 files changed, 114 insertions(+), 6 deletions(-) diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in index fdf5e3e7dc1c..ee3dd6b21514 100644 --- a/libgcobol/config.h.in +++ b/libgcobol/config.h.in @@ -6,9 +6,16 @@ /* Define to 1 if you have the header file. */ #undef HAVE_COMPLEX_H +/* Define to 1 if you have the declaration of `program_invocation_short_name', + and to 0 if you don't. */ +#undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + /* Define to 1 if you have the header file. */ #undef HAVE_FENV_H @@ -21,6 +28,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_FPTRAP_H +/* Define to 1 if you have the `getprogname' function. */ +#undef HAVE_GETPROGNAME + /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV diff --git a/libgcobol/configure b/libgcobol/configure index 6821591852af..06e7544822cb 100755 --- a/libgcobol/configure +++ b/libgcobol/configure @@ -2380,6 +2380,52 @@ $as_echo "$ac_res" >&6; } } # ac_fn_cxx_check_header_compile +# ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES +# --- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_cxx_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_decl + # ac_fn_cxx_check_func LINENO FUNC VAR # # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -2796,6 +2842,8 @@ as_fn_append ac_header_list " fenv.h" as_fn_append ac_header_list " fptrap.h" as_fn_append ac_header_list " complex.h" as_fn_append ac_header_list " stdlib.h" +as_fn_append ac_header_list " errno.h" +as_fn_append ac_func_list " getprogname" as_fn_append ac_func_list " random_r" as_fn_append ac_func_list " srandom_r" as_fn_append ac_func_list " initstate_r" @@ -11750,7 +11798,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11753 "configure" +#line 11801 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11856,7 +11904,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11859 "configure" +#line 11907 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17016,7 +17064,29 @@ done -# These are GLIBC + + +# Look for a way to represent the program name +# First, check the GLIBC case +ac_fn_cxx_check_decl "$LINENO"
[gcc r15-10118] cobol: Allow for undefined NAME_MAX [PR119217]
https://gcc.gnu.org/g:1066f31c3d2f28a85f8c89446166120a45eba8dc commit r15-10118-g1066f31c3d2f28a85f8c89446166120a45eba8dc Author: Rainer Orth Date: Thu May 8 09:39:26 2025 +0200 cobol: Allow for undefined NAME_MAX [PR119217] All users of symbols.h fail to compile on Solaris: /vol/gcc/src/hg/master/local/gcc/cobol/symbols.h: At global scope: /vol/gcc/src/hg/master/local/gcc/cobol/symbols.h:1365:13: error: ‘NAME_MAX’ was not declared in this scope 1365 | char name[NAME_MAX]; | ^~~~ NAME_MAX being undefined is allowed by POSIX.1, actually: it's listed for under "Pathname Variable Values": A definition of one of the symbolic constants in the following list shall be omitted from the header on specific implementations where the corresponding value is equal to or greater than the stated minimum, but where the value can vary depending on the file to which it is applied. The actual value supported for a specific pathname shall be provided by the pathconf() function. As a hack, this patch provides a fallback definition to allow the build to finish. In fact it turned out that cbl_funtion_t.name isn't filename related and never set at all, so this patch serves as a mere stopgap fix to unbreak the build until a real solution can be figured out. Bootstrapped without regressions on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu. 2025-04-08 Rainer Orth gcc/cobol: PR cobol/119217 * symbols.h (NAME_MAX): Define fallback. (cherry picked from commit 1df8fffba30bf4022dda762bf61acf16ac704c67) Diff: --- gcc/cobol/symbols.h | 5 + 1 file changed, 5 insertions(+) diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index adfa8d979b2f..50c5d48ff9f5 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -46,6 +46,11 @@ #include #include +// Provide fallback definition. +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + #define PICTURE_MAX 64 extern const char *numed_message;
[gcc r15-10113] cobol: Fix up exception handling [PR119364]
https://gcc.gnu.org/g:167f3663ccc7d0a5cf2a83e0c29461ca79841e99 commit r15-10113-g167f3663ccc7d0a5cf2a83e0c29461ca79841e99 Author: Jakub Jelinek Date: Fri May 2 19:10:59 2025 +0200 cobol: Fix up exception handling [PR119364] The following patch on top of the https://gcc.gnu.org/pipermail/gcc-patches/2025-May/682500.html fixes most of the remaining make check-cobol FAILs in the i686-linux -> x86_64-linux cross-compiler. Using the testing environment detailed in https://gcc.gnu.org/pipermail/gcc-patches/2025-April/680403.html with this patch I get just cobol.dg/group1/declarative_1.cob FAILs in i686-linux -> x86_64-linux cross and no FAILs in x86_64-linux native one. The patch isn't needed just for cross-compilation with different hosts, but also on x86_64-linux/aarch64-linux native, because without it the FE is hashing padding bits which contain random garbage and making code generation decisions based on that. That is very much against the reproduceability requirements. 2025-05-02 Jakub Jelinek PR cobol/119364 * structs.h (cbl_enabled_exception_type_node): New variable declaration. * structs.cc (cbl_enabled_exception_type_node): New variable. (create_cbl_enabled_exception_t): New function. (create_our_type_nodes): Initialize cbl_enabled_exception_type_node using it. * genapi.cc (stash_exceptions): Don't compare padding bits to determine if the exceptions are the same as last time. Use cbl_enabled_exception_type_node for target size and field offsets and native_encode_expr to write each field into byte sequence. (cherry picked from commit c77d04506e6abdc45969d0ff146204be7485244a) Diff: --- gcc/cobol/genapi.cc | 66 +--- gcc/cobol/structs.cc | 25 gcc/cobol/structs.h | 1 + 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index eba10b0bdfe3..dca52ce080d5 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -13301,24 +13301,29 @@ static void stash_exceptions( const cbl_enabled_exceptions_array_t *enabled ) { // We need to create a static array of bytes - size_t narg = enabled->nbytes(); - unsigned char *p = (unsigned char *)(enabled->ecs); + size_t nec = enabled->nec; + size_t sz = int_size_in_bytes(cbl_enabled_exception_type_node); + size_t narg = nec * sz; + cbl_enabled_exception_t *p = enabled->ecs; - static size_t prior_narg = 0; - static size_t max_narg = 128; - static unsigned char *prior_p = (unsigned char *)xmalloc(max_narg); + static size_t prior_nec = 0; + static size_t max_nec = 0; + static cbl_enabled_exception_t *prior_p; bool we_got_new_data = false; - if( prior_narg != narg ) + if( prior_nec != nec ) { we_got_new_data = true; } else { -// The narg counts are the same. -for(size_t i=0; i max_narg ) + if( nec > max_nec ) { -max_narg = narg; -prior_p = (unsigned char *)xrealloc(prior_p, max_narg); +max_nec = nec; +prior_p = (cbl_enabled_exception_t *) + xrealloc(prior_p, max_nec * sizeof(cbl_enabled_exception_t)); } - memcpy(prior_p, p, narg); + memcpy((unsigned char *)prior_p, (unsigned char *)p, + nec * sizeof(cbl_enabled_exception_t)); static int count = 1; @@ -13355,12 +13362,33 @@ stash_exceptions( const cbl_enabled_exceptions_array_t *enabled ) TREE_TYPE(constr) = array_of_chars_type; TREE_STATIC(constr)= 1; TREE_CONSTANT(constr) = 1; - -for(size_t i=0; i
[gcc r15-10126] cobol: Eliminate exception "blob"; streamline some code generation.
https://gcc.gnu.org/g:08e58db367d94e6abc8b3d00cebc2db88c0aa828 commit r15-10126-g08e58db367d94e6abc8b3d00cebc2db88c0aa828 Author: Robert Dubner Date: Fri May 16 11:12:04 2025 -0400 cobol: Eliminate exception "blob"; streamline some code generation. This eliminates some of the last vestiges of creating a structure at host-time that is intended for use at target-time. It removes some unnecessary processing when exceptions are not enabled. It improves the creation of code that handles table subscripts and refmod parameters. gcc/cobol/ChangeLog: * cobol1.cc (cobol_langhook_handle_option): Eliminate OPT_M. * except.cc (cbl_enabled_exception_t::dump): Formatting. (symbol_declaratives_add): Remove. (declarative_runtime_match): Change to no-blob processing. * exceptg.h (declarative_runtime_match): Change declaration. (symbol_declaratives_add): Remove declaration. * gcobc: Dialect handling. * genapi.cc (parser_compile_ecs): Formatting; add SHOW_IF_PARSE. (parser_compile_dcls): Likewise. (parser_statement_begin): Avoid unnecessary store_location_stuff() call. (gg_get_depending_on_value): Streamline get_depending_on_value_from_odo(). (depending_on_value): Likewise. (parser_display_field): Formatting. (parser_display): Handle case ENV_NAME_e. (parser_file_open): Avoid unnecessary store_location_stuff. (parser_file_close): Likewise. (parser_file_read): Likewise. (parser_file_write): Likewise. (parser_file_delete): Likewise. (parser_file_rewrite): Likewise. (parser_file_start): Likewise. (parser_intrinsic_subst): Streamline get_depending_on_value_from_odo(). (parser_intrinsic_call_1): Likewise. (parser_lsearch_start): Likewise. (parser_bsearch_start): Likewise. (parser_sort): Likewise. (store_location_stuff): Avoid unnecessary assignments. (parser_pop_exception): Formatting. * genmath.cc (parser_add): Avoid var_decl_default_compute_error assignment when doing fast_add(). (parser_subtract): Likewise. * genutil.cc (REFER): Macro for analyzing code generation. (get_integer_value): Use data_decl_node for integer value from FldLiteralN. (get_data_offset): Streamline exception code processing. (get_and_check_refstart_and_reflen): Likewise. (get_depending_on_value_from_odo): Likewise. (get_depending_on_value): Likewise. (refer_is_clean): Formatting. (refer_refmod_length): Streamline exception code processing. (refer_fill_depends): Likewise. (refer_offset): Likewise. (refer_size_dest): Likewise. (refer_size_source): Likewise. * genutil.h (get_depending_on_value_from_odo): Likewise. * lang-specs.h: Options definition. * lang.opt: -M as in c.opt. * lexio.h: Formatting. * parse.y: Expand -dialect suggestions; SECTION SEGMENT messages. * parse_ante.h (declarative_runtime_match): Dialect handling. (labels_dump): Likewise. (class current_tokens_t): Likewise. (class prog_descr_t): Make program_index size_t to prevent padding bytes. * scan.l: POP_FILE directive. * scan_ante.h (class enter_leave_t): Better handle line number when processing COPY statements. * symbols.cc (symbol_elem_cmp): Eliminate SymFunction. (symbols_dump): Likewise. (symbol_label_section_exists): Likewise. * symbols.h (NAME_MAX): Eliminate. (Was part of SymFunction). (dialect_is): Improve dialect handling. (dialect_gcc): Likewise. (dialect_ibm): Likewise. (dialect_gnu): Likewise. (enum symbol_type_t): Eliminate SymFunction. * util.cc (symbol_type_str): Likewise. (class unique_stack): Option -M handling. (cobol_set_pp_option): Likewise. (parse_file): Likewise. * util.h (cobol_set_pp_option): Likewise. libgcobol/ChangeLog: * common-defs.h (struct cbl_declarative_t): Eliminate blobl. * libgcobol.cc (__gg__set_env_name): Code for ENVIRONMENT-NAME/VALUE. (__gg__set_env_value): Likewise. gcc/testsuite/ChangeLog: * cobol.dg/group1/declarative_1.cob: Handle modified exception handling. (cherry picked from commit 92b6485a75cabaf64f1f74ba7ab73a5204c9d0aa) Diff: --- gcc/cobol/cobol1.cc | 23 +- gcc/cobol/except.cc | 111 ++--- gcc/cobol/exceptg.h
[gcc r15-10123] libgcobol: Allow for lack of LOG_PERROR
https://gcc.gnu.org/g:5ce4d3e211d43d069d60fea8d53dab7115a235db commit r15-10123-g5ce4d3e211d43d069d60fea8d53dab7115a235db Author: Rainer Orth Date: Tue May 13 09:43:48 2025 +0200 libgcobol: Allow for lack of LOG_PERROR The libgcobol build is broken again on Solaris: /vol/gcc/src/hg/master/local/libgcobol/libgcobol.cc: In function ‘void default_exception_handler(ec_type_t)’: /vol/gcc/src/hg/master/local/libgcobol/libgcobol.cc:11196:44: error: ‘LOG_PERROR’ was not declared in this scope; did you mean ‘LOG_ERR’? 11196 | static int priority = LOG_INFO, option = LOG_PERROR, facility = LOG_USER; |^~ |LOG_ERR /vol/gcc/src/hg/master/local/libgcobol/libgcobol.cc:11202:28: error: ‘facility’ was not declared in this scope 11202 | openlog(ident, option, facility); |^~~~ LOG_PERROR is a BSD extension not present on Solaris due to its System V heritage, and Linux syslog(3) documents: LOG_PERROR (Not in POSIX.1-2001 or POSIX.1-2008.) Also log the message to stderr. This patch provides a fallback definition, just the minimum to unbreak the build. Tested on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu. 2025-05-12 Rainer Orth libgcobol: * libgcobol.cc [!LOG_PERROR] (LOG_PERROR): Provide fallback. (cherry picked from commit 90fee97d528e8447648c37f9df1daa3445e598bc) Diff: --- libgcobol/libgcobol.cc | 5 + 1 file changed, 5 insertions(+) diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index 2de87cbfc487..56b1a7bf5876 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -75,6 +75,11 @@ #include "exceptl.h" +/* BSD extension. */ +#if !defined(LOG_PERROR) +#define LOG_PERROR 0 +#endif + #if !defined (HAVE_STRFROMF32) # if __FLT_MANT_DIG__ == 24 && __FLT_MAX_EXP__ == 128 static int
[gcc r15-10129] cobol: Multiple PRs; formatting; exception processing.
https://gcc.gnu.org/g:907e343138c9e4eee09c7e263418a45c67fbd116 commit r15-10129-g907e343138c9e4eee09c7e263418a45c67fbd116 Author: Robert Dubner Date: Tue May 20 13:35:15 2025 -0400 cobol: Multiple PRs; formatting; exception processing. The PRs mentined here have either been previously fixed, or are fixed by this commit. gcc/cobol/ChangeLog: PR cobol/119770 PR cobol/119772 PR cobol/119790 PR cobol/119771 PR cobol/119810 PR cobol/119335 PR cobol/119632 * cdf-copy.cc (GLOB_BRACE): Eliminate . * cdfval.h (_CDF_VAL_H_): Switch to C++ headers. * copybook.h (class copybook_elem_t): Eliminate . (class copybook_t): Likewise. * gcobc: Numerous changes to improve utility. * gcobol.1: Correct names in the list of functions. * genapi.cc (compare_binary_binary): Use has_attr() function. * lexio.cc (cdftext::lex_open): Typo; filename logic. (cdftext::process_file): Filename logic. * parse.y: Numerous parsing changes. * parse_ante.h (new_alphanumeric): C++ includes; changes to temporaries. (new_tempnumeric): Likewise. (new_tempnumeric_float): Likewise. (set_real_from_capacity): Created. * scan.l: Use yy_pop_state(). * scan_ante.h (typed_name): Find figconst from data.initial. * symbols.cc (symbol_valid_udf_args): Eliminate. (symbols_update): figconst processing. (new_temporary_impl): For functions, set .initial to function name. (temporaries_t::acquire): Likewise. (new_alphanumeric): Likewise. (new_temporary): Likewise. * symbols.h (_SYMBOLS_H_): Use C++ includes. (cbl_figconst_tok): Change handling of figconst. (cbl_figconst_field_of): Change handling of figconst. (symbol_valid_udf_args): Eliminate. * symfind.cc (symbol_match2): Change declaration. (symbol_match): Change declaration. libgcobol/ChangeLog: * charmaps.cc: Switch to C++ includes. * common-defs.h: Likewise. * constants.cc: Likewise. * ec.h: Remove #include . * gcobolio.h (GCOBOLIO_H_): Switch to C++ includes. * gfileio.cc: Likewise. * gmath.cc: Likewise. * intrinsic.cc: Comment formatting; C++ includes. * io.cc: C++ includes. * libgcobol.cc: (__gg__stash_exceptions): Eliminate. * valconv.cc: Switch to C++ includes. Co-Authored-By: James K. Lowden (cherry picked from commit fba34a0cc55488ad89becf81cf2c9ac517d244d4) Diff: --- gcc/cobol/cdf-copy.cc | 88 +++ gcc/cobol/cdfval.h | 6 +- gcc/cobol/copybook.h| 13 +-- gcc/cobol/gcobc | 141 ++-- gcc/cobol/gcobol.1 | 54 - gcc/cobol/genapi.cc | 4 +- gcc/cobol/lexio.cc | 7 +- gcc/cobol/parse.y | 283 +++- gcc/cobol/parse_ante.h | 35 -- gcc/cobol/scan.l| 2 +- gcc/cobol/scan_ante.h | 4 + gcc/cobol/symbols.cc| 63 +++ gcc/cobol/symbols.h | 19 ++-- gcc/cobol/symfind.cc| 4 +- libgcobol/charmaps.cc | 14 ++- libgcobol/common-defs.h | 5 +- libgcobol/constants.cc | 19 ++-- libgcobol/ec.h | 1 - libgcobol/gcobolio.h| 3 +- libgcobol/gfileio.cc| 18 +-- libgcobol/gmath.cc | 19 ++-- libgcobol/intrinsic.cc | 22 ++-- libgcobol/io.cc | 11 +- libgcobol/libgcobol.cc | 14 +-- libgcobol/valconv.cc| 7 +- 25 files changed, 456 insertions(+), 400 deletions(-) diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 059596c08f41..99f5866ae86f 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -35,23 +35,12 @@ // We regret any confusion engendered. #include "config.h" -#include #include "cobol-system.h" #include "cbldiag.h" #include "util.h" #include "copybook.h" -// GLOB_BRACE and GLOB_TILDE are BSD extensions. Provide fallback definitions -// if necessary. -#ifndef GLOB_BRACE -#define GLOB_BRACE 0 -#endif - -#ifndef GLOB_TILDE -#define GLOB_TILDE 0 -#endif - #define COUNT_OF(X) (sizeof(X) / sizeof(X[0])) /* @@ -86,7 +75,6 @@ * space. This function only applies them. */ -extern int yydebug; const char * cobol_filename(); bool is_fixed_format(); bool is_reference_format(); @@ -190,12 +178,6 @@ esc( size_t len, const char input[] ) { return buffer; // caller must strdup static buffer } -static int -glob_error(const char *epath, int eerrno) { - dbgmsg("%s: COPY file search: '%s': %s", __func__, epath, xstrerror(eerrno)); - return 0; -} - void copybook_directory_add( const char gcob_copybook[] ) { if( !gcob_copybook ) return; @@ -242
[gcc r15-10128] cobol: sqrt(0) is not an ec-argument error. [PR119885]
https://gcc.gnu.org/g:e7f1334ad02d4913346238aba58b0025ab7f455c commit r15-10128-ge7f1334ad02d4913346238aba58b0025ab7f455c Author: Robert Dubner Date: Tue May 20 11:49:43 2025 -0400 cobol: sqrt(0) is not an ec-argument error. [PR119885] libgcobol PR cobol/119885 * intrinsic.cc: (__gg__sqrt): Change test from <= zero to < zero. gcc/testsuite * cobol.dg/group2/FUNCTION_SQRT__2_.cob: Testcase. * cobol.dg/group2/FUNCTION_SQRT__2_.out: Known-good for the testcase. (cherry picked from commit d44beb132850a8ced1b0614e2724f18465b4a737) Diff: --- gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.cob | 13 + gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.out | 5 + libgcobol/intrinsic.cc | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.cob b/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.cob new file mode 100644 index ..c1f4ba8684a6 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.cob @@ -0,0 +1,13 @@ + *> { dg-do run } + *> { dg-output-file "group2/FUNCTION_SQRT__2_.out" } +program-id. sqbug. +procedure division. +if function sqrt (0) = 0*>if4034.2 +display 'ok' else display 'bad'. +display "sqrt(0) " function trim (function exception-status) +set last exception to off +if function sqrt (-0.1) = 0*>if4034.2 +display 'ok' else display 'bad'. +display "sqrt(-0.1) " function trim (function exception-status) +goback. + diff --git a/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.out b/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.out new file mode 100644 index ..0783ac5abb17 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/FUNCTION_SQRT__2_.out @@ -0,0 +1,5 @@ +ok +sqrt(0) "" +bad +sqrt(-0.1) "EC-ARGUMENT-FUNCTION" + diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 37ae13e262fe..d6dfcb981a5e 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -3565,7 +3565,7 @@ __gg__sqrt( cblc_field_t *dest, source_offset, source_size); - if( value <= GCOB_FP128_LITERAL(0.0) ) + if( value < GCOB_FP128_LITERAL(0.0) ) { exception_raise(ec_argument_function_e); }
[gcc r15-10116] cobol: Don't require GLOB_BRACE etc. [PR119217]
https://gcc.gnu.org/g:320f24a3b26aa8dc0640aa56b63bc9ef30ca043b commit r15-10116-g320f24a3b26aa8dc0640aa56b63bc9ef30ca043b Author: Rainer Orth Date: Thu May 8 09:21:45 2025 +0200 cobol: Don't require GLOB_BRACE etc. [PR119217] cdf-copy.cc doesn't compile on Solaris: /vol/gcc/src/hg/master/local/gcc/cobol/cdf-copy.cc: In member function ‘int copybook_elem_t::open_file(const char*, bool)’: /vol/gcc/src/hg/master/local/gcc/cobol/cdf-copy.cc:317:34: error: ‘GLOB_BRACE’ was not declared in this scope; did you mean ‘GLOB_ERR’? 317 | static int flags = GLOB_MARK | GLOB_BRACE | GLOB_TILDE; | ^~ | GLOB_ERR /vol/gcc/src/hg/master/local/gcc/cobol/cdf-copy.cc:317:47: error: ‘GLOB_TILDE’ was not declared in this scope 317 | static int flags = GLOB_MARK | GLOB_BRACE | GLOB_TILDE; | ^~ GLOB_BRACE and GLOB_TILDE are BSD extensions not in POSIX.1, thus missing on Solaris probably due to its System V heritage. This patch introduces fallback definitions to avoid this. Bootstrapped without regressions on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu. 2025-04-08 Rainer Orth gcc/cobol: PR cobol/119217 * cdf-copy.cc (GLOB_BRACE): Define fallback. (GLOB_TILDE): Likewise. (cherry picked from commit aacaa3b13bca508cb6cb803d11cb942b2de8c0db) Diff: --- gcc/cobol/cdf-copy.cc | 10 ++ 1 file changed, 10 insertions(+) diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 2e4bfb623d1e..059596c08f41 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -42,6 +42,16 @@ #include "util.h" #include "copybook.h" +// GLOB_BRACE and GLOB_TILDE are BSD extensions. Provide fallback definitions +// if necessary. +#ifndef GLOB_BRACE +#define GLOB_BRACE 0 +#endif + +#ifndef GLOB_TILDE +#define GLOB_TILDE 0 +#endif + #define COUNT_OF(X) (sizeof(X) / sizeof(X[0])) /*
[gcc r15-10125] cobol: One additional edit to testsuite/cobol.dg/group1/check_88.cob [PR120251]
https://gcc.gnu.org/g:aa66c628206d10d101f9d3528b3b641189fc280e commit r15-10125-gaa66c628206d10d101f9d3528b3b641189fc280e Author: Robert Dubner Date: Thu May 15 13:33:16 2025 -0400 cobol: One additional edit to testsuite/cobol.dg/group1/check_88.cob [PR120251] Missed one edit. This fixes that. gcc/testsuite/ChangeLog: PR cobol/120251 * cobol.dg/group1/check_88.cob: One final regex "." instead of "ß" (cherry picked from commit fae53928595341981f08ded4edcbba07ee1d5d04) Diff: --- gcc/testsuite/cobol.dg/group1/check_88.cob | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/cobol.dg/group1/check_88.cob b/gcc/testsuite/cobol.dg/group1/check_88.cob index 18a299fc282b..f1d0685e478a 100644 --- a/gcc/testsuite/cobol.dg/group1/check_88.cob +++ b/gcc/testsuite/cobol.dg/group1/check_88.cob @@ -17,7 +17,7 @@ *> { dg-output {.* Bundesstra.e(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output {There should be no spaces before the final quote(\n|\r\n|\r)} } -*> { dg-output {".* Bundesstraße"(\n|\r\n|\r)} } +*> { dg-output {".* Bundesstra.e"(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output { IsLow ""(\n|\r\n|\r)} } *> { dg-output { IsZero "000"(\n|\r\n|\r)} }
[gcc r15-10124] cobol: Don't display 0xFF HIGH-VALUE characters in testcases. [PR120251]
https://gcc.gnu.org/g:412994e3d304229f60ef3bc597c87bae4bfb4e22 commit r15-10124-g412994e3d304229f60ef3bc597c87bae4bfb4e22 Author: Robert Dubner Date: Thu May 15 12:01:12 2025 -0400 cobol: Don't display 0xFF HIGH-VALUE characters in testcases. [PR120251] The tests were displaying 0xFF characters, and the resulting generated output changed with the system locale. The check_88 test was modified so that the regex comparisons ignore those character positions. Two of the other tests were changed to output hexadecimal rather than character strings. There is one new test, and the other inspect testcases were edited to remove an unimportant back-apostrophe that had found its way into the source code sequence number area. gcc/testsuite/ChangeLog: PR cobol/120251 * cobol.dg/group1/check_88.cob: Ignore characters above 0x80. * cobol.dg/group2/ALLOCATE_Rule_8_OPTION_INITIALIZE_with_figconst.cob: Output HIGH-VALUE as hex, rather than as characters. * cobol.dg/group2/ALLOCATE_Rule_8_OPTION_INITIALIZE_with_figconst.out: Likewise. * cobol.dg/group2/INSPECT_CONVERTING_TO_figurative_constants.cob: Typo. * cobol.dg/group2/INSPECT_CONVERTING_TO_figurative_constants.out: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_1.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_2.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_3.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_4.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_5-f.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_6.cob: Likewise. * cobol.dg/group2/INSPECT_ISO_Example_7.cob: Likewise. * cobol.dg/group2/Multiple_INDEXED_BY_variables_with_the_same_name.cob: New test. * cobol.dg/group2/Multiple_INDEXED_BY_variables_with_the_same_name.out: New test. (cherry picked from commit 022d8e25e49021b378a4e6c24c2f0c380a066690) Diff: --- gcc/testsuite/cobol.dg/group1/check_88.cob | 12 +-- ...CATE_Rule_8_OPTION_INITIALIZE_with_figconst.cob | 3 ++- ...CATE_Rule_8_OPTION_INITIALIZE_with_figconst.out | 3 +-- .../INSPECT_CONVERTING_TO_figurative_constants.cob | 12 +-- .../INSPECT_CONVERTING_TO_figurative_constants.out | 10 - .../cobol.dg/group2/INSPECT_ISO_Example_1.cob | 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_2.cob | 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_3.cob | 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_4.cob | 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_5-f.cob| 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_6.cob | 2 +- .../cobol.dg/group2/INSPECT_ISO_Example_7.cob | 2 +- ...ple_INDEXED_BY_variables_with_the_same_name.cob | 24 ++ ...ple_INDEXED_BY_variables_with_the_same_name.out | 3 +++ 14 files changed, 54 insertions(+), 27 deletions(-) diff --git a/gcc/testsuite/cobol.dg/group1/check_88.cob b/gcc/testsuite/cobol.dg/group1/check_88.cob index 4a7723eb92a3..18a299fc282b 100644 --- a/gcc/testsuite/cobol.dg/group1/check_88.cob +++ b/gcc/testsuite/cobol.dg/group1/check_88.cob @@ -3,25 +3,25 @@ *> { dg-output {\-> <\-(\n|\r\n|\r)} } *> { dg-output {\->"""<\-(\n|\r\n|\r)} } *> { dg-output {\->000<\-(\n|\r\n|\r)} } -*> { dg-output {\->ÿÿÿ<\-(\n|\r\n|\r)} } +*> { dg-output {\->.*<\-(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output {\-><\-(\n|\r\n|\r)} } *> { dg-output {\-><\-(\n|\r\n|\r)} } *> { dg-output {\-><\-(\n|\r\n|\r)} } *> { dg-output {\-><\-(\n|\r\n|\r)} } -*> { dg-output {\-><\-(\n|\r\n|\r)} } +*> { dg-output {\->.*<\-(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output {There should be no garbage after character 32(\n|\r\n|\r)} } *> { dg-output {\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\*\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-(\n|\r\n|\r)} } -*> { dg-output {üüü Bundesstraße (\n|\r\n|\r)} } -*> { dg-output {üüü Bundesstraße (\n|\r\n|\r)} } +*> { dg-output {.* Bundesstra.e(\n|\r\n|\r)} } +*> { dg-output {.* Bundesstra.e(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output {There should be no spaces before the final quote(\n|\r\n|\r)} } -*> { dg-output {"üüü Bundesstraße"(\n|\r\n|\r)} } +*> { dg-output {".* Bundesstraße"(\n|\r\n|\r)} } *> { dg-output { (\n|\r\n|\r)} } *> { dg-output { IsLow ""(\n|\r\n|\r)} } *> { dg-output { IsZero "000"(\n|\r\n|\r)} } -*> { dg-output { IsHi"ÿÿÿ"(\n|\r\n|\r)} } +*> { dg-output { IsHi".*"(\n|\r\n|\r)} } *> { dg-output { IsBob "bob"(\n|\r\n|\r)} } *> { dg-output { IsQuote "(\n|\r\n|\r)} } *> { dg-output { IsS
[gcc r15-10130] cobol: Wrap the call to fprintf in a libgcobol routine. [PR119524]
https://gcc.gnu.org/g:7305d78ab9478422ac03d17399e2384859a73c81 commit r15-10130-g7305d78ab9478422ac03d17399e2384859a73c81 Author: Robert Dubner Date: Sun Jun 1 12:32:37 2025 -0400 cobol: Wrap the call to fprintf in a libgcobol routine. [PR119524] gcc/cobol/ChangeLog: PR cobol/119524 * gengen.cc (gg_printf): Use the new __gg__fprintf_stderr() function instead of generating a call to fprintf(). libgcobol/ChangeLog: PR cobol/119524 * libgcobol.cc (__gg__fprintf_stderr): New function. (cherry picked from commit 213cb633e7ec9b291768a4da0cd6d67679221aeb) Diff: --- gcc/cobol/gengen.cc| 16 +--- libgcobol/libgcobol.cc | 14 ++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc index 91f67d534f6e..a5f143cf2342 100644 --- a/gcc/cobol/gengen.cc +++ b/gcc/cobol/gengen.cc @@ -2152,18 +2152,6 @@ gg_printf(const char *format_string, ...) int nargs = 0; tree args[ARG_LIMIT]; - // Because this routine is intended for debugging, we are sending the - // text to STDERR - - // Because we don't actually use stderr ourselves, we just pick it up as a - // VOID_P and pass it along to fprintf() - tree t_stderr = gg_declare_variable(VOID_P, "stderr", - NULL_TREE, - vs_external_reference); - - gg_push_context(); - - args[nargs++] = t_stderr; args[nargs++] = build_string_literal(strlen(format_string)+1, format_string); va_list ap; @@ -2197,7 +2185,7 @@ gg_printf(const char *format_string, ...) static tree function = NULL_TREE; if( !function ) { -function = gg_get_function_address(INT, "fprintf"); +function = gg_get_function_address(INT, "__gg__fprintf_stderr"); } tree stmt = build_call_array_loc (location_from_lineno(), @@ -2206,8 +2194,6 @@ gg_printf(const char *format_string, ...) nargs, args); gg_append_statement(stmt); - - gg_pop_context(); } tree diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index 66405baf99b1..3ab74636601b 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -49,6 +49,7 @@ #include #include #include +#include #if __has_include() # include // for program_invocation_short_name #endif @@ -13151,3 +13152,16 @@ __gg__set_env_value(cblc_field_t *value, // And now, anticlimactically, set the variable: setenv(trimmed_env, trimmed_val, 1); } + +extern "C" +void +__gg__fprintf_stderr(const char *format_string, ...) + { + /* This routine allows the compiler to send stuff to stderr in a way + that is straightforward to use.. */ + va_list ap; + va_start(ap, format_string); + vfprintf(stderr, format_string, ap); + va_end(ap); + } +
[gcc r15-10117] cobol: Initialize regmatch_t portably [PR119217]
https://gcc.gnu.org/g:43bf1b391b4b34a9e0be07770aeec2e8c6b08b25 commit r15-10117-g43bf1b391b4b34a9e0be07770aeec2e8c6b08b25 Author: Rainer Orth Date: Thu May 8 09:29:56 2025 +0200 cobol: Initialize regmatch_t portably [PR119217] The dts.h initialization of regmatch_t currently breaks Solaris compilation: In file included from /vol/gcc/src/hg/master/local/gcc/cobol/lexio.h:208, from /vol/gcc/src/hg/master/local/gcc/cobol/lexio.cc:36: /vol/gcc/src/hg/master/local/gcc/cobol/dts.h: In constructor ‘dts::csub_match::csub_match(const char*)’: /vol/gcc/src/hg/master/local/gcc/cobol/dts.h:36:35: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive] 36 | static regmatch_t empty = { -1, -1 }; | ^~ | | | int The problem is that Solaris regmatch_t has additional members before rm_so and rm_eo, as is always allowed by POSIX.1 typedef struct { const char *rm_sp, *rm_ep; /* Start pointer, end pointer */ regoff_trm_so, rm_eo; /* Start offset, end offset */ int rm_ss, rm_es; /* Used internally */ } regmatch_t; so the initialization doesn't do what it's supposed to do. Fixed by initializing the rm_so and rm_eo members explicitly. Bootstrapped without regressions on amd64-pc-solaris2.11, sparcv9-sun-solaris2.11, and x86_64-pc-linux-gnu. 2025-04-08 Rainer Orth gcc/cobol: PR cobol/119217 * dts.h (csub_match): Initialize rm_so, rm_eo fields explicitly. (cherry picked from commit 12d6fa2a21140166181ae3be7711d60e62c569d7) Diff: --- gcc/cobol/dts.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/cobol/dts.h b/gcc/cobol/dts.h index c345dc7e64ab..dfd7c4c24f71 100644 --- a/gcc/cobol/dts.h +++ b/gcc/cobol/dts.h @@ -33,7 +33,8 @@ namespace dts { : input(input) , first(NULL), second(NULL), matched(false) { - static regmatch_t empty = { -1, -1 }; + static regmatch_t empty; + empty.rm_so = empty.rm_eo = -1; regmatch_t& self(*this); self = empty; }
[gcc r15-10139] libgcobol: Add license.
https://gcc.gnu.org/g:fd735329ee8bddd34be4a341aa04132c9503dadf commit r15-10139-gfd735329ee8bddd34be4a341aa04132c9503dadf Author: James K. Lowden Date: Fri Jun 20 10:16:26 2025 -0400 libgcobol: Add license. libgcobol/ChangeLog: * LICENSE: New file. (cherry picked from commit 632a50abc3a99cace8abc6ed3817f7eb1312c9d2) Diff: --- libgcobol/LICENSE | 27 +++ 1 file changed, 27 insertions(+) diff --git a/libgcobol/LICENSE b/libgcobol/LICENSE new file mode 100644 index ..3937993c56a2 --- /dev/null +++ b/libgcobol/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2021-2025 Symas Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. +* Neither the name of the Symas Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[gcc r15-10148] cobol: Fix build on 32-bit Darwin [PR120621]
https://gcc.gnu.org/g:79c7ed9d45d1862fb1ac4e6f3653bf8892c3afe6 commit r15-10148-g79c7ed9d45d1862fb1ac4e6f3653bf8892c3afe6 Author: Rainer Orth Date: Fri Jul 11 09:56:18 2025 +0200 cobol: Fix build on 32-bit Darwin [PR120621] Bootstrapping trunk with 32-bit-default on Mac OS X 10.11 (i386-apple-darwin15) fails: /vol/gcc/src/hg/master/local/gcc/cobol/lexio.cc: In static member function 'static void cdftext::process_file(filespan_t, int, bool)': /vol/gcc/src/hg/master/local/gcc/cobol/lexio.cc:1859:14: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'size_t' {aka 'long unsigned int'} [-Werror=format=] 1859 | dbgmsg("%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED ", opening %s on fd %d", | ^ 1860 | __func__, __LINE__,mfile.lineno(), | ~~ | | | size_t {aka long unsigned int} In file included from /vol/gcc/src/hg/master/local/gcc/system.h:1244, from /vol/gcc/src/hg/master/local/gcc/cobol/cobol-system.h:61, from /vol/gcc/src/hg/master/local/gcc/cobol/lexio.cc:33: /vol/gcc/src/hg/master/local/gcc/hwint.h:135:51: note: format string is defined here 135 | #define HOST_SIZE_T_PRINT_UNSIGNED "%" GCC_PRISZ "u" | ~~^ | | | unsigned int | %" GCC_PRISZ "lu On Darwin, size_t is always long unsigned int. However, unsigned int and long unsigned int are both 32-bit, so hwint.h selects %u for the format. As documented there, the arg needs to be cast to fmt_size_t to avoid the error. This isn't an issue on other 32-bit platforms like Solaris/i386 or Linux/i686 since they use unsigned int for size_t. /vol/gcc/src/hg/master/local/gcc/cobol/parse.y: In function 'int yyparse()': /vol/gcc/src/hg/master/local/gcc/cobol/parse.y:10215:36: error: format '%zu' expects argument of type 'size_t', but argument 4 has type 'int' [-Werror=format=] 10215 | error_msg(loc, "FUNCTION %qs has " |^~~ 10216 | "inconsistent parameter type %zu (%qs)", | ~~~ 10217 | keyword_str($1), p - args.data(), name_of(p->field) ); | ~~~ | | | int The arg (p - args.data())) is ptrdiff_t (int on 32-bit Darwin), while the %zu format expect size_t (long unsigned int). The patch therefore casts the ptrdiff_t arg to long and prints it as such. There are two more instances of the same problem: /vol/gcc/src/hg/master/local/gcc/cobol/util.cc: In member function 'void cbl_field_t::report_invalid_initial_value(const YYLTYPE&) const': /vol/gcc/src/hg/master/local/gcc/cobol/util.cc:905:80: error: format '%zu' expects argument of type 'size_t', but argument 6 has type 'int' [-Werror=format=] 905 | error_msg(loc, "%s cannot represent VALUE %qs exactly (max %c%zu)", | ~~^ | | | long unsigned int | %u 906 | name, data.initial, '.', pend - p); | | | | int In file included from /vol/gcc/src/hg/master/local/gcc/cobol/scan.l:48: /vol/gcc/src/hg/master/local/gcc/cobol/scan_ante.h: In function 'int numstr_of(const char*, radix_t)': /vol/gcc/src/hg/master/local/gcc/cobol/scan_ante.h:152:25: error: format '%zu' expects argument of type 'size_t', but argument 4 has type 'int' [-Werror=format=] 152 | error_msg(yylloc, "significand of %s has more than 36 digits (%zu)", input, nx); | ^ ~~ |
[gcc r15-10141] cobol: Normalize generating and using function_decls.
https://gcc.gnu.org/g:3f8dfda16b836e20eb898202943dee647232cace commit r15-10141-g3f8dfda16b836e20eb898202943dee647232cace Author: Robert Dubner Date: Sun Jun 29 10:54:36 2025 -0400 cobol: Normalize generating and using function_decls. Because COBOL doesn't require function prototypes, it is possible to, for example, CALL "getcwd" USING and then later CALL "getcwd" USING RETURNING The second call "knows" that the return value is a char*, but the first one does not. So, the first one gets a default return value type of SSIZE_t, which later needs to be replaced with CHAR_P. These [all too] extensive changes ensure that all references to a particular function use the same function_decl, and take measures to make sure that one function_decl is back-modified, if necessary, with the best return value type. gcc/cobol/ChangeLog: * Make-lang.in: Incorporate gcobol.clean. * except.cc (cbl_enabled_exceptions_t::dump): Update debug message. * genapi.cc (gg_attribute_bit_get): Formatting. (file_static_variable): Formatting. (trace1_init): Formatting. (build_main_that_calls_something): Normalize function_decl use. (parser_call_target): Likewise. (set_call_convention): Likewise. (parser_call_target_convention): Likewise. (parser_call_targets_dump): Likewise. (function_handle_from_name): Likewise. (function_pointer_from_name): Likewise. (parser_initialize_programs): Likewise. (parser_statement_begin): Formatting. (parser_leave_file): Use function_decl FIFO. (enter_program_common): Normalize function_decl use. (parser_enter_program): Normalize function_decl use. (tree_type_from_field_type): Normalize function_decl use. (is_valuable): Comment. (pe_stuff): Change name to program_end_stuff. (program_end_stuff): Likewise. (parser_exit): Likewise. (parser_division): Normalize function_decl use. (create_and_call): Normalize function_decl use. (parser_call): Normalize function_decl use. (parser_set_pointers): Normalize function_decl use. (parser_program_hierarchy): Normalize function_decl use. (psa_FldLiteralA): Defeat attempt to re-use literals. (Fails on some aarch64). (parser_symbol_add): Error message formatting. * genapi.h: Formatting. * gengen.cc (struct cbl_translation_unit_t): Add function_decl FIFO. (show_type): Rename to gg_show_type. (gg_show_type): Correct an error message. (gg_assign): Formatting; change error handling. (gg_modify_function_type): Normalize function_decl use. (gg_define_function_with_no_parameters): Fold into gg_defint_function(). (function_decl_key): Normalize function_decl use. (gg_peek_fn_decl): Normalize function_decl use. (gg_build_fn_decl): Normalize function_decl use. (gg_define_function): Normalize function_decl use. (gg_tack_on_function_parameters): Remove. (gg_finalize_function): Normalize function_decl use. (gg_leaving_the_source_code_file): Normalize function_decl use. (gg_call_expr_list): Normalize function_decl use. (gg_trans_unit_var_decl): Normalize function_decl use. (gg_insert_into_assemblerf): New function; formatting. * gengen.h (struct gg_function_t): Eliminate "is_truly_nested" flag. (gg_assign): Incorporate return value. (gg_define_function): Normalize function_decl use. (gg_define_function_with_no_parameters): Eliminate. (gg_build_fn_decl): Normalize function_decl use. (gg_peek_fn_decl): Normalize function_decl use. (gg_modify_function_type): Normalize function_decl use. (gg_call_expr_list): Normalize function_decl use. (gg_get_function_decl): Normalize function_decl use. (location_from_lineno): Prefix with "extern". (gg_open): Likewise. (gg_close): Likewise. (gg_get_indirect_reference): Likewise. (gg_insert_into_assembler): Likewise. (gg_insert_into_assemblerf): Likewise. (gg_show_type): New declaration. (gg_leaving_the_source_code_file): New declaration. * parse.y: Format debugging message. * parse_ante.h: Normalize function_decl use. (cherry picked from commit dd92d6acb416e138b21f00f34df54cb740e40e4c) Diff: --- gcc/cobol/Make-lang.in | 7 + gcc/cobol/except.cc| 4 +- gcc/cobol/genapi.cc| 431 +++ gcc/cobol/genapi.h | 2 +- gcc/cobol
[gcc r15-10142] cobol: Revise diagnostic linemap management.
https://gcc.gnu.org/g:d6115f773e868b94a5195b73ba249cf86b22deb2 commit r15-10142-gd6115f773e868b94a5195b73ba249cf86b22deb2 Author: James K. Lowden Date: Mon Jun 30 16:51:49 2025 -0400 cobol: Revise diagnostic linemap management. Update linemap filename before location in both parsers. Rely on parser to update linemap. Lexer maintains location. Various small syntax corrections and extensions. PR cobol/120772 PR cobol/120779 PR cobol/120790 PR cobol/120791 PR cobol/120794 gcc/cobol/ChangeLog: * gcobc: Supply -fPIC for shared objects. * genapi.cc (linemap_add): Delete empty macro. (parser_enter_file): Do not call linemap_add. (parser_leave_file): Same. * gengen.cc (location_from_lineno): Remove function. * lexio.cc (parse_replacing_term): Allow empty term. (cdftext::process_file): Always append to output. (cdftext::segment_line): Output #line directives. * lexio.h (struct span_t): Count lines in span. * parse.y: Revamp REPOSITORY, and minor syntax extensions. * parse_ante.h (input_file_status_notify): Update linemap filename before location. (intrinsic_token_of): Declare. (parser_move_carefully): Support MOVE pointer. * parse_util.h (intrinsic_token_of): New function. * scan.l: New EOF logic, accept NOT=, own yylloc and yylineno. * scan_ante.h (class enter_leave_t): Do not store newline count. (cdf_location_set): Remove declaration. (ydfltype_of): New function. (update_location): Accept location parameter. (reset_location): New function. (YY_USER_ACTION): Use update_location(). (YY_USER_INIT): Update CDF location. (verify_ws): New function. (wait_for_the_child): Removed. * symbols.h (cobol_fileline_set): return line number. * util.cc (valid_move): Use range-based for loop. (struct input_file_t): Remove line_map pointer. (class unique_stack): New peek() member function. (cobol_lineno_save): Rename to overload cobol_lineno(). (cobol_lineno): Replaces cobol_lineno_save(). (cobol_filename): Return void. (location_from_lineno): New function used by genapi.cc. (cdf_location_set): Remove. (matched_length): No change. (cobol_fileline_set): Return line number. (fisspace): Remove extra semicolon. (fisprint): Same. * util.h (cobol_filename_restore): Return void. (cobol_lineno_save): Remove declaration. (cobol_lineno): Declare. (cherry picked from commit 612c4c104ac0c2726d2de27f350040ad5f8d5776) Diff: --- gcc/cobol/gcobc| 7 +- gcc/cobol/genapi.cc| 9 -- gcc/cobol/gengen.cc| 8 - gcc/cobol/lexio.cc | 26 +++- gcc/cobol/lexio.h | 9 ++ gcc/cobol/parse.y | 109 ++ gcc/cobol/parse_ante.h | 11 +- gcc/cobol/parse_util.h | 9 ++ gcc/cobol/scan.l | 389 + gcc/cobol/scan_ante.h | 113 +++--- gcc/cobol/symbols.h| 2 +- gcc/cobol/util.cc | 83 ++- gcc/cobol/util.h | 5 +- 13 files changed, 439 insertions(+), 341 deletions(-) diff --git a/gcc/cobol/gcobc b/gcc/cobol/gcobc index 8c2245f5f82c..01c75dd191e4 100755 --- a/gcc/cobol/gcobc +++ b/gcc/cobol/gcobc @@ -35,6 +35,10 @@ ##output set the mode variable. Everything else is appended to the ##opts variable. ## +## - -fPIC is added to the command line if $mode is "-shared". That +##option applies only to "certain machines", per the gcc info +##manual. For this script to be portable across machines, -fPIC +##would have to be set more judiciously. if [ "$COBCPY" ] then @@ -478,12 +482,13 @@ do *) if [ -z "$output_name" ] # first non-option argument is source file name then - output_name=$(basename ${opt%.*}) + output_name=$(basename "${opt%.*}") case $mode in -c) output_name="$output_name".o ;; -shared) output_name="$output_name".so + opts="$opts -fPIC" ;; esac opts="$opts -o $output_name" diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index d73601cd9d07..80177886dbc6 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -3635,8 +3635,6 @@ parser_first_statement( int lineno ) } } -#define linemap_add(...) - void parser_enter_file(const char *filename) { @@ -3668,9 +3666,6 @@ parser_enter_file(const char *filename) } } - // Let the linemap routine know
[gcc r15-10136] cobol: Eliminate unguarded clock_gettime dependencies. [PR119975]
https://gcc.gnu.org/g:8df603ce1c0f69eb4ffe01d044096dbd082d406d commit r15-10136-g8df603ce1c0f69eb4ffe01d044096dbd082d406d Author: Robert Dubner Date: Wed Jun 11 15:49:41 2025 -0400 cobol: Eliminate unguarded clock_gettime dependencies. [PR119975] These changes are help make it possible to compile on MacOS. In addition to guarding clock_settime() calls, it removes the use of structures and constants needed for clock_settime(). libgcobol/ChangeLog: PR cobol/119975 * intrinsic.cc (__gg__current_date): Eliminate CLOCK_REALTIME. (__gg__seconds_past_midnight): Likewise. (__gg__formatted_current_date): Likewise. (__gg__random): Likewise. (__gg__random_next): Likewise. * libgcobol.cc: include . (__gg__abort): Eliminate CLOCK_REALTIME. (cobol_time): Likewise. (get_time_nanoseconds): Rename. (get_time_nanoseconds_local): Comment; Eliminate CLOCK_REALTIME. (__gg__clock_gettime): Likewise. (__gg__get_date_hhmmssff): Likewise. * libgcobol.h (__gg__clock_gettime): Eliminate clockid_t from declaration. (cherry picked from commit 582dda08eabc8f7dc9c504c0010d778bd6ff09b2) Diff: --- libgcobol/intrinsic.cc | 12 ++-- libgcobol/libgcobol.cc | 44 ++-- libgcobol/libgcobol.h | 2 +- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc index 2d8d79c1c7c7..81ae638630f1 100644 --- a/libgcobol/intrinsic.cc +++ b/libgcobol/intrinsic.cc @@ -1219,7 +1219,7 @@ __gg__current_date(cblc_field_t *dest) { // FUNCTION CURRENT-DATE struct cbl_timespec tp = {}; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec char retval[DATE_STRING_BUFFER_SIZE]; timespec_to_string(retval, tp); @@ -1236,7 +1236,7 @@ __gg__seconds_past_midnight(cblc_field_t *dest) struct tm tm; __int128 retval=0; - __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec + __gg__clock_gettime(&tp); // time_t tv_sec; long tv_nsec localtime_r(&tp.tv_sec, &tm); retval += tm.tm_hour; @@ -1460,7 +1460,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string size_t input_offset, size_t input_size) { - // FUNCTION CURRENT-DATE + // FUNCTION FORMATTED-CURRENT-DATE // Establish the destination, and set it to spaces char *d= PTRCAST(char, dest->data); @@ -1485,7 +1485,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // Destination string } struct cbl_timespec ts = {}; - __gg__clock_gettime(CLOCK_REALTIME, &ts); + __gg__clock_gettime(&ts); struct tm tm = {}; #ifdef HAVE_STRUCT_TM_TM_ZONE @@ -3433,7 +3433,7 @@ __gg__random( cblc_field_t *dest, state = (char *)malloc(state_len); struct cbl_timespec ts; -__gg__clock_gettime(CLOCK_REALTIME, &ts); +__gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } int seed = (int)__gg__binary_value_from_qualified_field(&rdigits, @@ -3473,7 +3473,7 @@ __gg__random_next(cblc_field_t *dest) buf->state = NULL; state = (char *)malloc(state_len); struct cbl_timespec ts; -__gg__clock_gettime(CLOCK_REALTIME, &ts); +__gg__clock_gettime(&ts); initstate_r( ts.tv_nsec, state, state_len, buf); } random_r(buf, &retval_31); diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc index f8697afd59cb..81b5b7af8121 100644 --- a/libgcobol/libgcobol.cc +++ b/libgcobol/libgcobol.cc @@ -69,6 +69,7 @@ #include #include #include +#include #include #include "exceptl.h" @@ -264,7 +265,7 @@ class ec_status_t { , operation(file_op_none) , mode(file_mode_none_e) , user_status(nullptr) -, filename(nullptr) +, filename(nullptr) {} explicit file_status_t( const cblc_file_t *file ) : ifile(file->symbol_table_index) @@ -558,7 +559,7 @@ __gg__abort(const char *msg) abort(); } -void +void __gg__mabort() { __gg__abort("Memory allocation error\n"); @@ -2290,7 +2291,7 @@ static time_t cobol_time() { struct cbl_timespec tp; - __gg__clock_gettime(CLOCK_REALTIME, &tp); + __gg__clock_gettime(&tp); return tp.tv_sec; } @@ -2402,12 +2403,28 @@ int_from_digits(const char * &p, int ndigits) return retval; } -uint64_t -get_time_nanoseconds() +// For testing purposes, this undef causes the use of gettimeofday(). +// #undef HAVE_CLOCK_GETTIME + +static uint64_t +get_time_nanoseconds_local() { // This code was unabashedly stolen from gcc/timevar.cc. // It returns the Unix epoch with nine decimal places. + /* No
[gcc r15-10145] cobol: Respect error in cobol.install-common.
https://gcc.gnu.org/g:2e508448cfad64aae20a259b6fa5a7e5fd0e2eb6 commit r15-10145-g2e508448cfad64aae20a259b6fa5a7e5fd0e2eb6 Author: James K. Lowden Date: Tue Jul 1 13:51:44 2025 -0400 cobol: Respect error in cobol.install-common. If GCOBOL_INSTALL_NAME fails to install, do not install GCOBC_INSTALL_NAME. gcc/cobol/ChangeLog: * Make-lang.in: Use && instead of semicolon between commands. (cherry picked from commit ffe49d47a8452cee7865c96bd58565b9c2153b0e) Diff: --- gcc/cobol/Make-lang.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index 18eb3b0f1e54..e884212eb769 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -287,7 +287,7 @@ cobol.install-common: installdirs rm -f $(DESTDIR)$(bindir)/$(GCOBOL_TARGET_INSTALL_NAME)$(exeext); \ rm -f $(DESTDIR)$(bindir)/$(GCOBC_TARGET_INSTALL_NAME)$(exeext); \ ( cd $(DESTDIR)$(bindir) && \ - $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) ); \ + $(LN) $(GCOBOL_INSTALL_NAME)$(exeext) $(GCOBOL_TARGET_INSTALL_NAME)$(exeext) && \ $(LN) $(GCOBC_INSTALL_NAME)$(exeext) $(GCOBC_TARGET_INSTALL_NAME)$(exeext) ); \ fi; \ fi
[gcc r15-10144] cobol: Repair printf format of size_t.
https://gcc.gnu.org/g:8536d47f4bbd98476778199728f54f4074ca90ed commit r15-10144-g8536d47f4bbd98476778199728f54f4074ca90ed Author: Robert Dubner Date: Tue Jul 1 12:02:21 2025 -0400 cobol: Repair printf format of size_t. gcc/cobol/ChangeLog: * parse.y: printf() of size_t is %zu, not %ld. (cherry picked from commit f471ed487ab36651d48c6c31fb28d36a42a30829) Diff: --- gcc/cobol/parse.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 57a41bbca718..74637c9641f5 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -12404,7 +12404,7 @@ numstr2i( const char input[], radix_t radix ) { return output; } if( erc == -1 ) { -yywarn("'%s' was accepted as %ld", input, integer); +yywarn("'%s' was accepted as %zu", input, integer); } return output; }
[gcc r15-10147] cobol: Add PUSH and POP to CDF.
https://gcc.gnu.org/g:d780100c63ffd3b96c4be218edc60627dba1fcc1 commit r15-10147-gd780100c63ffd3b96c4be218edc60627dba1fcc1 Author: James K. Lowden Date: Wed Jul 9 18:14:40 2025 -0400 cobol: Add PUSH and POP to CDF. Introduce cdf_directives_t class to centralize management of CDF state. Move existing CDF state variables and functions into the new class. gcc/cobol/ChangeLog: PR cobol/120765 * cdf.y: Extend grammar for new CDF syntax, relocate dictionary. * cdfval.h (cdf_dictionary): Use new CDF dictionary. * dts.h: Remove useless assignment, note incorrect behavior. * except.cc: Remove obsolete EC state. * gcobol.1: Document CDF in its own section. * genapi.cc (parser_statement_begin): Use new EC state function. (parser_file_merge): Same. (parser_check_fatal_exception): Same. * genutil.cc (get_and_check_refstart_and_reflen): Same. (get_depending_on_value_from_odo): Same. (get_data_offset): Same. (process_this_exception): Same. * lexio.cc (check_push_pop_directive): New function. (check_source_format_directive): Restrict regex search to 1 line. (cdftext::free_form_reference_format): Use new function. * parse.y: Define new CDF tokens, use new CDF state. * parse_ante.h (cdf_tokens): Use new CDF state. (redefined_token): Same. (class prog_descr_t): Remove obsolete CDF state. (class program_stack_t): Same. (current_call_convention): Same. * scan.l: Recognize new CDF tokens. * scan_post.h (is_cdf_token): Same. * symbols.h (cdf_current_tokens): Change current_call_convention to return void. * token_names.h: Regenerate. * udf/stored-char-length.cbl: Use new PUSH/POP CDF functionality. * util.cc (class cdf_directives_t): Define cdf_directives_t. (current_call_convention): Same. (cdf_current_tokens): Same. (cdf_dictionary): Same. (cdf_enabled_exceptions): Same. (cdf_push): Same. (cdf_push_call_convention): Same. (cdf_push_current_tokens): Same. (cdf_push_dictionary): Same. (cdf_push_enabled_exceptions): Same. (cdf_push_source_format): Same. (cdf_pop): Same. (cdf_pop_call_convention): Same. (cdf_pop_current_tokens): Same. (cdf_pop_dictionary): Same. (cdf_pop_enabled_exceptions): Same. (cdf_pop_source_format): Same. * util.h (cdf_push): Declare cdf_directives_t. (cdf_push_call_convention): Same. (cdf_push_current_tokens): Same. (cdf_push_dictionary): Same. (cdf_push_enabled_exceptions): Same. (cdf_push_source_format): Same. (cdf_pop): Same. (cdf_pop_call_convention): Same. (cdf_pop_current_tokens): Same. (cdf_pop_dictionary): Same. (cdf_pop_source_format): Same. (cdf_pop_enabled_exceptions): Same. libgcobol/ChangeLog: * common-defs.h (cdf_enabled_exceptions): Use new CDF state. (cherry picked from commit 3f59a1cac717f8af84e884e9ec0f6ef14e102e6e) Diff: --- gcc/cobol/cdf.y | 94 +- gcc/cobol/cdfval.h |4 + gcc/cobol/dts.h | 14 +- gcc/cobol/except.cc |2 - gcc/cobol/gcobol.1 | 192 +-- gcc/cobol/genapi.cc |6 +- gcc/cobol/genutil.cc |7 + gcc/cobol/lexio.cc | 72 +- gcc/cobol/parse.y| 21 +- gcc/cobol/parse_ante.h | 48 +- gcc/cobol/scan.l | 13 + gcc/cobol/scan_post.h|2 + gcc/cobol/symbols.h |3 +- gcc/cobol/token_names.h | 2228 +- gcc/cobol/udf/stored-char-length.cbl |4 + gcc/cobol/util.cc| 90 +- gcc/cobol/util.h | 15 + libgcobol/common-defs.h |2 +- 18 files changed, 1541 insertions(+), 1276 deletions(-) diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index f1a791245854..840eb5033151 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -105,14 +105,14 @@ void input_file_status_notify(); using std::map; - static map dictionary; - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static bool cdfval_add( const char name[], const cdfval_t& value, bool override = false ) { +cdf_values_t& dictionary( cdf_dictionary() ); + if( scanner_parsing() ) { if( ! override ) { if( dictionary.find(name) != dictionary.end() ) return fa
[gcc r15-10150] cobol: Eliminate cppcheck warnings in gcc/cobol .cc files.
https://gcc.gnu.org/g:f27c6d83f9dcb0189ba8a5fe7e0094160b797091 commit r15-10150-gf27c6d83f9dcb0189ba8a5fe7e0094160b797091 Author: Robert Dubner Date: Mon Jul 14 16:41:35 2025 -0400 cobol: Eliminate cppcheck warnings in gcc/cobol .cc files. These changes eliminate various cppcheck warnings, mostly involving C-Style casting and applying "const" to various variables and formal parameters. Some tab characters were eliminated, and some lines were trimmed to seventy-nine characters. gcc/cobol/ChangeLog: * cobol1.cc (cobol_langhook_handle_option): Eliminate cppcheck warnings. * dts.h: Likewise. * except.cc (cbl_enabled_exceptions_t::dump): Likewise. * gcobolspec.cc (lang_specific_driver): Likewise. * genapi.cc (parser_file_merge): Likewise. * gengen.cc (gg_unique_in_function): Likewise. (gg_declare_variable): Likewise. (gg_peek_fn_decl): Likewise. (gg_define_function): Likewise. * genmath.cc (set_up_on_exception_label): Likewise. (set_up_compute_error_label): Likewise. (arithmetic_operation): Likewise. (fast_divide): Likewise. * genutil.cc (get_and_check_refstart_and_reflen): Likewise. (get_depending_on_value_from_odo): Likewise. (get_data_offset): Likewise. (get_binary_value): Likewise. (process_this_exception): Likewise. (copy_little_endian_into_place): Likewise. (refer_is_clean): Likewise. (refer_fill_depends): Likewise. * genutil.h (process_this_exception): Likewise. (copy_little_endian_into_place): Likewise. (refer_is_clean): Likewise. * lexio.cc (check_push_pop_directive): Likewise. (check_source_format_directive): Likewise. (location_in): Likewise. (lexer_input): Likewise. (cdftext::lex_open): Likewise. (lexio_dialect_mf): Likewise. (valid_sequence_area): Likewise. (cdftext::free_form_reference_format): Likewise. (cdftext::segment_line): Likewise. * lexio.h (struct span_t): Likewise. * scan_ante.h (trim_location): Likewise. * symbols.cc (symbol_elem_cmp): Likewise. (symbol_alphabet): Likewise. (end_of_group): Likewise. (cbl_field_t::attr_str): Likewise. (symbols_update): Likewise. (symbol_typedef_add): Likewise. (symbol_field_add): Likewise. (new_temporary_impl): Likewise. (symbol_label_section_exists): Likewise. (symbol_program_callables): Likewise. (file_status_status_of): Likewise. * symfind.cc (is_data_field): Likewise. (finalize_symbol_map2): Likewise. (class in_scope): Likewise. (symbol_match2): Likewise. * util.cc (get_current_dir_name): Likewise. (gb4): Likewise. (class cdf_directives_t): Likewise. (cbl_field_t::report_invalid_initial_value): Likewise. (literal_subscript_oob): Likewise. (cbl_refer_t::str): Likewise. (date_time_fmt): Likewise. (class unique_stack): Likewise. (cobol_set_pp_option): Likewise. (cobol_filename): Likewise. (cobol_filename_restore): Likewise. (gcc_location_set_impl): Likewise. (ydferror): Likewise. (error_msg_direct): Likewise. (yyerror): Likewise. (cbl_unimplemented_at): Likewise. (cherry picked from commit c1be1d75126c8e946943b6dd94a3a0dea392888a) Diff: --- gcc/cobol/cobol1.cc | 8 +++-- gcc/cobol/dts.h | 2 +- gcc/cobol/except.cc | 2 +- gcc/cobol/gcobolspec.cc | 5 ++-- gcc/cobol/genapi.cc | 3 +- gcc/cobol/gengen.cc | 15 -- gcc/cobol/genmath.cc| 25 gcc/cobol/genutil.cc| 80 +++-- gcc/cobol/genutil.h | 6 ++-- gcc/cobol/lexio.cc | 31 ++- gcc/cobol/lexio.h | 4 +-- gcc/cobol/scan_ante.h | 3 +- gcc/cobol/symbols.cc| 50 ++- gcc/cobol/symfind.cc| 14 - gcc/cobol/util.cc | 79 +--- 15 files changed, 177 insertions(+), 150 deletions(-) diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index 4bd79f1f6057..3146da578998 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -357,7 +357,7 @@ cobol_langhook_handle_option (size_t scode, return true; case OPT_M: - cobol_set_pp_option('M'); +cobol_set_pp_option('M'); return true; case OPT_fstatic_call: @@ -368,16 +368,18 @@ cobol_langhook_handle_option (size_t scode, ws
[gcc r16-2617] x86: Pass -mno-80387 to compile pr121208-1(a|b).c
https://gcc.gnu.org/g:c6d1f58da7eb72e8bac307d342e4655012b36a89 commit r16-2617-gc6d1f58da7eb72e8bac307d342e4655012b36a89 Author: H.J. Lu Date: Tue Jul 29 09:11:34 2025 -0700 x86: Pass -mno-80387 to compile pr121208-1(a|b).c Pass -mno-80387 to compile pr121208-1(a|b).c to silence .../pr121208-1a.c:11:1: sorry, unimplemented: 80387 instructions aren’t allowed in a function with the ‘no_caller_saved_registers’ attribute PR target/121208 * gcc.target/i386/pr121208-1a.c (dg-options): Add -mno-80387. * gcc.target/i386/pr121208-1b.c (dg-options): Likewise. Signed-off-by: H.J. Lu Diff: --- gcc/testsuite/gcc.target/i386/pr121208-1a.c | 2 +- gcc/testsuite/gcc.target/i386/pr121208-1b.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/i386/pr121208-1a.c b/gcc/testsuite/gcc.target/i386/pr121208-1a.c index ac851cb50d86..cb8bd0bc8d28 100644 --- a/gcc/testsuite/gcc.target/i386/pr121208-1a.c +++ b/gcc/testsuite/gcc.target/i386/pr121208-1a.c @@ -1,5 +1,5 @@ /* { dg-do compile { target *-*-linux* } } */ -/* { dg-options "-O2 -fPIC -mtls-dialect=gnu" } */ +/* { dg-options "-O2 -fPIC -mno-80387 -mtls-dialect=gnu" } */ extern __thread int bar; extern void func (void); diff --git a/gcc/testsuite/gcc.target/i386/pr121208-1b.c b/gcc/testsuite/gcc.target/i386/pr121208-1b.c index b97ac715c655..037e9a0899c1 100644 --- a/gcc/testsuite/gcc.target/i386/pr121208-1b.c +++ b/gcc/testsuite/gcc.target/i386/pr121208-1b.c @@ -1,4 +1,4 @@ /* { dg-do compile { target *-*-linux* } } */ -/* { dg-options "-O2 -fPIC -mtls-dialect=gnu2" } */ +/* { dg-options "-O2 -fPIC -mno-80387 -mtls-dialect=gnu2" } */ #include "pr121208-1a.c"
[gcc(refs/users/meissner/heads/work216-bugs)] Update ChangeLog.*
https://gcc.gnu.org/g:1d88d08cff9b76f7378ed7d761c491bcb9395a4c commit 1d88d08cff9b76f7378ed7d761c491bcb9395a4c Author: Michael Meissner Date: Tue Jul 29 11:46:41 2025 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.bugs | 33 +++-- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs index 2f4f7abe9827..bb008f0db672 100644 --- a/gcc/ChangeLog.bugs +++ b/gcc/ChangeLog.bugs @@ -1,4 +1,4 @@ - Branch work216-bugs, patch #110 + Branch work216-bugs, patch #111 Fix PR 118541, do not generate floating point cmoves for IEEE compares. @@ -32,7 +32,7 @@ GCC currently generates the following code: xxsel 1,0,12,1 blr -This is because ifcvt.c optimizes the conditional floating point move to use the +This is because ifcvt.cc optimizes the conditional floating point move to use the XSCMPGTDP instruction. However, the XSCMPGTDP instruction will generate an interrupt if one of the @@ -40,7 +40,7 @@ arguments is a signalling NaN and signalling NaNs can generate an interrupt. The IEEE comparison functions (isgreater, etc.) require that the comparison not raise an interrupt. -The following patch changes the PowerPC back end so that ifcvt.c will not change +The following patch changes the PowerPC back end so that ifcvt.cc will not change the if/then test and move into a conditional move if the comparison is one of the comparisons that do not raise an error with signalling NaNs and -Ofast is not used. If a normal comparison is used or -Ofast is used, GCC will continue @@ -84,36 +84,33 @@ power11: gcc/ PR target/118541 - * config/rs6000/predicates.md (fpmask_comparison_operator): Add NE, LT, - LE. - (invert_fpmask_comparison_operator): Delete. + * config/rs6000/predicates.md (fpmask_comparison_operator): Add comments. + (invert_fpmask_comparison_operator): Delete, ifcvt.cc will handle + inverting the comparison operator. * config/rs6000/rs6000-protos.h (enum rev_cond_allowed): New enumeration. (rs6000_reverse_condition): Add argument. - * config/rs6000/rs6000.cc (rs6000_reverse_condition): Do not allow - comparisons to be reversed for floating point conditional moves that - involve IEEE comparison functions which cannot trap on signaling NaNs. - If this is a jump, we allow the comparison to be reversed. + * config/rs6000/rs6000.cc (rs6000_reverse_condition): Add argument which + controls whether comparisons can be reversed for floating point + conditional moves that involve IEEE comparison functions which cannot + trap on signaling NaNs. If this is a jump, we allow the comparison to + be reversed. (rs6000_emit_sCOND): Adjust rs6000_reverse_condition call to not allow reversing floating point comparisons that involve IEEE comparison functions. * config/rs6000/rs6000.h (REVERSE_CONDITION): Likewise. * config/rs6000/rs6000.md (movcc_invert_p9): Delete insn. - (fpmask, SFDF iterator): Allow NE, LT, and LE comparisons, - reversing the arguments and the comprison operation. (movcc_invert_p10): Delete insn. - (fpmask, IEEE128 iterator): Allow NE, LT, and LE comparisons, - reversing the arguments and the comprison operation. - (reverse_branch_comparison): Name insn. - Adjust rs6000_reverse_condition calls. + (reverse_branch_comparison): Name insn. Adjust rs6000_reverse_condition + calls. gcc/testsuite/ PR target/118541 * gcc.target/powerpc/pr118541-1.c: New test. * gcc.target/powerpc/pr118541-2.c: Likewise. - * gcc.target/powerpc/pr118541-3.c: Likewise. - * gcc.target/powerpc/pr118541-4.c: Likewise. + + Branch work216-bugs, patch #110 was reverted Branch work216-bugs, patch #102
[gcc r15-10122] cobol: Eliminate padding bytes from cbl_declarative_t. [PR119377]
https://gcc.gnu.org/g:d6da95bc4ce45e57ec47016275a2a9a12c8ef0ce commit r15-10122-gd6da95bc4ce45e57ec47016275a2a9a12c8ef0ce Author: Robert Dubner Date: Sun May 11 13:43:32 2025 -0400 cobol: Eliminate padding bytes from cbl_declarative_t. [PR119377] By changing the type of a variable in the cbl_declarative_t structure from "bool" to "uint32_t", three uninitialized padding bytes were turned into initialized bytes. This eliminates the valgrind error caused by those uninitialized values. This is an interim fix, which expediently eliminates the valgrind problem. The underlying design flaw, which involves turning a host-side C++ structure into a run-time data block, is slated for complete replacement in the next few weeks. libgcobol/ChangeLog: PR cobol/119377 * common-defs.h: (struct cbl_declaratives_t): Change "bool global" to "uint32_t global". (cherry picked from commit d7d24f9cc55d5cf0a70a984d4e63e8a307710d9e) Diff: --- libgcobol/common-defs.h | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h index 026f377e74b2..e3471c5ccc3d 100644 --- a/libgcobol/common-defs.h +++ b/libgcobol/common-defs.h @@ -458,11 +458,25 @@ struct cbl_enabled_exception_t { struct cbl_declarative_t { enum { files_max = 16 }; size_t section; // implies program - bool global; + uint32_t global; // See the note below ec_type_t type; uint32_t nfile, files[files_max]; cbl_file_mode_t mode; +/* The ::global member originally was "bool global". A bool, however, occupies +only one byte of storage. The structure, in turn, is constructed on +four-byte boundaries for members, so there were three padding bytes between +the single byte of global and the ::type member. + +When used to create a "blob", where the structure was treated as a stream +of bytes that were used to create a constructor for an array of bytes, +valgrind noticed that those three padding bytes were not initialized, and +generated the appropriate error message. This made it hard to find other +problems. + +Changing the declaration from "bool" to "uint32_t" seems to have eliminated +the valgrind error without affecting overall performance. */ + cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e ) : section(0), global(false) , type(ec_none_e)
[gcc r15-10127] Regenerate cobol/lang.opt.urls
https://gcc.gnu.org/g:d33eb8356da0b419ca57185b0b746db7a5f43862 commit r15-10127-gd33eb8356da0b419ca57185b0b746db7a5f43862 Author: Mark Wielaard Date: Sun May 18 16:20:10 2025 +0200 Regenerate cobol/lang.opt.urls The Cobol frontend lang.opt got -M added, but lang.opt.urls wasn't regenerated. Fixes: 92b6485a75ca ("cobol: Eliminate exception "blob"; streamline some code generation.") gcc/cobol/ChangeLog: * lang.opt.urls: Regenerated. (cherry picked from commit f32946cc54a7de59498b42e3450ff124dffeb2d7) Diff: --- gcc/cobol/lang.opt.urls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/cobol/lang.opt.urls b/gcc/cobol/lang.opt.urls index 69f52973c025..78fc491fa67f 100644 --- a/gcc/cobol/lang.opt.urls +++ b/gcc/cobol/lang.opt.urls @@ -10,6 +10,9 @@ UrlSuffix(gcc/Preprocessor-Options.html#index-D-1) I UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Options.html#index-I) +M +UrlSuffix(gcc/Preprocessor-Options.html#index-M) LangUrlSuffix_D(gdc/Code-Generation.html#index-M) + ffixed-form LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-ffixed-form)
[gcc r15-10143] cobol: Update test case for intrinsic function syntax.
https://gcc.gnu.org/g:1951807f10b7d5122c6f8c9817af7bd90682454a commit r15-10143-g1951807f10b7d5122c6f8c9817af7bd90682454a Author: Robert Dubner Date: Tue Jul 1 11:07:18 2025 -0400 cobol: Update test case for intrinsic function syntax. gcc/testsuite/ChangeLog: * cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob: Append INTRINSIC keyword. (cherry picked from commit 63f44b398f5938503cbd1e168bcc723697c9e9ad) Diff: --- .../cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob index b94adf580264..39a0c5b33da2 100644 --- a/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob +++ b/gcc/testsuite/cobol.dg/group2/Intrinsics_without_FUNCTION_keyword__2_.cob @@ -5,8 +5,8 @@ ENVIRONMENT DIVISION. CONFIGURATIONSECTION. REPOSITORY. - FUNCTION PI - FUNCTION E. + FUNCTION PI INTRINSIC + FUNCTION E INTRINSIC. DATA DIVISION. WORKING-STORAGE SECTION. 01 ZPIC 99V99.
[gcc r15-10134] cobol: Diagnostic messages, Flex build, and some cppcheck reports. [PR120328, PR119695]
https://gcc.gnu.org/g:cd1fd184020d319d117768f2de1500569b3b1e67 commit r15-10134-gcd1fd184020d319d117768f2de1500569b3b1e67 Author: Robert Dubner Date: Fri Jun 6 16:32:22 2025 -0400 cobol: Diagnostic messages, Flex build, and some cppcheck reports. [PR120328, PR119695] Remove %0x and similar from diagnostic framework messages. Remove %zu from printf messages because it is not supported on some platforms. Corrections in response to cppcheck. Sundry small fixes. gcc/cobol/ChangeLog: PR cobol/120328 * Make-lang.in: Success with non-English locale. PR cobol/119695 * cbldiag.h (cbl_unimplemented_at): Comment: * cdf-copy.cc (copybook_elem_t::open_file): Indentation. * cdf.y: YYABORT on certain errors. * cdfval.h (cdf_value): Const parameter. * copybook.h (class copybook_elem_t): Initialization. (class uppername_t): Explicit constructor. * except.cc (ec_type_descr): Remove %04s. (cbl_enabled_exceptions_t::dump): Remove %zu. * exceptg.h (class exception_turn_t): Explicit constructor. * genapi.cc (parser_perform_conditional): Remove %zu. (set_exception_environment): Formatting. (parser_statement_begin): Exception overhead. (parser_perform_conditional): Formatting: (parser_perform_conditional_end): Eliminate size_t. (parser_check_fatal_exception): Exception overhead. (parser_perform_conditional_end): Remove %zu. * inspect.h (struct cbx_inspect_match_t): Const reference. (struct cbx_inspect_t): Const parameter. * lexio.cc (cdftext::process_file): Remove %zu. * lexio.h (struct YYLTYPE): Remove unneeded struct. (YYLTYPE_IS_DECLARED): Likewise. (YYLTYPE_IS_TRIVIAL): Likewise. * parse.y: Comment; change DOT. * scan.l: Scan function names without swallowing whitespace. * scan_ante.h (scanner_parsing): Remove %zu. (scanner_parsing_pop): Remove %zu. (binary_integer_usage): Remove %zu. * scan_post.h (prelex): Correct post-CDF resumption. (yylex): Clearer message. * symbols.cc (symbol_table_extend): Explicit constructor. (elementize): Const parameter. (is_variable_length): Correct always-false. (symbols_update): Remove unnecessary shadow variable. (struct symbol_elem_t): Const parameter. (symbol_alphabet_add): Const parameter. (new_literal_add): Initialization. * symbols.h (class cbl_domain_elem_t): Correct assignment. (struct cbl_span_t): Improve constructor. (struct cbl_refer_t): Initialization. (struct cbl_alphabet_t): Rename shadow variable. (struct cbl_file_key_t): Remove unused constructor. (struct symbol_elem_t): Initialization. (struct cbl_until_addresses_t): Use unsigned int, for messages. (struct cbl_prog_hier_t): Initialization. (struct cbl_perform_tgt_t): Repair constructor. (struct cbl_label_t): Const parameter. (symbol_typedef_add): Const parameter. (symbol_field_add): Explicit constructor. (symbol_label_add): Explicit constructor. (symbol_program_add): Remove C-style "struct" use. (symbol_special_add): Remove C-style "struct" use. (symbol_alphabet_add): Const parameter. (symbol_file_add): Remove C-style "struct" use. (symbol_section_add): Remove C-style "struct" use. * symfind.cc: Const parameter. * util.cc (gb4): New function. * util.h (gb4): New function. * TODO: New file. libgcobol/ChangeLog: * common-defs.h (enum cbl_file_mode_t): Whitespace. (enum file_stmt_t): Likewise. (ec_cmp): Likewise. (struct cbl_declarative_t): Add "explicit" keyword. (class cbl_enabled_exceptions_t): Whitespace. * gfileio.cc: Remove cppcheck comment. * libgcobol.cc (class ec_status_t): Add "explicit" keyword. (match_declarative): Remove %zu. (default_exception_handler): Likwise. (__gg__check_fatal_exception): Exception overhead. (__gg__exception_push): Remove %zu. (__gg__exception_pop): Likewise. (cbl_enabled_exception_t::dump): Likewise. (__gg__match_exception): Exception overhead; remove %zu. (cbl_enabled_exceptions_t::dump): Remove %zu. (__gg__set_exception_environment): Likewise. Co-authored-by: James K. Lowden Co-authored-by: Robert Dubner (cherry picked from commit 37f5fdd008399c239e0689f2e864519505c78c7e) Diff: --- gcc/cobol/Make-lang.in | 3
[gcc r15-10151] cobol: Improved linemap and diagnostic handling; PIC validation. [PR120402]
https://gcc.gnu.org/g:84296ba2a410193f795456392ca96718af7166b6 commit r15-10151-g84296ba2a410193f795456392ca96718af7166b6 Author: Robert Dubner Date: Mon Jul 21 12:58:47 2025 -0400 cobol: Improved linemap and diagnostic handling; PIC validation. [PR120402] Implementation of PICTURE string validation for PR120402. Expanded some printf format attributes. Improved debugging and diagnostic messages. Improved linemap and line location tracking in support of diagnostic messages and location_t tagging of GENERIC nodes for improved GDB-COBOL performance. Assorted changes to eliminate cppcheck warnings. Co-Authored-By: James K. Lowden Co-Authored-By: Robert Dubner gcc/cobol/ChangeLog: PR cobol/120402 * Make-lang.in: Elminate commented-out scripting. * cbldiag.h (_CBLDIAG_H): Change #if 0 to #if GCOBOL_GETENV (warn_msg): Add printf attributes. (location_dump): Add debugging message. * cdf.y: Improved linemap tracking. * genapi.cc (treeplet_fill_source): const attribute for formal parameter. (insert_nop): Created to consolidate var_decl_nop writes. (build_main_that_calls_something): Move generation to the end of executable. (level_88_helper): Formatting. (parser_call_targets_dump): Formatting. (function_pointer_from_name): const attribute for formal parameter. (parser_initialize_programs): const attribute for formal parameter. (parser_statement_begin): Improved linemap handling. (section_label): Improved linemap handling. (paragraph_label): Improved linemap handling. (pseudo_return_pop): Improved linemap handling. (leave_procedure): Formatting. (parser_enter_section): Improved linemap handling. (parser_enter_paragraph): Improved linemap handling. (parser_perform): Formatting. (parser_leave_file): Move creation of main() to this routine. (parser_enter_program): Move creation of main from here to leave_file. (parser_accept): Formatting. const attribute for formal parameter. (parser_accept_command_line): const attribute for formal parameter. (parser_accept_command_line_count): const attribute for formal parameter. (parser_accept_envar): Likewise. (parser_set_envar): Likewise. (parser_display): Likewise. (get_exhibit_name): Implement EXHIBIT verb. (parser_exhibit): Likewise. (parser_sleep): const attribute for formal parameter. (parser_division): Improved linemap handling. (parser_classify): const attribute for formal parameter. (create_iline_address_pairs): Improved linemap handling. (parser_perform_start): Likewise. (perform_inline_until): Likewise. (perform_inline_testbefore_varying): Likewise. (parser_perform_until): Likewise. (parser_perform_inline_times): Likewise. (parser_intrinsic_subst): const attribute for formal parameter. (parser_file_merge): Formatting. (create_and_call): Improved linemap handling. (mh_identical): const attribute for formal parameter. (mh_numeric_display): const attribute for formal parameter. (mh_little_endian): Likewise. (mh_source_is_group): Likewise. (psa_FldLiteralA): Formatting. * genapi.h (parser_accept): const attribute for formal parameter. (parser_accept_envar): Likewise. (parser_set_envar): Likewise. (parser_accept_command_line): Likewise. (parser_accept_command_line_count): Likewise. (parser_add): Likewise. (parser_classify): Likewise. (parser_sleep): Likewise. (parser_exhibit): Likewise. (parser_display): Likewise. (parser_initialize_programs): Likewise. (parser_intrinsic_subst): Likewise. * gengen.cc (gg_assign): Improved linemap handling. (gg_add_field_to_structure): Likewise. (gg_define_from_declaration): Likewise. (gg_build_relational_expression): Likewise. (gg_goto_label_decl): Likewise. (gg_goto): Likewise. (gg_printf): Likewise. (gg_fprintf): Likewise. (gg_memset): Likewise. (gg_memchr): Likewise. (gg_memcpy): Likewise. (gg_memmove): Likewise. (gg_strcpy): Likewise. (gg_strcmp): Likewise. (gg_strncmp): Likewise. (gg_return): Likewise. (chain_parameter_to_function): Likewise. (gg_define_function): Likewise. (gg_get_function_decl): Likewise. (gg_call_expr): Lik
[gcc r15-10149] cobol: Minor changes to genapi.cc to eliminate CPPCHECK warnings.
https://gcc.gnu.org/g:7dc3a3720cdf1b467f9a8ed92d4cbb7cf657ef54 commit r15-10149-g7dc3a3720cdf1b467f9a8ed92d4cbb7cf657ef54 Author: Robert Dubner Date: Fri Jul 11 17:11:21 2025 -0400 cobol: Minor changes to genapi.cc to eliminate CPPCHECK warnings. Several hundred cppcheck warnings were eliminated. Most of these changes were replacing C-style casts, checking for NULL pointers, establishing some variables and formal parameters as const, and moving some variables around to tidy up their scopes. One memory leak was found and eliminated as a result of the cppcheck. gcc/cobol/ChangeLog: * Make-lang.in: Eliminate the .cc.o override. * genapi.cc (level_88_helper): Eliminate cppcheck warning. (get_level_88_domain): Likewise. (get_class_condition_string): Likewise. (parser_call_targets_dump): Likewise. (parser_compile_ecs): Likewise. (initialize_variable_internal): Likewise. (move_tree): Likewise. (combined_name): Likewise. (assembler_label): Likewise. (find_procedure): Likewise. (parser_perform): Likewise. (parser_perform_times): Likewise. (internal_perform_through): Likewise. (internal_perform_through_times): Likewise. (psa_FldLiteralN): Likewise. (psa_FldBlob): Likewise. (parser_accept): Likewise. (parser_accept_exception): Likewise. (parser_accept_exception_end): Likewise. (parser_accept_command_line): Likewise. (parser_accept_envar): Likewise. (parser_display_internal): Likewise. (parser_display): Likewise. (parser_assign): Likewise. (parser_initialize_table): Likewise. (parser_arith_error): Likewise. (parser_arith_error_end): Likewise. (parser_division): Likewise. (label_fetch): Likewise. (parser_label_label): Likewise. (parser_label_goto): Likewise. (parser_perform_start): Likewise. (parser_perform_conditional): Likewise. (parser_perform_conditional_end): Likewise. (parser_perform_until): Likewise. (parser_file_delete): Likewise. (parser_intrinsic_subst): Likewise. (create_lsearch_address_pairs): Likewise. (parser_bsearch_start): Likewise. (is_ascending_key): Likewise. (parser_sort): Likewise. (parser_file_sort): Likewise. (parser_return_start): Likewise. (parser_file_merge): Likewise. (parser_string_overflow): Likewise. (parser_unstring): Likewise. (parser_string): Likewise. (parser_call_exception): Likewise. (create_and_call): Likewise. (mh_identical): Likewise. (move_helper): Likewise. (binary_initial_from_float128): Likewise. (initial_from_initial): Likewise. (psa_FldLiteralA): Likewise. (parser_local_add): Likewise. (parser_symbol_add): Likewise. * genapi.h (parser_display): Likewise. * gengen.cc (gg_call_expr): Explict check for NULL_TREE. (gg_call): Likewise. * show_parse.h (SHOW_PARSE_LABEL_OK): Likewise. (TRACE1_FIELD_VALUE): Likewise. (CHECK_FIELD): Likewise. (CHECK_FIELD2): Likewise. (CHECK_LABEL): Likewise. * util.cc (cbl_internal_error): Apply [[noreturn]] attribute. * util.h (cbl_internal_error): Likewise. libgcobol/ChangeLog: * common-defs.h (PTRCAST): Moved here from libgcobol.h. * libgcobol.h (PTRCAST): Deleted. (cherry picked from commit 9b9753718e202073a3343d196a2eae13df80f408) Diff: --- gcc/cobol/Make-lang.in | 28 +--- gcc/cobol/genapi.cc | 433 +--- gcc/cobol/genapi.h | 4 +- gcc/cobol/gengen.cc | 4 +- gcc/cobol/show_parse.h | 49 +- gcc/cobol/util.cc | 2 + gcc/cobol/util.h| 2 +- libgcobol/common-defs.h | 8 + libgcobol/libgcobol.h | 7 - 9 files changed, 334 insertions(+), 203 deletions(-) diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index ee494b86f0cc..22de3b15bdea 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -385,22 +385,12 @@ selftest-cobol: lang_checks += check-cobol -# -# Front-end specific flags: Originally done for the COBOL front end, this -# scripting applies CXXFLAGS_FOR_COBOL only to compilations of source code in the -# gcc/cobol source code tree. Both forms can be used: -# -# CXXFLAGS_FOR_COBOL=xxx ../configure --enable-languages= -# and -# make CXXFLAGS_FOR_COBOL=yyy -# -# The second form overrides the first. -# -# To
[gcc r15-10140] cobol: Correct diagnostic strings for 32-bit builds.
https://gcc.gnu.org/g:9717324b7e867460f0e4023b12ad4a9d3633d889 commit r15-10140-g9717324b7e867460f0e4023b12ad4a9d3633d889 Author: James K. Lowden Date: Fri Jun 20 12:43:51 2025 -0400 cobol: Correct diagnostic strings for 32-bit builds. Avoid %z for printf-family. Cast pid_t to long. Avoid use of YYUNDEF for old Bison versions. PR cobol/120621 gcc/cobol/ChangeLog: * genapi.cc (parser_compile_ecs): Cast argument to unsigned long. (parser_compile_dcls): Same. (parser_division): RAII. (inspect_tally): Cast argument to unsigned long. * lexio.cc (cdftext::lex_open): Cast pid_t to long. * parse.y: hard-code values for old versions of Bison, and message format. * scan_ante.h (wait_for_the_child): Cast pid_t to long. (cherry picked from commit 007392c0f93cf46b9e87aebdd04e123e3381fc07) Diff: --- gcc/cobol/genapi.cc | 25 + gcc/cobol/lexio.cc| 6 +++--- gcc/cobol/parse.y | 8 gcc/cobol/scan_ante.h | 9 ++--- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 0ea41f167afa..42f1599a87f6 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -957,8 +957,8 @@ parser_compile_ecs( const std::vector& ecs ) { SHOW_PARSE_HEADER char ach[64]; -snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", - ecs.size(), as_voidp(retval)); +snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(ecs.size()), as_voidp(retval)); SHOW_PARSE_TEXT(ach) SHOW_PARSE_END } @@ -966,8 +966,8 @@ parser_compile_ecs( const std::vector& ecs ) { TRACE1_HEADER char ach[64]; -snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", - ecs.size(), as_voidp(retval)); +snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(ecs.size()), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -1006,8 +1006,8 @@ parser_compile_dcls( const std::vector& dcls ) { SHOW_PARSE_HEADER char ach[64]; -snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", - dcls.size(), as_voidp(retval)); +snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(dcls.size()), as_voidp(retval)); SHOW_PARSE_TEXT(ach); SHOW_PARSE_END } @@ -1015,8 +1015,8 @@ parser_compile_dcls( const std::vector& dcls ) { TRACE1_HEADER char ach[64]; -snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", - dcls.size(), as_voidp(retval)); +snprintf(ach, sizeof(ach), " Size is %lu; retval is %p", + gb4(dcls.size()), as_voidp(retval)); TRACE1_TEXT_ABC("", ach, ""); TRACE1_END } @@ -6898,7 +6898,7 @@ parser_division(cbl_division_t division, // There are 'nusing' elements in the PROCEDURE DIVISION USING list. - tree parameter; + tree parameter = NULL_TREE; tree rt_i = gg_define_int(); for(size_t i=0; i(pid)); if( WIFSIGNALED(status) ) { - cbl_errx( "%s pid %d terminated by %s", - filter, kid, strsignal(WTERMSIG(status)) ); + cbl_errx( "%s pid %ld terminated by %s", +filter, static_cast(kid), strsignal(WTERMSIG(status)) ); } if( WIFEXITED(status) ) { if( (status = WEXITSTATUS(status)) != 0 ) { diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 99295e8db3e3..f0faaa415776 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -11409,8 +11409,8 @@ keyword_str( int token ) { switch( token ) { case YYEOF: return "YYEOF"; case YYEMPTY: return "YYEMPTY"; - case YYerror: return "YYerror"; - case YYUNDEF: return "invalid token"; + case 256: return "YYerror"; + case 257: return "invalid token"; // YYUNDEF } if( token < 256 ) { @@ -12359,7 +12359,7 @@ numstr2i( const char input[], radix_t radix ) { return output; } if( erc == -1 ) { -yywarn("'%s' was accepted as %wd", input, integer); +yywarn("'%s' was accepted as %zu", input, integer); } return output; } @@ -13141,7 +13141,7 @@ literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) { // X(0): subscript 1 of for out of range for 02 X OCCURS 4 to 6 error_msg(loc, "%s(%s): subscript %zu out of range " - "for %s %s OCCURS %lu%s", + "for %s %s OCCURS %zu%s", oob->name, subscript_names.c_str(), 1 + isub, oob->level_str(), oob->name, oob->occurs.bounds.lower, upper_phrase ); diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index 037c929aff33..96b688e75128 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -824,17 +824,20 @@ wait_for_the_child(void) { } if( WIFSIGNALED(status) ) { -yywarn( "process %d terminated by %s", pid, strsignal(WTERMS
[gcc r15-10131] cobol: Honor HAVE_CLOCK_GETTIME and HAVE_GETTIMEOFDAY. [PR119975]
https://gcc.gnu.org/g:c48cce8872c3b66f28727b8dee8349ec72e1f234 commit r15-10131-gc48cce8872c3b66f28727b8dee8349ec72e1f234 Author: Robert Dubner Date: Mon Jun 2 15:55:20 2025 -0400 cobol: Honor HAVE_CLOCK_GETTIME and HAVE_GETTIMEOFDAY. [PR119975] These changes cause genapi.cc to use whichever of clock_gettime() or gettimeofday() are available. This prevents compilation errors on systems where clock_gettime() is not available. gcc/cobol/ChangeLog: PR cobol/119975 * genapi.cc (parser_intrinsic_call_0): Use get_time_64() function. * genutil.cc (get_time_64): Definition created. * genutil.h (get_time_64): Declaration created. (cherry picked from commit 8fc9e03a70fd08b54449b05833b00e7f8ad01c25) Diff: --- gcc/cobol/genapi.cc | 4 +++- gcc/cobol/genutil.cc | 23 +++ gcc/cobol/genutil.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 2ce9cad5c0d6..5e983ab503c2 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -10491,7 +10491,9 @@ parser_intrinsic_call_0(cbl_field_t *tgt, { // Pass __gg__when_compiled() the time from right now. struct timespec tp; -clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec +uint64_t now = get_time_64(); +tp.tv_sec = now / 10; +tp.tv_nsec = now % 10; store_location_stuff(function_name); gg_call(VOID, diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index d0aaf2b3215f..e971043164c7 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -2119,3 +2119,26 @@ qualified_data_location(cbl_refer_t &refer) return gg_add(member(refer.field->var_decl_node, "data"), refer_offset(refer)); } + +uint64_t +get_time_64() +{ + // This code was unabashedly stolen from gcc/timevar.cc. + // It returns the Unix epoch with nine decimal places. + + uint64_t retval = 0; + +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; + clock_gettime (CLOCK_REALTIME, &ts); + retval = ts.tv_sec * 10 + ts.tv_nsec; + return retval; +#endif +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + gettimeofday (&tv, NULL); + retval = tv.tv_sec * 10 + tv.tv_usec * 1000; + return retval; +#endif + return retval; +} \ No newline at end of file diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h index 2f4bc36eace7..43102d7cc544 100644 --- a/gcc/cobol/genutil.h +++ b/gcc/cobol/genutil.h @@ -155,4 +155,7 @@ void build_array_of_fourplets( int ngroup, size_t N, cbl_refer_t *refers); void get_depending_on_value_from_odo(tree retval, cbl_field_t *odo); +uint64_t get_time_64(); + + #endif
[gcc r15-10152] cobol: Tweak adjustments to location_t of GENERIC nodes for PERFORM.
https://gcc.gnu.org/g:0879a2a840c9209b3bf54e2dc40355c263f28924 commit r15-10152-g0879a2a840c9209b3bf54e2dc40355c263f28924 Author: Robert Dubner Date: Wed Jul 23 08:44:54 2025 -0400 cobol: Tweak adjustments to location_t of GENERIC nodes for PERFORM. COBOL has a group of PERFORM statements that require careful adjustments to the location_t elements of the GENERIC nodes so that the COBOL-aware version of GDB behaves properly. These changes are in service of that goal. gcc/cobol/ChangeLog: * genapi.cc (leave_procedure): Adjust location_t for PERFORM. (parser_perform_times): Likewise. (internal_perform_through_times): Likewise. (perform_outofline_before_until): Likewise. (perform_outofline_after_until): Likewise. (perform_outofline_testafter_varying): Likewise. (perform_outofline_before_varying): Likewise. (cherry picked from commit 3cc2116fe6694b0e52855427fc1fd1335c6d00b6) Diff: --- gcc/cobol/genapi.cc | 7 +++ 1 file changed, 7 insertions(+) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 52e75e583556..666802ea137e 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -2858,6 +2858,7 @@ leave_procedure(struct cbl_proc_t *procedure, bool /*section*/) char *psz; psz = xasprintf("_procret." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)symbol_label_id(procedure->label)); +token_location_override(current_location_minus_one()); gg_insert_into_assembler(psz); free(psz); pseudo_return_pop(procedure); @@ -3445,6 +3446,7 @@ parser_perform_times( cbl_label_t *proc_1, cbl_refer_t count ) sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler(ach); } @@ -3598,6 +3600,7 @@ internal_perform_through_times( cbl_label_t *proc_1, sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler( ach ); } @@ -8440,6 +8443,7 @@ perform_outofline_before_until(struct cbl_perform_tgt_t *tgt, sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler( ach ); } @@ -8503,6 +8507,7 @@ perform_outofline_after_until(struct cbl_perform_tgt_t *tgt, sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler( ach ); } @@ -8623,6 +8628,7 @@ perform_outofline_testafter_varying(struct cbl_perform_tgt_t *tgt, sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler( ach ); } @@ -8766,6 +8772,7 @@ perform_outofline_before_varying( struct cbl_perform_tgt_t *tgt, sprintf(ach, "_procretb." HOST_SIZE_T_PRINT_DEC ":", (fmt_size_t)our_pseudo_label); + token_location_override(current_location_minus_one()); gg_insert_into_assembler( ach ); }
[gcc r15-10138] cobol: Correct diagnostic strings to rectify bootstrap build
https://gcc.gnu.org/g:efc75cbe390a83dbf7bfe9d90dd16dfc030cead4 commit r15-10138-gefc75cbe390a83dbf7bfe9d90dd16dfc030cead4 Author: James K. Lowden Date: Tue Jun 17 18:31:33 2025 -0400 cobol: Correct diagnostic strings to rectify bootstrap build Apply patch from Jakub to enable diagnostics. Use %<%> and %qs liberally. PR cobol/120621 gcc/cobol/ChangeLog: * cbldiag.h (yyerror): Add diagnostic attributes. (yywarn): Same. (error_msg): Same. (yyerrorvl): Same. (cbl_unimplementedw): Same. (cbl_unimplemented): Same. (cbl_unimplemented_at): Same. * cdf-copy.cc (copybook_elem_t::open_file): Supply string argument. * cdf.y: Use %<%>. * cobol-system.h (if): Check GCC_VERSION. (ATTRIBUTE_GCOBOL_DIAG): Define. * except.cc (cbl_enabled_exception_t::dump): Remove extra %s. * genapi.cc (get_class_condition_string): Use acceptable message. (get_bytes_needed): Same. (move_tree): Same. (get_string_from): Same. (internal_perform_through): Same. (tree_type_from_field_type): Same. (is_valuable): Same. (parser_logop): Same. (parser_relop): Same. (parser_relop_long): Same. (parser_if): Same. (parser_setop): Same. (parser_perform_conditional): Same. (parser_file_add): Same. (parser_file_open): Same. (parser_file_close): Same. (parser_file_read): Same. (parser_file_write): Same. (inspect_replacing): Same. (parser_sort): Same. (parser_file_sort): Same. (parser_file_merge): Same. (create_and_call): Same. (parser_bitop): Same. (parser_bitwise_op): Same. (hijack_for_development): Same. (mh_source_is_literalN): Same. (mh_dest_is_float): Same. (parser_symbol_add): Same. * gengen.cc (show_type): Use acceptable message. (gg_find_field_in_struct): Same. (gg_declare_variable): Same. (gg_printf): Same. (gg_fprintf): Same. (gg_tack_on_function_parameters): Same. (gg_define_function): Same. (gg_get_function_decl): Same. (gg_finalize_function): Same. (gg_call_expr): Same. (gg_call): Same. (gg_insert_into_assembler): Define new function. (gg_insert_into_assemblerf): Use gg_insert_into_assembler(). * gengen.h (gg_insert_into_assembler): Simpler function declaration. (gg_insert_into_assemblerf): Declare new function. * genmath.cc (parser_op): Use acceptable message. * genutil.cc (get_binary_value): Use acceptable message. * lexio.cc (parse_replacing_pair): Correct diagnostic arguments. (preprocess_filter_add): Same. (cdftext::open_input): Same. * parse.y: Use acceptable messages. * parse_ante.h (struct evaluate_elem_t): Use %<%>. (is_callable): Same. * parse_util.h (intrinsic_invalid_parameter): Use %qs. * scan.l: Use dialect_error(). * scan_ante.h (numstr_of): Use %qs. (scanner_token): Quote COBOL tokens in messages. (scanner_parsing): Correct diagnostic message. (scanner_parsing_toggle): Quote COBOL tokens in messages. (scanner_parsing_pop): Same. (typed_name): Use %qs. * scan_post.h (prelex): Quote COBOL tokens in message. * show_parse.h (CHECK_FIELD): Use acceptable message format. (CHECK_LABEL): Same. * symbols.cc (symbol_field_same_as): Remove extra spaces. (cbl_alphabet_t::assign): Use %<%>. (cbl_field_t::internalize): Quote library name in message. * symbols.h (struct os_locale_t): Constify codeset. (class temporaries_t): Add copy constructor. (struct cbl_alphabet_t): Use acceptable message. * util.cc (symbol_type_str): Use cbl_internal_error. (cbl_field_type_str): Same. (is_elementary): Same. (cbl_field_t::report_invalid_initial_value): Use %qs. (class unique_stack): Avoid %m. (ydferror): Declare function with attributes. (error_msg): Same. (cobol_fileline_set): Use %<%>. (os_locale_t): Remove use of xstrdup. (cobol_parse_files): Quote C names in message. (dialect_error): Use %<%>. * util.h (cbl_message): Add attributes. (cbl_internal_error): Same. (cbl_err): Same. (cbl_errx): Same. (cherry picked from commit 14b8f077e4409ca0d188f0ed55891a18ba2ecd7d) Di
[gcc r15-10133] cobol: Guard clock_gettime(). [PR119975]
https://gcc.gnu.org/g:6c214d4e458afd628c6e511df8a6cc1e5f4ab776 commit r15-10133-g6c214d4e458afd628c6e511df8a6cc1e5f4ab776 Author: Robert Dubner Date: Thu Jun 5 10:53:02 2025 -0400 cobol: Guard clock_gettime(). [PR119975] This attempts to eliminate "'clock_gettime' not declared..." when building on x86_64-apple-darwin15.6.0. Calls to clock_gettime have been reduced to two locations. Both have been guarded with gcc/cobol/ChangeLog: PR cobol/119975 * genapi.cc (parser_intrinsic_call_0): Use get_time_nanoseconds(). * genutil.cc (get_time_64): Rename to get_time_nanoseconds(). (get_time_nanoseconds): Likewise. * genutil.h (get_time_64): Likewise. (get_time_nanoseconds): Likewise. * util.cc (class cbl_timespec): Timing routine uses get_time_nanoseconds(). (operator-): Likewise. (parse_file): Likewise. libgcobol/ChangeLog: PR cobol/119975 * configure.ac: AC_CHECK_LIB(rt, clock_gettime). * config.h.in: Likewise. * configure: Likewise. * gfileio.cc: Remove in-line cppcheck-suppress. * intrinsic.cc (timespec_to_string): Use guarded clock_gettime(). (__gg__current_date): Likewise. (__gg__seconds_past_midnight): Likewise. (__gg__formatted_current_date): Likewise. (__gg__random): Likewise. (__gg__random_next): Likewise. (__gg__when_compiled): Likewise. * libgcobol.cc (cobol_time): Likewise. (get_time_nanoseconds): Likewise. (__gg__clock_gettime): Likewise. (__gg__get_date_hhmmssff): Likewise. * libgcobol.h (__gg__clock_gettime): Likewise. (struct cbl_timespec): Likewise. (cherry picked from commit 2e334900f4ddcd804e3b324402544a572d306ab6) Diff: --- gcc/cobol/genapi.cc| 2 +- gcc/cobol/genutil.cc | 2 +- gcc/cobol/genutil.h| 2 +- gcc/cobol/util.cc | 19 +- libgcobol/config.h.in | 3 +++ libgcobol/configure| 53 ++ libgcobol/configure.ac | 11 +++ libgcobol/gfileio.cc | 2 -- libgcobol/intrinsic.cc | 14 ++--- libgcobol/libgcobol.cc | 34 libgcobol/libgcobol.h | 10 +- 11 files changed, 130 insertions(+), 22 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 5e983ab503c2..bde8151ece79 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -10491,7 +10491,7 @@ parser_intrinsic_call_0(cbl_field_t *tgt, { // Pass __gg__when_compiled() the time from right now. struct timespec tp; -uint64_t now = get_time_64(); +uint64_t now = get_time_nanoseconds(); tp.tv_sec = now / 10; tp.tv_nsec = now % 10; diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index e971043164c7..f1098f02768e 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -2121,7 +2121,7 @@ qualified_data_location(cbl_refer_t &refer) } uint64_t -get_time_64() +get_time_nanoseconds() { // This code was unabashedly stolen from gcc/timevar.cc. // It returns the Unix epoch with nine decimal places. diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h index 43102d7cc544..fb582e5a493f 100644 --- a/gcc/cobol/genutil.h +++ b/gcc/cobol/genutil.h @@ -155,7 +155,7 @@ void build_array_of_fourplets( int ngroup, size_t N, cbl_refer_t *refers); void get_depending_on_value_from_odo(tree retval, cbl_field_t *odo); -uint64_t get_time_64(); +uint64_t get_time_nanoseconds(); #endif diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 75a0b26c0a91..e92f069bee1b 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -65,6 +65,7 @@ #include "inspect.h" #include "../../libgcobol/io.h" #include "genapi.h" +#include "genutil.h" #pragma GCC diagnostic ignored "-Wunused-result" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" @@ -2141,22 +2142,25 @@ cobol_fileline_set( const char line[] ) { return file.name; } +//#define TIMING_PARSE +#ifdef TIMING_PARSE class cbl_timespec { - struct timespec now; + uint64_t now; // Nanoseconds public: cbl_timespec() { -clock_gettime(CLOCK_MONOTONIC, &now); +now = get_time_nanoseconds(); } double ns() const { -return now.tv_sec * 10 + now.tv_nsec; +return now; } friend double operator-( const cbl_timespec& now, const cbl_timespec& then ); }; double -operator-( const cbl_timespec& then, const cbl_timespec& now ) { +operator-( const cbl_timespec& now, const cbl_timespec& then ) { return (now.ns() - then.ns()) / 10; } +#endif static int parse_file( const char filename[] ) @@ -2172,15 +2176,20 @@ parse_file( const char filenam
[gcc r15-10153] cobol: Honor the "-static" command-line option. [PR119231]
https://gcc.gnu.org/g:4e568451bface5d15fc0bb28bc6794612f32677c commit r15-10153-g4e568451bface5d15fc0bb28bc6794612f32677c Author: Robert Dubner Date: Thu Jul 24 12:09:36 2025 -0400 cobol: Honor the "-static" command-line option. [PR119231] gcc/cobol/ChangeLog: PR cobol/119231 * gcobolspec.cc: (lang_specific_driver): Pass OPT_static through. Handle -static and -static-libgcobol properly. gcc/testsuite/ChangeLog: * cobol.dg/group2/_-static__compilation.cob: Modify for -static warning. * cobol.dg/group2/_-static__compilation.out: Removed. (cherry picked from commit 44e32178031e89399710c3ee7444891631a9c8ec) Diff: --- gcc/cobol/gcobolspec.cc | 13 +++-- gcc/testsuite/cobol.dg/group2/_-static__compilation.cob | 4 ++-- gcc/testsuite/cobol.dg/group2/_-static__compilation.out | 2 -- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gcc/cobol/gcobolspec.cc b/gcc/cobol/gcobolspec.cc index 9532d4256b22..2f3092da5d85 100644 --- a/gcc/cobol/gcobolspec.cc +++ b/gcc/cobol/gcobolspec.cc @@ -478,7 +478,10 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, break; #endif case OPT_static: +#if defined (HAVE_LD_STATIC_DYNAMIC) +append_arg(decoded_options[i]); static_in_general = true; +#endif break; default: @@ -506,17 +509,23 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, need_libgcobol = false; } + if( static_in_general ) +{ +// These two options interfere with each other. +static_libgcobol = false; +} + if( need_libgcobol ) { add_arg_lib(COBOL_LIBRARY, static_libgcobol); } if( need_libdl ) { -add_arg_lib(DL_LIBRARY, static_in_general); +add_arg_lib(DL_LIBRARY, false); } if( need_libstdc ) { -add_arg_lib(STDCPP_LIBRARY, static_in_general); +add_arg_lib(STDCPP_LIBRARY, false); } if( prior_main ) diff --git a/gcc/testsuite/cobol.dg/group2/_-static__compilation.cob b/gcc/testsuite/cobol.dg/group2/_-static__compilation.cob index 7843d3d27aac..f344a84c3988 100644 --- a/gcc/testsuite/cobol.dg/group2/_-static__compilation.cob +++ b/gcc/testsuite/cobol.dg/group2/_-static__compilation.cob @@ -1,7 +1,7 @@ *> { dg-do run } *> { dg-options "-static" } - *> { dg-output-file "group2/_-static__compilation.out" } - + *> { dg-prune-output {warning} } + *> { dg-output {hello, world} } IDENTIFICATION DIVISION. PROGRAM-ID. prog. PROCEDURE DIVISION. diff --git a/gcc/testsuite/cobol.dg/group2/_-static__compilation.out b/gcc/testsuite/cobol.dg/group2/_-static__compilation.out deleted file mode 100644 index ae0e5111caef.. --- a/gcc/testsuite/cobol.dg/group2/_-static__compilation.out +++ /dev/null @@ -1,2 +0,0 @@ -hello, world -
[gcc r15-10135] cobol: Variety of small changes in answer to cppcheck diagnostics.
https://gcc.gnu.org/g:f79a7d0f7b3f79c8e234ca870c0abf5b3101368e commit r15-10135-gf79a7d0f7b3f79c8e234ca870c0abf5b3101368e Author: James K. Lowden Date: Tue Jun 10 10:34:28 2025 -0400 cobol: Variety of small changes in answer to cppcheck diagnostics. Remove non-ASCII input and blank lines from gcobol.1. Restrict cobol.clean target to compiler object files. gcc/cobol/ChangeLog: * Make-lang.in: cobol.clean does not remove libgcobol files. * cdf.y: Suppress 1 cppcheck false positive. * cdfval.h (scanner_parsing): Partial via cppcheck for PR119324. * gcobol.1: Fix groff errors. * gcobolspec.cc (append_arg): Const parameter. * parse_ante.h (intrinsic_call_2): Avoid NULL dereference. (cherry picked from commit 70c3dd9a81cdefcaf24a66ec0c1ceddf5d3984dd) Diff: --- gcc/cobol/Make-lang.in | 3 +-- gcc/cobol/cdf.y | 1 + gcc/cobol/cdfval.h | 8 gcc/cobol/gcobol.1 | 12 +--- gcc/cobol/gcobolspec.cc | 2 +- gcc/cobol/parse_ante.h | 2 +- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in index 993e4c6ffb02..5f293e1f9874 100644 --- a/gcc/cobol/Make-lang.in +++ b/gcc/cobol/Make-lang.in @@ -351,8 +351,7 @@ cobol.srcman: cobol.mostlyclean: cobol.clean: - rm -fr gcobol cobol1 cobol/*\ - ../*/libgcobol/* + rm -fr gcobol cobol1 cobol/* cobol.distclean: diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index 0440d0216af9..e4d2feaaf52e 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -891,6 +891,7 @@ verify_integer( const YDFLTYPE& loc, const cdfval_base_t& val ) { return true; } +// cppcheck-suppress returnTempReference const cdfval_base_t& cdfval_base_t::operator()( const YDFLTYPE& loc ) { static cdfval_t zero(0); diff --git a/gcc/cobol/cdfval.h b/gcc/cobol/cdfval.h index 09c21ab08e50..c4387b080661 100644 --- a/gcc/cobol/cdfval.h +++ b/gcc/cobol/cdfval.h @@ -38,6 +38,14 @@ bool scanner_parsing(); +/* cdfval_base_t has no constructor because otherwise: + * cobol/cdf.h:172:7: note: ‘YDFSTYPE::YDFSTYPE()’ is implicitly deleted + * because the default definition would be ill-formed: + * 172 | union YDFSTYPE + * + * We use the derived type cdfval_t, which can be properly constructed and + * operated on, but tell Bison only about its POD base class. + */ struct YDFLTYPE; struct cdfval_base_t { bool off; diff --git a/gcc/cobol/gcobol.1 b/gcc/cobol/gcobol.1 index 0ce890e97229..6db54009fcf7 100644 --- a/gcc/cobol/gcobol.1 +++ b/gcc/cobol/gcobol.1 @@ -39,7 +39,7 @@ compiles \*[lang] source code to object code, and optionally produces an executable binary or shared object. As a GCC component, it accepts all options that affect code-generation and linking. Options specific to \*[lang] are listed below. -.Bl -tag -width \0\0debug +.Bl -tag -width "\0\0debug" .It Fl main Ar filename .Nm will generate a @@ -197,14 +197,12 @@ Otherwise, columns 1-6 are examined. If those characters are all digits or blanks, the file is assumed to be in .Em "fixed-form reference format", also with the indicator in column 7. - If not auto-detected as .Em "fixed-form reference format" or .Em "extended source format", the file is assumed to be in .Em "free-form reference format". - .Pp . .It Fl fcobol-exceptions Ar exception Op Ns , Ns Ar exception Ns ... @@ -1088,7 +1086,7 @@ the directive must appear before .Pp To test a feature-set variable, use .Dl >>IF Ar feature Li DEFINED -.. +. .Ss Copybooks .Nm supports the CDF @@ -1294,7 +1292,7 @@ stores and converts numbers. Converting the floating-point value to the numeric display value 0055110 is done by multiplying 55.10...\& by 1,000 and then truncating the result to an integer. And it turns out that even -though 55.11 can’t be represented in floating-point as an exact value, +though 55.11 can't be represented in floating-point as an exact value, the product of the multiplication, 55110, is an exact value. .Pp In cases where it is important for conversions to have predictable @@ -1325,7 +1323,7 @@ specified for a calculation, then the intermediate result becomes a . .Ss A warning about binary floating point comparison The cardinal rule when doing comparisons involving floating-point -values: Never, ever, test for equality. It’s just not worth the hassle. +values: Never, ever, test for equality. It's just not worth the hassle. .Pp For example: .Bd -literal @@ -1361,7 +1359,7 @@ and you really test the code. And then avoid it anyway. .Pp Finally, it is observably the case that the .Nm -implementations of floating-point conversions and comparisons don’t +implementations of floating-point conversions and comparisons don't precisely match the behavior of other \*[lang] compilers. .Pp You have been warned. diff --git a/gcc/cobol/gcobolspec.cc b/gcc/cobol/gcobolspec.cc index d
[gcc r16-2602] testsuite: Fix C++14 test failure with modules test [PR121285]
https://gcc.gnu.org/g:3f2ff7b106b2de44839979f622c669155bdb340a commit r16-2602-g3f2ff7b106b2de44839979f622c669155bdb340a Author: Nathaniel Shead Date: Tue Jul 29 21:20:03 2025 +1000 testsuite: Fix C++14 test failure with modules test [PR121285] I hadn't validated this test worked in C++14 before submitting, fixed thusly. PR testsuite/121285 gcc/testsuite/ChangeLog: * g++.dg/modules/class-11_a.H: Make static_asserts valid for C++14. Signed-off-by: Nathaniel Shead Diff: --- gcc/testsuite/g++.dg/modules/class-11_a.H | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/g++.dg/modules/class-11_a.H b/gcc/testsuite/g++.dg/modules/class-11_a.H index f7bbf9d15061..799dbdd733c1 100644 --- a/gcc/testsuite/g++.dg/modules/class-11_a.H +++ b/gcc/testsuite/g++.dg/modules/class-11_a.H @@ -20,7 +20,7 @@ struct pr106381 { struct L1 : pr106381 { char x; // { dg-warning "offset" "" { target c++14 } } }; -static_assert(sizeof(L1) == sizeof(pr106381)); +static_assert(sizeof(L1) == sizeof(pr106381), ""); struct pr120012 { @@ -33,4 +33,4 @@ struct pr120012 { struct L2 : pr120012 { unsigned char y; // { dg-warning "offset" "" { target c++20 } } }; -static_assert(sizeof(L2) > sizeof(pr120012)); +static_assert(sizeof(L2) > sizeof(pr120012), "");
[gcc r16-2601] tree-optimization/120687 - avoid disturbing reduction chains in reassoc
https://gcc.gnu.org/g:e8a51144c02e1cf210db5763e435802ac6fa6ad9 commit r16-2601-ge8a51144c02e1cf210db5763e435802ac6fa6ad9 Author: Richard Biener Date: Tue Jul 29 10:05:32 2025 +0200 tree-optimization/120687 - avoid disturbing reduction chains in reassoc Reassoc carefully ranks operands to form reduction chains for vectorization so we are careful to not apply any width related changes in the early pass. Unfortunately we are not careful enough. The following gates fma related re-ordering and also the >= 3 ops tail "optimization" which is the culprit here. This does not fix the reported inefficient vectorization when using signed integer reductions yet. PR tree-optimization/120687 * tree-ssa-reassoc.cc (reassociate_bb): Do not disturb the sorted operand order in the early pass. * tree-vect-slp.cc (vect_analyze_slp): Dump when a detected reduction chain fails SLP discovery. * gcc.dg/vect/pr120687-1.c: New testcase. * gcc.dg/vect/pr120687-2.c: Likewise. Diff: --- gcc/testsuite/gcc.dg/vect/pr120687-1.c | 16 gcc/testsuite/gcc.dg/vect/pr120687-2.c | 17 + gcc/tree-ssa-reassoc.cc| 10 ++ gcc/tree-vect-slp.cc | 3 +++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr120687-1.c b/gcc/testsuite/gcc.dg/vect/pr120687-1.c new file mode 100644 index ..ce9cf6301ceb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120687-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +unsigned +frd (unsigned *p, unsigned *lastone) +{ + unsigned sum = 0; + for (; p <= lastone; p += 16) +sum += p[0] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + p[7] + + p[8] + p[9] + p[10] + p[11] + p[12] + p[13] + p[14] + p[15]; + return sum; +} + +/* { dg-final { scan-tree-dump "reduction: detected reduction chain" "vect" } } */ +/* { dg-final { scan-tree-dump-not "SLP discovery of reduction chain failed" "vect" } } */ +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr120687-2.c b/gcc/testsuite/gcc.dg/vect/pr120687-2.c new file mode 100644 index ..dfc6dc726e9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120687-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-ffast-math" } */ + +float +frd (float *p, float *lastone) +{ + float sum = 0; + for (; p <= lastone; p += 16) +sum += p[0] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + p[7] + + p[8] + p[9] + p[10] + p[11] + p[12] + p[13] + p[14] + p[15]; + return sum; +} + +/* { dg-final { scan-tree-dump "reduction: detected reduction chain" "vect" } } */ +/* { dg-final { scan-tree-dump-not "SLP discovery of reduction chain failed" "vect" } } */ +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */ diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index 3c38f3d7a19f..c140f76766eb 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -7167,9 +7167,10 @@ reassociate_bb (basic_block bb) /* If the target support FMA, rank_ops_for_fma will detect if the chain has fmas and rearrange the ops if so. */ - if (direct_internal_fn_supported_p (IFN_FMA, - TREE_TYPE (lhs), - opt_type) + if (!reassoc_insert_powi_p + && direct_internal_fn_supported_p (IFN_FMA, +TREE_TYPE (lhs), +opt_type) && (rhs_code == PLUS_EXPR || rhs_code == MINUS_EXPR)) { mult_num = rank_ops_for_fma (&ops); @@ -7200,7 +7201,8 @@ reassociate_bb (basic_block bb) to make sure the ones that get the double binary op are chosen wisely. */ int len = ops.length (); - if (len >= 3 + if (!reassoc_insert_powi_p + && len >= 3 && (!has_fma /* width > 1 means ranking ops results in better parallelism. Check current value to avoid diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index cb27d166c553..a9c7105f47e6 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -4950,6 +4950,9 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size, max_tree_size, &limit, force_single_lane)) { + if (dump_e
[gcc r15-10104] c++, coroutines: CWG2563 promise lifetime extension [PR115908].
https://gcc.gnu.org/g:b4da8ee3e613502b50501773f5ecb494d3a51c8b commit r15-10104-gb4da8ee3e613502b50501773f5ecb494d3a51c8b Author: Iain Sandoe Date: Sat May 31 19:59:04 2025 +0100 c++, coroutines: CWG2563 promise lifetime extension [PR115908]. This implements the final piece of the revised CWG2563 wording; "It exits the scope of promise only if the coroutine completed without suspending." Considering the coroutine to be made up of two components; a 'ramp' and a 'body' where the body represents the user's original code and the ramp is responsible for setup of that and for returning some object to the original caller. Coroutine state, and responsibility for its release. A coroutine has some state that persists across suspensions. The state has two components: * State that is specified by the standard and persists for the entire life of the coroutine. * Local state that is constructed/destructed as scopes in the original function body are entered/exited. The destruction of local state is always the responsibility of the body code. The persistent state (and the overall storage for the state) must be managed in two places: * The ramp function (which allocates and builds this - and can, in some cases, be responsible for destroying it) * The re-written function body which can destroy it when that body completes its final suspend - or when the handle.destroy () is called. In all cases the ramp holds responsibility for constructing the standard- mandated persistent state. There are four ways in which the ramp might be re-entered after starting the function body: A The body could suspend (one might expect that to be the 'normal' case for most coroutines). B The body might complete either synchronously or via continuations. C An exception might be thrown during the setup of the initial await expression, before the initial awaiter resumes. D An exception might be processed by promise.unhandled_exception () and that, in turn, might re-throw it (or throw something else). In this case, the coroutine is considered suspended at the final suspension point. Once the coroutine has passed initial suspend (i.e. the initial awaiter await_resume() has been called) the body is considered to have a use of the state. Until the ramp return value has been constructed, the ramp is considered to have a use of the state. To manage these interacting conditions we allocate a reference counter for the frame state. This is initialised to 1 by the ramp as part of its startup (note that failures/exceptions in the startup code are handled locally to the ramp). When the body returns (either normally, or by exception) the ramp releases its use. Once the rewritten coroutine body is started, the body is considered to have a use of the frame. This use (potentially) needs to be released if an exception is thrown from the body. We implement this using an eh-only cleanup around the initial await. If we have the case D above, then we do not release the body use. In case: A, typically the ramp would be re-entered with the body holding a use, and therefore the ramp should not destroy the state. B, both the body and ramp will have released their uses, and the ramp should destroy the state. C, we must arrange for the body to release its use, because we require the ramp to cleanup in this circumstance. D is an outlier, since the responsibility for destruction of the state now rests with the user's code (via a handle.destroy() call). NOTE: In the case that the body has never suspended before such an exception occurs, the only reasonable way for the user code to obtain the necessary handle is if unhandled_exception() throws the handle or some object that contains the handle. That is outside of the designs here - if the user code might need this corner-case, then such provision will have to be made. In the ramp, we implement destruction for the persistent frame state by means of cleanups. These are run conditionally when the reference count is 0 signalling that both the body and the ramp have completed. In the body, once we pass the final suspend, then we test the use and delete the state if the use is 0. PR c++/115908 PR c++/118074 PR c++/95615 gcc/cp/ChangeLog: * coroutines.cc (coro_frame_refcount_id): New. (coro_init_identifiers): Initialise coro_frame_refcount_id. (build_actor_fn): Set up initial_await_resume_called. Handle decrementing of the frame reference count. Return dire
[gcc r15-10105] c++: add passing testcases [PR120243]
https://gcc.gnu.org/g:823d5948aa2d8937befcb35f7b1bb9e33346efd9 commit r15-10105-g823d5948aa2d8937befcb35f7b1bb9e33346efd9 Author: Jason Merrill Date: Wed Jul 9 11:13:19 2025 -0400 c++: add passing testcases [PR120243] These pass now; the first was fixed by r16-1507. PR c++/120243 gcc/testsuite/ChangeLog: * g++.dg/coroutines/torture/pr120243-unhandled-1.C: New test. * g++.dg/coroutines/torture/pr120243-unhandled-2.C: New test. (cherry picked from commit 2492bab503f57f2cf6e08e5c104f7a1d31d34047) Diff: --- .../coroutines/torture/pr120243-unhandled-1.C | 33 + .../coroutines/torture/pr120243-unhandled-2.C | 34 ++ 2 files changed, 67 insertions(+) diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-1.C b/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-1.C new file mode 100644 index ..16bfef16fd8a --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-1.C @@ -0,0 +1,33 @@ +// PR c++/120243 +// { dg-do run } + +#include + +struct coro { + struct promise_type { +promise_type() = default; + +std::suspend_never initial_suspend() const noexcept { return {}; } +std::suspend_never final_suspend() const noexcept { return {}; } + +void unhandled_exception() { throw; } + +coro get_return_object() { return {}; } +void return_void() {} + +}; +}; + +int main() { +auto c = []() -> coro { +throw "hello"; +__builtin_abort(); +co_return; +}; +try { +c(); +} +catch(...) { +__builtin_printf("Caught!\n"); +} +} diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-2.C b/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-2.C new file mode 100644 index ..614c4ec9be66 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr120243-unhandled-2.C @@ -0,0 +1,34 @@ +// PR c++/120243 +// { dg-do run } + +#include + +struct coro { + struct promise_type { +promise_type() = default; + +std::suspend_always initial_suspend() const noexcept { return {}; } +std::suspend_always final_suspend() const noexcept { return {}; } + +void unhandled_exception() { throw; } + +coro get_return_object() { return {std::coroutine_handle::from_promise(*this)}; } +void return_void() {} +}; + +std::coroutine_handle h; +}; + +int main() { +auto c = []() -> coro { +throw "hello"; +__builtin_abort(); +co_return; +}; +try { +c().h.resume(); +} +catch(...) { +__builtin_printf("Caught!\n"); +} +}
[gcc r15-10106] c++, coroutines: Handle allocation fail returns [PR121219].
https://gcc.gnu.org/g:f67c851f03cf14c82a43045ea567ab5fb06377ac commit r15-10106-gf67c851f03cf14c82a43045ea567ab5fb06377ac Author: Iain Sandoe Date: Wed Jul 23 16:22:32 2025 +0100 c++, coroutines: Handle allocation fail returns [PR121219]. The current implementation was returning the result of the g_r_o_o_a_f call independently of the return expressions for 'normal' cases. This prevents the NVRO that we need to guarantee copy elision for the ramp return values - when these are initialised from a temporary of the same type. The solution here reorders the code so that the regular return expression appears before the allocation-failed case. Ensure that the g_r_o and associated code appears in a distinct scope. These steps are to meet the constaints of NRV. PR c++/121219 gcc/cp/ChangeLog: * coroutines.cc (cp_coroutine_transform::build_ramp_function): Reorder the return expressions for the 'normal' and 'allocation failed' cases so that NRV constraints are met. gcc/testsuite/ChangeLog: * g++.dg/coroutines/torture/pr121219.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit a2775feb7c7de9f21f79052e2b6a752a3eb08f07) Diff: --- gcc/cp/coroutines.cc | 39 -- gcc/testsuite/g++.dg/coroutines/torture/pr121219.C | 149 + 2 files changed, 174 insertions(+), 14 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 306424c22b02..3fe22ac98024 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -5066,6 +5066,8 @@ cp_coroutine_transform::build_ramp_function () check the returned pointer and call the func if it's null. Otherwise, no check, and we fail for noexcept/fno-exceptions cases. */ + tree grooaf_if_stmt = NULL_TREE; + tree alloc_ok_scope = NULL_TREE; if (grooaf) { /* [dcl.fct.def.coroutine] / 10 (part 3) @@ -5073,20 +5075,11 @@ cp_coroutine_transform::build_ramp_function () control to the caller of the coroutine and the return value is obtained by a call to T::get_return_object_on_allocation_failure(), where T is the promise type. */ - tree if_stmt = begin_if_stmt (); tree cond = build1 (CONVERT_EXPR, frame_ptr_type, nullptr_node); - cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond); - finish_if_stmt_cond (cond, if_stmt); - r = NULL_TREE; - if (void_ramp_p) - /* Execute the get-return-object-on-alloc-fail call... */ - finish_expr_stmt (grooaf); - else - /* Get the fallback return object. */ - r = grooaf; - finish_return_stmt (r); - finish_then_clause (if_stmt); - finish_if_stmt (if_stmt); + cond = build2 (NE_EXPR, boolean_type_node, coro_fp, cond); + grooaf_if_stmt = begin_if_stmt (); + finish_if_stmt_cond (cond, grooaf_if_stmt); + alloc_ok_scope = begin_compound_stmt (BCS_NORMAL); } /* Dereference the frame pointer, to use in member access code. */ @@ -5311,7 +5304,6 @@ cp_coroutine_transform::build_ramp_function () a temp which is then used to intialize the return object, including NVRO. */ - /* Temporary var to hold the g_r_o across the function body. */ coro_gro = coro_build_and_push_artificial_var (loc, "_Coro_gro", gro_type, orig_fn_decl, NULL_TREE); @@ -5344,9 +5336,28 @@ cp_coroutine_transform::build_ramp_function () /* The ramp is done, we just need the return statement, which we build from the return object we constructed before we called the actor. */ + /* This is our 'normal' exit. */ r = void_ramp_p ? NULL_TREE : convert_from_reference (coro_gro); finish_return_stmt (r); + if (grooaf) +{ + finish_compound_stmt (alloc_ok_scope); + finish_then_clause (grooaf_if_stmt); + + begin_else_clause (grooaf_if_stmt); + /* We come here if the frame allocation failed. */ + r = NULL_TREE; + if (void_ramp_p) + /* Execute the get-return-object-on-alloc-fail call... */ + finish_expr_stmt (grooaf); + else + /* Get the fallback return object. */ + r = grooaf; + finish_return_stmt (r); + finish_if_stmt (grooaf_if_stmt); +} + finish_compound_stmt (ramp_fnbody); return true; } diff --git a/gcc/testsuite/g++.dg/coroutines/torture/pr121219.C b/gcc/testsuite/g++.dg/coroutines/torture/pr121219.C new file mode 100644 index ..d1e7cb1e0225 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/torture/pr121219.C @@ -0,0 +1,149 @@ +// PR c++/121219 +// { dg-do run } + +#include +#ifdef OUTPUT +#include +#endif +#include + +struct Task { +struct promise_type; +using handle_type = std::coroutine_handle; + +struct promise_type { +Task* task_; +int resu
[gcc r15-10107] Darwin: account for macOS 26
https://gcc.gnu.org/g:c677121d3843e383906a4d7679dc647808ddab3a commit r15-10107-gc677121d3843e383906a4d7679dc647808ddab3a Author: Francois-Xavier Coudert Date: Mon Jul 14 12:14:00 2025 +0200 Darwin: account for macOS 26 darwin25 will be named macOS 26 (codename Tahoe). This is a change from darwin24, which was macOS 15. We need to adapt the driver to this new numbering scheme. 2025-07-14 François-Xavier Coudert gcc/ChangeLog: PR target/120645 * config/darwin-driver.cc: Account for latest macOS numbering scheme. gcc/testsuite/ChangeLog: * gcc.dg/darwin-minversion-link.c: Account for macOS 26. (cherry picked from commit cc4f3397331f6ecd5e775cf963c65face0145f3f) Diff: --- gcc/config/darwin-driver.cc | 22 -- gcc/testsuite/gcc.dg/darwin-minversion-link.c | 1 + 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/gcc/config/darwin-driver.cc b/gcc/config/darwin-driver.cc index 224e0a0de700..e83b7cdc0c95 100644 --- a/gcc/config/darwin-driver.cc +++ b/gcc/config/darwin-driver.cc @@ -64,7 +64,8 @@ validate_macosx_version_min (const char *version_str) major = strtoul (version_str, &end, 10); - /* macOS 10, 11, and 12 are known. clang accepts up to 99. */ + /* macOS 10, 11, 12, 13, 14, 15 and 26 are known. + clang accepts up to 99. */ if (major < 10 || major > 99) return NULL; @@ -159,15 +160,16 @@ darwin_find_version_from_kernel (void) if (*version_p++ != '.') goto parse_failed; - /* Darwin20 sees a transition to macOS 11. In this, it seems that the - mapping to macOS minor version and patch level is now always 0, 0 - (at least for macOS 11 and 12). */ - if (major_vers >= 20) -{ - /* Apple clang doesn't include the minor version or the patch level -in the object file, nor does it pass it to ld */ - asprintf (&new_flag, "%d.00.00", major_vers - 9); -} + /* Darwin25 saw a transition to macOS 26. */ + if (major_vers >= 25) +/* Apple clang doesn't include the minor version or the patch level + in the object file, nor does it pass it to ld */ +asprintf (&new_flag, "%d.00.00", major_vers + 1); + /* Darwin20 saw a transition to macOS 11. */ + else if (major_vers >= 20) +/* Apple clang doesn't include the minor version or the patch level + in the object file, nor does it pass it to ld */ +asprintf (&new_flag, "%d.00.00", major_vers - 9); else if (major_vers - 4 <= 4) /* On 10.4 and earlier, the old linker is used which does not support three-component system versions. diff --git a/gcc/testsuite/gcc.dg/darwin-minversion-link.c b/gcc/testsuite/gcc.dg/darwin-minversion-link.c index af712a1b8963..55f7c7ea8374 100644 --- a/gcc/testsuite/gcc.dg/darwin-minversion-link.c +++ b/gcc/testsuite/gcc.dg/darwin-minversion-link.c @@ -20,6 +20,7 @@ /* { dg-additional-options "-mmacosx-version-min=013.000.00 -DCHECK=13" { target *-*-darwin22* } } */ /* { dg-additional-options "-mmacosx-version-min=014.000.00 -DCHECK=14" { target *-*-darwin23* } } */ /* { dg-additional-options "-mmacosx-version-min=015.000.00 -DCHECK=15" { target *-*-darwin24* } } */ +/* { dg-additional-options "-mmacosx-version-min=026.000.00 -DCHECK=26" { target *-*-darwin25* } } */ int main ()
[gcc r15-10103] c++, coroutines: Remove use of coroutine handle in the frame.
https://gcc.gnu.org/g:a169a4718b5b621f1770789e55eb8c441f7d0fcd commit r15-10103-ga169a4718b5b621f1770789e55eb8c441f7d0fcd Author: Iain Sandoe Date: Mon Jun 16 09:12:29 2025 +0300 c++, coroutines: Remove use of coroutine handle in the frame. We have been keeping a copy of coroutine_handle in the state frame, as it was expected to be efficient to use this to initialize the argument to await_suspend. This does not turn out to be the case and intializing the value is obstructive to CGW2563 fixes. This removes the use. gcc/cp/ChangeLog: * coroutines.cc (struct coroutine_info): Update comments. (struct coro_aw_data): Remove self_handle and add in information to create the handle in lowering. (expand_one_await_expression): Build a temporary coroutine handle. (build_actor_fn): Remove reference to the frame copy of the coroutine handle. (cp_coroutine_transform::wrap_original_function_body): Remove reference to the frame copy of the coroutine handle. Signed-off-by: Iain Sandoe (cherry picked from commit 8a3acd8cf449636079acb3d1dfcbcabb074b75af) Diff: --- gcc/cp/coroutines.cc | 63 ++-- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 0443f5170ed7..6a7c75e3866b 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -206,11 +206,10 @@ struct GTY((for_user)) coroutine_info tree traits_type; /* The cached traits type for this function. */ tree handle_type; /* The cached coroutine handle for this function. */ tree self_h_proxy; /* A handle instance that is used as the proxy for the -one that will eventually be allocated in the coroutine -frame. */ +one that will eventually be built in lowering. */ tree promise_proxy; /* Likewise, a proxy promise instance. */ - tree from_address; /* handle_type from_address function. */ - tree return_void; /* The expression for p.return_void() if it exists. */ + tree from_address; /* handle_type from_address() function. */ + tree return_void; /* The expression for p.return_void(), if it exists. */ location_t first_coro_keyword; /* The location of the keyword that made this function into a coroutine. */ @@ -1997,12 +1996,13 @@ struct coro_aw_data tree coro_fp;/* Frame pointer var. */ tree resume_idx; /* This is the index var in the frame. */ tree i_a_r_c;/* initial suspend await_resume() was called if true. */ - tree self_h; /* This is a handle to the current coro (frame var). */ tree cleanup;/* This is where to go once we complete local destroy. */ tree cororet;/* This is where to go if we suspend. */ tree corocont; /* This is where to go if we continue. */ tree dispatch; /* This is where we go if we restart the dispatch. */ tree conthand; /* This is the handle for a continuation. */ + tree handle_type; /* Handle type for this coroutine... */ + tree hfa_m; /* ... and handle.from_address() for this. */ unsigned index; /* This is our current resume index. */ }; @@ -2120,6 +2120,18 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */ tree susp_type = TREE_TYPE (suspend); + tree susp_call = suspend; + if (TREE_CODE (suspend) == TARGET_EXPR) +susp_call = TARGET_EXPR_INITIAL (suspend); + gcc_checking_assert (TREE_CODE (susp_call) == CALL_EXPR); + tree dummy_ch = build_dummy_object (data->handle_type); + r = fold_convert (build_pointer_type (void_type_node), data->coro_fp); + vec *args = make_tree_vector_single (r); + tree hfa = cp_fold_rvalue ( +build_new_method_call (dummy_ch, data->hfa_m, &args, NULL_TREE, + LOOKUP_NORMAL, NULL, tf_warning_or_error)); + release_tree_vector (args); + CALL_EXPR_ARG (susp_call, call_expr_nargs (susp_call) - 1) = hfa; bool is_cont = false; /* NOTE: final suspend can't resume; the "resume" label in that case @@ -2601,23 +2613,6 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Now we start building the rewritten function body. */ add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label)); - /* actor's coroutine 'self handle'. */ - tree ash = coro_build_frame_access_expr (actor_frame, coro_self_handle_id, - false, tf_warning_or_error); - /* So construct the self-handle from the frame address. */ - tree hfa_m = get_coroutine_from_address (orig); - /* Should have been set earlier by coro_promise_type_found_p. */ - gcc_assert (hfa_m); - - tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_f
[gcc r15-10100] c++, coroutines: Avoid UNKNOWN_LOCATION synthesizing code [PR120273].
https://gcc.gnu.org/g:38db03d978017b3c4eefb1b1239793e50a84b25a commit r15-10100-g38db03d978017b3c4eefb1b1239793e50a84b25a Author: Iain Sandoe Date: Tue Jun 3 13:07:27 2025 +0100 c++, coroutines: Avoid UNKNOWN_LOCATION synthesizing code [PR120273]. Some of the lookup code is expecting to find a valid (not UNKNOWN) location, which triggers in the reported case. To avoid this, we are reverting the change to use UNKNOWN_LOCATION for synthesizing the wrapper, and instead using the start and end locations of the original function. PR c++/120273 gcc/cp/ChangeLog: * coroutines.cc (cp_coroutine_transform::wrap_original_function_body): Use function start and end locations when synthesizing code. (cp_coroutine_transform::cp_coroutine_transform): Set the function end location. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120273.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit 3b95be7bd1882add4b1e22f6b70bc130cd465eca) Diff: --- gcc/cp/coroutines.cc | 15 gcc/testsuite/g++.dg/coroutines/pr120273.C | 58 ++ 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 6477c7969737..5e33cc09adc9 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4330,8 +4330,7 @@ cp_coroutine_transform::wrap_original_function_body () { /* Avoid the code here attaching a location that makes the debugger jump. */ iloc_sentinel stable_input_loc (fn_start); - location_t loc = UNKNOWN_LOCATION; - input_location = loc; + location_t loc = fn_start; /* This will be our new outer scope. */ tree update_body @@ -4472,7 +4471,7 @@ cp_coroutine_transform::wrap_original_function_body () /* If the coroutine has a frame that needs to be freed, this will be set by the ramp. */ - var = coro_build_artificial_var (fn_start, coro_frame_needs_free_id, + var = coro_build_artificial_var (loc, coro_frame_needs_free_id, boolean_type_node, orig_fn_decl, NULL_TREE); DECL_CHAIN (var) = var_list; var_list = var; @@ -4484,7 +4483,7 @@ cp_coroutine_transform::wrap_original_function_body () tree ueh = coro_build_promise_expression (orig_fn_decl, promise, coro_unhandled_exception_identifier, -fn_start, NULL, /*musthave=*/true); +loc, NULL, /*musthave=*/true); /* Create and initialize the initial-await-resume-called variable per [dcl.fct.def.coroutine] / 5.3. */ tree i_a_r_c @@ -4546,9 +4545,9 @@ cp_coroutine_transform::wrap_original_function_body () tree ueh_meth = lookup_promise_method (orig_fn_decl, coro_unhandled_exception_identifier, -fn_start, /*musthave=*/false); +loc, /*musthave=*/false); if (!ueh_meth || ueh_meth == error_mark_node) - warning_at (fn_start, 0, "no member named %qE in %qT", + warning_at (loc, 0, "no member named %qE in %qT", coro_unhandled_exception_identifier, get_coroutine_promise_type (orig_fn_decl)); } @@ -4561,6 +4560,10 @@ cp_coroutine_transform::wrap_original_function_body () add_stmt (return_void); } + /* We are now doing actions associated with the end of the function, so + point to the closing brace. */ + input_location = loc = fn_end; + /* co_return branches to the final_suspend label, so declare that now. */ fs_label = create_named_label_with_ctx (loc, "final.suspend", NULL_TREE); diff --git a/gcc/testsuite/g++.dg/coroutines/pr120273.C b/gcc/testsuite/g++.dg/coroutines/pr120273.C new file mode 100644 index ..19b9e51b9faf --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr120273.C @@ -0,0 +1,58 @@ +// PR120273 +// { dg-additional-options "-Wno-literal-suffix" } +namespace std { +void declval(); +template < typename > struct invoke_result; +template < typename _Fn > using invoke_result_t = invoke_result< _Fn >; +template < typename _Derived, typename _Base > +concept derived_from = __is_base_of(_Base, _Derived); +template < typename, typename > +concept convertible_to = requires { declval; }; +template < char... > int operator""ms(); +template < typename _Result, typename > struct coroutine_traits : _Result {}; +template < typename = void > struct coroutine_handle { + static coroutine_handle from_address(void *); + operator coroutine_handle<>(); + void *address(); +}; +} + +using namespace std; + +template < class > using CoroutineHandle = coroutine_handle<>; + +template < class Callable > + requires(derived_from< invoke_result_t< Calla
[gcc r15-10098] c++, coroutines: Handle builtin_constant_p [PR116775].
https://gcc.gnu.org/g:a94894ffd5ca5c607160f8fde8eccd60d681c108 commit r15-10098-ga94894ffd5ca5c607160f8fde8eccd60d681c108 Author: Iain Sandoe Date: Mon Jun 9 11:00:47 2025 +0100 c++, coroutines: Handle builtin_constant_p [PR116775]. Since the folding of this builtin happens after the main coroutine FE lowering, we need to account for await expressions in that lowering. Since these expressions have a property of being not evaluated, but do not have the full constraints of an unevaluatated context, we want to apply the checks and then remove the await expressions so that they no longer participate in the analysis and lowering. When a builtin_constant_p call is encountered, and the operand contains any await expression, we check to see if the operand can be a constant and replace the call with its result. PR c++/116775 gcc/cp/ChangeLog: * 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. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr116775.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit ab3f04b73e5a1dd734d3bab64b4878d2d0cc29ad) Diff: --- gcc/cp/coroutines.cc | 23 +- gcc/testsuite/g++.dg/coroutines/pr116775.C | 68 ++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 8a36e0ae7fd3..6a85cb71a332 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3442,7 +3442,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 @@ -3459,6 +3460,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); diff --git a/gcc/testsuite/g++.dg/coroutines/pr116775.C b/gcc/testsuite/g++.dg/coroutines/pr116775.C new file mode 100644 index ..981e27af27b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr116775.C @@ -0,0 +1,68 @@ +// { dg-additional-options "-fsyntax-only" } +// PR116775 +#include +#ifndef OUTPUT +# define PRINT(X) +# define PRINTF(...) +#else +#include +# 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_yiel
[gcc r16-2622] RISC-V: Add testcases for unsigned avg ceil vx combine.
https://gcc.gnu.org/g:7aa9565a62ea2ce04e2ddf61e1932bc123374988 commit r16-2622-g7aa9565a62ea2ce04e2ddf61e1932bc123374988 Author: Pan Li Date: Mon Jul 28 20:12:31 2025 +0800 RISC-V: Add testcases for unsigned avg ceil vx combine. The unsigned avg ceil share the vaaddux.vx for the vx combine, so add the test case to make sure it works well as expected. The below test suites are passed for this patch series. * The rv64gcv fully regression test. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c: Add asm check for unsigned avg ceil. * gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c: Ditto. * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h: Add test helper macros. * gcc.target/riscv/rvv/autovec/vx_vf/vx_binary_data.h: Add test data. * gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u16.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u32.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u64.c: New test. * gcc.target/riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u8.c: New test. Signed-off-by: Pan Li Diff: --- .../gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c | 5 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c | 2 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u32.c | 2 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u64.c | 6 +- .../gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u8.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u16.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u32.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u64.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-5-u8.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u16.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u32.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u64.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx-6-u8.c | 1 + .../gcc.target/riscv/rvv/autovec/vx_vf/vx_binary.h | 17 ++ .../riscv/rvv/autovec/vx_vf/vx_binary_data.h | 196 + .../riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u16.c | 17 ++ .../riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u32.c | 17 ++ .../riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u64.c | 17 ++ .../riscv/rvv/autovec/vx_vf/vx_vaadd-run-2-u8.c| 17 ++ 20 files changed, 303 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c index e7b1ef077950..8e7a78892613 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u64.c @@ -19,4 +19,7 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ /* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ -/* { dg-final { scan-assembler-times {vaaddu.vx} 1 { target { no-opts "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m2" "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m4" } } } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 2 { target { no-opts { + "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m2" + "-O3 -mrvv-vector-bits=zvl -mrvv-max-lmul=m4" + } } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c index 559887e69b0e..d213c18d9aee 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-1-u8.c @@ -19,4 +19,4 @@ TEST_BINARY_VX_UNSIGNED_0(T) /* { dg-final { scan-assembler-times {vminu.vx} 2 } } */ /* { dg-final { scan-assembler-times {vsaddu.vx} 1 } } */ /* { dg-final { scan-assembler-times {vssubu.vx} 1 } } */ -/* { dg-final { scan-assembler-times {vaaddu.vx} 1 } } */ +/* { dg-final { scan-assembler-times {vaaddu.vx} 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vx_vf/vx-4-u16.c b/gcc/testsuite/gcc.target/ri
[gcc(refs/users/meissner/heads/work217-bugs)] Fix PR 118541, do not generate floating point cmoves for IEEE compares.
https://gcc.gnu.org/g:4de62af5387421886ea50aa3564b92bb19f01660 commit 4de62af5387421886ea50aa3564b92bb19f01660 Author: Michael Meissner Date: Wed Jul 30 02:04:47 2025 -0400 Fix PR 118541, do not generate floating point cmoves for IEEE compares. In bug PR target/118541 on power9, power10, and power11 systems, for the function: extern double __ieee754_acos (double); double __acospi (double x) { double ret = __ieee754_acos (x) / 3.14; return __builtin_isgreater (ret, 1.0) ? 1.0 : ret; } GCC currently generates the following code: Power9 Power10 and Power11 == === bl __ieee754_acos bl __ieee754_acos@notoc nop plfd 0,.LC0@pcrel addis 9,2,.LC2@toc@ha xxspltidp 12,1065353216 addi 1,1,32 addi 1,1,32 lfd 0,.LC2@toc@l(9) ld 0,16(1) addis 9,2,.LC0@toc@ha fdiv 0,1,0 ld 0,16(1) mtlr 0 lfd 12,.LC0@toc@l(9)xscmpgtdp 1,0,12 fdiv 0,1,0 xxsel 1,0,12,1 mtlr 0 blr xscmpgtdp 1,0,12 xxsel 1,0,12,1 blr This is because ifcvt.cc optimizes the conditional floating point move to use the XSCMPGTDP instruction. However, the XSCMPGTDP instruction will generate an interrupt if one of the arguments is a signalling NaN and signalling NaNs can generate an interrupt. The IEEE comparison functions (isgreater, etc.) require that the comparison not raise an interrupt. The following patch changes the PowerPC back end so that ifcvt.cc will not change the if/then test and move into a conditional move if the comparison is one of the comparisons that do not raise an error with signalling NaNs and -Ofast is not used. If a normal comparison is used or -Ofast is used, GCC will continue to generate XSCMPGTDP and XXSEL. For the following code: #include double ieee_compare (double a, double b, double c, double d) { return isgreater (a, b) ? c : d; } /* Verify normal > does generate xscmpgtdp. */ double normal_compare (double a, double b, double c, double d) { return a > b ? c : d; } with the following patch, GCC generates the following for power9, power10, and power11: ieee_compare: fcmpu 0,1,2 fmr 1,4 bnglr 0 fmr 1,3 blr normal_compare: xscmpgtdp 1,1,2 xxsel 1,4,3,1 blr 2025-07-30 Michael Meissner gcc/ PR target/118541 * config/rs6000/predicates.md (fpmask_comparison_operator): Add NE, LT, LE. (invert_fpmask_comparison_operator): Delete. * config/rs6000/rs6000-protos.h (enum cond_reverse_fp): New enumeration. (rs6000_reverse_condition): Add argument. * config/rs6000/rs6000.cc (rs6000_reverse_condition): Add argument which controls whether floating point comparisons can be reversed for conditional moves that involve IEEE comparison functions. The IEEE comparison functions are required to not trap on signaling NaNs. If this is a jump, we allow the comparison to be reversed. (rs6000_emit_sCOND): Adjust rs6000_reverse_condition call to not allow reversing floating point comparisons that involve IEEE comparison functions. * config/rs6000/rs6000.h (REVERSE_CONDITION): Likewise. * config/rs6000/rs6000.md (movcc_p9): Add support to convert NE into EQ by swapping the true/false values during the split. (movcc_invert_p9): Delete insn. (fpmask, SFDF iterator): Add support for NE, LT and LE. (movcc_p10): Add support to convert NE into EQ by swapping the true/false values during the split. (movcc_invert_p10): Delete insn. (fpmask, IEEE128 iterator): Add support for NE, LT and LE. (reverse_branch_comparison): Name the insn. Adjust the rs6000_reverse_condition calls. gcc/testsuite/ PR target/118541 * gcc.target/powerpc/pr118541-1.c: New test. * gcc.target/powerpc/pr118541-2.c: Likewise. Diff: --- gcc/config/rs6000/predicates.md | 11 +- gcc/config/rs6000/rs6000-protos
[gcc(refs/users/meissner/heads/work217-bugs)] Update ChangeLog.*
https://gcc.gnu.org/g:8bd0e53ce972e5c9e939225b392d264f496d6d1a commit 8bd0e53ce972e5c9e939225b392d264f496d6d1a Author: Michael Meissner Date: Wed Jul 30 02:06:19 2025 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.bugs | 118 + 1 file changed, 118 insertions(+) diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs index 5ca8e803434c..ccaa5d442843 100644 --- a/gcc/ChangeLog.bugs +++ b/gcc/ChangeLog.bugs @@ -1,3 +1,121 @@ + Branch work217-bugs, patch #110 + +Fix PR 118541, do not generate floating point cmoves for IEEE compares. + +In bug PR target/118541 on power9, power10, and power11 systems, for the +function: + +extern double __ieee754_acos (double); + +double +__acospi (double x) +{ + double ret = __ieee754_acos (x) / 3.14; + return __builtin_isgreater (ret, 1.0) ? 1.0 : ret; +} + +GCC currently generates the following code: + +Power9 Power10 and Power11 +== === +bl __ieee754_acos bl __ieee754_acos@notoc +nop plfd 0,.LC0@pcrel +addis 9,2,.LC2@toc@ha xxspltidp 12,1065353216 +addi 1,1,32 addi 1,1,32 +lfd 0,.LC2@toc@l(9) ld 0,16(1) +addis 9,2,.LC0@toc@ha fdiv 0,1,0 +ld 0,16(1) mtlr 0 +lfd 12,.LC0@toc@l(9)xscmpgtdp 1,0,12 +fdiv 0,1,0 xxsel 1,0,12,1 +mtlr 0 blr +xscmpgtdp 1,0,12 +xxsel 1,0,12,1 +blr + +This is because ifcvt.cc optimizes the conditional floating point move to use the +XSCMPGTDP instruction. + +However, the XSCMPGTDP instruction will generate an interrupt if one of the +arguments is a signalling NaN and signalling NaNs can generate an interrupt. +The IEEE comparison functions (isgreater, etc.) require that the comparison not +raise an interrupt. + +The following patch changes the PowerPC back end so that ifcvt.cc will not change +the if/then test and move into a conditional move if the comparison is one of +the comparisons that do not raise an error with signalling NaNs and -Ofast is +not used. If a normal comparison is used or -Ofast is used, GCC will continue +to generate XSCMPGTDP and XXSEL. + +For the following code: + + #include + +double +ieee_compare (double a, double b, double c, double d) +{ + return isgreater (a, b) ? c : d; +} + +/* Verify normal > does generate xscmpgtdp. */ + +double +normal_compare (double a, double b, double c, double d) +{ + return a > b ? c : d; +} + +with the following patch, GCC generates the following for power9, power10, and +power11: + +ieee_compare: +fcmpu 0,1,2 +fmr 1,4 +bnglr 0 +fmr 1,3 +blr + +normal_compare: +xscmpgtdp 1,1,2 +xxsel 1,4,3,1 +blr + +2025-07-30 Michael Meissner + +gcc/ + + PR target/118541 + * config/rs6000/predicates.md (fpmask_comparison_operator): Add NE, LT, + LE. + (invert_fpmask_comparison_operator): Delete. + * config/rs6000/rs6000-protos.h (enum cond_reverse_fp): New enumeration. + (rs6000_reverse_condition): Add argument. + * config/rs6000/rs6000.cc (rs6000_reverse_condition): Add argument which + controls whether floating point comparisons can be reversed for + conditional moves that involve IEEE comparison functions. The IEEE + comparison functions are required to not trap on signaling NaNs. If + this is a jump, we allow the comparison to be reversed. + (rs6000_emit_sCOND): Adjust rs6000_reverse_condition call to not allow + reversing floating point comparisons that involve IEEE comparison + functions. + * config/rs6000/rs6000.h (REVERSE_CONDITION): Likewise. + * config/rs6000/rs6000.md (movcc_p9): Add support + to convert NE into EQ by swapping the true/false values during the + split. + (movcc_invert_p9): Delete insn. + (fpmask, SFDF iterator): Add support for NE, LT and LE. + (movcc_p10): Add support to convert NE into EQ by swapping the + true/false values during the split. + (movcc_invert_p10): Delete insn. + (fpmask, IEEE128 iterator): Add support for NE, LT and LE. + (reverse_branch_comparison): Name the insn. Adjust the + rs6000_reverse_condition calls. + +gcc/testsuite/ + + PR target/118541 + * gcc.target/powerpc/pr118541-1.c: New test. + * gcc.target/powerpc/pr118541-2.c: Likewise. + Branch work217-bugs, patch #104 PR target/120681
[gcc r16-2620] simplify-rtx: Fix Distribute subregs over logic ops [PR121302]
https://gcc.gnu.org/g:ef49f8e9480129433cc803625ae8c6877cf59453 commit r16-2620-gef49f8e9480129433cc803625ae8c6877cf59453 Author: Andrew Pinski Date: Tue Jul 29 17:02:44 2025 -0700 simplify-rtx: Fix Distribute subregs over logic ops [PR121302] r16-2614-g965564eafb721f had a typo where it would assume byte==0 rather than use the byte (offset) that was passed. This fixes that typo and also fixes the comment since it is not just about lowerpart subregs but all non-paradoxical subregs. Pushed as obvious after bootstrap/test on x86_64-linux-gnu. PR rtl-optimization/121302 gcc/ChangeLog: * simplify-rtx.cc (simplify_context::simplify_subreg): Use byte instead of 0 when calling simplify_subreg. Signed-off-by: Andrew Pinski Diff: --- gcc/simplify-rtx.cc | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 125048da1817..442da9f40fae 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -8398,7 +8398,7 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, return simplify_gen_relational (GET_CODE (op), outermode, innermode, XEXP (op, 0), XEXP (op, 1)); - /* Distribute lowpart subregs through logic ops in cases where one term + /* Distribute non-paradoxical subregs through logic ops in cases where one term disappears. (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X) @@ -8416,7 +8416,7 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR) && CONSTANT_P (XEXP (op, 1))) { - rtx op1_subreg = simplify_subreg (outermode, XEXP (op, 1), innermode, 0); + rtx op1_subreg = simplify_subreg (outermode, XEXP (op, 1), innermode, byte); if (op1_subreg == CONSTM1_RTX (outermode)) { if (GET_CODE (op) == IOR) @@ -8424,13 +8424,13 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, rtx op0 = XEXP (op, 0); if (GET_CODE (op) == XOR) op0 = simplify_gen_unary (NOT, innermode, op0, innermode); - return simplify_gen_subreg (outermode, op0, innermode, 0); + return simplify_gen_subreg (outermode, op0, innermode, byte); } if (op1_subreg == CONST0_RTX (outermode)) return (GET_CODE (op) == AND ? op1_subreg - : simplify_gen_subreg (outermode, XEXP (op, 0), innermode, 0)); + : simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte)); } return NULL_RTX;
[gcc(refs/users/meissner/heads/work217-test)] Merge commit 'refs/users/meissner/heads/work217-test' of git+ssh://gcc.gnu.org/git/gcc into me/work2
https://gcc.gnu.org/g:8df1b4f0afd467135f3521a684166199303f93ba commit 8df1b4f0afd467135f3521a684166199303f93ba Merge: 597e67b627fe 23981a20b9c8 Author: Michael Meissner Date: Wed Jul 30 01:08:45 2025 -0400 Merge commit 'refs/users/meissner/heads/work217-test' of git+ssh://gcc.gnu.org/git/gcc into me/work217-test Diff:
[gcc(refs/users/meissner/heads/work217-test)] Add ChangeLog.test and update REVISION.
https://gcc.gnu.org/g:597e67b627fefdd4a770a642957feaa02caedd15 commit 597e67b627fefdd4a770a642957feaa02caedd15 Author: Michael Meissner Date: Wed Jul 30 00:55:33 2025 -0400 Add ChangeLog.test and update REVISION. 2025-07-30 Michael Meissner gcc/ * ChangeLog.test: New file for branch. * REVISION: Update. Diff: --- gcc/ChangeLog.test | 14 ++ gcc/REVISION | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog.test b/gcc/ChangeLog.test new file mode 100644 index ..3a265a1dd76b --- /dev/null +++ b/gcc/ChangeLog.test @@ -0,0 +1,14 @@ + Branch work217-test, baseline + +2025-07-30 Michael Meissner + +Add ChangeLog.test and update REVISION. + +2025-07-30 Michael Meissner + +gcc/ + + * ChangeLog.test: New file for branch. + * REVISION: Update. + + Clone branch diff --git a/gcc/REVISION b/gcc/REVISION index fe518eccb19e..e95ad51f2e6b 100644 --- a/gcc/REVISION +++ b/gcc/REVISION @@ -1 +1 @@ -work217 branch +work217-test branch
[gcc/meissner/heads/work217-test] (4 commits) Merge commit 'refs/users/meissner/heads/work217-test' of gi
The branch 'meissner/heads/work217-test' was updated to point to: 8df1b4f0afd4... Merge commit 'refs/users/meissner/heads/work217-test' of gi It previously pointed to: 23981a20b9c8... Add ChangeLog.test and update REVISION. Diff: Summary of changes (added commits): --- 8df1b4f... Merge commit 'refs/users/meissner/heads/work217-test' of gi 597e67b... Add ChangeLog.test and update REVISION. 0e19d41... Update ChangeLog.* (*) 8987e2d... Add support for -mcpu=future (*) (*) This commit already exists in another branch. Because the reference `refs/users/meissner/heads/work217-test' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc(refs/users/meissner/heads/work217-sha)] Merge commit 'refs/users/meissner/heads/work217-sha' of git+ssh://gcc.gnu.org/git/gcc into me/work21
https://gcc.gnu.org/g:bf0af3dc70068356fc7198936c59862a39750b81 commit bf0af3dc70068356fc7198936c59862a39750b81 Merge: 418b18ebefec a7618998d979 Author: Michael Meissner Date: Wed Jul 30 01:07:30 2025 -0400 Merge commit 'refs/users/meissner/heads/work217-sha' of git+ssh://gcc.gnu.org/git/gcc into me/work217-sha Diff:
[gcc(refs/users/meissner/heads/work217-bugs)] Add power9 and power10 float to logical optimizations.
https://gcc.gnu.org/g:34cd661629c34d74d0b69810be7cc9974c683b41 commit 34cd661629c34d74d0b69810be7cc9974c683b41 Author: Michael Meissner Date: Wed Jul 30 01:11:00 2025 -0400 Add power9 and power10 float to logical optimizations. I was answering an email from a co-worker and I pointed him to work I had done for the Power8 era that optimizes the 32-bit float math library in Glibc. In doing so, I discovered with the Power9 and later computers, this optimization is no longer taking place. The glibc 32-bit floating point math functions have code that looks like: union u { float f; uint32_t u32; }; float math_foo (float x, unsigned int mask) { union u arg; float x2; arg.f = x; arg.u32 &= mask; x2 = arg.f; /* ... */ } On power8 with the optimization it generates: xscvdpspn 0,1 sldi 9,4,32 mtvsrd 32,9 xxland 1,0,32 xscvspdpn 1,1 I.e., it converts the SFmode to the memory format (instead of the DFmode that is used within the register), converts the mask so that it is in the vector register in the upper 32-bits, and does a XXLAND (i.e. there is only one direct move from GPR to vector register). Then after doing this, it converts the upper 32-bits back to DFmode. If the XSCVSPDN instruction took the value in the normal 32-bit scalar in a vector register, we wouldn't have needed the SLDI of the mask. On power9/power10/power11 it currently generates: xscvdpspn 0,1 mfvsrwz 2,0 and 2,2,4 mtvsrws 1,2 xscvspdpn 1,1 blr I.e convert to SFmode representation, move the value to a GPR, do an AND operation, move the 32-bit value with a splat, and then convert it back to DFmode format. With this patch, it now generates: xscvdpspn 0,1 mtvsrwz 32,2 xxland 32,0,32 xxspltw 1,32,1 xscvspdpn 1,1 blr I.e. convert to SFmode representation, move the mask to the vector register, do the operation using XXLAND. Splat the value to get the value in the correct location, and then convert back to DFmode. I have built GCC with the patches in this patch set applied on both little and big endian PowerPC systems and there were no regressions. Can I apply this patch to the trunk? 2025-07-30 Michael Meissner gcc/ PR target/117487 * config/rs6000/vsx.md (SFmode logical peephoole): Update comments in the original code that supports power8. Add a new define_peephole2 to do the optimization on power9/power10. gcc/testsuite/ PR target/117487 * gcc.target/powerpc/pr117487.c: New test. Diff: --- gcc/config/rs6000/vsx.md| 142 +++- gcc/testsuite/gcc.target/powerpc/pr117487.c | 67 + 2 files changed, 204 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index dd3573b80868..0082a36831a5 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -6264,7 +6264,7 @@ (SFBOOL_MFVSR_A 3) ;; move to gpr src (SFBOOL_BOOL_D 4) ;; and/ior/xor dest (SFBOOL_BOOL_A1 5) ;; and/ior/xor arg1 - (SFBOOL_BOOL_A2 6) ;; and/ior/xor arg1 + (SFBOOL_BOOL_A2 6) ;; and/ior/xor arg2 (SFBOOL_SHL_D7) ;; shift left dest (SFBOOL_SHL_A8) ;; shift left arg (SFBOOL_MTVSR_D 9) ;; move to vecter dest @@ -6304,18 +6304,18 @@ ;; GPR, and instead move the integer mask value to the vector register after a ;; shift and do the VSX logical operation. -;; The insns for dealing with SFmode in GPR registers looks like: +;; The insns for dealing with SFmode in GPR registers looks like on power8: ;; (set (reg:V4SF reg2) (unspec:V4SF [(reg:SF reg1)] UNSPEC_VSX_CVDPSPN)) ;; -;; (set (reg:DI reg3) (unspec:DI [(reg:V4SF reg2)] UNSPEC_P8V_RELOAD_FROM_VSX)) +;; (set (reg:DI reg3) (zero_extend:DI (reg:SI reg2))) ;; -;; (set (reg:DI reg4) (and:DI (reg:DI reg3) (reg:DI reg3))) +;; (set (reg:DI reg4) (and:SI (reg:SI reg3) (reg:SI mask))) ;; ;; (set (reg:DI reg5) (ashift:DI (reg:DI reg4) (const_int 32))) ;; ;; (set (reg:SF reg6) (unspec:SF [(reg:DI reg5)] UNSPEC_P8V_MTVSRD)) ;; -;; (set (reg:SF reg6) (unspec:SF [(reg:SF reg6)] UNSPEC_VSX_CVSPDPN)) +;; (set (reg:SF reg7) (unspec:SF [(reg:SF reg6)] UNSPEC_VSX_CVSPDPN)) (define_peephole2 [(match_scratch:DI SFBOOL_TMP_G
[gcc(refs/users/meissner/heads/work217-bugs)] PR 992493: Optimize splat of a V2DF/V2DI extract with constant element
https://gcc.gnu.org/g:a501bb30ccfb4e1dfe359cbfaf6e200072115c7f commit a501bb30ccfb4e1dfe359cbfaf6e200072115c7f Author: Michael Meissner Date: Wed Jul 30 01:13:01 2025 -0400 PR 992493: Optimize splat of a V2DF/V2DI extract with constant element We had optimizations for splat of a vector extract for the other vector types, but we missed having one for V2DI and V2DF. This patch adds a combiner insn to do this optimization. In looking at the source, we had similar optimizations for V4SI and V4SF extract and splats, but we missed doing V2DI/V2DF. Without the patch for the code: vector long long splat_dup_l_0 (vector long long v) { return __builtin_vec_splats (__builtin_vec_extract (v, 0)); } the compiler generates (on a little endian power9): splat_dup_l_0: mfvsrld 9,34 mtvsrdd 34,9,9 blr Now it generates: splat_dup_l_0: xxpermdi 34,34,34,3 blr 2025-07-30 Michael Meissner gcc/ PR target/99293 * config/rs6000/vsx.md (vsx_splat_extract_): New insn. gcc/testsuite/ PR target/99293 * gcc.target/powerpc/builtins-1.c: Adjust insn count. * gcc.target/powerpc/pr99293.c: New test. Diff: --- gcc/config/rs6000/vsx.md | 18 ++ gcc/testsuite/gcc.target/powerpc/builtins-1.c | 2 +- gcc/testsuite/gcc.target/powerpc/pr99293.c| 22 ++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 0082a36831a5..f47c4e2f7766 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -4798,6 +4798,24 @@ "lxvdsx %x0,%y1" [(set_attr "type" "vecload")]) +;; Optimize SPLAT of an extract from a V2DF/V2DI vector with a constant element +(define_insn "*vsx_splat_extract_" + [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa") + (vec_duplicate:VSX_D +(vec_select: + (match_operand:VSX_D 1 "vsx_register_operand" "wa") + (parallel [(match_operand 2 "const_0_to_1_operand" "n")]] + "VECTOR_MEM_VSX_P (mode)" +{ + int which_word = INTVAL (operands[2]); + if (!BYTES_BIG_ENDIAN) +which_word = 1 - which_word; + + operands[3] = GEN_INT (which_word ? 3 : 0); + return "xxpermdi %x0,%x1,%x1,%3"; +} + [(set_attr "type" "vecperm")]) + ;; V4SI splat support (define_insn "vsx_splat_v4si" [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa,wa") diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1.c b/gcc/testsuite/gcc.target/powerpc/builtins-1.c index 8410a5fd4319..4e7e5384675f 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtins-1.c +++ b/gcc/testsuite/gcc.target/powerpc/builtins-1.c @@ -1035,4 +1035,4 @@ foo156 (vector unsigned short usa) /* { dg-final { scan-assembler-times {\mvmrglb\M} 3 } } */ /* { dg-final { scan-assembler-times {\mvmrgew\M} 4 } } */ /* { dg-final { scan-assembler-times {\mvsplth|xxsplth\M} 4 } } */ -/* { dg-final { scan-assembler-times {\mxxpermdi\M} 44 } } */ +/* { dg-final { scan-assembler-times {\mxxpermdi\M} 42 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr99293.c b/gcc/testsuite/gcc.target/powerpc/pr99293.c new file mode 100644 index ..20adc1f27f65 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99293.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx" } */ + +/* Test for PR 99263, which wants to do: + __builtin_vec_splats (__builtin_vec_extract (v, n)) + + where v is a V2DF or V2DI vector and n is either 0 or 1. Previously the + compiler would do a direct move to the GPR registers to select the item and a + direct move from the GPR registers to do the splat. */ + +vector long long splat_dup_l_0 (vector long long v) +{ + return __builtin_vec_splats (__builtin_vec_extract (v, 0)); +} + +vector long long splat_dup_l_1 (vector long long v) +{ + return __builtin_vec_splats (__builtin_vec_extract (v, 1)); +} + +/* { dg-final { scan-assembler-times "xxpermdi" 2 } } */
[gcc(refs/users/meissner/heads/work217-bugs)] PR target/120528 -- Simplify zero extend from memory to VSX register on power10
https://gcc.gnu.org/g:37fa3ee1fc243d32e0ac4c560931c65df8f7335f commit 37fa3ee1fc243d32e0ac4c560931c65df8f7335f Author: Michael Meissner Date: Wed Jul 30 01:13:42 2025 -0400 PR target/120528 -- Simplify zero extend from memory to VSX register on power10 Previously GCC would zero extend a DImode value in memory to a TImode target in a vector register by firt zero extending the DImode value into a GPR TImode register pair, and then do a MTVSRDD to move this value to a VSX register. For example, consider the following code: #ifndef TYPE #define TYPE unsigned long long #endif void mem_to_vsx (TYPE *p, __uint128_t *q) { /* lxvrdx 0,0,3 stxv 0,0(4) */ __uint128_t x = *p; __asm__ (" # %x0" : "+wa" (x)); *q = x; } It currently generates the following code on power10: mem_to_vsx: ld 10,0(3) li 11,0 mtvsrdd 0,11,10 #APP # 0 #NO_APP stxv 0,0(4) blr Instead it could generate: mem_to_vsx: lxvrdx 0,0,3 #APP # 0 #NO_APP stxv 0,0(4) blr The lxvr{b,h,w,d}x instructions were added in power10, and they load up a vector register with a byte, half-word, word, or double-word value in the right most bits, and fill the remaining bits to 0. I noticed this code when working on PR target/108958 (which I just posted the patch). This patch creates a peephole2 to catch this case, and it eliminates creating the TImode variable. Instead it just does the LXVR{B,H,W,D}x instruction directly. I have built GCC with the patches in this patch set applied on both little and big endian PowerPC systems and there were no regressions. Can I apply this patch to GCC 16? 2025-07-30 Michael Meissner gcc/ PR target/120528 * config/rs6000/rs6000.md (zero_extend??ti2 peephole2): Add a peephole2 to simplify zero extending a QI/HI/SI/DImode value in memory to a TImode target in a vector register to use the LXVR{B,H,W,D}X instructins. gcc/testsuite/ PR target/120528 * gcc.target/powerpc/pr120528.c: New test. Diff: --- gcc/config/rs6000/rs6000.md | 69 ++ gcc/testsuite/gcc.target/powerpc/pr120528.c | 91 + 2 files changed, 160 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 9c718ca2a226..d7315f915de6 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -970,6 +970,75 @@ (set_attr "length" "4,8")]) +;; On power10, optimize zero extending a QI/HI/SI/DImode value from memory that +;; is going to a vector register target by generating a LXVR{B,H,W,D}X +;; instruction without creating the TImode value in a GPR and using MTVSRDD to +;; move it to the vector register. +(define_peephole2 + [(set (match_operand:DI 0 "int_reg_operand") + (match_operand:DI 1 "memory_operand")) + (set (match_operand:DI 2 "base_reg_operand") + (const_int 0)) + (set (match_operand:TI 3 "vsx_register_operand") + (match_operand:TI 4 "int_reg_operand"))] + "TARGET_POWER10 && TARGET_POWERPC64 + && (reg_or_subregno (operands[0]) + == reg_or_subregno (operands[4]) + !!WORDS_BIG_ENDIAN) + && (reg_or_subregno (operands[2]) + == reg_or_subregno (operands[4]) + !WORDS_BIG_ENDIAN) + && peep2_reg_dead_p (3, operands[4]) + && (REG_P (XEXP (operands[1], 0)) + || SUBREG_P (XEXP (operands[1], 0)) + || GET_CODE (XEXP (operands[1], 0)) == PLUS)" + [(set (match_dup 3) + (zero_extend:TI (match_dup 5)))] +{ + rtx mem = operands[1]; + rtx addr = XEXP (mem, 0); + + if (indexed_or_indirect_address (addr, DImode)) +operands[5] = mem; + else +{ + rtx op2 = operands[2]; + emit_insn (gen_rtx_SET (op2, addr)); + operands[5] = change_address (mem, DImode, op2); +} +}) + +(define_peephole2 + [(set (match_operand:DI 0 "int_reg_operand") + (zero_extend:DI +(match_operand:QHSI 1 "memory_operand"))) + (set (match_operand:DI 2 "base_reg_operand") + (const_int 0)) + (set (match_operand:TI 3 "vsx_register_operand") + (match_operand:TI 4 "int_reg_operand"))] + "TARGET_POWER10 && TARGET_POWERPC64 + && (reg_or_subregno (operands[0]) + == reg_or_subregno (operands[4]) + !!WORDS_BIG_ENDIAN) + && (reg_or_subregno (operands[2]) + == reg_or_subregno (operands[4]) + !WORDS_BIG_ENDIAN) + && peep2_reg_dead_p (3, operands[4]) + && (REG_P (XEXP (operands[1], 0)) + || SUBREG_P
[gcc(refs/users/meissner/heads/work217-bugs)] PR target/108958 -- simplify mtvsrdd to zero extend GPR DImode to VSX TImode
https://gcc.gnu.org/g:4e4c2fd1cf2c8bffee718c128c8cd4f7c0b5bec6 commit 4e4c2fd1cf2c8bffee718c128c8cd4f7c0b5bec6 Author: Michael Meissner Date: Wed Jul 30 01:14:26 2025 -0400 PR target/108958 -- simplify mtvsrdd to zero extend GPR DImode to VSX TImode Before this patch GCC would zero extend a DImode GPR value to TImode by first zero extending the DImode value into a GPR TImode register pair, and then do a MTVSRDD to move this value to a VSX register. For example, consider the following code: #ifndef TYPE #define TYPE unsigned long long #endif void gpr_to_vsx (TYPE x, __uint128_t *p) { __uint128_t y = x; __asm__ (" # %x0" : "+wa" (y)); *p = y; } Currently GCC generates: gpr_to_vsx: mr 10,3 li 11,0 mtvsrdd 0,11,10 #APP # 0 #NO_APP stxv 0,0(4) blr I.e. the mr and li instructions create the zero extended TImode value in a GPR, and then the mtvsrdd instruction moves both registers into a single vector register. Instead, GCC should generate the following code. Since the mtvsrdd instruction will clear the upper 64 bits if the 2nd argument is 0 (non-zero values are a GPR to put in the upper 64 bits): gpr_to_vsx: mtvsrdd 0,0,3 #APP # 0 #NO_APP stxv 0,0(4) blr Originally, I posted a patch that added the zero_extendsiti2 insn. I got some pushback about using reload_completed in the split portion of the define_insn_and_split. However, this is a case where you absolutely have to use the reload_completed test, because if you split the code before register allocation to handle the normal, the split insns will not be compiled to generate the appropriate mtvsrdd without creating the TImode value in the GPR register. I can imagine there might be concern about favoring generating code using the vector registers instead of using the GPR registers if the code does not require the TImode value to be in a vector register. I completely rewrote the patch. This patch creates a peephole2 to catch this case, and it eliminates creating the TImode variable. Instead it just does the MTVSRDD instruction directly. That way it will not influence register allocation, and the code will only be generated in the specific case where we need the TImode value in a vector register. I have built GCC with the patches in this patch set applied on both little and big endian PowerPC systems and there were no regressions. Can I apply this patch to GCC 16? 2025-07-30 Michael Meissner gcc/ PR target/108958 * config/rs6000/rs6000.md (UNSPEC_ZERO_EXTEND): New unspec. (zero_extendsiti2 peephole2): Add a peephole2 to simplify zero extend between DImode value in a GPR to a TImode target in a vector register. (zero_extendsiti2_vsx): New insn. gcc/testsuite/ PR target/108958 * gcc.target/powerpc/pr108958.c: New test. Diff: --- gcc/config/rs6000/rs6000.md | 26 gcc/testsuite/gcc.target/powerpc/pr108958.c | 47 + 2 files changed, 73 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d7315f915de6..5a56ad79a9ee 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -173,6 +173,7 @@ UNSPEC_XXSPLTIW_CONST UNSPEC_FMAX UNSPEC_FMIN + UNSPEC_ZERO_EXTEND ]) ;; @@ -969,6 +970,31 @@ (set_attr "dot" "yes") (set_attr "length" "4,8")]) +;; Optimize zero_extendsiti2 from a GPR to a GPR and then moving the GPR to a +;; VSX register +(define_peephole2 + [(set (match_operand:DI 0 "int_reg_operand") + (match_operand:DI 1 "int_reg_operand")) + (set (match_operand:DI 2 "int_reg_operand") + (const_int 0)) + (set (match_operand:TI 3 "vsx_register_operand") + (match_operand:TI 4 "int_reg_operand"))] + "TARGET_DIRECT_MOVE_64BIT + && (reg_or_subregno (operands[0]) + == reg_or_subregno (operands[4]) + !!WORDS_BIG_ENDIAN) + && (reg_or_subregno (operands[2]) + == reg_or_subregno (operands[4]) + !WORDS_BIG_ENDIAN) + && peep2_reg_dead_p (3, operands[4])" + [(set (match_dup 3) + (unspec:TI [(match_dup 1)] UNSPEC_ZERO_EXTEND))]) + +(define_insn "*zero_extendsiti2_vsx" + [(set (match_operand:TI 0 "vsx_register_operand" "=wa") + (unspec:TI [(match_operand:DI 1 "int_reg_operand" "r")] + UNSPEC_ZERO_EXTEND))] + "TARGET_DIRECT_MOVE_64BIT" + "mtvsrdd %x0,0,%
[gcc(refs/users/meissner/heads/work217-bugs)] PR target/120681 - allow -mcmodel=large with PC relative addressing
https://gcc.gnu.org/g:82c1e22ada8bbaa27afdce4cfc84c71f1d37ae7e commit 82c1e22ada8bbaa27afdce4cfc84c71f1d37ae7e Author: Michael Meissner Date: Wed Jul 30 01:15:33 2025 -0400 PR target/120681 - allow -mcmodel=large with PC relative addressing When I implemented the pc-relative support for power10 in GCC, I disabled using pc-relative support for -mcmodel=large. At the time, I didn't want to dig into the issues. It is now time to allow -mcmodel=large to generate pc-relative code. This patch allows -mcmodel=large to use prefixed addressing on power10, power11, and possibly other future PowerPC processors in addition to the current -mcmodel=medium support. 2025-07-30 Michael Meissner gcc/ PR target/120681 * config/rs6000/linux64.h (PCREL_SUPPORTED_BY_OS): Allow large code model as well as medium code model. * config/rs6000/rs6000.cc (rs6000_option_override_internal): Likewise. (rs6000_elf_declare_function_name): Don't create the local/non-local labels for large code model if we are using PC-relative addressing. gcc/testsuite/ PR target/120681 * gcc.target/powerpc/pr120681.c: New test. Diff: --- gcc/config/rs6000/linux64.h | 5 +++-- gcc/config/rs6000/rs6000.cc | 13 ++- gcc/testsuite/gcc.target/powerpc/pr120681.c | 34 + 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 0316d8cb65da..cf60ff14e108 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -564,7 +564,8 @@ extern int dot_symbols; /* Enable using prefixed PC-relative addressing on POWER10 if the ABI supports it. The ELF v2 ABI only supports PC-relative relocations for - the medium code model. */ + the medium/large code models. */ #define PCREL_SUPPORTED_BY_OS (TARGET_POWER10 && TARGET_PREFIXED \ && ELFv2_ABI_CHECK \ -&& TARGET_CMODEL == CMODEL_MEDIUM) +&& (TARGET_CMODEL == CMODEL_MEDIUM \ +|| TARGET_CMODEL == CMODEL_LARGE)) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index cf86572b70c0..7b35a4ea0031 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -4373,12 +4373,15 @@ rs6000_option_override_internal (bool global_init_p) && (rs6000_isa_flags_explicit & OPTION_MASK_PCREL) == 0) rs6000_isa_flags |= OPTION_MASK_PCREL; - /* -mpcrel requires -mcmodel=medium, but we can't check TARGET_CMODEL until - after the subtarget override options are done. */ - else if (TARGET_PCREL && TARGET_CMODEL != CMODEL_MEDIUM) + /* -mpcrel requires medium or large code models, but we can't check + TARGET_CMODEL until after the subtarget override options are done. */ + else if (TARGET_PCREL + && TARGET_CMODEL != CMODEL_MEDIUM + && TARGET_CMODEL != CMODEL_LARGE) { if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0) - error ("%qs requires %qs", "-mpcrel", "-mcmodel=medium"); + error ("%qs requires %qs or %qs", "-mpcrel", "-mcmodel=medium", + "-mcmodel=large"); rs6000_isa_flags &= ~OPTION_MASK_PCREL; } @@ -21369,7 +21372,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl) ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); - if (TARGET_CMODEL == CMODEL_LARGE + if (TARGET_CMODEL == CMODEL_LARGE && !TARGET_PCREL && rs6000_global_entry_point_prologue_needed_p ()) { char buf[256]; diff --git a/gcc/testsuite/gcc.target/powerpc/pr120681.c b/gcc/testsuite/gcc.target/powerpc/pr120681.c new file mode 100644 index ..d883d1c8a951 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr120681.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* { dg-require-effective-target powerpc_pcrel } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2 -mcmodel=large" } */ + +/* PR target/120681 -- verify that -mcpu=power10 -mcmodel=large uses PC + relative addressing instead of using TOC addressing. */ + +#ifndef TYPE +#define TYPE unsigned long +#endif + +extern TYPE global_var; + +void +set_global (TYPE value) +{ + /* + * Generate: + * pld 9,global_var@got@pcrel + * std 3,0(9) + * + * Not: + * addis 9,2,.LC0@toc@ha + * ld9,.LC0@toc@l(9) + * std 3,0(9) + */ + + global_var = value; +} + +/* { dg-final { scan-assembler {@got@pcrel} } } */ +/* { dg-final { scan-assembler-not {@toc@ha}} } */ +/* { dg-final { scan-assembler-not {@toc@l} } } */
[gcc(refs/users/meissner/heads/work217-bugs)] Update ChangeLog.*
https://gcc.gnu.org/g:38501e5227561f090135f68153702b6e2d6a5514 commit 38501e5227561f090135f68153702b6e2d6a5514 Author: Michael Meissner Date: Wed Jul 30 01:19:34 2025 -0400 Update ChangeLog.* Diff: --- gcc/ChangeLog.bugs | 329 + 1 file changed, 329 insertions(+) diff --git a/gcc/ChangeLog.bugs b/gcc/ChangeLog.bugs index f79402345eee..5ca8e803434c 100644 --- a/gcc/ChangeLog.bugs +++ b/gcc/ChangeLog.bugs @@ -1,3 +1,332 @@ + Branch work217-bugs, patch #104 + +PR target/120681 - allow -mcmodel=large with PC relative addressing + +When I implemented the pc-relative support for power10 in GCC, I +disabled using pc-relative support for -mcmodel=large. At the time, I +didn't want to dig into the issues. It is now time to allow +-mcmodel=large to generate pc-relative code. + +This patch allows -mcmodel=large to use prefixed addressing on power10, +power11, and possibly other future PowerPC processors in addition to +the current -mcmodel=medium support. + +2025-07-30 Michael Meissner + +gcc/ + + PR target/120681 + * config/rs6000/linux64.h (PCREL_SUPPORTED_BY_OS): Allow large + code model as well as medium code model. + * config/rs6000/rs6000.cc (rs6000_option_override_internal): + Likewise. + (rs6000_elf_declare_function_name): Don't create the + local/non-local labels for large code model if we are using + PC-relative addressing. + +gcc/testsuite/ + + PR target/120681 + * gcc.target/powerpc/pr120681.c: New test. + + Branch work217-bugs, patch #103 + +PR target/108958 -- simplify mtvsrdd to zero extend GPR DImode to VSX TImode + +Before this patch GCC would zero extend a DImode GPR value to TImode by first +zero extending the DImode value into a GPR TImode register pair, and then do a +MTVSRDD to move this value to a VSX register. + +For example, consider the following code: + + #ifndef TYPE + #define TYPE unsigned long long + #endif + + void + gpr_to_vsx (TYPE x, __uint128_t *p) + { + __uint128_t y = x; + __asm__ (" # %x0" : "+wa" (y)); + *p = y; + } + +Currently GCC generates: + + gpr_to_vsx: + mr 10,3 + li 11,0 + mtvsrdd 0,11,10 + #APP +# 0 + #NO_APP + stxv 0,0(4) + blr + +I.e. the mr and li instructions create the zero extended TImode value +in a GPR, and then the mtvsrdd instruction moves both registers into a +single vector register. + +Instead, GCC should generate the following code. Since the mtvsrdd +instruction will clear the upper 64 bits if the 2nd argument is 0 +(non-zero values are a GPR to put in the upper 64 bits): + + gpr_to_vsx: + mtvsrdd 0,0,3 + #APP +# 0 + #NO_APP + stxv 0,0(4) + blr + +Originally, I posted a patch that added the zero_extendsiti2 insn. I +got some pushback about using reload_completed in the split portion of +the define_insn_and_split. However, this is a case where you +absolutely have to use the reload_completed test, because if you split +the code before register allocation to handle the normal, the split +insns will not be compiled to generate the appropriate mtvsrdd without +creating the TImode value in the GPR register. I can imagine there +might be concern about favoring generating code using the vector +registers instead of using the GPR registers if the code does not +require the TImode value to be in a vector register. + +I completely rewrote the patch. This patch creates a peephole2 to +catch this case, and it eliminates creating the TImode variable. +Instead it just does the MTVSRDD instruction directly. That way it +will not influence register allocation, and the code will only be +generated in the specific case where we need the TImode value in a +vector register. + +I have built GCC with the patches in this patch set applied on both +little and big endian PowerPC systems and there were no regressions. +Can I apply this patch to GCC 16? + +2025-07-30 Michael Meissner + +gcc/ + + PR target/108958 + * config/rs6000/rs6000.md (UNSPEC_ZERO_EXTEND): New unspec. + (zero_extendsiti2 peephole2): Add a peephole2 to simplify zero + extend between DImode value in a GPR to a TImode target in a + vector register. + (zero_extendsiti2_vsx): New insn. + +gcc/testsuite/ + + PR target/108958 + * gcc.target/powerpc/pr108958.c: New test. + + Branch work217-bugs, patch #102 + +PR target/120528 -- Simplify zero extend from memory to VSX register on power10 + +Previously GCC would zero extend a DImode value in memory to a TImode +target in a vector register by firt zero extending the DImode value +into a GPR TImode register pair, and then do a
[gcc r16-2613] testsuite: Generalise aarch64/saturating_arithmetic*.c
https://gcc.gnu.org/g:cc9c041fd1c84de8960bb2f3b30f8d53b059cba4 commit r16-2613-gcc9c041fd1c84de8960bb2f3b30f8d53b059cba4 Author: Richard Sandiford Date: Tue Jul 29 15:58:33 2025 +0100 testsuite: Generalise aarch64/saturating_arithmetic*.c gcc.target/aarch64/saturating_arithmetic_{1,2}.c expect w0 and w1 to be duplicated into vectors. The tests expected the duplication of w1 to happen first, but the other order would be fine too. A later simplify-rtx.cc patch happens to change the order. gcc/testsuite/ * gcc.target/aarch64/saturating_arithmetic_1.c: Allow w0 and w1 to be duplicated in either order. * gcc.target/aarch64/saturating_arithmetic_2.c: Likewise. Diff: --- gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c | 12 ++-- gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c | 8 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c index acd2e11f41d3..8fc1569845b5 100644 --- a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c +++ b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_1.c @@ -4,24 +4,24 @@ /* ** uadd: -** dup v([0-9]+).8b, w1 -** dup v([0-9]+).8b, w0 +** dup v([0-9]+).8b, w[01] +** dup v([0-9]+).8b, w[01] ** uqadd b([0-9]+), (?:b\2, b\1|b\1, b\2) ** umovw0, v\3.b\[0\] ** ret */ /* ** uadd2: -** dup v([0-9]+).8b, w1 -** dup v([0-9]+).8b, w0 +** dup v([0-9]+).8b, w[01] +** dup v([0-9]+).8b, w[01] ** uqadd b([0-9]+), (?:b\2, b\1|b\1, b\2) ** umovw0, v\3.b\[0\] ** ret */ /* ** usub: { xfail *-*-* } -** dup v([0-9]+).8b, w1 -** dup v([0-9]+).8b, w0 +** dup v([0-9]+).8b, w[01] +** dup v([0-9]+).8b, w[01] ** uqsub b([0-9]+), b\1, b\2 ** umovw0, v\3.b\[0\] ** ret diff --git a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c index 86c88f8447c3..dd0fefac6393 100644 --- a/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c +++ b/gcc/testsuite/gcc.target/aarch64/saturating_arithmetic_2.c @@ -4,16 +4,16 @@ /* ** uadd: -** dup v([0-9]+).4h, w1 -** dup v([0-9]+).4h, w0 +** dup v([0-9]+).4h, w[01] +** dup v([0-9]+).4h, w[01] ** uqadd h([0-9]+), (?:h\2, h\1|h\1, h\2) ** umovw0, v\3.h\[0\] ** ret */ /* ** uadd2: -** dup v([0-9]+).4h, w1 -** dup v([0-9]+).4h, w0 +** dup v([0-9]+).4h, w[01] +** dup v([0-9]+).4h, w[01] ** uqadd h([0-9]+), (?:h\2, h\1|h\1, h\2) ** umovw0, v\3.h\[0\] ** ret
[gcc r16-2612] testsuite: Make aarch64/cmpbr.c more forgiving
https://gcc.gnu.org/g:9c3f2cb35d03a33a49f996855e913be6d3af2437 commit r16-2612-g9c3f2cb35d03a33a49f996855e913be6d3af2437 Author: Richard Sandiford Date: Tue Jul 29 15:58:33 2025 +0100 testsuite: Make aarch64/cmpbr.c more forgiving The 8-bit and 16-bit tests in cmpbr.c assumed an inverted operand order ("w1, w0"), but it's possible to use the uninverted operand order too. This patch generalises the tests to support both forms. This is a prerequisite for a later patch that adds a new simplify-rtx.cc rule. gcc/testsuite/ * gcc.target/aarch64/cmpbr.c: Support both operand orders for 8-bit and 16-bit comparisons. Diff: --- gcc/testsuite/gcc.target/aarch64/cmpbr.c | 40 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr.c b/gcc/testsuite/gcc.target/aarch64/cmpbr.c index a86af9dce8e6..34630f9a2bfc 100644 --- a/gcc/testsuite/gcc.target/aarch64/cmpbr.c +++ b/gcc/testsuite/gcc.target/aarch64/cmpbr.c @@ -121,7 +121,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_eq_x1: -** cbbeq w1, w0, .L([0-9]+) +** cbbeq (?:w1, w0|w0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -129,7 +129,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_ne_x1: -** cbbne w1, w0, .L([0-9]+) +** cbbne (?:w1, w0|w0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -137,7 +137,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_ult_x1: -** cbbhi w1, w0, .L([0-9]+) +** (?:cbbhiw1, w0|cbblow0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -145,7 +145,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_ule_x1: -** cbbhs w1, w0, .L([0-9]+) +** (?:cbbhsw1, w0|cbblsw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -153,7 +153,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_ugt_x1: -** cbblo w1, w0, .L([0-9]+) +** (?:cbblow1, w0|cbbhiw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -161,7 +161,7 @@ FAR_BRANCH(u64, 42); /* ** u8_x0_uge_x1: -** cbbls w1, w0, .L([0-9]+) +** (?:cbblsw1, w0|cbbhsw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -169,7 +169,7 @@ FAR_BRANCH(u64, 42); /* ** i8_x0_slt_x1: -** cbbgt w1, w0, .L([0-9]+) +** (?:cbbgtw1, w0|cbbltw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -177,7 +177,7 @@ FAR_BRANCH(u64, 42); /* ** i8_x0_sle_x1: -** cbbge w1, w0, .L([0-9]+) +** (?:cbbgew1, w0|cbblew0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -185,7 +185,7 @@ FAR_BRANCH(u64, 42); /* ** i8_x0_sgt_x1: -** cbblt w1, w0, .L([0-9]+) +** (?:cbbltw1, w0|cbbgtw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -193,7 +193,7 @@ FAR_BRANCH(u64, 42); /* ** i8_x0_sge_x1: -** cbble w1, w0, .L([0-9]+) +** (?:cbblew1, w0|cbbgew0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -201,7 +201,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_eq_x1: -** cbheq w1, w0, .L([0-9]+) +** cbheq (?:w1, w0|w0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -209,7 +209,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_ne_x1: -** cbhne w0|w1, w1|w0, .L([0-9]+) +** cbhne (?:w1, w0|w0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -217,7 +217,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_ult_x1: -** cbhhi w1, w0, .L([0-9]+) +** (?:cbhhiw1, w0|cbhlow0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -225,7 +225,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_ule_x1: -** cbhhs w1, w0, .L([0-9]+) +** (?:cbhhsw1, w0|cbhlsw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -233,7 +233,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_ugt_x1: -** cbhlo w1, w0, .L([0-9]+) +** (?:cbhlow1, w0|cbhhiw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -241,7 +241,7 @@ FAR_BRANCH(u64, 42); /* ** u16_x0_uge_x1: -** cbhls w1, w0, .L([0-9]+) +** (?:cbhlsw1, w0|cbhhsw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -249,7 +249,7 @@ FAR_BRANCH(u64, 42); /* ** i16_x0_slt_x1: -** cbhgt w1, w0, .L([0-9]+) +** (?:cbhgtw1, w0|cbhltw0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -257,7 +257,7 @@ FAR_BRANCH(u64, 42); /* ** i16_x0_sle_x1: -** cbhge w1, w0, .L([0-9]+) +** (?:cbhgew1, w0|cbhlew0, w1), .L([0-9]+) ** b not_taken ** .L\1: ** b taken @@ -265,7 +265,7 @@ FAR_BRANCH(u64, 42); /* ** i16_x0
[gcc r16-2611] aarch64: Fix function_expander::get_reg_target
https://gcc.gnu.org/g:668936caf0662a4eea62144c98fdfc8cf30b79d8 commit r16-2611-g668936caf0662a4eea62144c98fdfc8cf30b79d8 Author: Richard Sandiford Date: Tue Jul 29 15:58:32 2025 +0100 aarch64: Fix function_expander::get_reg_target function_expander::get_reg_target didn't actually check for a register, meaning that it could return a memory target instead. That doesn't really matter for the current direct and indirect uses (svundef*, svcreate*, and svset*) but it will for later patches. gcc/ * config/aarch64/aarch64-sve-builtins.cc (function_expander::get_reg_target): Check whether the target is a valid register_operand. Diff: --- gcc/config/aarch64/aarch64-sve-builtins.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 2b627a950602..01833a8de732 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -4004,7 +4004,8 @@ rtx function_expander::get_reg_target () { machine_mode target_mode = result_mode (); - if (!possible_target || GET_MODE (possible_target) != target_mode) + if (!possible_target + || !register_operand (possible_target, target_mode)) possible_target = gen_reg_rtx (target_mode); return possible_target; }
[gcc r15-10086] c++, coroutines: Fix identification of coroutine ramps [PR120453].
https://gcc.gnu.org/g:4b2da16d0493f4154825ebdcbd8fad2f79a95ed5 commit r15-10086-g4b2da16d0493f4154825ebdcbd8fad2f79a95ed5 Author: Iain Sandoe Date: Thu May 29 11:00:18 2025 +0100 c++, coroutines: Fix identification of coroutine ramps [PR120453]. The existing implementation, incorrectly, tried to use DECL_RAMP_FN in check_return_expr to determine if we are handling a ramp func. However, that query is only set for the resume/destroy functions. Replace the use of DECL_RAMP_FN with a new query. PR c++/120453 gcc/cp/ChangeLog: * cp-tree.h (DECL_RAMP_P): New. * typeck.cc (check_return_expr): Use DECL_RAMP_P instead of DECL_RAMP_FN. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120453.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit 217b7f655227a52e5fe26729baa09dc6083ed577) Diff: --- gcc/cp/cp-tree.h | 4 ++ gcc/cp/typeck.cc | 2 +- gcc/testsuite/g++.dg/coroutines/pr120453.C | 95 ++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index eb32ec0ce4ed..619cd6bc1687 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5522,6 +5522,10 @@ decl_template_parm_check (const_tree t, const char *f, int l, const char *fn) #define DECL_RAMP_FN(NODE) \ (coro_get_ramp_function (NODE)) +/* For a FUNCTION_DECL this is true if it is a coroutine ramp. */ +#define DECL_RAMP_P(NODE) \ + DECL_COROUTINE_P (NODE) && !DECL_RAMP_FN (NODE) + /* True for an OMP_ATOMIC that has dependent parameters. These are stored as an expr in operand 1, and integer_zero_node or clauses in operand 0. */ #define OMP_ATOMIC_DEPENDENT_P(NODE) \ diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index f6693d99eb86..9cb821a7e9fc 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -11587,7 +11587,7 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) /* Don't check copy-initialization for NRV in a coroutine ramp; we implement this case as NRV, but it's specified as directly initializing the return value from get_return_object(). */ - if (DECL_RAMP_FN (current_function_decl) && named_return_value_okay_p) + if (DECL_RAMP_P (current_function_decl) && named_return_value_okay_p) converted = true; /* First convert the value to the function's return type, then diff --git a/gcc/testsuite/g++.dg/coroutines/pr120453.C b/gcc/testsuite/g++.dg/coroutines/pr120453.C new file mode 100644 index ..2f2c4ece008b --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr120453.C @@ -0,0 +1,95 @@ +// PR120453 - reduced testcase amended to add a TaskBase move constructor +// and a LazyTask destructor, to more closely match the original code. +// { dg-additional-options "-w" } +namespace std { +template struct __coroutine_traits_impl; +template + requires requires { typename _Result; } +struct __coroutine_traits_impl<_Result>; +template struct coroutine_traits : _Result {}; +template struct coroutine_handle { + static coroutine_handle from_address(void *); + operator coroutine_handle<>(); + void *address(); +}; +struct suspend_never { + bool await_ready(); + void await_suspend(coroutine_handle<>); + void await_resume(); +}; +} // namespace std + +namespace QCoro { +namespace detail { +template +concept has_await_methods = requires(T t) { t; }; +} // namespace detail + +template +concept Awaitable = detail::has_await_methods; +namespace detail { +struct TaskFinalSuspend { + bool await_ready() noexcept; + template + void await_suspend(std::coroutine_handle) noexcept; + void await_resume() noexcept; +}; +struct TaskPromiseBase { + std::suspend_never initial_suspend(); + auto final_suspend() noexcept { return TaskFinalSuspend{}; } + template auto &&await_transform(T &&); +}; +struct TaskPromise : TaskPromiseBase { + void unhandled_exception(); +}; +template struct TaskAwaiterBase { + bool await_ready(); + void await_suspend(std::coroutine_handle<>); +}; +template class, typename> struct TaskBase { + TaskBase() = default; + TaskBase(TaskBase &&) = default; + void operator=(TaskBase &&); + auto operator co_await() const; + std::coroutine_handle<> mCoroutine; +}; +} // namespace detail +template struct Task : detail::TaskBase {}; +} // namespace QCoro + +namespace QCoro::detail { +template auto &&TaskPromiseBase::await_transform(T &&awaitable) { + return awaitable; +} + +template class TaskImpl, typename PromiseType> +auto TaskBase::operator co_await() const { + class TaskAwaiter : public TaskAwaiterBase { + public: +TaskAwaiter(std::coroutine_handle<>); +auto await_resume() {} + }; + return TaskAwaiter{mCoroutine}; +} + +} // namespace QCoro::detail + +namespace QCoro { +template class LazyTask ; +namespace detail { +struct LazyTaskPromise : TaskProm
[gcc r16-2614] simplify-rtx: Simplify subregs of logic ops
https://gcc.gnu.org/g:965564eafb721f813a3112f1bba8d8fae32b commit r16-2614-g965564eafb721f813a3112f1bba8d8fae32b Author: Richard Sandiford Date: Tue Jul 29 15:58:34 2025 +0100 simplify-rtx: Simplify subregs of logic ops This patch adds a new rule for distributing lowpart subregs through ANDs, IORs, and XORs with a constant, in cases where one of the terms then disappears. For example: (lowart-subreg:QI (and:HI x 0x100)) simplifies to zero and (lowart-subreg:QI (and:HI x 0xff)) simplifies to (lowart-subreg:QI x). This would often be handled at some point using nonzero bits. However, the specific case I want the optimisation for is SVE predicates, where nonzero bit tracking isn't currently an option. Specifically: the predicate modes VNx8BI, VNx4BI and VNx2BI have the same size as VNx16BI, but treat only every second, fourth, or eighth bit as significant. Thus if we have: (subreg:VNx8BI (and:VNx16BI x C)) where C is the repeating constant { 1, 0, 1, 0, ... }, then the AND only clears bits that are made insignificant by the subreg, and so the result is equal to (subreg:VNx8BI x). Later patches rely on this. gcc/ * simplify-rtx.cc (simplify_context::simplify_subreg): Distribute lowpart subregs through AND/IOR/XOR, if doing so eliminates one of the terms. (test_scalar_int_ext_ops): Add some tests of the above for integers. * config/aarch64/aarch64.cc (aarch64_test_sve_folding): Likewise add tests for predicate modes. Diff: --- gcc/config/aarch64/aarch64.cc | 34 gcc/simplify-rtx.cc | 75 ++- 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index cb1699ab7c5c..a6d6bed97e8a 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -31964,9 +31964,43 @@ aarch64_test_sysreg_encoding_clashes (void) static void aarch64_test_sve_folding () { + aarch64_target_switcher switcher (AARCH64_FL_SVE); + tree res = fold_unary (BIT_NOT_EXPR, ssizetype, ssize_int (poly_int64 (1, 1))); ASSERT_TRUE (operand_equal_p (res, ssize_int (poly_int64 (-2, -1; + + auto build_v16bi = [](bool a, bool b) +{ + rtx_vector_builder builder (VNx16BImode, 2, 1); + builder.quick_push (a ? const1_rtx : const0_rtx); + builder.quick_push (b ? const1_rtx : const0_rtx); + return builder.build (); +}; + rtx v16bi_10 = build_v16bi (1, 0); + rtx v16bi_01 = build_v16bi (0, 1); + + for (auto mode : { VNx8BImode, VNx4BImode, VNx2BImode }) +{ + rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1); + rtx subreg = lowpart_subreg (VNx16BImode, reg, mode); + rtx and1 = simplify_gen_binary (AND, VNx16BImode, subreg, v16bi_10); + ASSERT_EQ (lowpart_subreg (mode, and1, VNx16BImode), reg); + rtx and0 = simplify_gen_binary (AND, VNx16BImode, subreg, v16bi_01); + ASSERT_EQ (lowpart_subreg (mode, and0, VNx16BImode), CONST0_RTX (mode)); + + rtx ior1 = simplify_gen_binary (IOR, VNx16BImode, subreg, v16bi_10); + ASSERT_EQ (lowpart_subreg (mode, ior1, VNx16BImode), CONSTM1_RTX (mode)); + rtx ior0 = simplify_gen_binary (IOR, VNx16BImode, subreg, v16bi_01); + ASSERT_EQ (lowpart_subreg (mode, ior0, VNx16BImode), reg); + + rtx xor1 = simplify_gen_binary (XOR, VNx16BImode, subreg, v16bi_10); + ASSERT_RTX_EQ (lowpart_subreg (mode, xor1, VNx16BImode), +lowpart_subreg (mode, gen_rtx_NOT (VNx16BImode, subreg), +VNx16BImode)); + rtx xor0 = simplify_gen_binary (XOR, VNx16BImode, subreg, v16bi_01); + ASSERT_EQ (lowpart_subreg (mode, xor0, VNx16BImode), reg); +} } /* Run all target-specific selftests. */ diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index cbe61b49bf69..125048da1817 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -8394,9 +8394,45 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op, && VECTOR_MODE_P (innermode) && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode)) && known_eq (GET_MODE_UNIT_SIZE (outermode), - GET_MODE_UNIT_SIZE (innermode))) + GET_MODE_UNIT_SIZE (innermode))) return simplify_gen_relational (GET_CODE (op), outermode, innermode, XEXP (op, 0), XEXP (op, 1)); + + /* Distribute lowpart subregs through logic ops in cases where one term + disappears. + + (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X) + (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1) + (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X)) + + if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones. + + (subreg:M1 (and:M2 X C2)) ->
[gcc r15-10085] c++, coroutines: Allow NVRO in more cases for ramp functions.
https://gcc.gnu.org/g:491b8b29ff58353fa840b08087a9151c650a2ef8 commit r15-10085-g491b8b29ff58353fa840b08087a9151c650a2ef8 Author: Iain Sandoe Date: Sat May 10 17:22:55 2025 +0100 c++, coroutines: Allow NVRO in more cases for ramp functions. The constraints of the c++ coroutines specification require the ramp to construct a return object early in the function. This will be returned at some later time. This is implemented as NVRO but requires that copying be well-formed even though it will be elided. Special-case ramp functions to allow this. gcc/cp/ChangeLog: * typeck.cc (check_return_expr): Suppress conversions for NVRO in coroutine ramp functions. Signed-off-by: Iain Sandoe (cherry picked from commit d87caa9d3595ca845c9282cef8b0c9a656d8def0) Diff: --- gcc/cp/typeck.cc | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index fb5b04f28e86..f6693d99eb86 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -11584,6 +11584,12 @@ check_return_expr (tree retval, bool *no_warning, bool *dangling) && call_from_lambda_thunk_p (retval)) converted = true; + /* Don't check copy-initialization for NRV in a coroutine ramp; we +implement this case as NRV, but it's specified as directly +initializing the return value from get_return_object(). */ + if (DECL_RAMP_FN (current_function_decl) && named_return_value_okay_p) + converted = true; + /* First convert the value to the function's return type, then to the type of return value's location to handle the case that functype is smaller than the valtype. */
[gcc r15-10084] c++: Set the outer brace marker for missed cases.
https://gcc.gnu.org/g:868a11b2f9a874071112f43cacdd65d5d399c26a commit r15-10084-g868a11b2f9a874071112f43cacdd65d5d399c26a Author: Iain Sandoe Date: Sat May 10 17:12:44 2025 +0100 c++: Set the outer brace marker for missed cases. In some cases, a function might be declared as FUNCTION_NEEDS_BODY_BLOCK but all the content is contained within that block. However, poplevel is currently assuming that such cases would always contain subblocks. In the case that we do have a body block, but there are no subblocks then st the outer brace marker on the body block. This situation occurs for at least coroutine lambda ramp functions and empty constructors. gcc/cp/ChangeLog: * decl.cc (poplevel): Set BLOCK_OUTER_CURLY_BRACE_P on the body block for functions with no subblocks. Signed-off-by: Iain Sandoe (cherry picked from commit 689bc394efe9e042acb37799deec6568c0f63a45) Diff: --- gcc/cp/decl.cc | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 4e97093b1341..9cf75936d7af 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -846,11 +846,9 @@ poplevel (int keep, int reverse, int functionbody) DECL_INITIAL (current_function_decl) = block ? block : subblocks; if (subblocks) { - if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) - { - if (BLOCK_SUBBLOCKS (subblocks)) - BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1; - } + if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl) + && BLOCK_SUBBLOCKS (subblocks)) + BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1; else BLOCK_OUTER_CURLY_BRACE_P (subblocks) = 1; }
[gcc r16-2615] RISC-V: Generate -mcpu and -mtune options from riscv-cores.def.
https://gcc.gnu.org/g:b752a4df1232f54bb66fa0f7343118b593e0a6de commit r16-2615-gb752a4df1232f54bb66fa0f7343118b593e0a6de Author: Dongyan Chen Date: Wed Jun 25 21:20:25 2025 +0800 RISC-V: Generate -mcpu and -mtune options from riscv-cores.def. Automatically generate -mcpu and -mtune options in invoke.texi from the unified riscv-cores.def metadata, ensuring documentation stays in sync with definitions and reducing manual maintenance. gcc/ChangeLog: * Makefile.in: Add riscv-mcpu.texi and riscv-mtune.texi to the list of files to be processed by the Texinfo generator. * config/riscv/t-riscv: Add rule for generating riscv-mcpu.texi and riscv-mtune.texi. * doc/invoke.texi: Replace hand‑written extension table with `@include riscv-mcpu.texi` and `@include riscv-mtune.texi` to pull in auto‑generated entries. * config/riscv/gen-riscv-mcpu-texi.cc: New file. * config/riscv/gen-riscv-mtune-texi.cc: New file. * doc/riscv-mcpu.texi: New file. * doc/riscv-mtune.texi: New file. Diff: --- gcc/Makefile.in | 2 +- gcc/config/riscv/gen-riscv-mcpu-texi.cc | 43 gcc/config/riscv/gen-riscv-mtune-texi.cc | 41 +++ gcc/config/riscv/t-riscv | 37 - gcc/doc/invoke.texi | 23 ++- gcc/doc/riscv-mcpu.texi | 69 gcc/doc/riscv-mtune.texi | 59 +++ 7 files changed, 251 insertions(+), 23 deletions(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 7314a3b42252..d7d5cbe72770 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3720,7 +3720,7 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi\ contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \ fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi \ implement-c.texi implement-cxx.texi gcov-tool.texi gcov-dump.texi \ -lto-dump.texi riscv-ext.texi +lto-dump.texi riscv-ext.texi riscv-mcpu.texi riscv-mtune.texi # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with # the generated tm.texi; the latter might have a more recent timestamp, diff --git a/gcc/config/riscv/gen-riscv-mcpu-texi.cc b/gcc/config/riscv/gen-riscv-mcpu-texi.cc new file mode 100644 index ..9681438fb9fd --- /dev/null +++ b/gcc/config/riscv/gen-riscv-mcpu-texi.cc @@ -0,0 +1,43 @@ +#include +#include +#include + +int +main () +{ + puts ("@c Copyright (C) 2025 Free Software Foundation, Inc."); + puts ("@c This is part of the GCC manual."); + puts ("@c For copying conditions, see the file gcc/doc/include/fdl.texi."); + puts (""); + puts ("@c This file is generated automatically using"); + puts ("@c gcc/config/riscv/gen-riscv-mcpu-texi.cc from:"); + puts ("@c gcc/config/riscv/riscv-cores.def"); + puts (""); + puts ("@c Please *DO NOT* edit manually."); + puts (""); + puts ("@samp{Core Name}"); + puts (""); + puts ("@opindex mcpu"); + puts ("@item -mcpu=@var{processor-string}"); + puts ("Use architecture of and optimize the output for the given processor, specified"); + puts ("by particular CPU name. Permissible values for this option are:"); + puts (""); + puts (""); + + std::vector coreNames; + +#define RISCV_CORE(CORE_NAME, ARCH, MICRO_ARCH) \ + coreNames.push_back (CORE_NAME); +#include "riscv-cores.def" +#undef RISCV_CORE + + for (size_t i = 0; i < coreNames.size(); ++i) { +if (i == coreNames.size() - 1) { + printf("@samp{%s}.\n", coreNames[i].c_str()); +} else { + printf("@samp{%s},\n\n", coreNames[i].c_str()); +} + } + + return 0; +} diff --git a/gcc/config/riscv/gen-riscv-mtune-texi.cc b/gcc/config/riscv/gen-riscv-mtune-texi.cc new file mode 100644 index ..1bdfe2ad00f1 --- /dev/null +++ b/gcc/config/riscv/gen-riscv-mtune-texi.cc @@ -0,0 +1,41 @@ +#include +#include +#include + +int +main () +{ + puts ("@c Copyright (C) 2025 Free Software Foundation, Inc."); + puts ("@c This is part of the GCC manual."); + puts ("@c For copying conditions, see the file gcc/doc/include/fdl.texi."); + puts (""); + puts ("@c This file is generated automatically using"); + puts ("@c gcc/config/riscv/gen-riscv-mtune-texi.cc from:"); + puts ("@c gcc/config/riscv/riscv-cores.def"); + puts (""); + puts ("@c Please *DO NOT* edit manually."); + puts (""); + puts ("@samp{Tune Name}"); + puts (""); + puts ("@opindex mtune"); + puts ("@item -mtune=@var{processor-string}"); + puts ("Optimize the output for the given processor, specified by microarchitecture or"); + puts ("particular CPU name. Permissible values for this option are:"); + puts (""); + puts (""); + + std::vector tuneNames; + +#define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
[gcc r15-10087] c++, coroutines: Address CWG2563 return value init [PR119916].
https://gcc.gnu.org/g:db4a02ca42cf25d6ab602e9cad067f8bdf26ab6d commit r15-10087-gdb4a02ca42cf25d6ab602e9cad067f8bdf26ab6d Author: Iain Sandoe Date: Mon May 12 19:47:42 2025 +0100 c++, coroutines: Address CWG2563 return value init [PR119916]. This addresses the clarification that, when the get_return_object is of a different type from the ramp return, any necessary conversions should be performed on the return expression (so that they typically occur after the function body has started execution). PR c++/119916 gcc/cp/ChangeLog: * coroutines.cc (cp_coroutine_transform::wrap_original_function_body): Do not initialise initial_await_resume_called here... (cp_coroutine_transform::build_ramp_function): ... but here. When the coroutine is not void, initialize a GRO object from promise.get_return_object(). Use this as the argument to the return expression. Use a regular cleanup for the GRO, since it is ramp-local. gcc/testsuite/ChangeLog: * g++.dg/coroutines/torture/special-termination-00-sync-completion.C: Amend for CWG2563 expected behaviour. * g++.dg/coroutines/torture/special-termination-01-self-destruct.C: Likewise. * g++.dg/coroutines/torture/pr119916.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit e06555a40c051d5062405b02f93b89b01a397f97) Diff: --- gcc/cp/coroutines.cc | 126 +++-- gcc/testsuite/g++.dg/coroutines/torture/pr119916.C | 66 +++ .../special-termination-00-sync-completion.C | 2 +- .../torture/special-termination-01-self-destruct.C | 2 +- 4 files changed, 109 insertions(+), 87 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index b92d09fa4ead..6280b1d1ad43 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4468,7 +4468,7 @@ cp_coroutine_transform::wrap_original_function_body () tree i_a_r_c = coro_build_artificial_var (loc, coro_frame_i_a_r_c_id, boolean_type_node, orig_fn_decl, -boolean_false_node); +NULL_TREE); DECL_CHAIN (i_a_r_c) = var_list; var_list = i_a_r_c; add_decl_expr (i_a_r_c); @@ -4884,7 +4884,6 @@ cp_coroutine_transform::build_ramp_function () add_decl_expr (coro_fp); tree coro_promise_live = NULL_TREE; - tree coro_gro_live = NULL_TREE; if (flag_exceptions) { /* Signal that we need to clean up the promise object on exception. */ @@ -4893,13 +4892,6 @@ cp_coroutine_transform::build_ramp_function () boolean_type_node, orig_fn_decl, boolean_false_node); - /* When the get-return-object is in the RETURN slot, we need to arrange -for cleanup on exception. */ - coro_gro_live - = coro_build_and_push_artificial_var (loc, "_Coro_gro_live", - boolean_type_node, orig_fn_decl, - boolean_false_node); - /* To signal that we need to cleanup copied function args. */ if (DECL_ARGUMENTS (orig_fn_decl)) for (tree arg = DECL_ARGUMENTS (orig_fn_decl); arg != NULL; @@ -4987,13 +4979,19 @@ cp_coroutine_transform::build_ramp_function () tree ramp_try_block = NULL_TREE; tree ramp_try_stmts = NULL_TREE; tree iarc_x = NULL_TREE; + tree coro_before_return = NULL_TREE; if (flag_exceptions) { + coro_before_return + = coro_build_and_push_artificial_var (loc, "_Coro_before_return", + boolean_type_node, orig_fn_decl, + boolean_true_node); iarc_x = coro_build_and_push_artificial_var_with_dve (loc, coro_frame_i_a_r_c_id, boolean_type_node, - orig_fn_decl, NULL_TREE, + orig_fn_decl, + boolean_false_node, deref_fp); ramp_try_block = begin_try_block (); ramp_try_stmts = begin_compound_stmt (BCS_TRY_BLOCK); @@ -5153,90 +5151,54 @@ cp_coroutine_transform::build_ramp_function () (loc, coro_resume_index_id, short_unsigned_type_node, orig_fn_decl, build_zero_cst (short_unsigned_type_node), deref_fp); - if (flag_exceptions && iarc_x) -{ - r = cp_build_init_expr (iarc_x, boolean_false_node); - finish_expr_stmt (r); -} - - /* Used for return objects in the RESULT slot. */ -
[gcc r15-10089] c++, coroutines: Clean up the ramp cleanups.
https://gcc.gnu.org/g:ae9ccc700bda405b387cd0a6318b00138027f388 commit r15-10089-gae9ccc700bda405b387cd0a6318b00138027f388 Author: Iain Sandoe Date: Mon May 12 20:38:48 2025 +0100 c++, coroutines: Clean up the ramp cleanups. This replaces the cleanup try-catch block in the ramp with a series of eh-only cleanup statements. Includes typo fixes from 83aa09e90487b52c1772eeffc4af577ee70536f1 dead code removal from 7bba8d48ea556a03bdc4e9076740b83d3db6599e gcc/cp/ChangeLog: * coroutines.cc (analyze_fn_parms): No longer create a parameter copy guard var. (cp_coroutine_transform::build_ramp_function): Replace ramp cleanup try-catch block with eh-only cleanup statements. * coroutines.h (struct param_info): Remove the entry for the parameter copy destructor guard. Signed-off-by: Iain Sandoe (cherry picked from commit 18df4a10bc96946401218019ec566d867238b3e4) Diff: --- gcc/cp/coroutines.cc | 211 +++ gcc/cp/coroutines.h | 1 - 2 files changed, 63 insertions(+), 149 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 39372239c8de..04ed5531997a 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4106,17 +4106,7 @@ analyze_fn_parms (tree orig, hash_map *param_uses) } parm.field_id = name; if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (parm.frame_type)) - { - char *buf = xasprintf ("_Coro_q%u_%s_live", parm_num, -DECL_NAME (arg) ? IDENTIFIER_POINTER (name) -: "__unnamed"); - parm.guard_var - = coro_build_artificial_var (UNKNOWN_LOCATION, get_identifier (buf), -boolean_type_node, orig, -boolean_false_node); - free (buf); - parm.trivial_dtor = false; - } + parm.trivial_dtor = false; else parm.trivial_dtor = true; } @@ -4883,39 +4873,6 @@ cp_coroutine_transform::build_ramp_function () coro_fp = pushdecl (coro_fp); add_decl_expr (coro_fp); - tree coro_promise_live = NULL_TREE; - if (flag_exceptions) -{ - /* Signal that we need to clean up the promise object on exception. */ - coro_promise_live - = coro_build_and_push_artificial_var (loc, "_Coro_promise_live", - boolean_type_node, orig_fn_decl, - boolean_false_node); - - /* To signal that we need to cleanup copied function args. */ - if (DECL_ARGUMENTS (orig_fn_decl)) - for (tree arg = DECL_ARGUMENTS (orig_fn_decl); arg != NULL; -arg = DECL_CHAIN (arg)) - { - param_info *parm_i = param_uses.get (arg); - if (parm_i->trivial_dtor) - continue; - parm_i->guard_var = pushdecl (parm_i->guard_var); - add_decl_expr (parm_i->guard_var); - } -} - - /* deref the frame pointer, to use in member access code. */ - tree deref_fp -= cp_build_indirect_ref (loc, coro_fp, RO_UNARY_STAR, -tf_warning_or_error); - tree frame_needs_free -= coro_build_and_push_artificial_var_with_dve (loc, - coro_frame_needs_free_id, - boolean_type_node, - orig_fn_decl, NULL_TREE, - deref_fp); - /* Build the frame. */ /* The CO_FRAME internal function is a mechanism to allow the middle end @@ -4959,25 +4916,23 @@ cp_coroutine_transform::build_ramp_function () finish_if_stmt (if_stmt); } + /* Dereference the frame pointer, to use in member access code. */ + tree deref_fp += cp_build_indirect_ref (loc, coro_fp, RO_UNARY_STAR, tf_warning_or_error); + /* For now, once allocation has succeeded we always assume that this needs destruction, there's no impl. for frame allocation elision. */ - r = cp_build_init_expr (frame_needs_free, boolean_true_node); - finish_expr_stmt (r); - - /* Set up the promise. */ - tree p -= coro_build_and_push_artificial_var_with_dve (loc, coro_promise_id, - promise_type, orig_fn_decl, - NULL_TREE, deref_fp); + tree frame_needs_free += coro_build_and_push_artificial_var_with_dve (loc, + coro_frame_needs_free_id, + boolean_type_node, + orig_fn_decl, + boolean_true_node, + deref_fp); + /*
[gcc r15-10088] c++, coroutines: Use decltype(auto) for the g_r_o.
https://gcc.gnu.org/g:df99f2de811719acb993ef23c6851163c5a3b9d4 commit r15-10088-gdf99f2de811719acb993ef23c6851163c5a3b9d4 Author: Iain Sandoe Date: Sun May 11 20:36:58 2025 +0100 c++, coroutines: Use decltype(auto) for the g_r_o. The revised wording for coroutines, uses decltype(auto) for the type of the get return object, which preserves references. It is quite reasonable for a coroutine body implementation to complete before control is returned to the ramp - and in that case we would be creating the ramp return object from an already- deleted promise object. Jason observes that this is a terrible situation and we should seek a resolution to it via core. Since the test added here explicitly performs the unsafe action dscribed above we expect it to fail (until a resolution is found). gcc/cp/ChangeLog: * coroutines.cc (cp_coroutine_transform::build_ramp_function): Use decltype(auto) to determine the type of the temporary get_return_object. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr115908.C: Count promise construction and destruction. Run the test and XFAIL it. Signed-off-by: Iain Sandoe (cherry picked from commit e71a6e002c6650a7a7be99277120d3e59ecb78a3) Diff: --- gcc/cp/coroutines.cc | 12 +++-- gcc/testsuite/g++.dg/coroutines/pr115908.C | 86 ++ 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 6280b1d1ad43..39372239c8de 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -5137,8 +5137,11 @@ cp_coroutine_transform::build_ramp_function () /* Check for a bad get return object type. [dcl.fct.def.coroutine] / 7 requires: The expression promise.get_return_object() is used to initialize the - returned reference or prvalue result object ... */ - tree gro_type = TREE_TYPE (get_ro); + returned reference or prvalue result object ... + When we use a local to hold this, it is decltype(auto). */ + tree gro_type += finish_decltype_type (get_ro, /*id_expression_or_member_access_p*/false, + tf_warning_or_error); if (VOID_TYPE_P (gro_type) && !void_ramp_p) { error_at (fn_start, "no viable conversion from % provided by" @@ -5176,7 +5179,7 @@ cp_coroutine_transform::build_ramp_function () = coro_build_and_push_artificial_var (loc, "_Coro_gro", gro_type, orig_fn_decl, NULL_TREE); - r = cp_build_init_expr (coro_gro, get_ro); + r = cp_build_init_expr (coro_gro, STRIP_REFERENCE_REF (get_ro)); finish_expr_stmt (r); tree coro_gro_cleanup = cxx_maybe_build_cleanup (coro_gro, tf_warning_or_error); @@ -5198,7 +5201,8 @@ cp_coroutine_transform::build_ramp_function () /* The ramp is done, we just need the return statement, which we build from the return object we constructed before we called the function body. */ - finish_return_stmt (void_ramp_p ? NULL_TREE : coro_gro); + r = void_ramp_p ? NULL_TREE : convert_from_reference (coro_gro); + finish_return_stmt (r); if (flag_exceptions) { diff --git a/gcc/testsuite/g++.dg/coroutines/pr115908.C b/gcc/testsuite/g++.dg/coroutines/pr115908.C index ac27d916de2b..a40cece11438 100644 --- a/gcc/testsuite/g++.dg/coroutines/pr115908.C +++ b/gcc/testsuite/g++.dg/coroutines/pr115908.C @@ -1,3 +1,16 @@ +// { dg-do run } + +// With the changes to deal with CWG2563 (and PR119916) we now use the +// referenced promise in the return expression. It is quite reasonable +// for a body implementation to complete before control is returned to +// the ramp - and in that case we would be creating the ramp return object +// from an already-deleted promise object. +// This is recognised to be a poor situation and resolution via a core +// issue is planned. + +// In this test we explicitly trigger the circumstance mentioned above. +// { dg-xfail-run-if "" { *-*-* } } + #include #ifdef OUTPUT @@ -6,23 +19,25 @@ struct Promise; -bool promise_live = false; +int promise_life = 0; struct Handle : std::coroutine_handle { + Handle(Promise &p) : std::coroutine_handle(Handle::from_promise(p)) { -if (!promise_live) - __builtin_abort (); #ifdef OUTPUT -std::cout << "Handle(Promise &)\n"; +std::cout << "Handle(Promise &) " << promise_life << std::endl; #endif -} -Handle(Promise &&p) : std::coroutine_handle(Handle::from_promise(p)) { -if (!promise_live) + if (promise_life <= 0) __builtin_abort (); + } + +Handle(Promise &&p) : std::coroutine_handle(Handle::from_promise(p)) { #ifdef OUTPUT -std::cout << "Handle(Promise &&)\n"; +std::cout << "Handle(Promise &&) " << promise_life << std::endl; #endif -} + i
[gcc r16-2610] [modula2] Tidyup remove unused local variables
https://gcc.gnu.org/g:21e16e4a1ab2d665d4ba662281ec404563e4ff58 commit r16-2610-g21e16e4a1ab2d665d4ba662281ec404563e4ff58 Author: Gaius Mulley Date: Tue Jul 29 15:52:58 2025 +0100 [modula2] Tidyup remove unused local variables This patch removes unused local variables from three procedures. gcc/m2/ChangeLog: * gm2-compiler/M2GenGCC.mod (FoldBecomes): Remove all local variables. (CodeIndrX): Remove length. Remove newstr. * gm2-compiler/M2Range.mod (FoldTypeIndrX): Remove desType. Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-compiler/M2GenGCC.mod | 5 - gcc/m2/gm2-compiler/M2Range.mod | 2 -- 2 files changed, 7 deletions(-) diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod index 4a9ced32dcfa..2507c536181c 100644 --- a/gcc/m2/gm2-compiler/M2GenGCC.mod +++ b/gcc/m2/gm2-compiler/M2GenGCC.mod @@ -2903,9 +2903,6 @@ END CheckStop ; *) PROCEDURE FoldBecomes (p: WalkAction; bb: BasicBlock; quad: CARDINAL) ; -VAR - op: QuadOperator ; - des, op2, expr: CARDINAL ; BEGIN IF DeclaredOperandsBecomes (p, quad) THEN @@ -8154,8 +8151,6 @@ VAR rightpos, typepos, indrxpos: CARDINAL ; - length, - newstr : tree ; location: location_t ; BEGIN GetQuadOtok (quad, indrxpos, op, left, type, right, diff --git a/gcc/m2/gm2-compiler/M2Range.mod b/gcc/m2/gm2-compiler/M2Range.mod index dcac2ba33c53..f1516d3a5e50 100644 --- a/gcc/m2/gm2-compiler/M2Range.mod +++ b/gcc/m2/gm2-compiler/M2Range.mod @@ -1869,14 +1869,12 @@ END FoldTypeAssign ; PROCEDURE FoldTypeIndrX (q: CARDINAL; tokenNo: CARDINAL; des, expr: CARDINAL; r: CARDINAL) ; VAR - desType, exprType: CARDINAL ; BEGIN (* Need to skip over a variable or temporary in des and expr so long as expr is not a procedure. In the case of des = *expr, both expr and des will be variables due to the property of indirection. *) - desType := GetType (des) ; IF IsProcedure (expr) THEN (* Must not GetType for a procedure as it gives the return type. *)
[gcc r15-10093] c++, coroutines: Some cleanups in build_actor.
https://gcc.gnu.org/g:f3fbacc8fd4fd9a488491394cd49fb88915db8fc commit r15-10093-gf3fbacc8fd4fd9a488491394cd49fb88915db8fc Author: Iain Sandoe Date: Sat May 31 16:13:40 2025 +0100 c++, coroutines: Some cleanups in build_actor. We were incorrectly guarding all the frame cleanups on the basis of frame_needs_free (which is always set for the present code-gen since we have no allocation elision). The net result being that the (incorrect) code was behaving as expected. We built, but never used, a label for the frame destruction; in practice it is never triggered independently of the promise and argument copy destruction. Finally there are a few instances where we had been building expressions manually rather than using higher-level APIs. gcc/cp/ChangeLog: * coroutines.cc (build_actor_fn): Remove an unused label, guard the frame deallocation correctly, use simpler APIs to build if and return statements. Signed-off-by: Iain Sandoe (cherry picked from commit 7037c72a8bb41ed07da64b23e14857a066a91baa) Diff: --- gcc/cp/coroutines.cc | 58 +++- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index a8e5143c54dd..c1eaf0ebb122 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2558,8 +2558,8 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Finish the resume dispatcher. */ finish_switch_stmt (dispatcher); - finish_else_clause (lsb_if); + finish_else_clause (lsb_if); finish_if_stmt (lsb_if); /* If we reach here then we've hit UB. */ @@ -2599,69 +2599,53 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* Add in our function body with the co_returns rewritten to final form. */ add_stmt (fnbody); - /* now do the tail of the function. */ + /* Now do the tail of the function; first cleanups. */ r = build_stmt (loc, LABEL_EXPR, del_promise_label); add_stmt (r); - /* Destructors for the things we built explicitly. */ + /* Destructors for the things we built explicitly. + promise... */ if (tree c = cxx_maybe_build_cleanup (promise_proxy, tf_warning_or_error)) -add_stmt (c); - - tree del_frame_label -= create_named_label_with_ctx (loc, "coro.delete.frame", actor); - r = build_stmt (loc, LABEL_EXPR, del_frame_label); - add_stmt (r); - - /* Here deallocate the frame (if we allocated it), which we will have at - present. */ - tree fnf2_x - = coro_build_frame_access_expr (actor_frame, coro_frame_needs_free_id, - false, tf_warning_or_error); +finish_expr_stmt (c); - tree need_free_if = begin_if_stmt (); - fnf2_x = build1 (CONVERT_EXPR, integer_type_node, fnf2_x); - tree cmp = build2 (NE_EXPR, integer_type_node, fnf2_x, integer_zero_node); - finish_if_stmt_cond (cmp, need_free_if); + /* Argument copies ... */ while (!param_dtor_list->is_empty ()) { tree parm_id = param_dtor_list->pop (); tree a = coro_build_frame_access_expr (actor_frame, parm_id, false, tf_warning_or_error); if (tree dtor = cxx_maybe_build_cleanup (a, tf_warning_or_error)) - add_stmt (dtor); + finish_expr_stmt (dtor); } + /* Here deallocate the frame (if we allocated it), which we will have at + present. */ + tree fnf2_x + = coro_build_frame_access_expr (actor_frame, coro_frame_needs_free_id, + false, tf_warning_or_error); + tree need_free_if = begin_if_stmt (); + finish_if_stmt_cond (fnf2_x, need_free_if); + /* Build the frame DTOR. */ tree del_coro_fr = build_coroutine_frame_delete_expr (actor_fp, frame_size, promise_type, loc); finish_expr_stmt (del_coro_fr); finish_then_clause (need_free_if); - tree scope = IF_SCOPE (need_free_if); - IF_SCOPE (need_free_if) = NULL; - r = do_poplevel (scope); - add_stmt (r); + finish_if_stmt (need_free_if); - /* done. */ - r = build_stmt (loc, RETURN_EXPR, NULL); - suppress_warning (r); /* We don't want a warning about this. */ - r = maybe_cleanup_point_expr_void (r); - add_stmt (r); + /* Done. */ + finish_return_stmt (NULL_TREE); /* This is the suspend return point. */ - r = build_stmt (loc, LABEL_EXPR, ret_label); - add_stmt (r); + add_stmt (build_stmt (loc, LABEL_EXPR, ret_label)); - r = build_stmt (loc, RETURN_EXPR, NULL); - suppress_warning (r); /* We don't want a warning about this. */ - r = maybe_cleanup_point_expr_void (r); - add_stmt (r); + finish_return_stmt (NULL_TREE); /* This is the 'continuation' return point. For such a case we have a coro handle (from the await_suspend() call) and we want handle.resume() to execute as a tailcall allowing arbitra
[gcc r15-10092] c++: Emit an error for attempted constexpr co_await [PR118903].
https://gcc.gnu.org/g:b9b3471a9eb3f490b74b57236b4c122045dbcf56 commit r15-10092-gb9b3471a9eb3f490b74b57236b4c122045dbcf56 Author: Iain Sandoe Date: Fri May 30 20:09:40 2025 +0100 c++: Emit an error for attempted constexpr co_await [PR118903]. We checked that the coroutine expressions were not suitable for constexpr, but did not emit and error when needed. PR c++/118903 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1): Emit an error when co_await et. al. are used in constexpr contexts. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr118903.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit 0ae77a05c416c9f750cb87f1bef0800651168b7e) Diff: --- gcc/cp/constexpr.cc| 3 +++ gcc/testsuite/g++.dg/coroutines/pr118903.C | 40 ++ 2 files changed, 43 insertions(+) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 9c034e83d47a..18cc7339507e 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -11035,6 +11035,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, case CO_AWAIT_EXPR: case CO_YIELD_EXPR: case CO_RETURN_EXPR: + if (flags & tf_error) + constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p, +"%qE is not a constant expression", t); return false; /* Assume a TU-local entity is not constant, we'll error later when diff --git a/gcc/testsuite/g++.dg/coroutines/pr118903.C b/gcc/testsuite/g++.dg/coroutines/pr118903.C new file mode 100644 index ..a577a9a0a552 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr118903.C @@ -0,0 +1,40 @@ +// { dg-additional-options "-fsyntax-only" } + +#include + +struct awaitable { +constexpr bool await_ready() { +return true; +} +void await_suspend(std::coroutine_handle) { + +} +constexpr int await_resume() { +return 42; +} +}; + +struct super_simple_coroutine { +struct promise_type { +constexpr auto initial_suspend() { +return std::suspend_never(); +} +constexpr auto final_suspend() const noexcept { +return std::suspend_never(); +} +constexpr void unhandled_exception() { +// do nothing +} +constexpr auto get_return_object() { +return super_simple_coroutine{}; +} +constexpr void return_void() { +} +}; +}; + +auto fib (float f) -> super_simple_coroutine { +// if `co_await` is part of BodyStatement of a function +// it makes it coroutine +constexpr int x = co_await awaitable{}; // { dg-error {'co_await awaitable..' is not a constant expression} } +}
[gcc r15-10090] c++, coroutines: Make a check more specific [PR109283].
https://gcc.gnu.org/g:20a4cf9f96fee2872c415055179fc3353f37e7f0 commit r15-10090-g20a4cf9f96fee2872c415055179fc3353f37e7f0 Author: Iain Sandoe Date: Thu May 29 15:45:29 2025 +0100 c++, coroutines: Make a check more specific [PR109283]. The check was intended to assert that we had visited contained ternary expressions with embedded co_awaits, but had been made too general - and therefore was ICEing on code that was actually OK. Fixed by checking specifically that no co_awaits embedded. PR c++/109283 gcc/cp/ChangeLog: * coroutines.cc (find_any_await): Only save the statement pointer if the caller passes a place for it. (flatten_await_stmt): When checking that ternary expressions have been handled, also check that they contain a co_await. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr109283.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit 977fadd69776e2a8a6daca43e1c898bc4f87154d) Diff: --- gcc/cp/coroutines.cc | 8 +--- gcc/testsuite/g++.dg/coroutines/pr109283.C | 23 +++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 04ed5531997a..a8e5143c54dd 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2882,8 +2882,8 @@ find_any_await (tree *stmt, int *dosub, void *d) if (TREE_CODE (*stmt) == CO_AWAIT_EXPR) { *dosub = 0; /* We don't need to consider this any further. */ - tree **p = (tree **) d; - *p = stmt; + if (d) + *(tree **)d = stmt; return *stmt; } return NULL_TREE; @@ -3133,7 +3133,9 @@ flatten_await_stmt (var_nest_node *n, hash_set *promoted, bool already_present = promoted->add (var); gcc_checking_assert (!already_present); tree inner = TARGET_EXPR_INITIAL (init); - gcc_checking_assert (TREE_CODE (inner) != COND_EXPR); + gcc_checking_assert + (TREE_CODE (inner) != COND_EXPR +|| !cp_walk_tree (&inner, find_any_await, nullptr, nullptr)); init = cp_build_modify_expr (input_location, var, INIT_EXPR, init, tf_warning_or_error); /* Simplify for the case that we have an init containing the temp diff --git a/gcc/testsuite/g++.dg/coroutines/pr109283.C b/gcc/testsuite/g++.dg/coroutines/pr109283.C new file mode 100644 index ..d73092b595e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr109283.C @@ -0,0 +1,23 @@ +// PR 109283. +// This used to ICE from a check set too widely. +#include + +struct foo +{ ~foo(); }; + +struct task +{ + struct promise_type + { + std::suspend_never initial_suspend(); + std::suspend_never final_suspend() noexcept; + std::suspend_never yield_value(foo); + void return_void(); + void unhandled_exception(); + task get_return_object(); + }; +}; + +task source(int b) { + co_yield b ? foo{} : foo{}; +}
[gcc r15-10096] c++: Fix template class lookup [PR120495, PR115605].
https://gcc.gnu.org/g:e25730c90a7bd90cb541b848d3c378d5fc713ef9 commit r15-10096-ge25730c90a7bd90cb541b848d3c378d5fc713ef9 Author: Iain Sandoe Date: Mon Jun 2 09:42:23 2025 +0100 c++: Fix template class lookup [PR120495, PR115605]. In the reported issues, using lookup_template_class () directly on (for example) the coroutine_handle identifier fails because a class-local TYPE_DECL is found. This is because, in the existing code, lookup is called with default parameters which means that class contexts are examined first. Fix this, when a context is provided by the caller, by doing lookup in namespace provided. PR c++/120495 PR c++/115605 gcc/cp/ChangeLog: * pt.cc (lookup_template_class): Honour provided namespace contexts when looking up class templates. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr120495.C: New test. * g++.dg/pr115605.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit cf588f1a8e7406ced5b08f32f9d23f015a240a31) Diff: --- gcc/cp/pt.cc | 30 ++-- gcc/testsuite/g++.dg/coroutines/pr120495.C | 55 ++ gcc/testsuite/g++.dg/pr115605.C| 10 ++ 3 files changed, 84 insertions(+), 11 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index be9af50f44f8..776bab0b8603 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10052,15 +10052,20 @@ tsubst_entering_scope (tree t, tree args, tsubst_flags_t complain, tree in_decl) D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. + If D1 is an identifier and CONTEXT is non-NULL, then the lookup is + carried out in CONTEXT. Currently, only namespaces are supported for + CONTEXT. + + If D1 is an identifier and CONTEXT is NULL, the lookup is performed + in the innermost non-namespace binding. + + Otherwise CONTEXT is ignored and no lookup is carried out. + IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. Issue error and warning messages under control of COMPLAIN. - If the template class is really a local class in a template - function, then the FUNCTION_CONTEXT is the function in which it is - being instantiated. - ??? Note that this function is currently called *twice* for each template-id: the first time from the parser, while creating the incomplete type (finish_template_type), and the second type during the @@ -10079,20 +10084,23 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, spec_entry **slot; spec_entry *entry; - if (identifier_p (d1)) + if (identifier_p (d1) && context) +{ + gcc_checking_assert (TREE_CODE (context) == NAMESPACE_DECL); + push_decl_namespace (context); + templ = lookup_name (d1, LOOK_where::NAMESPACE, LOOK_want::NORMAL); + pop_decl_namespace (); +} + else if (identifier_p (d1)) { tree value = innermost_non_namespace_value (d1); if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value)) templ = value; else - { - if (context) - push_decl_namespace (context); +{ templ = lookup_name (d1); templ = maybe_get_template_decl_from_type_decl (templ); - if (context) - pop_decl_namespace (); - } +} } else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1))) { diff --git a/gcc/testsuite/g++.dg/coroutines/pr120495.C b/gcc/testsuite/g++.dg/coroutines/pr120495.C new file mode 100644 index ..f59c34a86765 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr120495.C @@ -0,0 +1,55 @@ +// { dg-additional-options "-fsyntax-only" } + +#include +#include + +struct fire_and_forget { +}; + +template +struct std::coroutine_traits +{ +struct promise_type +{ +fire_and_forget get_return_object() const noexcept +{ +return{}; +} + +void return_void() const noexcept +{ +} + +suspend_never initial_suspend() const noexcept +{ +return{}; +} + +suspend_never final_suspend() const noexcept +{ +return{}; +} + +void unhandled_exception() const noexcept +{ +std::terminate(); +} +}; +}; + +struct foo +{ +fire_and_forget bar() +{ +co_await std::suspend_always{ }; +} + +private: +// The line below triggered the error. +using coroutine_handle = std::coroutine_handle<>; +}; + +int main() +{ +foo{}.bar(); +} diff --git a/gcc/testsuite/g++.dg/pr115605.C b/gcc/testsuite/g++.dg/pr115605.C new file mode 100644 index ..9e342555c894 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr115605.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } + +#include + +int foo() { +int const tupl
[gcc r15-10095] c++, coroutines: Make analyze_fn_params into a class method.
https://gcc.gnu.org/g:11cab9852408f3e0f760f9f799fe3a0d4905007a commit r15-10095-g11cab9852408f3e0f760f9f799fe3a0d4905007a Author: Iain Sandoe Date: Thu May 29 16:45:44 2025 +0100 c++, coroutines: Make analyze_fn_params into a class method. This continues code cleanups and migration to encapsulation of the whole coroutine transform. gcc/cp/ChangeLog: * coroutines.cc (analyze_fn_parms): Move from free function.. (cp_coroutine_transform::analyze_fn_parms):... to method. (cp_coroutine_transform::apply_transforms): Adjust call to analyze_fn_parms. * coroutines.h: Declare analyze_fn_parms. Signed-off-by: Iain Sandoe (cherry picked from commit 2a8af97e3528f812201687334f64b27b94d01271) Diff: --- gcc/cp/coroutines.cc | 20 +++- gcc/cp/coroutines.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index deaf32a9398b..4841c90824aa 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -4044,12 +4044,14 @@ rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) } /* Build up a set of info that determines how each param copy will be - handled. */ + handled. We store this in a hash map so that we can access it from + a tree walk callback that re-writes the original parameters to their + copies. */ -static void -analyze_fn_parms (tree orig, hash_map *param_uses) +void +cp_coroutine_transform::analyze_fn_parms () { - if (!DECL_ARGUMENTS (orig)) + if (!DECL_ARGUMENTS (orig_fn_decl)) return; /* Build a hash map with an entry for each param. @@ -4059,19 +4061,19 @@ analyze_fn_parms (tree orig, hash_map *param_uses) Then a tree list of the uses. The second two entries start out empty - and only get populated when we see uses. */ - bool lambda_p = LAMBDA_FUNCTION_P (orig); + bool lambda_p = LAMBDA_FUNCTION_P (orig_fn_decl); /* Count the param copies from 1 as per the std. */ unsigned parm_num = 1; - for (tree arg = DECL_ARGUMENTS (orig); arg != NULL; + for (tree arg = DECL_ARGUMENTS (orig_fn_decl); arg != NULL; ++parm_num, arg = DECL_CHAIN (arg)) { bool existed; - param_info &parm = param_uses->get_or_insert (arg, &existed); + param_info &parm = param_uses.get_or_insert (arg, &existed); gcc_checking_assert (!existed); parm.body_uses = NULL; tree actual_type = TREE_TYPE (arg); - actual_type = complete_type_or_else (actual_type, orig); + actual_type = complete_type_or_else (actual_type, orig_fn_decl); if (actual_type == NULL_TREE) actual_type = error_mark_node; parm.orig_type = actual_type; @@ -5266,7 +5268,7 @@ cp_coroutine_transform::apply_transforms () /* Collect information on the original function params and their use in the function body. */ - analyze_fn_parms (orig_fn_decl, ¶m_uses); + analyze_fn_parms (); /* Declare the actor and destroyer functions, the following code needs to see these. */ diff --git a/gcc/cp/coroutines.h b/gcc/cp/coroutines.h index 10698cf2e129..55caa6e61e36 100644 --- a/gcc/cp/coroutines.h +++ b/gcc/cp/coroutines.h @@ -126,6 +126,7 @@ private: bool inline_p = false; bool valid_coroutine = false; + void analyze_fn_parms (); void wrap_original_function_body (); bool build_ramp_function (); };
[gcc r15-10099] c++, coroutines: Improve diagnostics for awaiter/promise.
https://gcc.gnu.org/g:a2328db215cea44c2b3ad57a533b900723f43c10 commit r15-10099-ga2328db215cea44c2b3ad57a533b900723f43c10 Author: Iain Sandoe Date: Thu May 29 16:50:44 2025 +0100 c++, coroutines: Improve diagnostics for awaiter/promise. At present, we can issue diagnostics about missing or malformed awaiter or promise methods when we encounter their uses in the body of a user's function. We might then re-issue the same diagnostics when processing the initial or final await expressions. This change avoids such duplication, and also attempts to identify issues with the initial or final expressions specifically since diagnostics for those do not have any useful line number. gcc/cp/ChangeLog: * 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. gcc/testsuite/ChangeLog: * 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. Signed-off-by: Iain Sandoe (cherry picked from commit 4c014a9db521b24bd900eb9a6ac70988322a57da) Diff: --- gcc/cp/coroutines.cc | 29 +- gcc/cp/coroutines.h| 4 +++ .../g++.dg/coroutines/coro-missing-final-suspend.C | 4 +-- .../g++.dg/coroutines/coro1-missing-await-method.C | 2 +- .../g++.dg/coroutines/{pr104051.C => pr104051-0.C} | 4 +-- gcc/testsuite/g++.dg/coroutines/pr104051-1.C | 23 + 6 files changed, 55 insertions(+), 11 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 6a85cb71a332..6477c7969737 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; } @@ -4373,7 +4379,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 @@ -4567,7 +4572,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); @@ -5224,9 +5230,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"); @@ -5305,6 +5312,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 s
[gcc r15-10094] c++, coroutines: Simplify initial_await_resume_called.
https://gcc.gnu.org/g:81e04fd3d291739d4d2feb2e1b6fc62cd91742e6 commit r15-10094-g81e04fd3d291739d4d2feb2e1b6fc62cd91742e6 Author: Iain Sandoe Date: Thu May 29 13:43:37 2025 +0100 c++, coroutines: Simplify initial_await_resume_called. We do not need to generate this code early, since it does not affect any of the analysis. Lowering it later takes less code, and avoids modifying the initial await expresssion which will simplify changes to analysis to deal with open PRs. gcc/cp/ChangeLog: * coroutines.cc (expand_one_await_expression): Set the initial_await_resume_called flag here. (build_actor_fn): Populate the frame accessor for the initial_await_resume_called flag. (cp_coroutine_transform::wrap_original_function_body): Do not modify the initial_await expression to include the initial_await_resume_called flag here. Signed-off-by: Iain Sandoe (cherry picked from commit bfd4aae0a999375cf008b75c14607c7b94daced3) Diff: --- gcc/cp/coroutines.cc | 43 --- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index c1eaf0ebb122..deaf32a9398b 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2042,8 +2042,10 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) tree awaiter_calls = TREE_OPERAND (saved_co_await, 3); tree source = TREE_OPERAND (saved_co_await, 4); - bool is_final = (source - && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT); + bool is_final += (source && TREE_INT_CST_LOW (source) == (int) FINAL_SUSPEND_POINT); + bool is_initial += (source && TREE_INT_CST_LOW (source) == (int) INITIAL_SUSPEND_POINT); /* Build labels for the destinations of the control flow when we are resuming or destroying. */ @@ -2171,6 +2173,13 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d) /* Resume point. */ add_stmt (build_stmt (loc, LABEL_EXPR, resume_label)); + if (is_initial && data->i_a_r_c) +{ + r = cp_build_modify_expr (loc, data->i_a_r_c, NOP_EXPR, boolean_true_node, + tf_warning_or_error); + finish_expr_stmt (r); +} + /* This will produce the value (if one is provided) from the co_await expression. */ tree resume_call = TREE_VEC_ELT (awaiter_calls, 2); /* await_resume(). */ @@ -2671,8 +2680,12 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody, /* We've now rewritten the tree and added the initial and final co_awaits. Now pass over the tree and expand the co_awaits. */ + tree i_a_r_c = NULL_TREE; + if (flag_exceptions) +i_a_r_c = coro_build_frame_access_expr (actor_frame, coro_frame_i_a_r_c_id, + false, tf_warning_or_error); - coro_aw_data data = {actor, actor_fp, resume_idx_var, NULL_TREE, + coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c, ash, del_promise_label, ret_label, continue_label, restart_dispatch_label, continuation, 2}; cp_walk_tree (&actor_body, await_statement_expander, &data, NULL); @@ -4452,30 +4465,6 @@ cp_coroutine_transform::wrap_original_function_body () tree tcb = build_stmt (loc, TRY_BLOCK, NULL_TREE, NULL_TREE); add_stmt (tcb); TRY_STMTS (tcb) = push_stmt_list (); - if (initial_await != error_mark_node) - { - /* Build a compound expression that sets the -initial-await-resume-called variable true and then calls the -initial suspend expression await resume. -In the case that the user decides to make the initial await -await_resume() return a value, we need to discard it and, it is -a reference type, look past the indirection. */ - if (INDIRECT_REF_P (initial_await)) - initial_await = TREE_OPERAND (initial_await, 0); - /* In the case that the initial_await returns a target expression -we might need to look through that to update the await expr. */ - tree iaw = initial_await; - if (TREE_CODE (iaw) == TARGET_EXPR) - iaw = TARGET_EXPR_INITIAL (iaw); - gcc_checking_assert (TREE_CODE (iaw) == CO_AWAIT_EXPR); - tree vec = TREE_OPERAND (iaw, 3); - tree aw_r = TREE_VEC_ELT (vec, 2); - aw_r = convert_to_void (aw_r, ICV_STATEMENT, tf_warning_or_error); - tree update = build2 (MODIFY_EXPR, boolean_type_node, i_a_r_c, - boolean_true_node); - aw_r = cp_build_compound_expr (update, aw_r, tf_warning_or_error); - TREE_VEC_ELT (vec, 2) = aw_r; - } /* Add the initial await to the start of the user-authored function. */ finish_expr_stmt (initial_await); /* Append the origin
[gcc r15-10091] c++: Add co_await, co_yield and co_return to dump_expr.
https://gcc.gnu.org/g:ad8c618993682a02b758257e21647de28047c880 commit r15-10091-gad8c618993682a02b758257e21647de28047c880 Author: Iain Sandoe Date: Fri May 30 20:06:26 2025 +0100 c++: Add co_await, co_yield and co_return to dump_expr. These were omitted there as an oversight, most of the error handling for the coroutines code is specific rather than using generic %qE etc. gcc/cp/ChangeLog: * error.cc (dump_expr): Add co_await, co_yield and co_return. Signed-off-by: Iain Sandoe (cherry picked from commit 09cac2a833689f2535d6c2c88a67b2169df4e4d7) Diff: --- gcc/cp/error.cc | 21 + 1 file changed, 21 insertions(+) diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 499eb1b15a85..65b4b8de4059 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -3217,6 +3217,27 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) break; } +case CO_AWAIT_EXPR: + pp_cxx_ws_string (pp, "co_await"); + pp_cxx_whitespace (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + break; + +case CO_YIELD_EXPR: + pp_cxx_ws_string (pp, "co_yield"); + pp_cxx_whitespace (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + break; + +case CO_RETURN_EXPR: + pp_cxx_ws_string (pp, "co_return"); + if (TREE_OPERAND (t, 0)) + { + pp_cxx_whitespace (pp); + dump_expr (pp, TREE_OPERAND (t, 0), flags); + } + break; + /* This list is incomplete, but should suffice for now. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */
[gcc r15-10097] c++, coroutines: Ensure that the resumer is marked as can_throw.
https://gcc.gnu.org/g:956b6c30219b56381cb0b3765859c60545327707 commit r15-10097-g956b6c30219b56381cb0b3765859c60545327707 Author: Iain Sandoe Date: Sat Jun 7 17:01:15 2025 +0100 c++, coroutines: Ensure that the resumer is marked as can_throw. We must flag that the resumer might throw (since the wrapping of the original function body unconditionally adds a try-catch/rethrow). We also add code that might throw - even when the original function body would not. TODO: We could improve code-gen by recognising cases where the combined body + initial await expressions cannot throw and omitting the unneeded try/catch/rethrow wrapper. gcc/cp/ChangeLog: * coroutines.cc (build_actor_fn): Set can_throw. Signed-off-by: Iain Sandoe (cherry picked from commit e83c4bfc338fad0c87b2debb37ccfe98d148c7ac) Diff: --- gcc/cp/coroutines.cc | 5 + 1 file changed, 5 insertions(+) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 4841c90824aa..8a36e0ae7fd3 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2421,6 +2421,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);
[gcc r15-10102] c++, coroutines: Handle await expressions in assume attributes.
https://gcc.gnu.org/g:892892b455ba8be6a0bf373f338b251876ec4623 commit r15-10102-g892892b455ba8be6a0bf373f338b251876ec4623 Author: Iain Sandoe Date: Mon Jun 9 11:26:01 2025 +0100 c++,coroutines: Handle await expressions in assume attributes. Here we have an expression that is not evaluated but is still seen as potentially-evaluated. We handle this by determining if the operand has side-effects, producing a warning that the assume has been ignored and eliding it. gcc/cp/ChangeLog: * coroutines.cc (analyze_expression_awaits): Elide assume attributes containing await expressions, since these have side effects. Emit a diagnostic that this has been done. gcc/testsuite/ChangeLog: * g++.dg/coroutines/assume.C: New test. (cherry picked from commit 4ff09eb3422c525d514c869c7e0366fd5b40b561) Diff: --- gcc/cp/coroutines.cc | 13 +++ gcc/testsuite/g++.dg/coroutines/assume.C | 40 2 files changed, 53 insertions(+) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 17eed9d2559f..0443f5170ed7 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3496,6 +3496,19 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, void *d) } *do_subtree = 0; } + else if (!fn && CALL_EXPR_IFN (*stmt) == IFN_ASSUME) + { + tree expr = CALL_EXPR_ARG (*stmt, 0); + if (TREE_SIDE_EFFECTS (expr)) + { + location_t loc_e = cp_expr_location (expr); + location_t loc_s = cp_expr_location (*stmt); + location_t loc_n = make_location (loc_e, loc_s, loc_s); + warning_at (loc_n, OPT_Wattributes,"assumption ignored" + " because it contains an await-expression"); + *stmt = build_empty_stmt (loc_n); + } + } } break; case CO_YIELD_EXPR: diff --git a/gcc/testsuite/g++.dg/coroutines/assume.C b/gcc/testsuite/g++.dg/coroutines/assume.C new file mode 100644 index ..d007386f6bcc --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/assume.C @@ -0,0 +1,40 @@ +// { dg-additional-options "-fsyntax-only -Wattributes" } + +#include + +struct awaitable { +awaitable (int n) : delay{n} {} + +constexpr bool await_ready () const noexcept { return false; } +auto await_suspend (std::coroutine_handle<> h) const { +__builtin_abort (); +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}; } +}; +}; + +int h () { return 5; } + +Task foo() noexcept { +int x = 5; +[[assume (x == 5)]]; +[[assume (co_await awaitable{10})]]; // { dg-warning {assumption ignored because it contains an await-expression} } +[[assume ((h(),co_await awaitable{11}))]]; // { dg-warning {assumption ignored because it contains an await-expression} } +co_return; +}
[gcc r15-10101] c++, coroutines: Handle unevaluated contexts.
https://gcc.gnu.org/g:f4ae768a923359f67ec91cd3159de2ae39fa14d6 commit r15-10101-gf4ae768a923359f67ec91cd3159de2ae39fa14d6 Author: Iain Sandoe Date: Sun Jun 8 14:28:01 2025 +0100 c++, coroutines: Handle unevaluated contexts. From [expr.await]/2 We should not accept co_await, co_yield in unevaluated contexts. Currently (see PR68604) we do not mark typeid expressions as unevaluated since the standard rules mean that this depends on the value type. gcc/cp/ChangeLog: * coroutines.cc (finish_co_await_expr): Do not allow in an unevaluated context. (finish_co_yield_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/coroutines/unevaluated.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit e2bff264e8b92426b13aacec3087cb97971ec9b9) Diff: --- gcc/cp/coroutines.cc | 12 gcc/testsuite/g++.dg/coroutines/unevaluated.C | 25 + 2 files changed, 37 insertions(+) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 5e33cc09adc9..17eed9d2559f 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1467,6 +1467,12 @@ finish_co_await_expr (location_t kw, tree expr) if (!expr || error_operand_p (expr)) return error_mark_node; + if (cp_unevaluated_operand) +{ + error_at (kw, "%qs cannot be used in an unevaluated context","co_await"); + return error_mark_node; +} + if (!coro_common_keyword_context_valid_p (current_function_decl, kw, "co_await")) return error_mark_node; @@ -1547,6 +1553,12 @@ finish_co_yield_expr (location_t kw, tree expr) if (!expr || error_operand_p (expr)) return error_mark_node; + if (cp_unevaluated_operand) +{ + error_at (kw, "%qs cannot be used in an unevaluated context","co_yield"); + return error_mark_node; +} + /* Check the general requirements and simple syntax errors. */ if (!coro_common_keyword_context_valid_p (current_function_decl, kw, "co_yield")) diff --git a/gcc/testsuite/g++.dg/coroutines/unevaluated.C b/gcc/testsuite/g++.dg/coroutines/unevaluated.C new file mode 100644 index ..63dae38dea39 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/unevaluated.C @@ -0,0 +1,25 @@ +// { dg-additional-options "-fsyntax-only" } +#include +#include + +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 () {} +std::suspend_never yield_value (int) { return {}; } +}; +}; + +// We do not permit co_await, co_yield outside a function, and so uses in +// noexcept or requirements are covered by that. +Task foo() { +/* This one will currently fail - see PR68604. */ +const std::type_info& ti1 = typeid (co_await std::suspend_never{}); // { dg-error {'co_await' cannot be used in an unevaluated context} "" { xfail *-*-* } } +std::size_t x = sizeof (co_yield (19)); // { dg-error {'co_yield' cannot be used in an unevaluated context} } +decltype (co_await std::suspend_never{}) A; // { dg-error {'co_await' cannot be used in an unevaluated context} } +co_return; +}
[gcc r16-2599] PR modula2/121289 Poor warning location when using Wstyle option
https://gcc.gnu.org/g:e79e0fe2b1f101485e5e63e674e133692a3a0cb4 commit r16-2599-ge79e0fe2b1f101485e5e63e674e133692a3a0cb4 Author: Gaius Mulley Date: Tue Jul 29 09:09:58 2025 +0100 PR modula2/121289 Poor warning location when using Wstyle option This patch adds a token location parameter to CheckVariableAgainstKeyword and dependants ensuring that the warning is generated from the token associated with the variable rather than the end of the statement. gcc/m2/ChangeLog: PR modula2/121289 * gm2-compiler/M2Students.def (CheckVariableAgainstKeyword): New parameter tok. * gm2-compiler/M2Students.mod (CheckVariableAgainstKeyword): New parameter tok. Pass tok to PerformVariableKeywordCheck. (PerformVariableKeywordCheck): New parameter tok. Pass tok to MetaErrorStringT0. * gm2-compiler/P2SymBuild.mod (BuildVariable): Pass tok to CheckVariableAgainstKeyword. * gm2-libs-iso/LowLong.mod (except): Replace with ... (exceptSrc): ... this. * gm2-libs-iso/LowReal.mod (except): Replace with ... (exceptSrc): ... this. * gm2-libs-iso/LowShort.mod (except): Replace with ... (exceptSrc): ... this. * gm2-libs-iso/Processes.mod (Wait): Replace from with fromCor. * gm2-libs-iso/RndFile.mod (EndPos): Replace end with endP. * gm2-libs/SCmdArgs.mod (GetArg): Replace start with startPos. Replace end with endPos. (NArg): Replace start with startPos. Replace end with endPos. gcc/testsuite/ChangeLog: PR modula2/121289 * gm2/warnings/style/fail/badvarname.mod: New test. * gm2/warnings/style/fail/warnings-style-fail.exp: New test. Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-compiler/M2Students.def | 2 +- gcc/m2/gm2-compiler/M2Students.mod | 16 gcc/m2/gm2-compiler/P2SymBuild.mod | 2 +- gcc/m2/gm2-libs-iso/LowLong.mod| 10 ++--- gcc/m2/gm2-libs-iso/LowReal.mod| 14 +++ gcc/m2/gm2-libs-iso/LowShort.mod | 14 +++ gcc/m2/gm2-libs-iso/Processes.mod | 8 ++-- gcc/m2/gm2-libs-iso/RndFile.mod| 10 ++--- gcc/m2/gm2-libs/SCmdArgs.mod | 36 +- .../gm2/warnings/style/fail/badvarname.mod | 14 +++ .../warnings/style/fail/warnings-style-fail.exp| 44 ++ 11 files changed, 116 insertions(+), 54 deletions(-) diff --git a/gcc/m2/gm2-compiler/M2Students.def b/gcc/m2/gm2-compiler/M2Students.def index 7d67a0aef3cd..a3ecdcdb2f60 100644 --- a/gcc/m2/gm2-compiler/M2Students.def +++ b/gcc/m2/gm2-compiler/M2Students.def @@ -39,7 +39,7 @@ EXPORT QUALIFIED StudentVariableCheck, CheckVariableAgainstKeyword ; as a keyword except for its case. *) -PROCEDURE CheckVariableAgainstKeyword (name: Name) ; +PROCEDURE CheckVariableAgainstKeyword (tok: CARDINAL; name: Name) ; (* diff --git a/gcc/m2/gm2-compiler/M2Students.mod b/gcc/m2/gm2-compiler/M2Students.mod index e539eb0757a7..3df160a987c5 100644 --- a/gcc/m2/gm2-compiler/M2Students.mod +++ b/gcc/m2/gm2-compiler/M2Students.mod @@ -25,7 +25,7 @@ IMPLEMENTATION MODULE M2Students ; FROM SymbolTable IMPORT FinalSymbol, IsVar, IsProcedure, IsModule, GetMainModule, IsType, NulSym, IsRecord, GetSymName, GetNth, GetNthProcedure, GetDeclaredMod, NoOfParam ; FROM NameKey IMPORT GetKey, WriteKey, MakeKey, IsSameExcludingCase, NulName, makekey, KeyToCharStar ; -FROM M2MetaError IMPORT MetaErrorString0, MetaError2 ; +FROM M2MetaError IMPORT MetaErrorStringT0, MetaError2 ; FROM Lists IMPORT List, InitList, IsItemInList, IncludeItemIntoList ; FROM M2Reserved IMPORT IsReserved, toktype ; FROM DynamicStrings IMPORT String, InitString, KillString, ToUpper, InitStringCharStar, string, Mark, ToUpper, Dup ; @@ -78,11 +78,11 @@ END IsNotADuplicateName ; as a keyword except for its case. *) -PROCEDURE CheckVariableAgainstKeyword (name: Name) ; +PROCEDURE CheckVariableAgainstKeyword (tok: CARDINAL; name: Name) ; BEGIN IF StyleChecking THEN - PerformVariableKeywordCheck (name) + PerformVariableKeywordCheck (tok, name) END END CheckVariableAgainstKeyword ; @@ -91,7 +91,7 @@ END CheckVariableAgainstKeyword ; PerformVariableKeywordCheck - performs the check and constructs the metaerror notes if appropriate. *) -PROCEDURE PerformVariableKeywordCheck (name: Name) ; +PROCEDURE PerformVariableKeywordCheck (tok: CARDINAL; name: Name) ; VAR upper : Name ; token : toktype ; @@ -105,9 +105,11 @@ BEGIN THEN IF IsNotADuplicateName (name) THEN - MetaErrorString0 (Sprintf2 (Mark (Init