[gcc r14-9329] i386: Fix up the vzeroupper REG_DEAD/REG_UNUSED note workaround [PR114190]
https://gcc.gnu.org/g:1157d5de35b41eabe5ee51d532224864173c37bd commit r14-9329-g1157d5de35b41eabe5ee51d532224864173c37bd Author: Jakub Jelinek Date: Wed Mar 6 09:35:37 2024 +0100 i386: Fix up the vzeroupper REG_DEAD/REG_UNUSED note workaround [PR114190] When writing the rest_of_handle_insert_vzeroupper workaround to manually remove all the REG_DEAD/REG_UNUSED notes from the IL, I've missed that there is a df_analyze () call right after it and that the problems added earlier in the pass, like df_note_add_problem () done during mode switching, doesn't affect just the next df_analyze () call right after it, but all other df_analyze () calls until the end of the current pass where df_finish_pass removes the optional problems. So, as can be seen on the following patch, the workaround doesn't actually work there, because while rest_of_handle_insert_vzeroupper carefully removes all REG_DEAD/REG_UNUSED notes, the df_analyze () call at the end of the function immediately adds them in again (so, I must say I have no idea why the workaround worked on the earlier testcases). Now, I could move the df_analyze () call just before the REG_DEAD/REG_UNUSED note removal loop, but I think the following patch is better, because the df_analyze () call doesn't have to recompute the problem when we don't care about it and will actively strip all traces of it away. 2024-03-06 Jakub Jelinek PR rtl-optimization/114190 * config/i386/i386-features.cc (rest_of_handle_insert_vzeroupper): Call df_remove_problem for df_note before calling df_analyze. * gcc.target/i386/avx-pr114190.c: New test. Diff: --- gcc/config/i386/i386-features.cc | 1 + gcc/testsuite/gcc.target/i386/avx-pr114190.c | 27 +++ 2 files changed, 28 insertions(+) diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index d3b9ae81025..1de2a07ed75 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -2690,6 +2690,7 @@ rest_of_handle_insert_vzeroupper (void) } } + df_remove_problem (df_note); df_analyze (); return 0; } diff --git a/gcc/testsuite/gcc.target/i386/avx-pr114190.c b/gcc/testsuite/gcc.target/i386/avx-pr114190.c new file mode 100644 index 000..fc5b2615de2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx-pr114190.c @@ -0,0 +1,27 @@ +/* PR rtl-optimization/114190 */ +/* { dg-do run { target avx } } */ +/* { dg-options "-O2 -fno-dce -fharden-compares -mavx --param=max-rtl-if-conversion-unpredictable-cost=136 -mno-avx512f -Wno-psabi" } */ + +#include "avx-check.h" + +typedef unsigned char U __attribute__((vector_size (64))); +typedef unsigned int V __attribute__((vector_size (64))); +U u; + +V +foo (V a, V b) +{ + u[0] = __builtin_sub_overflow (0, (int) a[0], &a[b[7] & 5]) ? -u[1] : -b[3]; + b ^= 0 != b; + return (V) u + (V) a + (V) b; +} + +static void +avx_test (void) +{ + V x = foo ((V) { 1 }, (V) { 0, 0, 0, 1 }); + if (x[0] != -1U) +__builtin_abort (); + if (x[3] != -2U) +__builtin_abort (); +}
[gcc r14-9350] match.pd: Optimize a * !a to 0 [PR114009]
https://gcc.gnu.org/g:95b6ee96348041eaee9133f082b57f3e57ef0b11 commit r14-9350-g95b6ee96348041eaee9133f082b57f3e57ef0b11 Author: Jakub Jelinek Date: Thu Mar 7 08:43:16 2024 +0100 match.pd: Optimize a * !a to 0 [PR114009] The following patch attempts to fix an optimization regression through adding a simple simplification. We already have the /* (m1 CMP m2) * d -> (m1 CMP m2) ? d : 0 */ (if (!canonicalize_math_p ()) (for cmp (tcc_comparison) (simplify (mult:c (convert (cmp@0 @1 @2)) @3) (if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (@0))) (cond @0 @3 { build_zero_cst (type); }))) optimization which otherwise triggers during the a * !a multiplication, but that is done only late and we aren't able through range assumptions optimize it yet anyway. The patch adds a specific simplification for it. If a is zero, then a * !a will be 0 * 1 (or for signed 1-bit 0 * -1) and so 0. If a is non-zero, then a * !a will be a * 0 and so again 0. THe pattern is valid for scalar integers, complex integers and vector types, but I think will actually trigger only for the scalar integers. For vector types I've added other two with VEC_COND_EXPR in it, for complex there are different GENERIC trees to match and it is something that likely would be never matched in GIMPLE, so I didn't handle that. 2024-03-07 Jakub Jelinek PR tree-optimization/114009 * genmatch.cc (decision_tree::gen): Emit ARG_UNUSED for captures argument even for GENERIC, not just for GIMPLE. * match.pd (a * !a -> 0): New simplifications. * gcc.dg/tree-ssa/pr114009.c: New test. Diff: --- gcc/genmatch.cc | 2 +- gcc/match.pd | 11 +++ gcc/testsuite/gcc.dg/tree-ssa/pr114009.c | 33 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc index 61c4c8c0294..c982c95b70f 100644 --- a/gcc/genmatch.cc +++ b/gcc/genmatch.cc @@ -4071,7 +4071,7 @@ decision_tree::gen (vec &files, bool gimple) for (unsigned i = 0; i < as_a (s->s->s->match)->ops.length (); ++i) fp_decl (f, " tree ARG_UNUSED (_p%d),", i); - fp_decl (f, " tree *captures"); + fp_decl (f, " tree *ARG_UNUSED (captures)"); } for (unsigned i = 0; i < s->s->s->for_subst_vec.length (); ++i) { diff --git a/gcc/match.pd b/gcc/match.pd index 4edba7c84fb..9ce313323a3 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1219,6 +1219,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && tree_nop_conversion_p (type, TREE_TYPE (@1))) (lshift @0 @2))) +/* Fold a * !a into 0. */ +(simplify + (mult:c @0 (convert? (eq @0 integer_zerop))) + { build_zero_cst (type); }) +(simplify + (mult:c @0 (vec_cond (eq @0 integer_zerop) @1 integer_zerop)) + { build_zero_cst (type); }) +(simplify + (mult:c @0 (vec_cond (ne @0 integer_zerop) integer_zerop @1)) + { build_zero_cst (type); }) + /* Shifts by precision or greater result in zero. */ (for shift (lshift rshift) (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr114009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr114009.c new file mode 100644 index 000..3b0486e16ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr114009.c @@ -0,0 +1,33 @@ +/* PR tree-optimization/114009 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-psabi -fdump-tree-forwprop1" } */ +/* { dg-final { scan-tree-dump-times " return 0;" 3 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times " (?:return| =) { 0, 0, 0, 0 };" 1 "forwprop1" } } */ + +int +foo (int x) +{ + x = (x / 2) * 2; + return (!x) * x; +} + +int +bar (int x, int y) +{ + (void) x; + return y * !y; +} + +unsigned long long +baz (unsigned long long x) +{ + return (!x) * x; +} + +typedef int V __attribute__((vector_size (4 * sizeof (int; + +V +qux (V x) +{ + return x * (x == 0); +}
[gcc r14-9353] sccvn: Avoid UB in ao_ref_init_from_vn_reference [PR105533]
https://gcc.gnu.org/g:e1bd0f293d8407d4e8149fbafd470612323dc938 commit r14-9353-ge1bd0f293d8407d4e8149fbafd470612323dc938 Author: Jakub Jelinek Date: Thu Mar 7 10:01:08 2024 +0100 sccvn: Avoid UB in ao_ref_init_from_vn_reference [PR105533] When compiling libgcc or on e.g. int a[64]; int p; void foo (void) { int s = 1; while (p) { s -= 11; a[s] != 0; } } sccvn invokes UB in the compiler as detected by ubsan: ../../gcc/poly-int.h:1089:5: runtime error: left shift of negative value -40 The problem is that we still use C++11..C++17 as the implementation language and in those C++ versions shifting negative values left is UB (well defined since C++20) and above in offset += op->off << LOG2_BITS_PER_UNIT; op->off is poly_int64 with -40 value (in libgcc with -8). I understand the offset_int << LOG2_BITS_PER_UNIT shifts but it is then well defined during underlying implementation which is done on the uhwi limbs, but for poly_int64 we use offset += pop->off * BITS_PER_UNIT; a few lines earlier and I think that is both more readable in what it actually does and triggers UB only if there would be signed multiply overflow. In the end, the compiler will treat them the same at least at the RTL level (at least, if not and they aren't the same cost, it should). 2024-03-07 Jakub Jelinek PR middle-end/105533 * tree-ssa-sccvn.cc (ao_ref_init_from_vn_reference) : Multiple op->off by BITS_PER_UNIT instead of shifting it left by LOG2_BITS_PER_UNIT. Diff: --- gcc/tree-ssa-sccvn.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 88d3b2498b9..93649895056 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -1221,7 +1221,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref, if (maybe_eq (op->off, -1)) max_size = -1; else - offset += op->off << LOG2_BITS_PER_UNIT; + offset += op->off * BITS_PER_UNIT; break; case REALPART_EXPR:
[gcc r14-9354] expand: Fix UB in choose_mult_variant [PR105533]
https://gcc.gnu.org/g:c655c8d8d845b36c59babb2413ce7aa3584dbeda commit r14-9354-gc655c8d8d845b36c59babb2413ce7aa3584dbeda Author: Jakub Jelinek Date: Thu Mar 7 10:02:00 2024 +0100 expand: Fix UB in choose_mult_variant [PR105533] As documented in the function comment, choose_mult_variant attempts to compute costs of 3 different cases, val, -val and val - 1. The -val case is actually only done if val fits into host int, so there should be no overflow, but the val - 1 case is done unconditionally. val is shwi (but inside of synth_mult already uhwi), so when val is HOST_WIDE_INT_MIN, val - 1 invokes UB. The following patch fixes that by using val - HOST_WIDE_INT_1U, but I'm not really convinced it would DTRT for > 64-bit modes, so I've guarded it as well. Though, arch would need to have really strange costs that something that could be expressed as x << 63 would be better expressed as (x * 0x7fff) + 1 In the long term, I think we should just rewrite choose_mult_variant/synth_mult etc. to work on wide_int. 2024-03-07 Jakub Jelinek PR middle-end/105533 * expmed.cc (choose_mult_variant): Only try the val - 1 variant if val is not HOST_WIDE_INT_MIN or if mode has exactly HOST_BITS_PER_WIDE_INT precision. Avoid triggering UB while computing val - 1. * gcc.dg/pr105533.c: New test. Diff: --- gcc/expmed.cc | 14 +- gcc/testsuite/gcc.dg/pr105533.c | 9 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 5916d6ed1bc..4ec035e4843 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -3285,11 +3285,15 @@ choose_mult_variant (machine_mode mode, HOST_WIDE_INT val, limit.latency = mult_cost - op_cost; } - synth_mult (&alg2, val - 1, &limit, mode); - alg2.cost.cost += op_cost; - alg2.cost.latency += op_cost; - if (CHEAPER_MULT_COST (&alg2.cost, &alg->cost)) -*alg = alg2, *variant = add_variant; + if (val != HOST_WIDE_INT_MIN + || GET_MODE_UNIT_PRECISION (mode) == HOST_BITS_PER_WIDE_INT) +{ + synth_mult (&alg2, val - HOST_WIDE_INT_1U, &limit, mode); + alg2.cost.cost += op_cost; + alg2.cost.latency += op_cost; + if (CHEAPER_MULT_COST (&alg2.cost, &alg->cost)) + *alg = alg2, *variant = add_variant; +} return MULT_COST_LESS (&alg->cost, mult_cost); } diff --git a/gcc/testsuite/gcc.dg/pr105533.c b/gcc/testsuite/gcc.dg/pr105533.c new file mode 100644 index 000..912685e33f6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105533.c @@ -0,0 +1,9 @@ +/* PR middle-end/105533 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +long long +foo (long long x, long long y) +{ + return ((x < 0) & (y != 0)) * (-__LONG_LONG_MAX__ - 1); +}
[gcc r14-9355] bb-reorder: Fix -freorder-blocks-and-partition ICEs on aarch64 with asm goto [PR110079]
https://gcc.gnu.org/g:b209d905f5ce1fa9d76ce634fd54245ff340960b commit r14-9355-gb209d905f5ce1fa9d76ce634fd54245ff340960b Author: Jakub Jelinek Date: Thu Mar 7 10:02:49 2024 +0100 bb-reorder: Fix -freorder-blocks-and-partition ICEs on aarch64 with asm goto [PR110079] The following testcase ICEs, because fix_crossing_unconditional_branches thinks that asm goto is an unconditional jump and removes it, replacing it with unconditional jump to one of the labels. This doesn't happen on x86 because the function in question isn't invoked there at all: /* If the architecture does not have unconditional branches that can span all of memory, convert crossing unconditional branches into indirect jumps. Since adding an indirect jump also adds a new register usage, update the register usage information as well. */ if (!HAS_LONG_UNCOND_BRANCH) fix_crossing_unconditional_branches (); I think for the asm goto case, for the non-fallthru edge if any we should handle it like any other fallthru (and fix_crossing_unconditional_branches doesn't really deal with those, it only looks at explicit branches at the end of bbs and we are in cfglayout mode at that point) and for the labels we just pass the labels as immediates to the assembly and it is up to the user to figure out how to store them/branch to them or whatever they want to do. So, the following patch fixes this by not treating asm goto as a simple unconditional jump. I really think that on the !HAS_LONG_UNCOND_BRANCH targets we have a bug somewhere else, where outofcfglayout or whatever should actually create those indirect jumps on the crossing edges instead of adding normal unconditional jumps, I see e.g. in __attribute__((cold)) int bar (char *); __attribute__((hot)) int baz (char *); void qux (int x) { if (__builtin_expect (!x, 1)) goto l1; bar (""); goto l1; l1: baz (""); } void corge (int x) { if (__builtin_expect (!x, 0)) goto l1; baz (""); l2: return; l1: bar (""); goto l2; } with -O2 -freorder-blocks-and-partition on aarch64 before/after this patch just b .L? jumps which I believe are +-32MB, so if .text is larger than 32MB, it could fail to link, but this patch doesn't address that. 2024-03-07 Jakub Jelinek PR rtl-optimization/110079 * bb-reorder.cc (fix_crossing_unconditional_branches): Don't adjust asm goto. * gcc.dg/pr110079.c: New test. Diff: --- gcc/bb-reorder.cc | 3 ++- gcc/testsuite/gcc.dg/pr110079.c | 43 + 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gcc/bb-reorder.cc b/gcc/bb-reorder.cc index 3137f88a236..7998c0a148e 100644 --- a/gcc/bb-reorder.cc +++ b/gcc/bb-reorder.cc @@ -2266,7 +2266,8 @@ fix_crossing_unconditional_branches (void) /* Make sure the jump is not already an indirect or table jump. */ if (!computed_jump_p (last_insn) - && !tablejump_p (last_insn, NULL, NULL)) + && !tablejump_p (last_insn, NULL, NULL) + && asm_noperands (PATTERN (last_insn)) < 0) { /* We have found a "crossing" unconditional branch. Now we must convert it to an indirect jump. First create diff --git a/gcc/testsuite/gcc.dg/pr110079.c b/gcc/testsuite/gcc.dg/pr110079.c new file mode 100644 index 000..1682f9c2344 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr110079.c @@ -0,0 +1,43 @@ +/* PR rtl-optimization/110079 */ +/* { dg-do compile { target lra } } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-freorder-blocks-and-partition" { target freorder } } */ + +int a; +__attribute__((cold)) int bar (char *); +__attribute__((hot)) int baz (char *); + +void +foo (void) +{ +l1: + while (a) +; + bar (""); + asm goto ("" : : : : l2); + asm (""); +l2: + goto l1; +} + +void +qux (void) +{ + asm goto ("" : : : : l1); + bar (""); + goto l1; +l1: + baz (""); +} + +void +corge (void) +{ + asm goto ("" : : : : l1); + baz (""); +l2: + return; +l1: + bar (""); + goto l2; +}
[gcc r14-9359] analyzer: Fix up some -Wformat* warnings
https://gcc.gnu.org/g:a242f69693d2fcac428cb82bf843882dee84fc81 commit r14-9359-ga242f69693d2fcac428cb82bf843882dee84fc81 Author: Jakub Jelinek Date: Thu Mar 7 14:19:49 2024 +0100 analyzer: Fix up some -Wformat* warnings I'm seeing warnings like ../../gcc/analyzer/access-diagram.cc: In member function ‘void ana::bit_size_expr::print(pretty_printer*) const’: ../../gcc/analyzer/access-diagram.cc:399:26: warning: unknown conversion type character ‘E’ in format [-Wformat=] 399 | pp_printf (pp, _("%qE bytes"), bytes_expr); | ^~~ when building stage2/stage3 gcc. While such warnings would be understandable when building stage1 because one could e.g. have some older host compiler which doesn't understand some of the format specifiers, the above seems to be because we have in pretty-print.h #ifdef GCC_DIAG_STYLE #define GCC_PPDIAG_STYLE GCC_DIAG_STYLE #else #define GCC_PPDIAG_STYLE __gcc_diag__ #endif and use GCC_PPDIAG_STYLE e.g. for pp_printf, and while diagnostic-core.h has #ifndef GCC_DIAG_STYLE #define GCC_DIAG_STYLE __gcc_tdiag__ #endif (and similarly various FE headers include their own GCC_DIAG_STYLE) when including pretty-print.h before diagnostic-core.h we end up with __gcc_diag__ style rather than __gcc_tdiag__ style, which I think is the right thing for the analyzer, because analyzer seems to use default_tree_printer everywhere: grep pp_format_decoder.*=.default_tree_printer analyzer/* | wc -l 57 The following patch fixes that by making sure diagnostic-core.h is included before pretty-print.h. 2024-03-07 Jakub Jelinek * access-diagram.cc: Include diagnostic-core.h before including diagnostic.h or diagnostic-path.h. * sm-malloc.cc: Likewise. * diagnostic-manager.cc: Likewise. * call-summary.cc: Likewise. * record-layout.cc: Likewise. Diff: --- gcc/analyzer/access-diagram.cc | 1 + gcc/analyzer/call-summary.cc | 1 + gcc/analyzer/diagnostic-manager.cc | 2 +- gcc/analyzer/record-layout.cc | 1 + gcc/analyzer/sm-malloc.cc | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc index 24d203f9325..2836308c019 100644 --- a/gcc/analyzer/access-diagram.cc +++ b/gcc/analyzer/access-diagram.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "basic-block.h" #include "gimple.h" +#include "diagnostic-core.h" #include "diagnostic.h" #include "intl.h" #include "make-unique.h" diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc index 8b8567a1528..a569bb94cec 100644 --- a/gcc/analyzer/call-summary.cc +++ b/gcc/analyzer/call-summary.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tree.h" #include "tree-dfa.h" +#include "diagnostic-core.h" #include "diagnostic.h" #include "tree-diagnostic.h" #include "analyzer/analyzer.h" diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 246d052100f..08d92f9780e 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -24,11 +24,11 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tree.h" #include "input.h" +#include "diagnostic-core.h" #include "pretty-print.h" #include "gcc-rich-location.h" #include "gimple-pretty-print.h" #include "function.h" -#include "diagnostic-core.h" #include "diagnostic-event-id.h" #include "diagnostic-path.h" #include "bitmap.h" diff --git a/gcc/analyzer/record-layout.cc b/gcc/analyzer/record-layout.cc index 62951474bb7..567dfd9809a 100644 --- a/gcc/analyzer/record-layout.cc +++ b/gcc/analyzer/record-layout.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "basic-block.h" #include "gimple.h" +#include "diagnostic-core.h" #include "diagnostic.h" #include "tree-diagnostic.h" #include "analyzer/analyzer.h" diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index 2e0cf8a6887..a518816b2b8 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "options.h" #include "bitmap.h" +#include "diagnostic-core.h" #include "diagnostic-path.h" #include "analyzer/analyzer.h" #include "diagnostic-event-id.h"
[gcc r14-9385] dwarf2out: Emit DW_AT_export_symbols on anon unions/structs [PR113918]
https://gcc.gnu.org/g:05109b1bd5ef4ee9d78fe17d4563889694a26d05 commit r14-9385-g05109b1bd5ef4ee9d78fe17d4563889694a26d05 Author: Jakub Jelinek Date: Fri Mar 8 09:14:32 2024 +0100 dwarf2out: Emit DW_AT_export_symbols on anon unions/structs [PR113918] DWARF5 added DW_AT_export_symbols both for use on inline namespaces (where we emit it), but also on anonymous unions/structs (and we didn't emit that attribute there). The following patch fixes it. 2024-03-08 Jakub Jelinek PR debug/113918 gcc/ * dwarf2out.cc (gen_field_die): Emit DW_AT_export_symbols on anonymous unions or structs for -gdwarf-5 or -gno-strict-dwarf. gcc/c/ * c-tree.h (c_type_dwarf_attribute): Declare. * c-objc-common.h (LANG_HOOKS_TYPE_DWARF_ATTRIBUTE): Redefine. * c-objc-common.cc: Include dwarf2.h. (c_type_dwarf_attribute): New function. gcc/cp/ * cp-objcp-common.cc (cp_type_dwarf_attribute): Return 1 for DW_AT_export_symbols on anonymous structs or unions. gcc/testsuite/ * c-c++-common/dwarf2/pr113918.c: New test. Diff: --- gcc/c/c-objc-common.cc | 23 +++ gcc/c/c-objc-common.h| 3 +++ gcc/c/c-tree.h | 1 + gcc/cp/cp-objcp-common.cc| 5 + gcc/dwarf2out.cc | 11 ++ gcc/testsuite/c-c++-common/dwarf2/pr113918.c | 33 6 files changed, 76 insertions(+) diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc index 116b73af6db..b7c72d2609c 100644 --- a/gcc/c/c-objc-common.cc +++ b/gcc/c/c-objc-common.cc @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "gcc-rich-location.h" #include "stringpool.h" #include "attribs.h" +#include "dwarf2.h" static bool c_tree_printer (pretty_printer *, text_info *, const char *, int, bool, bool, bool, bool *, const char **); @@ -446,3 +447,25 @@ instantiation_dependent_expression_p (tree) { return false; } + +/* Return -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute + value otherwise. */ +int +c_type_dwarf_attribute (const_tree type, int attr) +{ + if (type == NULL_TREE) +return -1; + + switch (attr) +{ +case DW_AT_export_symbols: + if (RECORD_OR_UNION_TYPE_P (type) && TYPE_NAME (type) == NULL_TREE) + return 1; + break; + +default: + break; +} + + return -1; +} diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 35a59988e90..20af5a5bb94 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -119,6 +119,9 @@ static const scoped_attribute_specs *const c_objc_attribute_table[] = #undef LANG_HOOKS_GIMPLIFY_EXPR #define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr +#undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE +#define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE c_type_dwarf_attribute + #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 1fba9c8dae7..22b0009874b 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -731,6 +731,7 @@ extern bool c_warn_unused_global_decl (const_tree); extern void c_initialize_diagnostics (diagnostic_context *); extern bool c_var_mod_p (tree x, tree fn); extern alias_set_type c_get_alias_set (tree); +extern int c_type_dwarf_attribute (const_tree, int); /* in c-typeck.cc */ extern int in_alignof; diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index 85dde0459fa..86e0b49d46b 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -410,6 +410,11 @@ cp_type_dwarf_attribute (const_tree type, int attr) return 1; break; +case DW_AT_export_symbols: + if (ANON_AGGR_TYPE_P (type)) + return 1; + break; + default: break; } diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 03d73f9eecd..87e4240b871 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -25162,6 +25162,17 @@ gen_field_die (tree decl, struct vlr_context *ctx, dw_die_ref context_die) add_accessibility_attribute (decl_die, decl); + /* Add DW_AT_export_symbols to anonymous unions or structs. */ + if ((dwarf_version >= 5 || !dwarf_strict) && DECL_NAME (decl) == NULL_TREE) +if (tree type = member_declared_type (decl)) + if (lang_hooks.types.type_dwarf_attribute (TYPE_MAIN_VARIANT (type), +DW_AT_export_symbols) != -1) + { + dw_die_ref type_die = lookup_type_die (TYPE_MAIN_VARIANT (type)); + if (type_die && get_AT (type_die, DW_AT_export_symbols) == NULL) + add_AT_flag (type_die, DW_AT_export_symbols, 1); + } + /* Equate decl number to die, so that we can look up this decl later on. */ equate_decl_number_to_die (decl,
[gcc r14-9384] c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802]
https://gcc.gnu.org/g:3ecc5071797c4ceb6da67a6c2b2527a046091de2 commit r14-9384-g3ecc5071797c4ceb6da67a6c2b2527a046091de2 Author: Jakub Jelinek Date: Fri Mar 8 09:11:57 2024 +0100 c++: Fix up parameter pack diagnostics on xobj vs. varargs functions [PR113802] The simple presence of ellipsis as next token after the parameter declaration doesn't imply it is a parameter pack, it sometimes is, e.g. if its type is a pack, but sometimes is not and in that case it acts the same as if the next tokens were , ... instead of just ... The xobj param cannot be a function parameter pack though treats both the declarator->parameter_pack_p and token->type == CPP_ELLIPSIS as sufficient conditions for the error. The conditions for CPP_ELLIPSIS are done a little bit later in the same function and complex enough that IMHO shouldn't be repeated, on the other side for the declarator->parameter_pack_p case we clear that flag for xobj params for error recovery reasons. This patch just moves the diagnostics later (after the CPP_ELLIPSIS handling) and changes the error recovery behavior by pretending the this specifier didn't appear if an error is reported. 2024-03-08 Jakub Jelinek PR c++/113802 * parser.cc (cp_parser_parameter_declaration): Move the xobj_param_p pack diagnostics after ellipsis handling and if an error is reported, pretend this specifier didn't appear. Formatting fix. * g++.dg/cpp23/explicit-obj-diagnostics3.C (S0, S1, S2, S3, S4): Don't expect any diagnostics on f and fd member function templates, add similar templates with ...Selves instead of Selves as k and kd and expect diagnostics for those. Expect extra diagnostics in error recovery for g and gd member function templates. Diff: --- gcc/cp/parser.cc | 38 +++--- .../g++.dg/cpp23/explicit-obj-diagnostics3.C | 61 ++ 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index e32acfc30a2..bc3aa9dd6ad 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -25734,22 +25734,6 @@ cp_parser_parameter_declaration (cp_parser *parser, decl_specifiers.locations[ds_this] = 0; } - if (xobj_param_p - && ((declarator && declarator->parameter_pack_p) - || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))) -{ - location_t xobj_param - = make_location (decl_specifiers.locations[ds_this], -decl_spec_token_start->location, -input_location); - error_at (xobj_param, - "an explicit object parameter cannot " - "be a function parameter pack"); - /* Suppress errors that occur down the line. */ - if (declarator) - declarator->parameter_pack_p = false; -} - /* If a function parameter pack was specified and an implicit template parameter was introduced during cp_parser_parameter_declaration, change any implicit parameters introduced into packs. */ @@ -25762,9 +25746,10 @@ cp_parser_parameter_declaration (cp_parser *parser, (INNERMOST_TEMPLATE_PARMS (current_template_parms)); if (latest_template_parm_idx != template_parm_idx) - decl_specifiers.type = convert_generic_types_to_packs - (decl_specifiers.type, - template_parm_idx, latest_template_parm_idx); + decl_specifiers.type + = convert_generic_types_to_packs (decl_specifiers.type, + template_parm_idx, + latest_template_parm_idx); } if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -25794,6 +25779,21 @@ cp_parser_parameter_declaration (cp_parser *parser, } } + if (xobj_param_p + && (declarator ? declarator->parameter_pack_p +: PACK_EXPANSION_P (decl_specifiers.type))) +{ + location_t xobj_param + = make_location (decl_specifiers.locations[ds_this], +decl_spec_token_start->location, +input_location); + error_at (xobj_param, + "an explicit object parameter cannot " + "be a function parameter pack"); + xobj_param_p = false; + decl_specifiers.locations[ds_this] = 0; +} + /* The restriction on defining new types applies only to the type of the parameter, not to the default argument. */ parser->type_definition_forbidden_message = saved_message; diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C index 304cf029f8f..f6a892eb069 100644 --- a/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C +++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-diagnostics3.C @@ -24,101 +24,140
[gcc r14-9386] c-family, c++: Fix up handling of types which may have padding in __atomic_{compare_}exchange
https://gcc.gnu.org/g:eed4e541711ab4ae7783f75dd132e2acca71fdb9 commit r14-9386-geed4e541711ab4ae7783f75dd132e2acca71fdb9 Author: Jakub Jelinek Date: Fri Mar 8 09:15:39 2024 +0100 c-family, c++: Fix up handling of types which may have padding in __atomic_{compare_}exchange On Fri, Feb 16, 2024 at 01:51:54PM +, Jonathan Wakely wrote: > Ah, although __atomic_compare_exchange only takes pointers, the > compiler replaces that with a call to __atomic_compare_exchange_n > which takes the newval by value, which presumably uses an 80-bit FP > register and so the padding bits become indeterminate again. The problem is that __atomic_{,compare_}exchange lowering if it has a supported atomic 1/2/4/8/16 size emits code like: _3 = *p2; _4 = VIEW_CONVERT_EXPR (_3); so if long double or some small struct etc. has some carefully filled padding bits, those bits can be lost on the assignment. The library call for __atomic_{,compare_}exchange would actually work because it woiuld load the value from memory using integral type or memcpy. E.g. on void foo (long double *a, long double *b, long double *c) { __atomic_compare_exchange (a, b, c, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } we end up with -O0 with: fldt(%rax) fstpt -48(%rbp) movq-48(%rbp), %rax movq-40(%rbp), %rdx i.e. load *c from memory into 387 register, store it back to uninitialized stack slot (the padding bits are now random in there) and then load a __uint128_t (pair of GPR regs). The problem is that we first load it using whatever type the pointer points to and then VIEW_CONVERT_EXPR that value: p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR); p2 = build1 (VIEW_CONVERT_EXPR, I_type, p2); The following patch fixes that by creating a MEM_REF instead, with the I_type type, but with the original pointer type on the second argument for aliasing purposes, so we actually preserve the padding bits that way. With this patch instead of the above assembly we emit movq8(%rax), %rdx movq(%rax), %rax I had to add support for MEM_REF in pt.cc, though with the assumption that it has been already originally created with non-dependent types/operands (which is the case here for the __atomic*exchange lowering). 2024-03-08 Jakub Jelinek gcc/c-family/ * c-common.cc (resolve_overloaded_atomic_exchange): Instead of setting p1 to VIEW_CONVERT_EXPR (*p1), set it to MEM_REF with p1 and (typeof (p1)) 0 operands and I_type type. (resolve_overloaded_atomic_compare_exchange): Similarly for p2. gcc/cp/ * pt.cc (tsubst_expr): Handle MEM_REF. gcc/testsuite/ * g++.dg/ext/atomic-5.C: New test. Diff: --- gcc/c-family/c-common.cc| 22 +-- gcc/cp/pt.cc| 8 +++ gcc/testsuite/g++.dg/ext/atomic-5.C | 42 + 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index e15eff698df..48844b17f77 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -7793,9 +7793,14 @@ resolve_overloaded_atomic_exchange (location_t loc, tree function, /* Convert object pointer to required type. */ p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0); (*params)[0] = p0; - /* Convert new value to required type, and dereference it. */ - p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR); - p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1); + /* Convert new value to required type, and dereference it. + If *p1 type can have padding or may involve floating point which + could e.g. be promoted to wider precision and demoted afterwards, + state of padding bits might not be preserved. */ + build_indirect_ref (loc, p1, RO_UNARY_STAR); + p1 = build2_loc (loc, MEM_REF, I_type, + build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1), + build_zero_cst (TREE_TYPE (p1))); (*params)[1] = p1; /* Move memory model to the 3rd position, and end param list. */ @@ -7873,9 +7878,14 @@ resolve_overloaded_atomic_compare_exchange (location_t loc, tree function, p1 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p1); (*params)[1] = p1; - /* Convert desired value to required type, and dereference it. */ - p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR); - p2 = build1 (VIEW_CONVERT_EXPR, I_type, p2); + /* Convert desired value to required type, and dereference it. + If *p2 type can have padding or may involve floating point which + could e.g. be promoted to wider precision and demoted afterwards, + state of padding bits might not be preserved. */ + build_indirect_ref (loc, p2, RO_UNARY_STAR); + p2 = build2_loc (loc, MEM_REF, I_type, +
[gcc r14-9387] i386: Guard noreturn no-callee-saved-registers optimization with -mnoreturn-no-callee-saved-register
https://gcc.gnu.org/g:a307a26e8b392ba65edfdae15489556b7701db81 commit r14-9387-ga307a26e8b392ba65edfdae15489556b7701db81 Author: Jakub Jelinek Date: Fri Mar 8 09:18:19 2024 +0100 i386: Guard noreturn no-callee-saved-registers optimization with -mnoreturn-no-callee-saved-registers [PR38534] The following patch hides the noreturn no_callee_saved_registers (except bp) optimization with a not enabled by default option. The reason is that most noreturn functions should be called just once in a program (unless they are recursive or invoke longjmp or similar, for exceptions we already punt), so it isn't that essential to save a few instructions in their prologue, but more importantly because it interferes with debugging. And unlike most other optimizations, doesn't actually make it harder to debug the given function, which can be solved by recompiling the given function if it is too hard to debug, but makes it harder to debug the callers of that noreturn function. Those can be from a different translation unit, different binary or even different package, so if e.g. glibc abort needs to use all of the callee saved registers (%rbx, %rbp, %r12, %r13, %r14, %r15), debugging any programs which abort will be harder because any DWARF expressions which use those registers will be optimized out, not just in the immediate caller, but in other callers as well until some frame restores a particular register from some stack slot. 2024-03-08 Jakub Jelinek PR target/38534 * config/i386/i386.opt (mnoreturn-no-callee-saved-registers): New option. * config/i386/i386-options.cc (ix86_set_func_type): Don't use TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP unless ix86_noreturn_no_callee_saved_registers is enabled. * doc/invoke.texi (-mnoreturn-no-callee-saved-registers): Document. * gcc.target/i386/pr38534-1.c: Add -mnoreturn-no-callee-saved-registers to dg-options. * gcc.target/i386/pr38534-2.c: Likewise. * gcc.target/i386/pr38534-3.c: Likewise. * gcc.target/i386/pr38534-4.c: Likewise. * gcc.target/i386/pr38534-5.c: Likewise. * gcc.target/i386/pr38534-6.c: Likewise. * gcc.target/i386/pr114097-1.c: Likewise. * gcc.target/i386/stack-check-17.c: Likewise. Diff: --- gcc/config/i386/i386-options.cc| 6 -- gcc/config/i386/i386.opt | 4 gcc/doc/invoke.texi| 10 ++ gcc/testsuite/gcc.target/i386/pr114097-1.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-1.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-2.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-3.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-4.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-5.c | 2 +- gcc/testsuite/gcc.target/i386/pr38534-6.c | 2 +- gcc/testsuite/gcc.target/i386/stack-check-17.c | 2 +- 11 files changed, 26 insertions(+), 10 deletions(-) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 2f8c85f66d4..3cc147fa70c 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -3384,7 +3384,8 @@ ix86_set_func_type (tree fndecl) { /* No need to save and restore callee-saved registers for a noreturn function with nothrow or compiled with -fno-exceptions unless when - compiling with -O0 or -Og. So that backtrace works for those at least + compiling with -O0 or -Og, except that it interferes with debugging + of callers. So that backtrace works for those at least in most cases, save the bp register if it is used, because it often is used in callers to compute CFA. @@ -3401,7 +3402,8 @@ ix86_set_func_type (tree fndecl) if (lookup_attribute ("no_callee_saved_registers", TYPE_ATTRIBUTES (TREE_TYPE (fndecl no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS; - else if (TREE_THIS_VOLATILE (fndecl) + else if (ix86_noreturn_no_callee_saved_registers + && TREE_THIS_VOLATILE (fndecl) && optimize && !optimize_debug && (TREE_NOTHROW (fndecl) || !flag_exceptions) diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 5b4f1bff25f..d5f793a9e8b 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -659,6 +659,10 @@ mstore-max= Target RejectNegative Joined Var(ix86_store_max) Enum(prefer_vector_width) Init(PVW_NONE) Save Maximum number of bits that can be stored to memory efficiently. +mnoreturn-no-callee-saved-registers +Target Var(ix86_noreturn_no_callee_saved_registers) +Optimize noreturn functions by not saving callee-saved registers used in the function. + ;; ISA support m32 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2390d4781
[gcc r14-9388] bb-reorder: Fix assertion
https://gcc.gnu.org/g:d6bcc2e257026b383ac3e6ccdee13f7763b38621 commit r14-9388-gd6bcc2e257026b383ac3e6ccdee13f7763b38621 Author: Jakub Jelinek Date: Fri Mar 8 12:49:43 2024 +0100 bb-reorder: Fix assertion When touching bb-reorder yesterday, I've noticed the checking assert doesn't actually check what it meant to. Because asm_noperands returns >= 0 for inline asm patterns (in that case number of input+output+label operands, so asm goto has at least one) and -1 if it isn't inline asm. The following patch fixes the assertion to actually check that it is asm goto. 2024-03-08 Jakub Jelinek * bb-reorder.cc (fix_up_fall_thru_edges): Fix up checking assert, asm_noperands < 0 means it is not asm goto too. Diff: --- gcc/bb-reorder.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/bb-reorder.cc b/gcc/bb-reorder.cc index 7998c0a148e..ba11a2337ab 100644 --- a/gcc/bb-reorder.cc +++ b/gcc/bb-reorder.cc @@ -2024,7 +2024,8 @@ fix_up_fall_thru_edges (void) See PR108596. */ rtx_insn *j = BB_END (cur_bb); gcc_checking_assert (JUMP_P (j) - && asm_noperands (PATTERN (j))); + && (asm_noperands (PATTERN (j)) + > 0)); edge e2 = find_edge (cur_bb, e->dest); if (e2) e2->flags |= EDGE_CROSSING;
[gcc r14-9392] testsuite: Fix up pr113617 test for darwin [PR113617]
https://gcc.gnu.org/g:8263a4b6505f84973c2ed2fb8d4f2036ca335ff3 commit r14-9392-g8263a4b6505f84973c2ed2fb8d4f2036ca335ff3 Author: Jakub Jelinek Date: Fri Mar 8 15:18:56 2024 +0100 testsuite: Fix up pr113617 test for darwin [PR113617] The test attempts to link a shared library, and apparently Darwin doesn't allow by default for shared libraries to contain undefined symbols. The following patch just adds dummy definitions for the symbols, so that the library no longer has any undefined symbols at least in my linux testing. Furthermore, for target { !shared } targets (like darwin until the it is fixed in target-supports.exp), because we then link a program rather than shared library, the patch also adds a dummy main definition so that it can link. 2024-03-08 Jakub Jelinek PR rtl-optimization/113617 PR target/114233 * g++.dg/other/pr113617.C: Define -DSHARED when linking with -shared. * g++.dg/other/pr113617-aux.cc: Add definitions for used methods and templates not defined elsewhere. Diff: --- gcc/testsuite/g++.dg/other/pr113617-aux.cc | 39 ++ gcc/testsuite/g++.dg/other/pr113617.C | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/g++.dg/other/pr113617-aux.cc b/gcc/testsuite/g++.dg/other/pr113617-aux.cc index e6900e05a5f..0576cee34bd 100644 --- a/gcc/testsuite/g++.dg/other/pr113617-aux.cc +++ b/gcc/testsuite/g++.dg/other/pr113617-aux.cc @@ -7,3 +7,42 @@ void qux() { A a; a.foo(0, 0); } + +namespace R { +template<> +Y >::AI +Y >::operator->() +{ + return AI(); +} +template<> +Y >::AI +Y >::operator->() +{ + return AI(); +} +} + +N1::N2::N3::AB ab; + +N1::N2::N3::AB & +N1::N2::N3::AB::bleh() +{ + return ab; +} + +N1::N2::N3::AC::AC(int) +{ +} + +void +N1::N2::N3::AC::m1(R::S) +{ +} + +#ifndef SHARED +int +main() +{ +} +#endif diff --git a/gcc/testsuite/g++.dg/other/pr113617.C b/gcc/testsuite/g++.dg/other/pr113617.C index a02dda1420d..0ee62c134e6 100644 --- a/gcc/testsuite/g++.dg/other/pr113617.C +++ b/gcc/testsuite/g++.dg/other/pr113617.C @@ -2,7 +2,7 @@ // { dg-do link { target c++11 } } // { dg-options "-O2" } // { dg-additional-options "-fPIC" { target fpic } } */ -// { dg-additional-options "-shared" { target shared } } */ +// { dg-additional-options "-shared -DSHARED" { target shared } } */ // { dg-additional-sources pr113617-aux.cc } #include "pr113617.h"
[gcc r14-9393] contrib: Improve dg-extract-results.sh's Python detection [PR109668]
https://gcc.gnu.org/g:64273a7e6bd8ba60058174d147521dd65d705637 commit r14-9393-g64273a7e6bd8ba60058174d147521dd65d705637 Author: Sam James Date: Fri Mar 8 15:24:20 2024 +0100 contrib: Improve dg-extract-results.sh's Python detection [PR109668] 'python' on some systems (e.g. SLES 15) might be Python 2. Prefer python3, then python, then python2 (as the script still tries to work there). PR other/109668 * dg-extract-results.sh: Check for python3 before python. Check for python2 last. Diff: --- contrib/dg-extract-results.sh | 17 ++--- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/contrib/dg-extract-results.sh b/contrib/dg-extract-results.sh index 00ef80046f7..539d596a89d 100755 --- a/contrib/dg-extract-results.sh +++ b/contrib/dg-extract-results.sh @@ -28,14 +28,17 @@ PROGNAME=dg-extract-results.sh -# Try to use the python version if possible, since it tends to be faster. +# Try to use the python version if possible, since it tends to be faster and +# produces more stable results. PYTHON_VER=`echo "$0" | sed 's/sh$/py/'` -if test "$PYTHON_VER" != "$0" && - test -f "$PYTHON_VER" && - python -c 'import sys, getopt, re, io, datetime, operator; sys.exit (0 if sys.version_info >= (2, 6) else 1)' \ - > /dev/null 2> /dev/null; then - exec python $PYTHON_VER "$@" -fi +for python in python3 python python2 ; do + if test "$PYTHON_VER" != "$0" && + test -f "$PYTHON_VER" && + ${python} -c 'import sys, getopt, re, io, datetime, operator; sys.exit (0 if sys.version_info >= (2, 6) else 1)' \ + > /dev/null 2> /dev/null; then +exec ${python} $PYTHON_VER "$@" + fi +done usage() { cat <&2
[gcc r15-224] Update gennews for GCC 14.
https://gcc.gnu.org/g:7ee3f769529f8d418bf361eb821aab17a33567e3 commit r15-224-g7ee3f769529f8d418bf361eb821aab17a33567e3 Author: Jakub Jelinek Date: Tue May 7 08:48:19 2024 +0200 Update gennews for GCC 14. 2024-05-07 Jakub Jelinek * gennews (files): Add files for GCC 14. Diff: --- contrib/gennews | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/gennews b/contrib/gennews index 6b8bb40a58a..483907b0e19 100755 --- a/contrib/gennews +++ b/contrib/gennews @@ -23,6 +23,7 @@ website=http://gcc.gnu.org/ files=" +gcc-14/index.html gcc-14/changes.html gcc-13/index.html gcc-13/changes.html gcc-12/index.html gcc-12/changes.html gcc-11/index.html gcc-11/changes.html
[gcc r14-10172] Update gennews for GCC 14.
https://gcc.gnu.org/g:4f12e06d2d112823298ffcad9732785bb86cb022 commit r14-10172-g4f12e06d2d112823298ffcad9732785bb86cb022 Author: Jakub Jelinek Date: Tue May 7 08:48:19 2024 +0200 Update gennews for GCC 14. 2024-05-07 Jakub Jelinek * gennews (files): Add files for GCC 14. (cherry picked from commit 7ee3f769529f8d418bf361eb821aab17a33567e3) Diff: --- contrib/gennews | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/gennews b/contrib/gennews index 6b8bb40a58a..483907b0e19 100755 --- a/contrib/gennews +++ b/contrib/gennews @@ -23,6 +23,7 @@ website=http://gcc.gnu.org/ files=" +gcc-14/index.html gcc-14/changes.html gcc-13/index.html gcc-13/changes.html gcc-12/index.html gcc-12/changes.html gcc-11/index.html gcc-11/changes.html
[gcc r14-10177] gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876]
https://gcc.gnu.org/g:a1c8ae15d9df0caa839b47c8631571a1ec27e367 commit r14-10177-ga1c8ae15d9df0caa839b47c8631571a1ec27e367 Author: Jakub Jelinek Date: Tue Apr 30 11:22:32 2024 +0200 gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876] Seems when Martin S. implemented this, he coded there strict reading of the standard, which said that %lc with (wint_t) 0 argument is handled as wchar_t[2] temp = { arg, 0 }; %ls with temp arg and so shouldn't print any values. But, most of the libc implementations actually handled that case like %c with '\0' argument, adding a single NUL character, the only known exception is musl. Recently, C23 changed this in response to GB-141 and POSIX in https://austingroupbugs.net/view.php?id=1647 so that it should have the same behavior as %c with '\0'. Because there is implementation divergence, the following patch uses a range rather than hardcoding it to all 1s (i.e. the %c behavior), though the likely case is still 1 (forward looking plus most of implementations). The res.knownrange = true; assignment removed is redundant due to the same assignment done unconditionally before the if statement, rest is formatting fixes. I don't think the min >= 0 && min < 128 case is right either, I'd think it should be min >= 0 && max < 128, otherwise it is just some possible inputs are (maybe) ASCII and there can be others, but this code is a total mess anyway, with the min, max, likely (somewhere in [min, max]?) and then unlikely possibly larger than max, dunno, perhaps for at least some chars in the ASCII range the likely case could be for the ascii case; so perhaps just the one_2_one_ascii shouldn't set max to 1 and mayfail should be true for max >= 128. Anyway, didn't feel I should touch that right now. 2024-04-30 Jakub Jelinek PR tree-optimization/114876 * gimple-ssa-sprintf.cc (format_character): For min == 0 && max == 0, set max, likely and unlikely members to 1 rather than 0. Remove useless res.knownrange = true;. Formatting fixes. * gcc.dg/pr114876.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected diagnostics. (cherry picked from commit 6c6b70f07208ca14ba783933988c04c6fc2fff42) Diff: --- gcc/gimple-ssa-sprintf.cc | 20 +++-- gcc/testsuite/gcc.dg/pr114876.c| 34 ++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-1.c | 12 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc index abb934b08d5a..3b19f4d3f357 100644 --- a/gcc/gimple-ssa-sprintf.cc +++ b/gcc/gimple-ssa-sprintf.cc @@ -2177,8 +2177,7 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) res.knownrange = true; - if (dir.specifier == 'C' - || dir.modifier == FMT_LEN_l) + if (dir.specifier == 'C' || dir.modifier == FMT_LEN_l) { /* A wide character can result in as few as zero bytes. */ res.range.min = 0; @@ -2189,10 +2188,13 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) { if (min == 0 && max == 0) { - /* The NUL wide character results in no bytes. */ - res.range.max = 0; - res.range.likely = 0; - res.range.unlikely = 0; + /* In strict reading of older ISO C or POSIX, this required +no characters to be emitted. ISO C23 changes that, so +does POSIX, to match what has been implemented in most of the +implementations, namely emitting a single NUL character. +Let's use 0 for minimum and 1 for all the other values. */ + res.range.max = 1; + res.range.likely = res.range.unlikely = 1; } else if (min >= 0 && min < 128) { @@ -2200,11 +2202,12 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) is not a 1-to-1 mapping to the source character set or if the source set is not ASCII. */ bool one_2_one_ascii - = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 97); + = (target_to_host_charmap[0] == 1 + && target_to_host ('a') == 97); /* A wide character in the ASCII range most likely results in a single byte, and only unlikely in up to MB_LEN_MAX. */ - res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();; + res.range.max = one_2_one_ascii ? 1 : target_mb_len_max (); res.range.likely = 1; res.range.unlikely = target_mb_len_max (); res.mayfail = !one_2_one_ascii; @@ -2235,7 +2238,6 @@
[gcc r14-10178] libgomp: Add gfx90c, 1036 and 1103 declare variant tests
https://gcc.gnu.org/g:23cf0107684336e46fc5525bf22d3f6ee965b463 commit r14-10178-g23cf0107684336e46fc5525bf22d3f6ee965b463 Author: Jakub Jelinek Date: Thu May 2 11:56:16 2024 +0200 libgomp: Add gfx90c, 1036 and 1103 declare variant tests Recently -march=gfx{90c,1036,1103} support has been added, but corresponding changes weren't done in the testsuite. The following patch adds that. Tested on x86_64-linux (with fiji and gfx1103 devices; had to use OMP_DEFAULT_DEVICE=1 there, fiji doesn't really work due to LLVM dropping support, but we still list those as offloading devices). 2024-05-02 Jakub Jelinek * testsuite/libgomp.c/declare-variant-4.h (gfx90c, gfx1036, gfx1103): New functions. (f): Add #pragma omp declare variant directives for those. * testsuite/libgomp.c/declare-variant-4-gfx90c.c: New test. * testsuite/libgomp.c/declare-variant-4-gfx1036.c: New test. * testsuite/libgomp.c/declare-variant-4-gfx1103.c: New test. (cherry picked from commit 5eb25d1561dd22316331feee92164f97ca79d1c3) Diff: --- .../libgomp.c/declare-variant-4-gfx1036.c | 8 .../libgomp.c/declare-variant-4-gfx1103.c | 8 .../testsuite/libgomp.c/declare-variant-4-gfx90c.c | 8 libgomp/testsuite/libgomp.c/declare-variant-4.h| 24 ++ 4 files changed, 48 insertions(+) diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c new file mode 100644 index ..93b8641b3e15 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1036.c @@ -0,0 +1,8 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1036 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1036 \\(\\);" "optimized" } } */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c new file mode 100644 index ..6a6dc4fba3fd --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx1103.c @@ -0,0 +1,8 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx1103 } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx1103 \\(\\);" "optimized" } } */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c new file mode 100644 index ..44629a806b46 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/declare-variant-4-gfx90c.c @@ -0,0 +1,8 @@ +/* { dg-do link { target { offload_target_amdgcn } } } */ +/* { dg-additional-options -foffload=amdgcn-amdhsa } */ +/* { dg-additional-options -foffload=-march=gfx90c } */ +/* { dg-additional-options "-foffload=-fdump-tree-optimized" } */ + +#include "declare-variant-4.h" + +/* { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump "= gfx90c \\(\\);" "optimized" } } */ diff --git a/libgomp/testsuite/libgomp.c/declare-variant-4.h b/libgomp/testsuite/libgomp.c/declare-variant-4.h index d2e9194bf5b6..f244d09c655c 100644 --- a/libgomp/testsuite/libgomp.c/declare-variant-4.h +++ b/libgomp/testsuite/libgomp.c/declare-variant-4.h @@ -35,6 +35,13 @@ gfx90a (void) return 0x90a; } +__attribute__ ((noipa)) +int +gfx90c (void) +{ + return 0x90c; +} + __attribute__ ((noipa)) int gfx1030 (void) @@ -42,6 +49,13 @@ gfx1030 (void) return 0x1030; } +__attribute__ ((noipa)) +int +gfx1036 (void) +{ + return 0x1036; +} + __attribute__ ((noipa)) int gfx1100 (void) @@ -49,6 +63,13 @@ gfx1100 (void) return 0x1100; } +__attribute__ ((noipa)) +int +gfx1103 (void) +{ + return 0x1103; +} + #ifdef USE_FIJI_FOR_GFX803 #pragma omp declare variant(gfx803) match(device = {isa("fiji")}) #else @@ -58,8 +79,11 @@ gfx1100 (void) #pragma omp declare variant(gfx906) match(device = {isa("gfx906")}) #pragma omp declare variant(gfx908) match(device = {isa("gfx908")}) #pragma omp declare variant(gfx90a) match(device = {isa("gfx90a")}) +#pragma omp declare variant(gfx90c) match(device = {isa("gfx90c")}) #pragma omp declare variant(gfx1030) match(device = {isa("gfx1030")}) +#pragma omp declare variant(gfx1036) match(device = {isa("gfx1036")}) #pragma omp declare variant(gfx1100) match(device = {isa("gfx1100")}) +#pragma omp declare variant(gfx1103) match(device = {isa("gfx1103")}) __attribute__ ((noipa)) int f (void)
[gcc r15-302] tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956]
https://gcc.gnu.org/g:d4e25cf4f7c1f51a8824cc62bbb85a81a41b829a commit r15-302-gd4e25cf4f7c1f51a8824cc62bbb85a81a41b829a Author: Jakub Jelinek Date: Tue May 7 21:29:14 2024 +0200 tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956] In r9-5742 we've started allowing to inline always_inline functions into functions which have disabled e.g. address sanitization even when the always_inline function is implicitly from command line options sanitized. This mostly works fine because most of the asan instrumentation is done only late after ipa, but as the following testcase the .ASAN_MARK ifn calls gimplifier adds can result in ICEs. Fixed by dropping those during inlining, similarly to how we drop .TSAN_FUNC_EXIT calls. 2024-05-07 Jakub Jelinek PR sanitizer/114956 * tree-inline.cc: Include asan.h. (copy_bb): Remove also .ASAN_MARK calls if id->dst_fn has asan/hwasan sanitization disabled. * gcc.dg/asan/pr114956.c: New test. Diff: --- gcc/testsuite/gcc.dg/asan/pr114956.c | 26 ++ gcc/tree-inline.cc | 28 +--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/gcc.dg/asan/pr114956.c b/gcc/testsuite/gcc.dg/asan/pr114956.c new file mode 100644 index ..fb87d514f255 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr114956.c @@ -0,0 +1,26 @@ +/* PR sanitizer/114956 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsanitize=address,null" } */ + +int **a; +void qux (int *); + +__attribute__((always_inline)) static inline int * +foo (void) +{ + int b[1]; + qux (b); + return a[1]; +} + +__attribute__((no_sanitize_address)) void +bar (void) +{ + *a = foo (); +} + +void +baz (void) +{ + bar (); +} diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index b9fe2099d4f8..f31a34ac4105 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include "symbol-summary.h" #include "symtab-thunks.h" #include "symtab-clones.h" +#include "asan.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -2226,13 +2227,26 @@ copy_bb (copy_body_data *id, basic_block bb, } else if (call_stmt && id->call_stmt - && gimple_call_internal_p (stmt) - && gimple_call_internal_fn (stmt) == IFN_TSAN_FUNC_EXIT) - { - /* Drop TSAN_FUNC_EXIT () internal calls during inlining. */ - gsi_remove (©_gsi, false); - continue; - } + && gimple_call_internal_p (stmt)) + switch (gimple_call_internal_fn (stmt)) + { + case IFN_TSAN_FUNC_EXIT: + /* Drop .TSAN_FUNC_EXIT () internal calls during inlining. */ + gsi_remove (©_gsi, false); + continue; + case IFN_ASAN_MARK: + /* Drop .ASAN_MARK internal calls during inlining into + no_sanitize functions. */ + if (!sanitize_flags_p (SANITIZE_ADDRESS, id->dst_fn) + && !sanitize_flags_p (SANITIZE_HWADDRESS, id->dst_fn)) + { + gsi_remove (©_gsi, false); + continue; + } + break; + default: + break; + } /* Statements produced by inlining can be unfolded, especially when we constant propagated some operands. We can't fold
[gcc r15-303] expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907]
https://gcc.gnu.org/g:28ee13db2e9d995bd3728c4ff3a3545e24b39cd2 commit r15-303-g28ee13db2e9d995bd3728c4ff3a3545e24b39cd2 Author: Jakub Jelinek Date: Tue May 7 21:30:21 2024 +0200 expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907] The HF and BF modes have the same size/precision and neither is a subset nor superset of the other. So, using either __extendhfbf2 or __trunchfbf2 is weird. The expansion apparently emits __extendhfbf2, but on the libgcc side we apparently have __trunchfbf2 implemented. I think it is easier to switch to using what is available rather than adding new entrypoints to libgcc, even alias, because this is backportable. 2024-05-07 Jakub Jelinek PR middle-end/114907 * expr.cc (convert_mode_scalar): Use trunc_optab rather than sext_optab for HF->BF conversions. * optabs-libfuncs.cc (gen_trunc_conv_libfunc): Likewise. * gcc.dg/pr114907.c: New test. Diff: --- gcc/expr.cc | 12 ++-- gcc/optabs-libfuncs.cc | 4 +++- gcc/testsuite/gcc.dg/pr114907.c | 27 +++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index d4414e242cb9..9f66d4794459 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -355,8 +355,16 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) - /* Conversion between decimal float and binary float, same size. */ - tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + { + if (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format + && REAL_MODE_FORMAT (from_mode) == &ieee_half_format) + /* libgcc implements just __trunchfbf2, not __extendhfbf2. */ + tab = trunc_optab; + else + /* Conversion between decimal float and binary float, same + size. */ + tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + } else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)) tab = sext_optab; else diff --git a/gcc/optabs-libfuncs.cc b/gcc/optabs-libfuncs.cc index 02e9bf6ea5aa..26729910d92b 100644 --- a/gcc/optabs-libfuncs.cc +++ b/gcc/optabs-libfuncs.cc @@ -589,7 +589,9 @@ gen_trunc_conv_libfunc (convert_optab tab, if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode)) gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode); - if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)) + if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode) + && (REAL_MODE_FORMAT (float_tmode) != &arm_bfloat_half_format + || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format)) return; if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode)) diff --git a/gcc/testsuite/gcc.dg/pr114907.c b/gcc/testsuite/gcc.dg/pr114907.c new file mode 100644 index ..628746e1f8c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114907.c @@ -0,0 +1,27 @@ +/* PR middle-end/114907 */ +/* { dg-do run } */ +/* { dg-options "" } */ +/* { dg-add-options float16 } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-add-options bfloat16 } */ +/* { dg-require-effective-target bfloat16_runtime } */ + +__attribute__((noipa)) _Float16 +foo (__bf16 x) +{ + return (_Float16) x; +} + +__attribute__((noipa)) __bf16 +bar (_Float16 x) +{ + return (__bf16) x; +} + +int +main () +{ + if (foo (11.125bf16) != 11.125f16 + || bar (11.125f16) != 11.125bf16) +__builtin_abort (); +}
[gcc r14-10180] tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956]
https://gcc.gnu.org/g:aca573ea64ccfd54d4447e9a3200acd7a9157082 commit r14-10180-gaca573ea64ccfd54d4447e9a3200acd7a9157082 Author: Jakub Jelinek Date: Tue May 7 21:29:14 2024 +0200 tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956] In r9-5742 we've started allowing to inline always_inline functions into functions which have disabled e.g. address sanitization even when the always_inline function is implicitly from command line options sanitized. This mostly works fine because most of the asan instrumentation is done only late after ipa, but as the following testcase the .ASAN_MARK ifn calls gimplifier adds can result in ICEs. Fixed by dropping those during inlining, similarly to how we drop .TSAN_FUNC_EXIT calls. 2024-05-07 Jakub Jelinek PR sanitizer/114956 * tree-inline.cc: Include asan.h. (copy_bb): Remove also .ASAN_MARK calls if id->dst_fn has asan/hwasan sanitization disabled. * gcc.dg/asan/pr114956.c: New test. (cherry picked from commit d4e25cf4f7c1f51a8824cc62bbb85a81a41b829a) Diff: --- gcc/testsuite/gcc.dg/asan/pr114956.c | 26 ++ gcc/tree-inline.cc | 28 +--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/gcc.dg/asan/pr114956.c b/gcc/testsuite/gcc.dg/asan/pr114956.c new file mode 100644 index ..fb87d514f255 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr114956.c @@ -0,0 +1,26 @@ +/* PR sanitizer/114956 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsanitize=address,null" } */ + +int **a; +void qux (int *); + +__attribute__((always_inline)) static inline int * +foo (void) +{ + int b[1]; + qux (b); + return a[1]; +} + +__attribute__((no_sanitize_address)) void +bar (void) +{ + *a = foo (); +} + +void +baz (void) +{ + bar (); +} diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 238afb7de80e..5f427608d778 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include "symbol-summary.h" #include "symtab-thunks.h" #include "symtab-clones.h" +#include "asan.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -2226,13 +2227,26 @@ copy_bb (copy_body_data *id, basic_block bb, } else if (call_stmt && id->call_stmt - && gimple_call_internal_p (stmt) - && gimple_call_internal_fn (stmt) == IFN_TSAN_FUNC_EXIT) - { - /* Drop TSAN_FUNC_EXIT () internal calls during inlining. */ - gsi_remove (©_gsi, false); - continue; - } + && gimple_call_internal_p (stmt)) + switch (gimple_call_internal_fn (stmt)) + { + case IFN_TSAN_FUNC_EXIT: + /* Drop .TSAN_FUNC_EXIT () internal calls during inlining. */ + gsi_remove (©_gsi, false); + continue; + case IFN_ASAN_MARK: + /* Drop .ASAN_MARK internal calls during inlining into + no_sanitize functions. */ + if (!sanitize_flags_p (SANITIZE_ADDRESS, id->dst_fn) + && !sanitize_flags_p (SANITIZE_HWADDRESS, id->dst_fn)) + { + gsi_remove (©_gsi, false); + continue; + } + break; + default: + break; + } /* Statements produced by inlining can be unfolded, especially when we constant propagated some operands. We can't fold
[gcc r14-10181] expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907]
https://gcc.gnu.org/g:f43f346f19889a15a171a10c6ae1b1fe0a5bc038 commit r14-10181-gf43f346f19889a15a171a10c6ae1b1fe0a5bc038 Author: Jakub Jelinek Date: Tue May 7 21:30:21 2024 +0200 expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907] The HF and BF modes have the same size/precision and neither is a subset nor superset of the other. So, using either __extendhfbf2 or __trunchfbf2 is weird. The expansion apparently emits __extendhfbf2, but on the libgcc side we apparently have __trunchfbf2 implemented. I think it is easier to switch to using what is available rather than adding new entrypoints to libgcc, even alias, because this is backportable. 2024-05-07 Jakub Jelinek PR middle-end/114907 * expr.cc (convert_mode_scalar): Use trunc_optab rather than sext_optab for HF->BF conversions. * optabs-libfuncs.cc (gen_trunc_conv_libfunc): Likewise. * gcc.dg/pr114907.c: New test. (cherry picked from commit 28ee13db2e9d995bd3728c4ff3a3545e24b39cd2) Diff: --- gcc/expr.cc | 12 ++-- gcc/optabs-libfuncs.cc | 4 +++- gcc/testsuite/gcc.dg/pr114907.c | 27 +++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index d4414e242cb9..9f66d4794459 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -355,8 +355,16 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) - /* Conversion between decimal float and binary float, same size. */ - tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + { + if (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format + && REAL_MODE_FORMAT (from_mode) == &ieee_half_format) + /* libgcc implements just __trunchfbf2, not __extendhfbf2. */ + tab = trunc_optab; + else + /* Conversion between decimal float and binary float, same + size. */ + tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + } else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)) tab = sext_optab; else diff --git a/gcc/optabs-libfuncs.cc b/gcc/optabs-libfuncs.cc index 02e9bf6ea5aa..26729910d92b 100644 --- a/gcc/optabs-libfuncs.cc +++ b/gcc/optabs-libfuncs.cc @@ -589,7 +589,9 @@ gen_trunc_conv_libfunc (convert_optab tab, if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode)) gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode); - if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)) + if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode) + && (REAL_MODE_FORMAT (float_tmode) != &arm_bfloat_half_format + || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format)) return; if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode)) diff --git a/gcc/testsuite/gcc.dg/pr114907.c b/gcc/testsuite/gcc.dg/pr114907.c new file mode 100644 index ..628746e1f8c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114907.c @@ -0,0 +1,27 @@ +/* PR middle-end/114907 */ +/* { dg-do run } */ +/* { dg-options "" } */ +/* { dg-add-options float16 } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-add-options bfloat16 } */ +/* { dg-require-effective-target bfloat16_runtime } */ + +__attribute__((noipa)) _Float16 +foo (__bf16 x) +{ + return (_Float16) x; +} + +__attribute__((noipa)) __bf16 +bar (_Float16 x) +{ + return (__bf16) x; +} + +int +main () +{ + if (foo (11.125bf16) != 11.125f16 + || bar (11.125f16) != 11.125bf16) +__builtin_abort (); +}
[gcc r15-304] c++: Implement C++26 P2893R3 - Variadic friends [PR114459]
https://gcc.gnu.org/g:17458d2bc74b904968e6bdc12527eb040c8d2370 commit r15-304-g17458d2bc74b904968e6bdc12527eb040c8d2370 Author: Jakub Jelinek Date: Tue May 7 22:38:01 2024 +0200 c++: Implement C++26 P2893R3 - Variadic friends [PR114459] The following patch imeplements the C++26 P2893R3 - Variadic friends paper. The paper allows for the friend type declarations to specify more than one friend type specifier and allows to specify ... at the end of each. The patch doesn't introduce tentative parsing of friend-type-declaration non-terminal, but rather just extends existing parsing where it is a friend declaration which ends with ; after the declaration specifiers to the cases where it ends with ...; or , or ..., In that case it pedwarns for cxx_dialect < cxx26, handles the ... and if there is , continues in a loop to parse the further friend type specifiers. 2024-05-07 Jakub Jelinek PR c++/114459 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Predefine __cpp_variadic_friend=202403L for C++26. gcc/cp/ * parser.cc (cp_parser_member_declaration): Implement C++26 P2893R3 - Variadic friends. Parse friend type declarations with ... or with more than one friend type specifier. * friend.cc (make_friend_class): Allow TYPE_PACK_EXPANSION. * pt.cc (instantiate_class_template): Handle PACK_EXPANSION_P in friend classes. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C (__cpp_variadic_friend): Add test. * g++.dg/cpp26/variadic-friend1.C: New test. Diff: --- gcc/c-family/c-cppbuiltin.cc | 1 + gcc/cp/friend.cc | 3 +- gcc/cp/parser.cc | 126 ++ gcc/cp/pt.cc | 16 gcc/testsuite/g++.dg/cpp26/feat-cxx26.C | 6 ++ gcc/testsuite/g++.dg/cpp26/variadic-friend1.C | 58 6 files changed, 169 insertions(+), 41 deletions(-) diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index b6f25e4db3c0..d9b84a0f1b97 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1093,6 +1093,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_placeholder_variables=202306L"); cpp_define (pfile, "__cpp_structured_bindings=202403L"); cpp_define (pfile, "__cpp_deleted_function=202403L"); + cpp_define (pfile, "__cpp_variadic_friend=202403L"); } if (flag_concepts) { diff --git a/gcc/cp/friend.cc b/gcc/cp/friend.cc index 758ea87b1721..2e70d0160c46 100644 --- a/gcc/cp/friend.cc +++ b/gcc/cp/friend.cc @@ -279,7 +279,8 @@ make_friend_class (tree type, tree friend_type, bool complain) } if (! MAYBE_CLASS_TYPE_P (friend_type) - && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM) + && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM + && TREE_CODE (friend_type) != TYPE_PACK_EXPANSION) { /* N1791: If the type specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 775067ed4bc5..c4191200291d 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -28100,8 +28100,17 @@ cp_parser_member_declaration (cp_parser* parser) && cp_parser_parse_and_diagnose_invalid_type_name (parser)) goto out; /* If there is no declarator, then the decl-specifier-seq should - specify a type. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + specify a type. For C++26 Variadic friends don't just check for + a semicolon, but also for a comma and in both cases optionally + preceded by ellipsis. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON) + || (cp_parser_friend_p (&decl_specifiers) + && cxx_dialect >= cxx11 + && (cp_lexer_next_token_is (parser->lexer, CPP_COMMA) + || (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS) + && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON) + || cp_lexer_nth_token_is (parser->lexer, 2, + CPP_COMMA)) { /* If there was no decl-specifier-seq, and the next token is a `;', then we have something like: @@ -28136,44 +28145,81 @@ cp_parser_member_declaration (cp_parser* parser) { /* If the `friend' keyword was present, the friend must be introduced with a class-key. */ - if (!declares_class_or_enum && cxx_dialect < cxx11) -pedwarn (decl_spec_token_start->location, OPT_Wpedantic, - "in C++03 a class-key must be used " - "when declaring a friend"); - /* In this case: - -
[gcc r15-315] reassoc: Fix up optimize_range_tests_to_bit_test [PR114965]
https://gcc.gnu.org/g:9adec2d91e62a479474ae79df5b455fd4b8463ba commit r15-315-g9adec2d91e62a479474ae79df5b455fd4b8463ba Author: Jakub Jelinek Date: Wed May 8 10:17:32 2024 +0200 reassoc: Fix up optimize_range_tests_to_bit_test [PR114965] The optimize_range_tests_to_bit_test optimization normally emits a range test first: if (entry_test_needed) { tem = build_range_check (loc, optype, unshare_expr (exp), false, lowi, high); if (tem == NULL_TREE || is_gimple_val (tem)) continue; } so during the bit test we already know that exp is in the [lowi, high] range, but skips it if we have range info which tells us this isn't necessary. Also, normally it emits shifts by exp - lowi counter, but has an optimization to use just exp counter if the mask isn't a more expensive constant in that case and lowi is > 0 and high is smaller than prec. The following testcase is miscompiled because the two abnormal cases are triggered. The range of exp is [43, 43][48, 48][95, 95], so we on 64-bit arch decide we don't need the entry test, because 95 - 43 < 64. And we also decide to use just exp as counter, because the range test tests just for exp == 43 || exp == 48, so high is smaller than 64 too. Because 95 is in the exp range, we can't do that, we'd either need to do a range test first, i.e. if (exp - 43U <= 48U - 43U) if ((1UL << exp) & mask1)) or need to subtract lowi from the shift counter, i.e. if ((1UL << (exp - 43)) & mask2) but can't do both unless r.upper_bound () is < prec. The following patch ensures that. 2024-05-08 Jakub Jelinek PR tree-optimization/114965 * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): Don't try to optimize away exp - lowi subtraction from shift count unless entry test is emitted or unless r.upper_bound () is smaller than prec. * gcc.c-torture/execute/pr114965.c: New test. Diff: --- gcc/testsuite/gcc.c-torture/execute/pr114965.c | 30 ++ gcc/tree-ssa-reassoc.cc| 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr114965.c b/gcc/testsuite/gcc.c-torture/execute/pr114965.c new file mode 100644 index ..89d68e187015 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr114965.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/114965 */ + +static void +foo (const char *x) +{ + + char a = '0'; + while (1) +{ + switch (*x) + { + case '_': + case '+': + a = *x; + x++; + continue; + default: + break; + } + break; +} + if (a == '0' || a == '+') +__builtin_abort (); +} + +int +main () +{ + foo ("_"); +} diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index 61f54f07b577..556ecdebe2d7 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -3418,7 +3418,8 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length, We can avoid then subtraction of the minimum value, but the mask constant could be perhaps more expensive. */ if (compare_tree_int (lowi, 0) > 0 - && compare_tree_int (high, prec) < 0) + && compare_tree_int (high, prec) < 0 + && (entry_test_needed || wi::ltu_p (r.upper_bound (), prec))) { int cost_diff; HOST_WIDE_INT m = tree_to_uhwi (lowi);
[gcc r14-10184] reassoc: Fix up optimize_range_tests_to_bit_test [PR114965]
https://gcc.gnu.org/g:d54151df3ba0ee3203e0b8cb8f8fcd168a766c51 commit r14-10184-gd54151df3ba0ee3203e0b8cb8f8fcd168a766c51 Author: Jakub Jelinek Date: Wed May 8 10:17:32 2024 +0200 reassoc: Fix up optimize_range_tests_to_bit_test [PR114965] The optimize_range_tests_to_bit_test optimization normally emits a range test first: if (entry_test_needed) { tem = build_range_check (loc, optype, unshare_expr (exp), false, lowi, high); if (tem == NULL_TREE || is_gimple_val (tem)) continue; } so during the bit test we already know that exp is in the [lowi, high] range, but skips it if we have range info which tells us this isn't necessary. Also, normally it emits shifts by exp - lowi counter, but has an optimization to use just exp counter if the mask isn't a more expensive constant in that case and lowi is > 0 and high is smaller than prec. The following testcase is miscompiled because the two abnormal cases are triggered. The range of exp is [43, 43][48, 48][95, 95], so we on 64-bit arch decide we don't need the entry test, because 95 - 43 < 64. And we also decide to use just exp as counter, because the range test tests just for exp == 43 || exp == 48, so high is smaller than 64 too. Because 95 is in the exp range, we can't do that, we'd either need to do a range test first, i.e. if (exp - 43U <= 48U - 43U) if ((1UL << exp) & mask1)) or need to subtract lowi from the shift counter, i.e. if ((1UL << (exp - 43)) & mask2) but can't do both unless r.upper_bound () is < prec. The following patch ensures that. 2024-05-08 Jakub Jelinek PR tree-optimization/114965 * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): Don't try to optimize away exp - lowi subtraction from shift count unless entry test is emitted or unless r.upper_bound () is smaller than prec. * gcc.c-torture/execute/pr114965.c: New test. (cherry picked from commit 9adec2d91e62a479474ae79df5b455fd4b8463ba) Diff: --- gcc/testsuite/gcc.c-torture/execute/pr114965.c | 30 ++ gcc/tree-ssa-reassoc.cc| 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr114965.c b/gcc/testsuite/gcc.c-torture/execute/pr114965.c new file mode 100644 index ..89d68e187015 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr114965.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/114965 */ + +static void +foo (const char *x) +{ + + char a = '0'; + while (1) +{ + switch (*x) + { + case '_': + case '+': + a = *x; + x++; + continue; + default: + break; + } + break; +} + if (a == '0' || a == '+') +__builtin_abort (); +} + +int +main () +{ + foo ("_"); +} diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index 61f54f07b577..556ecdebe2d7 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -3418,7 +3418,8 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length, We can avoid then subtraction of the minimum value, but the mask constant could be perhaps more expensive. */ if (compare_tree_int (lowi, 0) > 0 - && compare_tree_int (high, prec) < 0) + && compare_tree_int (high, prec) < 0 + && (entry_test_needed || wi::ltu_p (r.upper_bound (), prec))) { int cost_diff; HOST_WIDE_INT m = tree_to_uhwi (lowi);
[gcc/redhat/heads/gcc-14-branch] (31 commits) Merge commit 'r14-10184-gd54151df3ba0ee3203e0b8cb8f8fcd168a
The branch 'redhat/heads/gcc-14-branch' was updated to point to: 9ae733ecd3cd... Merge commit 'r14-10184-gd54151df3ba0ee3203e0b8cb8f8fcd168a It previously pointed to: 748fd0ecf84c... Merge commit 'r14-10154-g7a00c459cbb913ac165a39d344a48fc278 Diff: Summary of changes (added commits): --- 9ae733e... Merge commit 'r14-10184-gd54151df3ba0ee3203e0b8cb8f8fcd168a d54151d... reassoc: Fix up optimize_range_tests_to_bit_test [PR114965] (*) cacc480... c++/c-common: Fix convert_vector_to_array_for_subscript for (*) 61a095b... c++/modules: Stream unmergeable temporaries by value again (*) f43f346... expansion: Use __trunchfbf2 calls rather than __extendhfbf2 (*) aca573e... tree-inline: Remove .ASAN_MARK calls when inlining function (*) 07dab3f... [PR modula2/113768][PR modula2/114133] bugfix constants mus (*) 23cf010... libgomp: Add gfx90c, 1036 and 1103 declare variant tests (*) a1c8ae1... gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) (*) 390bd23... c++/modules: imported spec befriending class tmpl [PR114889 (*) c6141ad... AVR: ipa/92606 - Don't optimize PROGMEM data against non-PR (*) 43b730b... Bump BASE-VER (*) cd0059a... Update ChangeLog and version files for release (*) 4f12e06... Update gennews for GCC 14. (*) 308a39c... Daily bump. (*) c7b4305... testsuite: c++: Skip g++.dg/analyzer on Solaris [PR111475] (*) 765ddff... Daily bump. (*) 43b7e2f... Daily bump. (*) 532d775... Daily bump. (*) d811080... [PATCH] PR modula2/114929 for loop fails to iterate down to (*) 3b4d6b6... c++: initializer_list and EH [PR114935] (*) db447ec... Revert "tree-optimization/114921 - _Float16 -> __bf16 isn't (*) d7c06a8... libstdc++: Update powerpc-linux-gnu baseline_symbols (*) 7963194... RISC-V: Add testcase for pr114734 (*) 5c42872... middle-end/114734 - wrong code with expand_call_mem_ref (*) 242fbc0... cfgrtl: Fix MEM_EXPR update in duplicate_insn_chain [PR1149 (*) fa7e05d... tree-optimization/114921 - _Float16 -> __bf16 isn't noop (*) f86f197... Daily bump. (*) 8e39d4f... Regenerate gcc.pot (*) 590a065... Daily bump. (*) 9ccb16d... Daily bump. (*) (*) This commit already exists in another branch. Because the reference `refs/vendors/redhat/heads/gcc-14-branch' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc r13-8730] openmp: Copy DECL_LANG_SPECIFIC and DECL_LANG_FLAG_? to tree-nested decl copy [PR114825]
https://gcc.gnu.org/g:6d30cfc3fc88976151d0d10e73e10111ccb71ee0 commit r13-8730-g6d30cfc3fc88976151d0d10e73e10111ccb71ee0 Author: Jakub Jelinek Date: Thu Apr 25 20:09:35 2024 +0200 openmp: Copy DECL_LANG_SPECIFIC and DECL_LANG_FLAG_? to tree-nested decl copy [PR114825] tree-nested.cc creates in 2 spots artificial VAR_DECLs, one of them is used both for debug info and OpenMP/OpenACC lowering purposes, the other solely for OpenMP/OpenACC lowering purposes. When the decls are used in OpenMP/OpenACC lowering, the OMP langhooks (mostly Fortran, C just a little and C++ doesn't have nested functions) then inspect the flags on the vars and based on that decide how to lower the corresponding clauses. Unfortunately we weren't copying DECL_LANG_SPECIFIC and DECL_LANG_FLAG_?, so the langhooks made decisions on the default flags on those instead. As the original decl isn't necessarily a VAR_DECL, could be e.g. PARM_DECL, using copy_node wouldn't work properly, so this patch just copies those flags in addition to other flags it was copying already. And I've removed code duplication by introducing a helper function which does copying common to both uses. 2024-04-25 Jakub Jelinek PR fortran/114825 * tree-nested.cc (get_debug_decl): New function. (get_nonlocal_debug_decl): Use it. (get_local_debug_decl): Likewise. * gfortran.dg/gomp/pr114825.f90: New test. (cherry picked from commit 14d48516e588ad2b35e2007b3970bdcb1b3f145c) Diff: --- gcc/testsuite/gfortran.dg/gomp/pr114825.f90 | 16 gcc/tree-nested.cc | 61 - 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/gcc/testsuite/gfortran.dg/gomp/pr114825.f90 b/gcc/testsuite/gfortran.dg/gomp/pr114825.f90 new file mode 100644 index ..b635476af61e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr114825.f90 @@ -0,0 +1,16 @@ +! PR fortran/114825 + +subroutine pr114825(b) + type t +real, allocatable :: m(:) + end type t + type(t), allocatable, target :: b(:) + type(t), pointer :: d + !$omp parallel private(d) + d => b(1) + !$omp end parallel +contains + subroutine sub +d => b(1) + end subroutine sub +end subroutine pr114825 diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc index 1418e1f7f562..0f44b3dc735e 100644 --- a/gcc/tree-nested.cc +++ b/gcc/tree-nested.cc @@ -1039,6 +1039,37 @@ get_frame_field (struct nesting_info *info, tree target_context, static void note_nonlocal_vla_type (struct nesting_info *info, tree type); +/* Helper for get_nonlocal_debug_decl and get_local_debug_decl. */ + +static tree +get_debug_decl (tree decl) +{ + tree new_decl += build_decl (DECL_SOURCE_LOCATION (decl), + VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); + DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); + DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); + TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); + TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); + TREE_READONLY (new_decl) = TREE_READONLY (decl); + TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); + DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; + if ((TREE_CODE (decl) == PARM_DECL + || TREE_CODE (decl) == RESULT_DECL + || VAR_P (decl)) + && DECL_BY_REFERENCE (decl)) +DECL_BY_REFERENCE (new_decl) = 1; + /* Copy DECL_LANG_SPECIFIC and DECL_LANG_FLAG_* for OpenMP langhook + purposes. */ + DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (decl); +#define COPY_DLF(n) DECL_LANG_FLAG_##n (new_decl) = DECL_LANG_FLAG_##n (decl) + COPY_DLF (0); COPY_DLF (1); COPY_DLF (2); COPY_DLF (3); + COPY_DLF (4); COPY_DLF (5); COPY_DLF (6); COPY_DLF (7); + COPY_DLF (8); +#undef COPY_DLF + return new_decl; +} + /* A subroutine of convert_nonlocal_reference_op. Create a local variable in the nested function with DECL_VALUE_EXPR set to reference the true variable in the parent function. This is used both for debug info @@ -1086,21 +1117,8 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl) x = build_simple_mem_ref_notrap (x); /* ??? We should be remapping types as well, surely. */ - new_decl = build_decl (DECL_SOURCE_LOCATION (decl), -VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); + new_decl = get_debug_decl (decl); DECL_CONTEXT (new_decl) = info->context; - DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl); - DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl); - TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl); - TREE_SIDE_EFFECTS (new_decl) = TREE_SIDE_EFFECTS (decl); - TREE_READONLY (new_decl) = TREE_READONLY (decl); - TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl); - DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1; - if ((TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == RESULT_DECL - || VAR_
[gcc r13-8731] c++: Fix constexpr evaluation of parameters passed by invisible reference [PR111284]
https://gcc.gnu.org/g:6f1b3f9c97e17aa717ae61bc70afa27adcb7ef44 commit r13-8731-g6f1b3f9c97e17aa717ae61bc70afa27adcb7ef44 Author: Jakub Jelinek Date: Thu Apr 25 20:45:04 2024 +0200 c++: Fix constexpr evaluation of parameters passed by invisible reference [PR111284] My r9-6136 changes to make a copy of constexpr function bodies before genericization modifies it broke the constant evaluation of non-POD arguments passed by value. In the callers such arguments are passed as reference to usually a TARGET_EXPR, but on the callee side until genericization they are just direct uses of a PARM_DECL with some class type. In cxx_bind_parameters_in_call I've used convert_from_reference to pretend it is passed by value and then cxx_eval_constant_expression is called there and evaluates that as an rvalue, followed by adjust_temp_type if the types don't match exactly (e.g. const Foo argument and passing to it reference to Foo TARGET_EXPR). The reason this doesn't work is that when the TARGET_EXPR in the caller is constant initialized, this for it is the address of the TARGET_EXPR_SLOT, but if the code later on pretends the PARM_DECL is just initialized to the rvalue of the constant evaluation of the TARGET_EXPR, it is as if there is a bitwise copy of the TARGET_EXPR to the callee, so this in the callee is then address of the PARM_DECL in the callee. The following patch attempts to fix that by constexpr evaluation of such arguments in the caller as an lvalue instead of rvalue, and on the callee side when seeing such a PARM_DECL, if we want an lvalue, lookup the value (lvalue) saved in ctx->globals (if any), and if wanting an rvalue, recursing with vc_prvalue on the looked up value (because it is there as an lvalue, nor rvalue). adjust_temp_type doesn't work for lvalues of non-scalarish types, for such types it relies on changing the type of a CONSTRUCTOR, but on the other side we know what we pass to the argument is addressable, so the patch on type mismatch takes address of the argument value, casts to reference to the desired type and dereferences it. 2024-04-25 Jakub Jelinek PR c++/111284 * constexpr.cc (cxx_bind_parameters_in_call): For PARM_DECLs with TREE_ADDRESSABLE types use vc_glvalue rather than vc_prvalue for cxx_eval_constant_expression and if it doesn't have the same type as it should, cast the reference type to reference to type before convert_from_reference and instead of adjust_temp_type take address of the arg, cast to reference to type and then convert_from_reference. (cxx_eval_constant_expression) : For lval case on parameters with TREE_ADDRESSABLE types lookup result in ctx->globals if possible. Otherwise if lookup in ctx->globals was successful for parameter with TREE_ADDRESSABLE type, recurse with vc_prvalue on the returned value. * g++.dg/cpp1z/constexpr-111284.C: New test. (cherry picked from commit f541757ba4632e204169dd08a5f10c782199af42) Diff: --- gcc/cp/constexpr.cc | 44 +-- gcc/testsuite/g++.dg/cpp1z/constexpr-111284.C | 19 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 216b98122007..acb5496085bb 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1800,13 +1800,18 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun, x = build_address (x); } if (TREE_ADDRESSABLE (type)) - /* Undo convert_for_arg_passing work here. */ - x = convert_from_reference (x); - /* Normally we would strip a TARGET_EXPR in an initialization context -such as this, but here we do the elision differently: we keep the -TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ - arg = cxx_eval_constant_expression (ctx, x, vc_prvalue, - non_constant_p, overflow_p); + { + /* Undo convert_for_arg_passing work here. */ + x = convert_from_reference (x); + arg = cxx_eval_constant_expression (ctx, x, vc_glvalue, + non_constant_p, overflow_p); + } + else + /* Normally we would strip a TARGET_EXPR in an initialization context + such as this, but here we do the elision differently: we keep the + TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm. */ + arg = cxx_eval_constant_expression (ctx, x, vc_prvalue, + non_constant_p, overflow_p); /* Don't VERIFY_CONSTANT here. */ if (*non_constant_p && ctx->quiet) break; @@ -1818,7 +1823,16 @@ cxx_
[gcc r13-8732] gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876]
https://gcc.gnu.org/g:e07df053031e109c50387c92d689950de1d193ab commit r13-8732-ge07df053031e109c50387c92d689950de1d193ab Author: Jakub Jelinek Date: Tue Apr 30 11:22:32 2024 +0200 gimple-ssa-sprintf: Use [0, 1] range for %lc with (wint_t) 0 argument [PR114876] Seems when Martin S. implemented this, he coded there strict reading of the standard, which said that %lc with (wint_t) 0 argument is handled as wchar_t[2] temp = { arg, 0 }; %ls with temp arg and so shouldn't print any values. But, most of the libc implementations actually handled that case like %c with '\0' argument, adding a single NUL character, the only known exception is musl. Recently, C23 changed this in response to GB-141 and POSIX in https://austingroupbugs.net/view.php?id=1647 so that it should have the same behavior as %c with '\0'. Because there is implementation divergence, the following patch uses a range rather than hardcoding it to all 1s (i.e. the %c behavior), though the likely case is still 1 (forward looking plus most of implementations). The res.knownrange = true; assignment removed is redundant due to the same assignment done unconditionally before the if statement, rest is formatting fixes. I don't think the min >= 0 && min < 128 case is right either, I'd think it should be min >= 0 && max < 128, otherwise it is just some possible inputs are (maybe) ASCII and there can be others, but this code is a total mess anyway, with the min, max, likely (somewhere in [min, max]?) and then unlikely possibly larger than max, dunno, perhaps for at least some chars in the ASCII range the likely case could be for the ascii case; so perhaps just the one_2_one_ascii shouldn't set max to 1 and mayfail should be true for max >= 128. Anyway, didn't feel I should touch that right now. 2024-04-30 Jakub Jelinek PR tree-optimization/114876 * gimple-ssa-sprintf.cc (format_character): For min == 0 && max == 0, set max, likely and unlikely members to 1 rather than 0. Remove useless res.knownrange = true;. Formatting fixes. * gcc.dg/pr114876.c: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-1.c: Adjust expected diagnostics. (cherry picked from commit 6c6b70f07208ca14ba783933988c04c6fc2fff42) Diff: --- gcc/gimple-ssa-sprintf.cc | 20 +++-- gcc/testsuite/gcc.dg/pr114876.c| 34 ++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-1.c | 12 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc index 18975708d2c2..e02977f0ac39 100644 --- a/gcc/gimple-ssa-sprintf.cc +++ b/gcc/gimple-ssa-sprintf.cc @@ -2170,8 +2170,7 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) res.knownrange = true; - if (dir.specifier == 'C' - || dir.modifier == FMT_LEN_l) + if (dir.specifier == 'C' || dir.modifier == FMT_LEN_l) { /* A wide character can result in as few as zero bytes. */ res.range.min = 0; @@ -2182,10 +2181,13 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) { if (min == 0 && max == 0) { - /* The NUL wide character results in no bytes. */ - res.range.max = 0; - res.range.likely = 0; - res.range.unlikely = 0; + /* In strict reading of older ISO C or POSIX, this required +no characters to be emitted. ISO C23 changes that, so +does POSIX, to match what has been implemented in most of the +implementations, namely emitting a single NUL character. +Let's use 0 for minimum and 1 for all the other values. */ + res.range.max = 1; + res.range.likely = res.range.unlikely = 1; } else if (min >= 0 && min < 128) { @@ -2193,11 +2195,12 @@ format_character (const directive &dir, tree arg, pointer_query &ptr_qry) is not a 1-to-1 mapping to the source character set or if the source set is not ASCII. */ bool one_2_one_ascii - = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 97); + = (target_to_host_charmap[0] == 1 + && target_to_host ('a') == 97); /* A wide character in the ASCII range most likely results in a single byte, and only unlikely in up to MB_LEN_MAX. */ - res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();; + res.range.max = one_2_one_ascii ? 1 : target_mb_len_max (); res.range.likely = 1; res.range.unlikely = target_mb_len_max (); res.mayfail = !one_2_one_ascii; @@ -2228,7 +2231,6 @@
[gcc r13-8735] reassoc: Fix up optimize_range_tests_to_bit_test [PR114965]
https://gcc.gnu.org/g:44d84db11ab724c34a8b1f8c0e06da1cc78439a2 commit r13-8735-g44d84db11ab724c34a8b1f8c0e06da1cc78439a2 Author: Jakub Jelinek Date: Wed May 8 10:17:32 2024 +0200 reassoc: Fix up optimize_range_tests_to_bit_test [PR114965] The optimize_range_tests_to_bit_test optimization normally emits a range test first: if (entry_test_needed) { tem = build_range_check (loc, optype, unshare_expr (exp), false, lowi, high); if (tem == NULL_TREE || is_gimple_val (tem)) continue; } so during the bit test we already know that exp is in the [lowi, high] range, but skips it if we have range info which tells us this isn't necessary. Also, normally it emits shifts by exp - lowi counter, but has an optimization to use just exp counter if the mask isn't a more expensive constant in that case and lowi is > 0 and high is smaller than prec. The following testcase is miscompiled because the two abnormal cases are triggered. The range of exp is [43, 43][48, 48][95, 95], so we on 64-bit arch decide we don't need the entry test, because 95 - 43 < 64. And we also decide to use just exp as counter, because the range test tests just for exp == 43 || exp == 48, so high is smaller than 64 too. Because 95 is in the exp range, we can't do that, we'd either need to do a range test first, i.e. if (exp - 43U <= 48U - 43U) if ((1UL << exp) & mask1)) or need to subtract lowi from the shift counter, i.e. if ((1UL << (exp - 43)) & mask2) but can't do both unless r.upper_bound () is < prec. The following patch ensures that. 2024-05-08 Jakub Jelinek PR tree-optimization/114965 * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): Don't try to optimize away exp - lowi subtraction from shift count unless entry test is emitted or unless r.upper_bound () is smaller than prec. * gcc.c-torture/execute/pr114965.c: New test. (cherry picked from commit 9adec2d91e62a479474ae79df5b455fd4b8463ba) Diff: --- gcc/testsuite/gcc.c-torture/execute/pr114965.c | 30 ++ gcc/tree-ssa-reassoc.cc| 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr114965.c b/gcc/testsuite/gcc.c-torture/execute/pr114965.c new file mode 100644 index ..89d68e187015 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr114965.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/114965 */ + +static void +foo (const char *x) +{ + + char a = '0'; + while (1) +{ + switch (*x) + { + case '_': + case '+': + a = *x; + x++; + continue; + default: + break; + } + break; +} + if (a == '0' || a == '+') +__builtin_abort (); +} + +int +main () +{ + foo ("_"); +} diff --git a/gcc/tree-ssa-reassoc.cc b/gcc/tree-ssa-reassoc.cc index c5020465c2b3..d8f5471951af 100644 --- a/gcc/tree-ssa-reassoc.cc +++ b/gcc/tree-ssa-reassoc.cc @@ -3411,7 +3411,8 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length, We can avoid then subtraction of the minimum value, but the mask constant could be perhaps more expensive. */ if (compare_tree_int (lowi, 0) > 0 - && compare_tree_int (high, prec) < 0) + && compare_tree_int (high, prec) < 0 + && (entry_test_needed || wi::ltu_p (r.upper_bound (), prec))) { int cost_diff; HOST_WIDE_INT m = tree_to_uhwi (lowi);
[gcc r13-8733] tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956]
https://gcc.gnu.org/g:d1ec7bc9cb0639a212422710ba647dc1aaea6eaa commit r13-8733-gd1ec7bc9cb0639a212422710ba647dc1aaea6eaa Author: Jakub Jelinek Date: Tue May 7 21:29:14 2024 +0200 tree-inline: Remove .ASAN_MARK calls when inlining functions into no_sanitize callers [PR114956] In r9-5742 we've started allowing to inline always_inline functions into functions which have disabled e.g. address sanitization even when the always_inline function is implicitly from command line options sanitized. This mostly works fine because most of the asan instrumentation is done only late after ipa, but as the following testcase the .ASAN_MARK ifn calls gimplifier adds can result in ICEs. Fixed by dropping those during inlining, similarly to how we drop .TSAN_FUNC_EXIT calls. 2024-05-07 Jakub Jelinek PR sanitizer/114956 * tree-inline.cc: Include asan.h. (copy_bb): Remove also .ASAN_MARK calls if id->dst_fn has asan/hwasan sanitization disabled. * gcc.dg/asan/pr114956.c: New test. (cherry picked from commit d4e25cf4f7c1f51a8824cc62bbb85a81a41b829a) Diff: --- gcc/testsuite/gcc.dg/asan/pr114956.c | 26 ++ gcc/tree-inline.cc | 28 +--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/gcc.dg/asan/pr114956.c b/gcc/testsuite/gcc.dg/asan/pr114956.c new file mode 100644 index ..fb87d514f255 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr114956.c @@ -0,0 +1,26 @@ +/* PR sanitizer/114956 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsanitize=address,null" } */ + +int **a; +void qux (int *); + +__attribute__((always_inline)) static inline int * +foo (void) +{ + int b[1]; + qux (b); + return a[1]; +} + +__attribute__((no_sanitize_address)) void +bar (void) +{ + *a = foo (); +} + +void +baz (void) +{ + bar (); +} diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 72a80c0c74da..73d5a9fadef3 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include "symbol-summary.h" #include "symtab-thunks.h" #include "symtab-clones.h" +#include "asan.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -2198,13 +2199,26 @@ copy_bb (copy_body_data *id, basic_block bb, } else if (call_stmt && id->call_stmt - && gimple_call_internal_p (stmt) - && gimple_call_internal_fn (stmt) == IFN_TSAN_FUNC_EXIT) - { - /* Drop TSAN_FUNC_EXIT () internal calls during inlining. */ - gsi_remove (©_gsi, false); - continue; - } + && gimple_call_internal_p (stmt)) + switch (gimple_call_internal_fn (stmt)) + { + case IFN_TSAN_FUNC_EXIT: + /* Drop .TSAN_FUNC_EXIT () internal calls during inlining. */ + gsi_remove (©_gsi, false); + continue; + case IFN_ASAN_MARK: + /* Drop .ASAN_MARK internal calls during inlining into + no_sanitize functions. */ + if (!sanitize_flags_p (SANITIZE_ADDRESS, id->dst_fn) + && !sanitize_flags_p (SANITIZE_HWADDRESS, id->dst_fn)) + { + gsi_remove (©_gsi, false); + continue; + } + break; + default: + break; + } /* Statements produced by inlining can be unfolded, especially when we constant propagated some operands. We can't fold
[gcc r13-8734] expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907]
https://gcc.gnu.org/g:cad27df08915ead8db3c7d512cfcc1866e7ece69 commit r13-8734-gcad27df08915ead8db3c7d512cfcc1866e7ece69 Author: Jakub Jelinek Date: Tue May 7 21:30:21 2024 +0200 expansion: Use __trunchfbf2 calls rather than __extendhfbf2 [PR114907] The HF and BF modes have the same size/precision and neither is a subset nor superset of the other. So, using either __extendhfbf2 or __trunchfbf2 is weird. The expansion apparently emits __extendhfbf2, but on the libgcc side we apparently have __trunchfbf2 implemented. I think it is easier to switch to using what is available rather than adding new entrypoints to libgcc, even alias, because this is backportable. 2024-05-07 Jakub Jelinek PR middle-end/114907 * expr.cc (convert_mode_scalar): Use trunc_optab rather than sext_optab for HF->BF conversions. * optabs-libfuncs.cc (gen_trunc_conv_libfunc): Likewise. * gcc.dg/pr114907.c: New test. (cherry picked from commit 28ee13db2e9d995bd3728c4ff3a3545e24b39cd2) Diff: --- gcc/expr.cc | 12 ++-- gcc/optabs-libfuncs.cc | 4 +++- gcc/testsuite/gcc.dg/pr114907.c | 27 +++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index 5dac06fa94b5..705d5b34eed6 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -351,8 +351,16 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp) && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) - /* Conversion between decimal float and binary float, same size. */ - tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + { + if (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format + && REAL_MODE_FORMAT (from_mode) == &ieee_half_format) + /* libgcc implements just __trunchfbf2, not __extendhfbf2. */ + tab = trunc_optab; + else + /* Conversion between decimal float and binary float, same + size. */ + tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab; + } else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)) tab = sext_optab; else diff --git a/gcc/optabs-libfuncs.cc b/gcc/optabs-libfuncs.cc index f1abe6916d34..4eb98be794b7 100644 --- a/gcc/optabs-libfuncs.cc +++ b/gcc/optabs-libfuncs.cc @@ -589,7 +589,9 @@ gen_trunc_conv_libfunc (convert_optab tab, if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode)) gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode); - if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)) + if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode) + && (REAL_MODE_FORMAT (float_tmode) != &arm_bfloat_half_format + || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format)) return; if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode)) diff --git a/gcc/testsuite/gcc.dg/pr114907.c b/gcc/testsuite/gcc.dg/pr114907.c new file mode 100644 index ..628746e1f8c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114907.c @@ -0,0 +1,27 @@ +/* PR middle-end/114907 */ +/* { dg-do run } */ +/* { dg-options "" } */ +/* { dg-add-options float16 } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-add-options bfloat16 } */ +/* { dg-require-effective-target bfloat16_runtime } */ + +__attribute__((noipa)) _Float16 +foo (__bf16 x) +{ + return (_Float16) x; +} + +__attribute__((noipa)) __bf16 +bar (_Float16 x) +{ + return (__bf16) x; +} + +int +main () +{ + if (foo (11.125bf16) != 11.125f16 + || bar (11.125f16) != 11.125bf16) +__builtin_abort (); +}
[gcc r15-340] testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224]
https://gcc.gnu.org/g:8fb65ec816ff8f0d529b6d30821abace4328c9a2 commit r15-340-g8fb65ec816ff8f0d529b6d30821abace4328c9a2 Author: Jakub Jelinek Date: Thu May 9 11:18:21 2024 +0200 testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224] The test FAILs on i686-linux due to .../gcc/testsuite/g++.dg/torture/vector-subaccess-1.C:16:6: warning: SSE vector argument without SSE enabled changes the ABI [-Wpsabi] excess warnings. This fixes it by adding -Wno-psabi, like commonly done in other tests. 2024-05-09 Jakub Jelinek PR c++/89224 * g++.dg/torture/vector-subaccess-1.C: Add -Wno-psabi as additional options. Diff: --- gcc/testsuite/g++.dg/torture/vector-subaccess-1.C | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C index 0c8958a4e034..4b909dae4926 100644 --- a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C +++ b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C @@ -1,4 +1,5 @@ /* PR c++/89224 */ +/* { dg-additional-options "-Wno-psabi" } */ /* The access of `vector[i]` has the same qualifiers as the original vector which was missing. */
[gcc r14-10189] testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224]
https://gcc.gnu.org/g:726e7a64edc22a33a5f495698722ba797793edca commit r14-10189-g726e7a64edc22a33a5f495698722ba797793edca Author: Jakub Jelinek Date: Thu May 9 11:18:21 2024 +0200 testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224] The test FAILs on i686-linux due to .../gcc/testsuite/g++.dg/torture/vector-subaccess-1.C:16:6: warning: SSE vector argument without SSE enabled changes the ABI [-Wpsabi] excess warnings. This fixes it by adding -Wno-psabi, like commonly done in other tests. 2024-05-09 Jakub Jelinek PR c++/89224 * g++.dg/torture/vector-subaccess-1.C: Add -Wno-psabi as additional options. (cherry picked from commit 8fb65ec816ff8f0d529b6d30821abace4328c9a2) Diff: --- gcc/testsuite/g++.dg/torture/vector-subaccess-1.C | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C index 0c8958a4e034..4b909dae4926 100644 --- a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C +++ b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C @@ -1,4 +1,5 @@ /* PR c++/89224 */ +/* { dg-additional-options "-Wno-psabi" } */ /* The access of `vector[i]` has the same qualifiers as the original vector which was missing. */
[gcc r13-8737] testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224]
https://gcc.gnu.org/g:6f7674a558aaa0c7b16657c35666ad9b12e1c219 commit r13-8737-g6f7674a558aaa0c7b16657c35666ad9b12e1c219 Author: Jakub Jelinek Date: Thu May 9 11:18:21 2024 +0200 testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224] The test FAILs on i686-linux due to .../gcc/testsuite/g++.dg/torture/vector-subaccess-1.C:16:6: warning: SSE vector argument without SSE enabled changes the ABI [-Wpsabi] excess warnings. This fixes it by adding -Wno-psabi, like commonly done in other tests. 2024-05-09 Jakub Jelinek PR c++/89224 * g++.dg/torture/vector-subaccess-1.C: Add -Wno-psabi as additional options. (cherry picked from commit 8fb65ec816ff8f0d529b6d30821abace4328c9a2) Diff: --- gcc/testsuite/g++.dg/torture/vector-subaccess-1.C | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C index 0c8958a4e034..4b909dae4926 100644 --- a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C +++ b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C @@ -1,4 +1,5 @@ /* PR c++/89224 */ +/* { dg-additional-options "-Wno-psabi" } */ /* The access of `vector[i]` has the same qualifiers as the original vector which was missing. */
[gcc r12-10435] testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224]
https://gcc.gnu.org/g:ffa41c65a375746fd26c2d620e634fb162726dfc commit r12-10435-gffa41c65a375746fd26c2d620e634fb162726dfc Author: Jakub Jelinek Date: Thu May 9 11:18:21 2024 +0200 testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224] The test FAILs on i686-linux due to .../gcc/testsuite/g++.dg/torture/vector-subaccess-1.C:16:6: warning: SSE vector argument without SSE enabled changes the ABI [-Wpsabi] excess warnings. This fixes it by adding -Wno-psabi, like commonly done in other tests. 2024-05-09 Jakub Jelinek PR c++/89224 * g++.dg/torture/vector-subaccess-1.C: Add -Wno-psabi as additional options. (cherry picked from commit 8fb65ec816ff8f0d529b6d30821abace4328c9a2) Diff: --- gcc/testsuite/g++.dg/torture/vector-subaccess-1.C | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C index 0c8958a4e034..4b909dae4926 100644 --- a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C +++ b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C @@ -1,4 +1,5 @@ /* PR c++/89224 */ +/* { dg-additional-options "-Wno-psabi" } */ /* The access of `vector[i]` has the same qualifiers as the original vector which was missing. */
[gcc r11-11423] testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224]
https://gcc.gnu.org/g:e6c869372f0ca8b28ac63c7eb26fde35b53aba37 commit r11-11423-ge6c869372f0ca8b28ac63c7eb26fde35b53aba37 Author: Jakub Jelinek Date: Thu May 9 11:18:21 2024 +0200 testsuite: Fix up vector-subaccess-1.C test for ia32 [PR89224] The test FAILs on i686-linux due to .../gcc/testsuite/g++.dg/torture/vector-subaccess-1.C:16:6: warning: SSE vector argument without SSE enabled changes the ABI [-Wpsabi] excess warnings. This fixes it by adding -Wno-psabi, like commonly done in other tests. 2024-05-09 Jakub Jelinek PR c++/89224 * g++.dg/torture/vector-subaccess-1.C: Add -Wno-psabi as additional options. (cherry picked from commit 8fb65ec816ff8f0d529b6d30821abace4328c9a2) Diff: --- gcc/testsuite/g++.dg/torture/vector-subaccess-1.C | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C index 0c8958a4e034..4b909dae4926 100644 --- a/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C +++ b/gcc/testsuite/g++.dg/torture/vector-subaccess-1.C @@ -1,4 +1,5 @@ /* PR c++/89224 */ +/* { dg-additional-options "-Wno-psabi" } */ /* The access of `vector[i]` has the same qualifiers as the original vector which was missing. */
[gcc r15-341] contrib: Add 9dbff9c05520a74e6cd337578f27b56c941f64f3 to ignored commits
https://gcc.gnu.org/g:de0b40ac5be8977a6bee8860f67d45011642f1a2 commit r15-341-gde0b40ac5be8977a6bee8860f67d45011642f1a2 Author: Jakub Jelinek Date: Thu May 9 12:15:51 2024 +0200 contrib: Add 9dbff9c05520a74e6cd337578f27b56c941f64f3 to ignored commits 2024-05-09 Jakub Jelinek * gcc-changelog/git_update_version.py: Add 9dbff9c05520a74e6cd337578f27b56c941f64f3 to IGNORED_COMMITS. Diff: --- contrib/gcc-changelog/git_update_version.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/gcc-changelog/git_update_version.py b/contrib/gcc-changelog/git_update_version.py index f194757b0cb7..3d9a28ccbdf3 100755 --- a/contrib/gcc-changelog/git_update_version.py +++ b/contrib/gcc-changelog/git_update_version.py @@ -39,7 +39,8 @@ IGNORED_COMMITS = ( 'e4cba49413ca429dc82f6aa2e88129ecb3fdd943', '1957bedf29a1b2cc231972aba680fe80199d5498', '040e5b0edbca861196d9e2ea2af5e805769c8d5d', -'8057f9aa1f7e70490064de796d7a8d42d446caf8') +'8057f9aa1f7e70490064de796d7a8d42d446caf8', +'9dbff9c05520a74e6cd337578f27b56c941f64f3') FORMAT = '%(asctime)s:%(levelname)s:%(name)s:%(message)s' logging.basicConfig(level=logging.INFO, format=FORMAT,
[gcc r15-344] contrib: Add 109f1b28fc94c93096506e3df0c25e331cef19d0 to ignored commits
https://gcc.gnu.org/g:5fe40f2c651af84b1a4ff6527ef4307591228a1b commit r15-344-g5fe40f2c651af84b1a4ff6527ef4307591228a1b Author: Jakub Jelinek Date: Thu May 9 13:01:31 2024 +0200 contrib: Add 109f1b28fc94c93096506e3df0c25e331cef19d0 to ignored commits 2024-05-09 Jakub Jelinek * gcc-changelog/git_update_version.py: Replace 9dbff9c05520a74e6cd337578f27b56c941f64f3 with 39f81924d88e3cc197fc3df74204c9b5e01e12f7 and 109f1b28fc94c93096506e3df0c25e331cef19d0 in IGNORED_COMMITS. Diff: --- contrib/gcc-changelog/git_update_version.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/gcc-changelog/git_update_version.py b/contrib/gcc-changelog/git_update_version.py index 3d9a28ccbdf3..24f6c43d0b25 100755 --- a/contrib/gcc-changelog/git_update_version.py +++ b/contrib/gcc-changelog/git_update_version.py @@ -40,7 +40,8 @@ IGNORED_COMMITS = ( '1957bedf29a1b2cc231972aba680fe80199d5498', '040e5b0edbca861196d9e2ea2af5e805769c8d5d', '8057f9aa1f7e70490064de796d7a8d42d446caf8', -'9dbff9c05520a74e6cd337578f27b56c941f64f3') +'109f1b28fc94c93096506e3df0c25e331cef19d0', +'39f81924d88e3cc197fc3df74204c9b5e01e12f7') FORMAT = '%(asctime)s:%(levelname)s:%(name)s:%(message)s' logging.basicConfig(level=logging.INFO, format=FORMAT,
[gcc r15-345] Manually update entries for the Revert Revert commits.
https://gcc.gnu.org/g:2790195500ec523cad9c7292816540e2fc19f456 commit r15-345-g2790195500ec523cad9c7292816540e2fc19f456 Author: Jakub Jelinek Date: Thu May 9 13:09:06 2024 +0200 Manually update entries for the Revert Revert commits. Diff: --- gcc/ChangeLog | 12 gcc/testsuite/ChangeLog | 11 +++ 2 files changed, 23 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12a7d754b232..fff1592f837f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -477,6 +477,18 @@ (Specific, *-*-solaris2*): Document Solaris 11.3 removal. Remove 11.3 references and caveats. Update for 11.4. +2024-05-07 Richard Biener + + Revert: + 2024-04-10 Richard Biener + + Revert: + 2024-03-27 Segher Boessenkool + + PR rtl-optimization/101523 + * combine.cc (try_combine): Don't do a 2-insn combination if + it does not in fact change I2. + 2024-05-07 Andrew Pinski PR middle-end/97263 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fa115f8fd425..9f87260fa17d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -94,6 +94,17 @@ * gcc.target/i386/cmov6.c: Fixed. +2024-05-08 Hans-Peter Nilsson + + Revert: + 2024-04-10 Hans-Peter Nilsson + + Revert: + 2024-04-05 Hans-Peter Nilsson + + * gcc.target/cris/pr93372-2.c: Tweak scan-assembler + checks to cover recent combine improvement. + 2024-05-07 Nathaniel Shead PR c++/114856
[gcc r15-350] testsuite: Fix up pr84508* tests [PR84508]
https://gcc.gnu.org/g:e02b5683e77c2b4317b23be72e43b6e6cc6c8e5b commit r15-350-ge02b5683e77c2b4317b23be72e43b6e6cc6c8e5b Author: Jakub Jelinek Date: Thu May 9 20:59:05 2024 +0200 testsuite: Fix up pr84508* tests [PR84508] The tests FAIL on x86_64-linux with /usr/bin/ld: cannot find -lubsan collect2: error: ld returned 1 exit status compiler exited with status 1 FAIL: gcc.target/i386/pr84508-1.c (test for excess errors) Excess errors: /usr/bin/ld: cannot find -lubsan The problem is that only *.dg/ubsan/ubsan.exp calls ubsan_init which adds the needed search paths to libubsan library. So, link/run tests for -fsanitize=undefined need to go into gcc.dg/ubsan/ or g++.dg/ubsan/, even when they are target specific. 2024-05-09 Jakub Jelinek PR target/84508 * gcc.target/i386/pr84508-1.c: Move to ... * gcc.dg/ubsan/pr84508-1.c: ... here. Restrict to i?86/x86_64 non-ia32 targets. * gcc.target/i386/pr84508-2.c: Move to ... * gcc.dg/ubsan/pr84508-2.c: ... here. Restrict to i?86/x86_64 non-ia32 targets. Diff: --- gcc/testsuite/{gcc.target/i386 => gcc.dg/ubsan}/pr84508-1.c | 3 ++- gcc/testsuite/{gcc.target/i386 => gcc.dg/ubsan}/pr84508-2.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.target/i386/pr84508-1.c b/gcc/testsuite/gcc.dg/ubsan/pr84508-1.c similarity index 74% rename from gcc/testsuite/gcc.target/i386/pr84508-1.c rename to gcc/testsuite/gcc.dg/ubsan/pr84508-1.c index bb3e28d017e9..d781e01c 100644 --- a/gcc/testsuite/gcc.target/i386/pr84508-1.c +++ b/gcc/testsuite/gcc.dg/ubsan/pr84508-1.c @@ -1,5 +1,6 @@ -/* { dg-do run { target { ! ia32 } } } */ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */ /* { dg-options "-fsanitize=undefined" } */ + #include int main() diff --git a/gcc/testsuite/gcc.target/i386/pr84508-2.c b/gcc/testsuite/gcc.dg/ubsan/pr84508-2.c similarity index 73% rename from gcc/testsuite/gcc.target/i386/pr84508-2.c rename to gcc/testsuite/gcc.dg/ubsan/pr84508-2.c index 32a8f20a5364..cf9c7db1d159 100644 --- a/gcc/testsuite/gcc.target/i386/pr84508-2.c +++ b/gcc/testsuite/gcc.dg/ubsan/pr84508-2.c @@ -1,5 +1,6 @@ -/* { dg-do run { target { ! ia32 } } } */ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */ /* { dg-options "-fsanitize=undefined" } */ + #include int main()
[gcc r15-358] c++, mingw: Fix up types of dtor hooks to __cxa_{, thread_}atexit/__cxa_throw on mingw ia32 [PR114968
https://gcc.gnu.org/g:e5d8fd9ce05611093191d500ebc39f150d0ece2b commit r15-358-ge5d8fd9ce05611093191d500ebc39f150d0ece2b Author: Jakub Jelinek Date: Fri May 10 09:21:38 2024 +0200 c++, mingw: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw on mingw ia32 [PR114968] __cxa_atexit/__cxa_thread_atexit/__cxa_throw functions accept function pointers to usually directly destructors rather than wrappers around them. Now, mingw ia32 uses implicitly __attribute__((thiscall)) calling conventions for METHOD_TYPE (where the this pointer is passed in %ecx register, the rest on the stack), so these functions use: in config/os/mingw32/os_defines.h: #if defined (__i386__) #define _GLIBCXX_CDTOR_CALLABI __thiscall #endif in libsupc++/cxxabi.h __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW; __cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void *) _GLIBCXX_NOTHROW; __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) __attribute__((__noreturn__)); Now, mingw for some weird reason uses #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true so it never actually uses __cxa_atexit, but does use __cxa_thread_atexit and __cxa_throw. Recent changes for modules result in more detailed __cxa_*atexit/__cxa_throw prototypes precreated by the compiler, and if that happens and one also includes , the compiler complains about mismatches in the prototypes. One thing is the missing thiscall attribute on the FUNCTION_TYPE, the other problem is that all of atexit/__cxa_atexit/__cxa_thread_atexit get function pointer types created by a single function, get_atexit_fn_ptr_type (), which creates it depending on if atexit or __cxa_atexit will be used as either void(*)(void) or void(*)(void *), but when using atexit and __cxa_thread_atexit it uses the wrong function type for __cxa_thread_atexit. The following patch adds a target hook to add the thiscall attribute to the function pointers, and splits the get_atexit_fn_ptr_type () function into get_atexit_fn_ptr_type () and get_cxa_atexit_fn_ptr_type (), the former always creates shared void(*)(void) type, the latter creates either void(*)(void*) (on most targets) or void(__attribute__((thiscall))*)(void*) (on mingw ia32). So that we don't waiste another GTY global tree for it, because cleanup_type used for the same purpose for __cxa_throw should be the same, the code changes it to use that type too. In register_dtor_fn then based on the decision whether to use atexit, __cxa_atexit or __cxa_thread_atexit it picks the right function pointer type, and also if it decides to emit a __tcf_* wrapper for the cleanup, uses that type for that wrapper so that it agrees on calling convention. 2024-05-10 Jakub Jelinek PR target/114968 gcc/ * target.def (use_atexit_for_cxa_atexit): Remove spurious space from comment. (adjust_cdtor_callabi_fntype): New cxx target hook. * targhooks.h (default_cxx_adjust_cdtor_callabi_fntype): Declare. * targhooks.cc (default_cxx_adjust_cdtor_callabi_fntype): New function. * doc/tm.texi.in (TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Add. * doc/tm.texi: Regenerate. * config/i386/i386.cc (ix86_cxx_adjust_cdtor_callabi_fntype): New function. (TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Redefine. gcc/cp/ * cp-tree.h (atexit_fn_ptr_type_node, cleanup_type): Adjust macro comments. (get_cxa_atexit_fn_ptr_type): Declare. * decl.cc (get_atexit_fn_ptr_type): Adjust function comment, only build type for atexit argument. (get_cxa_atexit_fn_ptr_type): New function. (get_atexit_node): Call get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type when using __cxa_atexit. (get_thread_atexit_node): Call get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type. (start_cleanup_fn): Add ob_parm argument, call get_cxa_atexit_fn_ptr_type or get_atexit_fn_ptr_type depending on it and create PARM_DECL also based on that argument. (register_dtor_fn): Adjust start_cleanup_fn caller, use get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type for use_dtor casts. * except.cc (build_throw): Use get_cxa_atexit_fn_ptr_type (). Diff: --- gcc/config/i386/i386.cc | 16 ++ gcc/cp/cp-tree.h| 7 +++--- gcc/cp/decl.cc | 59 +++-- gcc/cp/except.cc| 6 + gcc/doc/tm.texi | 8 +++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 1
[gcc r14-10193] c++, mingw: Fix up types of dtor hooks to __cxa_{, thread_}atexit/__cxa_throw on mingw ia32 [PR114968
https://gcc.gnu.org/g:a805de33f7be4f6886906ca5f4da493f3b743c76 commit r14-10193-ga805de33f7be4f6886906ca5f4da493f3b743c76 Author: Jakub Jelinek Date: Fri May 10 09:21:38 2024 +0200 c++, mingw: Fix up types of dtor hooks to __cxa_{,thread_}atexit/__cxa_throw on mingw ia32 [PR114968] __cxa_atexit/__cxa_thread_atexit/__cxa_throw functions accept function pointers to usually directly destructors rather than wrappers around them. Now, mingw ia32 uses implicitly __attribute__((thiscall)) calling conventions for METHOD_TYPE (where the this pointer is passed in %ecx register, the rest on the stack), so these functions use: in config/os/mingw32/os_defines.h: #if defined (__i386__) #define _GLIBCXX_CDTOR_CALLABI __thiscall #endif in libsupc++/cxxabi.h __cxa_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void*) _GLIBCXX_NOTHROW; __cxa_thread_atexit(void (_GLIBCXX_CDTOR_CALLABI *)(void*), void*, void *) _GLIBCXX_NOTHROW; __cxa_throw(void*, std::type_info*, void (_GLIBCXX_CDTOR_CALLABI *) (void *)) __attribute__((__noreturn__)); Now, mingw for some weird reason uses #define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true so it never actually uses __cxa_atexit, but does use __cxa_thread_atexit and __cxa_throw. Recent changes for modules result in more detailed __cxa_*atexit/__cxa_throw prototypes precreated by the compiler, and if that happens and one also includes , the compiler complains about mismatches in the prototypes. One thing is the missing thiscall attribute on the FUNCTION_TYPE, the other problem is that all of atexit/__cxa_atexit/__cxa_thread_atexit get function pointer types created by a single function, get_atexit_fn_ptr_type (), which creates it depending on if atexit or __cxa_atexit will be used as either void(*)(void) or void(*)(void *), but when using atexit and __cxa_thread_atexit it uses the wrong function type for __cxa_thread_atexit. The following patch adds a target hook to add the thiscall attribute to the function pointers, and splits the get_atexit_fn_ptr_type () function into get_atexit_fn_ptr_type () and get_cxa_atexit_fn_ptr_type (), the former always creates shared void(*)(void) type, the latter creates either void(*)(void*) (on most targets) or void(__attribute__((thiscall))*)(void*) (on mingw ia32). So that we don't waiste another GTY global tree for it, because cleanup_type used for the same purpose for __cxa_throw should be the same, the code changes it to use that type too. In register_dtor_fn then based on the decision whether to use atexit, __cxa_atexit or __cxa_thread_atexit it picks the right function pointer type, and also if it decides to emit a __tcf_* wrapper for the cleanup, uses that type for that wrapper so that it agrees on calling convention. 2024-05-10 Jakub Jelinek PR target/114968 gcc/ * target.def (use_atexit_for_cxa_atexit): Remove spurious space from comment. (adjust_cdtor_callabi_fntype): New cxx target hook. * targhooks.h (default_cxx_adjust_cdtor_callabi_fntype): Declare. * targhooks.cc (default_cxx_adjust_cdtor_callabi_fntype): New function. * doc/tm.texi.in (TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Add. * doc/tm.texi: Regenerate. * config/i386/i386.cc (ix86_cxx_adjust_cdtor_callabi_fntype): New function. (TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE): Redefine. gcc/cp/ * cp-tree.h (atexit_fn_ptr_type_node, cleanup_type): Adjust macro comments. (get_cxa_atexit_fn_ptr_type): Declare. * decl.cc (get_atexit_fn_ptr_type): Adjust function comment, only build type for atexit argument. (get_cxa_atexit_fn_ptr_type): New function. (get_atexit_node): Call get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type when using __cxa_atexit. (get_thread_atexit_node): Call get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type. (start_cleanup_fn): Add ob_parm argument, call get_cxa_atexit_fn_ptr_type or get_atexit_fn_ptr_type depending on it and create PARM_DECL also based on that argument. (register_dtor_fn): Adjust start_cleanup_fn caller, use get_cxa_atexit_fn_ptr_type rather than get_atexit_fn_ptr_type for use_dtor casts. * except.cc (build_throw): Use get_cxa_atexit_fn_ptr_type (). (cherry picked from commit e5d8fd9ce05611093191d500ebc39f150d0ece2b) Diff: --- gcc/config/i386/i386.cc | 16 ++ gcc/cp/cp-tree.h| 7 +++--- gcc/cp/decl.cc | 59 +++-- gcc/cp/except.cc| 6 + gcc/doc/tm.texi
[gcc r15-426] Manually add ChangeLog entry for r15-353-gd7bb8eaade3cd3aa70715c8567b4d7b08098e699
https://gcc.gnu.org/g:f3f02a750c7b34b751fa809ab03d29b2ccf0785d commit r15-426-gf3f02a750c7b34b751fa809ab03d29b2ccf0785d Author: Jakub Jelinek Date: Mon May 13 11:07:59 2024 +0200 Manually add ChangeLog entry for r15-353-gd7bb8eaade3cd3aa70715c8567b4d7b08098e699 Diff: --- gcc/ChangeLog | 26 ++ 1 file changed, 26 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68c11340a9c6..5d57c861fb62 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -247,6 +247,32 @@ * config/riscv/bitmanip.md: Add splitter for shadd feeding another add instruction. +2024-05-10 Aldy Hernandez + + Revert: + 2024-05-08 Aldy Hernandez + + * gimple-range-cache.cc (sbr_sparse_bitmap::sbr_sparse_bitmap): + Change irange to prange. + * gimple-range-fold.cc (fold_using_range::fold_stmt): Same. + (fold_using_range::range_of_address): Same. + * gimple-range-fold.h (range_of_address): Same. + * gimple-range-infer.cc (gimple_infer_range::add_nonzero): Same. + * gimple-range-op.cc (class cfn_strlen): Same. + * gimple-range-path.cc + (path_range_query::adjust_for_non_null_uses): Same. + * gimple-ssa-warn-access.cc (pass_waccess::check_pointer_uses): Same. + * tree-ssa-structalias.cc (find_what_p_points_to): Same. + * range-op-ptr.cc (range_op_table::initialize_pointer_ops): Remove + hybrid entries in table. + * range-op.cc (range_op_table::range_op_table): Add pointer + entries for bitwise and/or and min/max. + * value-range.cc (irange::verify_range): Add assert. + * value-range.h (irange::varying_compatible_p): Remove check for + error_mark_node. + (irange::supports_p): Remove pointer support. + * ipa-cp.h (ipa_supports_p): Add prange support. + 2024-05-09 Roger Sayle * simplify-rtx.cc (simplify_const_binary_operation): Constant
[gcc r15-427] tree-ssa-math-opts: Pattern recognize yet another .ADD_OVERFLOW pattern [PR113982]
https://gcc.gnu.org/g:b621482296f6dec0abb22ed39cc4ce6811535d47 commit r15-427-gb621482296f6dec0abb22ed39cc4ce6811535d47 Author: Jakub Jelinek Date: Mon May 13 11:15:27 2024 +0200 tree-ssa-math-opts: Pattern recognize yet another .ADD_OVERFLOW pattern [PR113982] We pattern recognize already many different patterns, and closest to the requested one also yc = (type) y; zc = (type) z; x = yc + zc; w = (typeof_y) x; if (x > max) where y/z has the same unsigned type and type is a wider unsigned type and max is maximum value of the narrower unsigned type. But apparently people are creative in writing this in diffent ways, this requests yc = (type) y; zc = (type) z; x = yc + zc; w = (typeof_y) x; if (x >> narrower_type_bits) The following patch implements that. 2024-05-13 Jakub Jelinek PR middle-end/113982 * tree-ssa-math-opts.cc (arith_overflow_check_p): Also return 1 for RSHIFT_EXPR by precision of maxval if shift result is only used in a cast or comparison against zero. (match_arith_overflow): Handle the RSHIFT_EXPR use case. * gcc.dg/pr113982.c: New test. Diff: --- gcc/testsuite/gcc.dg/pr113982.c | 60 gcc/tree-ssa-math-opts.cc | 121 ++-- 2 files changed, 177 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr113982.c b/gcc/testsuite/gcc.dg/pr113982.c new file mode 100644 index ..4c5be6cc832e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr113982.c @@ -0,0 +1,60 @@ +/* PR middle-end/113982 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-widening_mul" } */ + +#if __SIZEOF_INT128__ +typedef __uint128_t W; +typedef unsigned long long T; +#else +typedef unsigned long long W; +typedef unsigned int T; +#endif +#define B __CHAR_BIT__ * sizeof (T) + +struct S { int p; T r; }; + +struct S +foo (T x, T y) +{ + W z = (W) x + y; + return (struct S) { z >> B, (T) z }; +} + +struct S +bar (T x) +{ + W z = (W) x + 132; + return (struct S) { z >> B, (T) z }; +} + +struct S +baz (T x, unsigned short y) +{ + W z = (W) x + y; + return (struct S) { z >> B, (T) z }; +} + +struct S +qux (unsigned short x, T y) +{ + W z = (W) x + y; + return (struct S) { z >> B, (T) z }; +} + +struct S +corge (T x, T y) +{ + T w = x + y; + W z = (W) x + y; + return (struct S) { z >> B, w }; +} + +struct S +garple (T x, T y) +{ + W z = (W) x + y; + T w = x + y; + return (struct S) { z >> B, w }; +} + +/* { dg-final { scan-tree-dump-times "ADD_OVERFLOW" 6 "widening_mul" { target { i?86-*-* x86_64-*-* } } } } */ diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 705f4a4695ac..e8c804f09b7f 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -3947,6 +3947,66 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt, else return 0; + if (maxval + && ccode == RSHIFT_EXPR + && crhs1 == lhs + && TREE_CODE (crhs2) == INTEGER_CST + && wi::to_widest (crhs2) == TYPE_PRECISION (TREE_TYPE (maxval))) +{ + tree shiftlhs = gimple_assign_lhs (use_stmt); + if (!shiftlhs) + return 0; + use_operand_p use; + if (!single_imm_use (shiftlhs, &use, &cur_use_stmt)) + return 0; + if (gimple_code (cur_use_stmt) == GIMPLE_COND) + { + ccode = gimple_cond_code (cur_use_stmt); + crhs1 = gimple_cond_lhs (cur_use_stmt); + crhs2 = gimple_cond_rhs (cur_use_stmt); + } + else if (is_gimple_assign (cur_use_stmt)) + { + if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS) + { + ccode = gimple_assign_rhs_code (cur_use_stmt); + crhs1 = gimple_assign_rhs1 (cur_use_stmt); + crhs2 = gimple_assign_rhs2 (cur_use_stmt); + } + else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR) + { + tree cond = gimple_assign_rhs1 (cur_use_stmt); + if (COMPARISON_CLASS_P (cond)) + { + ccode = TREE_CODE (cond); + crhs1 = TREE_OPERAND (cond, 0); + crhs2 = TREE_OPERAND (cond, 1); + } + else + return 0; + } + else + { + enum tree_code sc = gimple_assign_rhs_code (cur_use_stmt); + tree castlhs = gimple_assign_lhs (cur_use_stmt); + if (!CONVERT_EXPR_CODE_P (sc) + || !castlhs + || !INTEGRAL_TYPE_P (TREE_TYPE (castlhs)) + || (TYPE_PRECISION (TREE_TYPE (castlhs)) + > TYPE_PRECISION (TREE_TYPE (maxval + return 0; + return 1; + } + } + else + return 0; + if ((ccode != EQ_EXPR && ccode != NE_EXPR) +
[gcc r13-8764] Manually add ChangeLog entries for various commits from 2024-05-09.
https://gcc.gnu.org/g:2e353c687dbd343ce592c5ec089774b2c699798a commit r13-8764-g2e353c687dbd343ce592c5ec089774b2c699798a Author: Jakub Jelinek Date: Mon May 13 15:09:04 2024 +0200 Manually add ChangeLog entries for various commits from 2024-05-09. Diff: --- gcc/analyzer/ChangeLog | 84 + gcc/jit/ChangeLog | 8 + gcc/testsuite/ChangeLog | 79 ++ 3 files changed, 171 insertions(+) diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index 5f1171c0da89..d3a520c19848 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -7,6 +7,19 @@ (register_sanitizer_builtins): New. (register_known_functions): Call register_sanitizer_builtins. +2024-05-09 David Malcolm + + Backported from master: + 2024-03-27 David Malcolm + + PR analyzer/114473 + * call-summary.cc + (call_summary_replay::convert_svalue_from_summary): Assert that + the types match. + (call_summary_replay::convert_region_from_summary): Likewise. + (call_summary_replay::convert_region_from_summary_1): Add missing + cast for the deref of RK_SYMBOLIC case. + 2024-05-09 David Malcolm PR analyzer/109251 @@ -23,6 +36,19 @@ (kf_va_arg::impl_call_pre): Pass arg_sval to va_arg_compatible_types_p. +2024-05-09 David Malcolm + + Backported from master: + 2024-01-31 David Malcolm + PR analyzer/113253 + * region-model.cc (region_model::on_stmt_pre): Add gcc_unreachable + for debug statements. + * state-purge.cc + (state_purge_per_ssa_name::state_purge_per_ssa_name): Skip any + debug stmts in the FOR_EACH_IMM_USE_FAST list. + * supergraph.cc (supergraph::supergraph): Don't add debug stmts + to the supernodes. + 2024-05-09 David Malcolm PR analyzer/112969 @@ -58,6 +84,64 @@ (concrete_binding::is_deleted): Likewise. (concrete_binding::is_empty): Likewise. +2024-05-09 David Malcolm + + Backported from master: + 2023-08-03 David Malcolm + + PR analyzer/110882 + * region.cc (int_size_in_bits): Fail on zero-sized types. + +2024-05-09 David Malcolm + + Backported from master: + 2023-07-19 David Malcolm + + PR analyzer/110700 + * region-model-manager.cc + (region_model_manager::get_or_create_int_cst): Assert that we have + an integral or pointer type. + * sm-taint.cc (taint_state_machine::check_for_tainted_divisor): + Don't check non-integral types. + +2024-05-09 Tim Lange + + Backported from master: + 2023-06-09 Tim Lange + + PR analyzer/109577 + * constraint-manager.cc (class sval_finder): Visitor to find + childs in svalue trees. + (constraint_manager::sval_constrained_p): Add new function to + check whether a sval might be part of an constraint. + * constraint-manager.h: Add sval_constrained_p function. + * region-model.cc (class size_visitor): Reverse behavior to not + emit a warning on not explicitly considered cases. + (region_model::check_region_size): + Adapt to size_visitor changes. + +2024-05-09 David Malcolm + + Backported from master: + 2023-06-09 David Malcolm + + PR analyzer/110112 + * region-model.cc (region_model::get_initial_value_for_global): + Move code to region::calc_initial_value_at_main. + * region.cc (region::get_initial_value_at_main): New function. + (region::calc_initial_value_at_main): New function, based on code + in region_model::get_initial_value_for_global. + (region::region): Initialize m_cached_init_sval_at_main. + (decl_region::get_svalue_for_constructor): Add a cache, splitting + out body to... + (decl_region::calc_svalue_for_constructor): ...this new function. + * region.h (region::get_initial_value_at_main): New decl. + (region::calc_initial_value_at_main): New decl. + (region::m_cached_init_sval_at_main): New field. + (decl_region::decl_region): Initialize m_ctor_svalue. + (decl_region::calc_svalue_for_constructor): New decl. + (decl_region::m_ctor_svalue): New field. + 2023-07-27 Release Manager * GCC 13.2.0 released. diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index 986c831a2729..07708072688f 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,11 @@ +2024-05-09 Vibhav Pant + + Backported from master: + 2023-10-25 Vibhav Pant + + * jit-recording.cc (recording::global::write_to_dump): Fix + dump of string literal initializers. + 2024-04-05 Iain Sandoe Backported from master: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 23a89209aeb7..878fb8f22549 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -9,6 +9,14 @@ *
[gcc r15-519] openmp: Diagnose using grainsize+num_tasks clauses together [PR115103]
https://gcc.gnu.org/g:7fdbefc575c24881356b5f4091fa57b5f7166a90 commit r15-519-g7fdbefc575c24881356b5f4091fa57b5f7166a90 Author: Jakub Jelinek Date: Wed May 15 18:34:44 2024 +0200 openmp: Diagnose using grainsize+num_tasks clauses together [PR115103] I've noticed that while we diagnose many other OpenMP exclusive clauses, we don't diagnose grainsize together with num_tasks on taskloop construct in all of C, C++ and Fortran (the implementation simply ignored grainsize in that case) and for Fortran also don't diagnose mixing nogroup clause with reduction clause(s). Fixed thusly. 2024-05-15 Jakub Jelinek PR c/115103 gcc/c/ * c-typeck.cc (c_finish_omp_clauses): Diagnose grainsize used together with num_tasks. gcc/cp/ * semantics.cc (finish_omp_clauses): Diagnose grainsize used together with num_tasks. gcc/fortran/ * openmp.cc (resolve_omp_clauses): Diagnose grainsize used together with num_tasks or nogroup used together with reduction. gcc/testsuite/ * c-c++-common/gomp/clause-dups-1.c: Add 2 further expected errors. * gfortran.dg/gomp/pr115103.f90: New test. Diff: --- gcc/c/c-typeck.cc | 22 -- gcc/cp/semantics.cc | 16 gcc/fortran/openmp.cc | 7 +++ gcc/testsuite/c-c++-common/gomp/clause-dups-1.c | 4 ++-- gcc/testsuite/gfortran.dg/gomp/pr115103.f90 | 14 ++ 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 4567b114734b..7ecca9f58c68 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -14722,6 +14722,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) tree *detach_seen = NULL; bool linear_variable_step_check = false; tree *nowait_clause = NULL; + tree *grainsize_seen = NULL; + bool num_tasks_seen = false; tree ordered_clause = NULL_TREE; tree schedule_clause = NULL_TREE; bool oacc_async = false; @@ -16021,8 +16023,6 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_PROC_BIND: case OMP_CLAUSE_DEVICE_TYPE: case OMP_CLAUSE_PRIORITY: - case OMP_CLAUSE_GRAINSIZE: - case OMP_CLAUSE_NUM_TASKS: case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_HINT: @@ -16048,6 +16048,16 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) pc = &OMP_CLAUSE_CHAIN (c); continue; + case OMP_CLAUSE_GRAINSIZE: + grainsize_seen = pc; + pc = &OMP_CLAUSE_CHAIN (c); + continue; + + case OMP_CLAUSE_NUM_TASKS: + num_tasks_seen = true; + pc = &OMP_CLAUSE_CHAIN (c); + continue; + case OMP_CLAUSE_MERGEABLE: mergeable_seen = true; pc = &OMP_CLAUSE_CHAIN (c); @@ -16333,6 +16343,14 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) *nogroup_seen = OMP_CLAUSE_CHAIN (*nogroup_seen); } + if (grainsize_seen && num_tasks_seen) +{ + error_at (OMP_CLAUSE_LOCATION (*grainsize_seen), + "% clause must not be used together with " + "% clause"); + *grainsize_seen = OMP_CLAUSE_CHAIN (*grainsize_seen); +} + if (detach_seen) { if (mergeable_seen) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index df62e2d80dbd..f90c304a65b7 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -7098,6 +7098,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) bool mergeable_seen = false; bool implicit_moved = false; bool target_in_reduction_seen = false; + bool num_tasks_seen = false; bitmap_obstack_initialize (NULL); bitmap_initialize (&generic_head, &bitmap_default_obstack); @@ -7656,6 +7657,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_NUM_TASKS: + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TASKS) + num_tasks_seen = true; + /* FALLTHRU */ + case OMP_CLAUSE_NUM_TEAMS: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_NUM_GANGS: @@ -9246,6 +9251,17 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } pc = &OMP_CLAUSE_CHAIN (c); continue; + case OMP_CLAUSE_GRAINSIZE: + if (num_tasks_seen) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause must not be used together with " + "% clause"); + *pc = OMP_CLAUSE_CHAIN (c); + continue; + } + pc = &OMP_CLAUSE_CHAIN (c); + continue; case OMP_CLAUSE_ORDERED: if (reduction_seen == -2) error_at (OMP_CLAUSE_LOCATION (c), di
[gcc r15-520] combine: Fix up simplify_compare_const [PR115092]
https://gcc.gnu.org/g:0b93a0ae153ef70a82ff63e67926a01fdab9956b commit r15-520-g0b93a0ae153ef70a82ff63e67926a01fdab9956b Author: Jakub Jelinek Date: Wed May 15 18:37:17 2024 +0200 combine: Fix up simplify_compare_const [PR115092] The following testcases are miscompiled (with tons of GIMPLE optimization disabled) because combine sees GE comparison of 1-bit sign_extract (i.e. something with [-1, 0] value range) with (const_int -1) (which is always true) and optimizes it into NE comparison of 1-bit zero_extract ([0, 1] value range) against (const_int 0). The reason is that simplify_compare_const first (correctly) simplifies the comparison to GE (ashift:SI something (const_int 31)) (const_int -2147483648) and then an optimization for when the second operand is power of 2 triggers. That optimization is fine for power of 2s which aren't the signed minimum of the mode, or if it is NE, EQ, GEU or LTU against the signed minimum of the mode, but for GE or LT optimizing it into NE (or EQ) against const0_rtx is wrong, those cases are always true or always false (but the function doesn't have a standardized way to tell callers the comparison is now unconditional). The following patch just disables the optimization in that case. 2024-05-15 Jakub Jelinek PR rtl-optimization/114902 PR rtl-optimization/115092 * combine.cc (simplify_compare_const): Don't optimize GE op0 SIGNED_MIN or LT op0 SIGNED_MIN into NE op0 const0_rtx or EQ op0 const0_rtx. * gcc.dg/pr114902.c: New test. * gcc.dg/pr115092.c: New test. Diff: --- gcc/combine.cc | 6 -- gcc/testsuite/gcc.dg/pr114902.c | 23 +++ gcc/testsuite/gcc.dg/pr115092.c | 16 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/gcc/combine.cc b/gcc/combine.cc index 71c9abc145c2..3b50bc3529c4 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -11852,8 +11852,10 @@ simplify_compare_const (enum rtx_code code, machine_mode mode, `and'ed with that bit), we can replace this with a comparison with zero. */ if (const_op - && (code == EQ || code == NE || code == GE || code == GEU - || code == LT || code == LTU) + && (code == EQ || code == NE || code == GEU || code == LTU + /* This optimization is incorrect for signed >= INT_MIN or +< INT_MIN, those are always true or always false. */ + || ((code == GE || code == LT) && const_op > 0)) && is_a (mode, &int_mode) && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT && pow2p_hwi (const_op & GET_MODE_MASK (int_mode)) diff --git a/gcc/testsuite/gcc.dg/pr114902.c b/gcc/testsuite/gcc.dg/pr114902.c new file mode 100644 index ..60684faa25d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114902.c @@ -0,0 +1,23 @@ +/* PR rtl-optimization/114902 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fno-tree-fre -fno-tree-forwprop -fno-tree-ccp -fno-tree-dominator-opts" } */ + +__attribute__((noipa)) +int foo (int x) +{ + int a = ~x; + int t = a & 1; + int e = -t; + int b = e >= -1; + if (b) +return 0; + __builtin_trap (); +} + +int +main () +{ + foo (-1); + foo (0); + foo (1); +} diff --git a/gcc/testsuite/gcc.dg/pr115092.c b/gcc/testsuite/gcc.dg/pr115092.c new file mode 100644 index ..c9047f4d321a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr115092.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/115092 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fgcse -ftree-pre -fno-tree-dominator-opts -fno-tree-fre -fno-guess-branch-probability" } */ + +int a, b, c = 1, d, e; + +int +main () +{ + int f, g = a; + b = -2; + f = -(1 >> ((c && b) & ~a)); + if (f <= b) +d = g / e; + return 0; +}
[gcc r15-521] c++: Optimize in maybe_clone_body aliases even when not at_eof [PR113208]
https://gcc.gnu.org/g:6ad7ca1bb905736c0f57688e93e9e77cbc71a325 commit r15-521-g6ad7ca1bb905736c0f57688e93e9e77cbc71a325 Author: Jakub Jelinek Date: Wed May 15 18:50:11 2024 +0200 c++: Optimize in maybe_clone_body aliases even when not at_eof [PR113208] This patch reworks the cdtor alias optimization, such that we can create aliases even when maybe_clone_body is called not at at_eof time, without trying to repeat it in maybe_optimize_cdtor. 2024-05-15 Jakub Jelinek Jason Merrill PR lto/113208 * cp-tree.h (maybe_optimize_cdtor): Remove. * decl2.cc (tentative_decl_linkage): Call maybe_make_one_only for implicit instantiations of maybe in charge ctors/dtors declared inline. (import_export_decl): Don't call maybe_optimize_cdtor. (c_parse_final_cleanups): Formatting fixes. * optimize.cc (can_alias_cdtor): Adjust condition, for HAVE_COMDAT_GROUP && DECL_ONE_ONLY && DECL_WEAK return true even if not DECL_INTERFACE_KNOWN. (maybe_clone_body): Don't clear DECL_SAVED_TREE, instead set it to void_node. (maybe_clone_body): Remove. * decl.cc (cxx_comdat_group): For DECL_CLONED_FUNCTION_P functions if SUPPORTS_ONE_ONLY return DECL_COMDAT_GROUP if already set. * g++.dg/abi/comdat3.C: New test. * g++.dg/abi/comdat4.C: New test. Diff: --- gcc/cp/cp-tree.h | 1 - gcc/cp/decl.cc | 7 + gcc/cp/decl2.cc| 32 ++- gcc/cp/optimize.cc | 63 ++ gcc/testsuite/g++.dg/abi/comdat3.C | 22 + gcc/testsuite/g++.dg/abi/comdat4.C | 28 + 6 files changed, 78 insertions(+), 75 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9a8c86591573..ba9e848c177f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7453,7 +7453,6 @@ extern bool handle_module_option (unsigned opt, const char *arg, int value); /* In optimize.cc */ extern tree clone_attrs(tree); extern bool maybe_clone_body (tree); -extern void maybe_optimize_cdtor (tree); /* In parser.cc */ extern tree cp_convert_range_for (tree, tree, tree, cp_decomp *, bool, diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index a139b293e00c..6fcab615d55e 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -19287,6 +19287,13 @@ cxx_comdat_group (tree decl) else break; } + /* If a ctor/dtor has already set the comdat group by +maybe_clone_body, don't override it. */ + if (SUPPORTS_ONE_ONLY + && TREE_CODE (decl) == FUNCTION_DECL + && DECL_CLONED_FUNCTION_P (decl)) + if (tree comdat = DECL_COMDAT_GROUP (decl)) + return comdat; } return decl; diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 6913efa53552..7baff46a1921 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -3325,16 +3325,23 @@ tentative_decl_linkage (tree decl) linkage of all functions, and as that causes writes to the data mapped in from the PCH file, it's advantageous to mark the functions at this point. */ - if (DECL_DECLARED_INLINE_P (decl) - && (!DECL_IMPLICIT_INSTANTIATION (decl) - || DECL_DEFAULTED_FN (decl))) + if (DECL_DECLARED_INLINE_P (decl)) { - /* This function must have external linkage, as -otherwise DECL_INTERFACE_KNOWN would have been -set. */ - gcc_assert (TREE_PUBLIC (decl)); - comdat_linkage (decl); - DECL_INTERFACE_KNOWN (decl) = 1; + if (!DECL_IMPLICIT_INSTANTIATION (decl) + || DECL_DEFAULTED_FN (decl)) + { + /* This function must have external linkage, as +otherwise DECL_INTERFACE_KNOWN would have been +set. */ + gcc_assert (TREE_PUBLIC (decl)); + comdat_linkage (decl); + DECL_INTERFACE_KNOWN (decl) = 1; + } + else if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)) + /* For implicit instantiations of cdtors try to make + it comdat, so that maybe_clone_body can use aliases. + See PR113208. */ + maybe_make_one_only (decl); } } else if (VAR_P (decl)) @@ -3604,9 +3611,6 @@ import_export_decl (tree decl) } DECL_INTERFACE_KNOWN (decl) = 1; - - if (DECL_CLONED_FUNCTION_P (decl)) -maybe_optimize_cdtor (decl); } /* Return an expression that performs the destruction of DECL, which @@ -5331,7 +5335,7 @@ c_parse_final_cleanups (void) node = node->get_alias_targe
[gcc r15-690] Manually add ChangeLog entry for r15-575-gda73261ce7731be7f2b164f1db796878cdc23365
https://gcc.gnu.org/g:83d3a218dfb3b7730884ada7e607cf72891d4c11 commit r15-690-g83d3a218dfb3b7730884ada7e607cf72891d4c11 Author: Jakub Jelinek Date: Mon May 20 09:48:27 2024 +0200 Manually add ChangeLog entry for r15-575-gda73261ce7731be7f2b164f1db796878cdc23365 Diff: --- gcc/ChangeLog | 29 + 1 file changed, 29 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfd2d42e287d..07aad1886112 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -359,6 +359,35 @@ (math_opts_dom_walker::after_dom_children): Try match saturation arith when IOR expr. +2024-05-16 Aldy Hernandez + + Revert: + 2024-05-10 Aldy Hernandez + + Revert: + 2024-05-08 Aldy Hernandez + + * gimple-range-cache.cc (sbr_sparse_bitmap::sbr_sparse_bitmap): + Change irange to prange. + * gimple-range-fold.cc (fold_using_range::fold_stmt): Same. + (fold_using_range::range_of_address): Same. + * gimple-range-fold.h (range_of_address): Same. + * gimple-range-infer.cc (gimple_infer_range::add_nonzero): Same. + * gimple-range-op.cc (class cfn_strlen): Same. + * gimple-range-path.cc + (path_range_query::adjust_for_non_null_uses): Same. + * gimple-ssa-warn-access.cc (pass_waccess::check_pointer_uses): Same. + * tree-ssa-structalias.cc (find_what_p_points_to): Same. + * range-op-ptr.cc (range_op_table::initialize_pointer_ops): Remove + hybrid entries in table. + * range-op.cc (range_op_table::range_op_table): Add pointer + entries for bitwise and/or and min/max. + * value-range.cc (irange::verify_range): Add assert. + * value-range.h (irange::varying_compatible_p): Remove check for + error_mark_node. + (irange::supports_p): Remove pointer support. + * ipa-cp.h (ipa_supports_p): Add prange support. + 2024-05-16 Aldy Hernandez PR tree-optimization/114985
[gcc r15-3045] c++: Parse and ignore attributes on base specifiers [PR110345]
https://gcc.gnu.org/g:1db5ca04da365ac57f7d788a85055edcf13da708 commit r15-3045-g1db5ca04da365ac57f7d788a85055edcf13da708 Author: Jakub Jelinek Date: Tue Aug 20 22:15:03 2024 +0200 c++: Parse and ignore attributes on base specifiers [PR110345] For C++ 26 P2552R3 I went through all the spots (except modules) where attribute-specifier-seq appears in the grammar and tried to construct a testcase in all those spots, for now for [[deprecated]] attribute. This is the third issue I found. https://eel.is/c++draft/class.derived#general-1 has attribute-specifier-seq at the start of base-specifier. The following patch parses it there and warns about those. 2024-08-20 Jakub Jelinek PR c++/110345 * parser.cc (cp_parser_base_specifier): Parse standard attributes at the start and emit a warning if there are any non-ignored ones. * g++.dg/cpp0x/gen-attrs-83.C: New test. Diff: --- gcc/cp/parser.cc | 17 - gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C | 10 ++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index c43889803482..28ebf2beb60a 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -28995,11 +28995,12 @@ cp_parser_base_clause (cp_parser* parser) /* Parse a base-specifier. base-specifier: - :: [opt] nested-name-specifier [opt] class-name - virtual access-specifier [opt] :: [opt] nested-name-specifier - [opt] class-name - access-specifier virtual [opt] :: [opt] nested-name-specifier - [opt] class-name + attribute-specifier-seq [opt] :: [opt] nested-name-specifier [opt] + class-name + attribute-specifier-seq [opt] virtual access-specifier [opt] :: [opt] + nested-name-specifier [opt] class-name + attribute-specifier-seq [opt] access-specifier virtual [opt] :: [opt] + nested-name-specifier [opt] class-name Returns a TREE_LIST. The TREE_PURPOSE will be one of ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to @@ -29017,6 +29018,12 @@ cp_parser_base_specifier (cp_parser* parser) bool class_scope_p, template_p; tree access = access_default_node; tree type; + location_t attrs_loc = cp_lexer_peek_token (parser->lexer)->location; + tree std_attrs = cp_parser_std_attribute_spec_seq (parser); + + if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs)) +warning_at (attrs_loc, OPT_Wattributes, + "attributes on base specifiers are ignored"); /* Process the optional `virtual' and `access-specifier'. */ while (!done) diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C new file mode 100644 index ..0ff1965d0ecf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-83.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++11 } } + +struct A {}; +struct B {}; +struct C {}; +struct D : [[]] [[]] A, + [[]] virtual public B, [[]] [[]] [[]] public virtual C {}; +struct E : [[gnu::deprecated]] A, // { dg-warning "attributes on base specifiers are ignored" } + [[gnu::deprecated]] virtual public B,// { dg-warning "attributes on base specifiers are ignored" } + [[gnu::deprecated]] public virtual C {}; // { dg-warning "attributes on base specifiers are ignored" }
[gcc r15-3046] c++: Appertain standard attributes after array closing square bracket to array type rather than decl
https://gcc.gnu.org/g:d05949558ef1c8eeeb07399174a64f968f70e3ee commit r15-3046-gd05949558ef1c8eeeb07399174a64f968f70e3ee Author: Jakub Jelinek Date: Tue Aug 20 22:17:41 2024 +0200 c++: Appertain standard attributes after array closing square bracket to array type rather than declarator [PR110345] For C++ 26 P2552R3 I went through all the spots (except modules) where attribute-specifier-seq appears in the grammar and tried to construct a testcase in all those spots, for now for [[deprecated]] attribute. This is the second issue I found. The comment already correctly says that attributes after closing ] appertain to the array type, but we were appending them to returned_attrs, so effectively applying them to the declarator (as if they appeared right after declarator-id). 2024-08-20 Jakub Jelinek PR c++/110345 * decl.cc (grokdeclarator): Apply declarator->std_attributes for cdk_array to type, rather than chaining it to returned_attrs. * g++.dg/cpp0x/gen-attrs-82.C: New test. * g++.dg/gomp/attrs-3.C (foo): Expect different diagnostics for omp::directive attribute after closing square bracket of an automatic declaration and add a test with the attribute after array's declarator-id. Diff: --- gcc/cp/decl.cc| 5 ++--- gcc/testsuite/g++.dg/cpp0x/gen-attrs-82.C | 4 gcc/testsuite/g++.dg/gomp/attrs-3.C | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 12139e1d8627..7ab73f1031d7 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -13317,9 +13317,8 @@ grokdeclarator (const cp_declarator *declarator, /* [dcl.array]/1: The optional attribute-specifier-seq appertains to the - array. */ - returned_attrs = attr_chainon (returned_attrs, - declarator->std_attributes); + array type. */ + decl_attributes (&type, declarator->std_attributes, 0); break; case cdk_function: diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-82.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-82.C new file mode 100644 index ..67c1a2098430 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-82.C @@ -0,0 +1,4 @@ +// { dg-do compile { target c++11 } } + +int a [[gnu::common]] [2]; +int b[2] [[gnu::common]]; // { dg-warning "'common' attribute does not apply to types" } diff --git a/gcc/testsuite/g++.dg/gomp/attrs-3.C b/gcc/testsuite/g++.dg/gomp/attrs-3.C index 7aab6370d499..5658b3a86895 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-3.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-3.C @@ -35,6 +35,7 @@ foo () int *[[omp::directive (threadprivate (t3))]] c; // { dg-warning "'omp::directive' scoped attribute directive ignored" } int &[[omp::directive (threadprivate (t4))]] d = b; // { dg-warning "'omp::directive' scoped attribute directive ignored" } typedef int T [[omp::directive (threadprivate (t5))]]; // { dg-error "'omp::directive' not allowed to be specified in this context" } - int e[10] [[omp::directive (threadprivate (t6))]]; // { dg-error "'omp::directive' not allowed to be specified in this context" } + int e [[omp::directive (threadprivate (t6))]] [10]; // { dg-error "'omp::directive' not allowed to be specified in this context" } + int f[10] [[omp::directive (threadprivate (t6))]]; // { dg-warning "'omp::directive' scoped attribute directive ignored" } struct [[omp::directive (threadprivate (t7))]] S {}; // { dg-error "'omp::directive' not allowed to be specified in this context" } }
[gcc r15-3048] libcpp: Adjust lang_defaults
https://gcc.gnu.org/g:447c32c5142a60278230f81ae6e50e41ef6d988e commit r15-3048-g447c32c5142a60278230f81ae6e50e41ef6d988e Author: Jakub Jelinek Date: Tue Aug 20 22:25:57 2024 +0200 libcpp: Adjust lang_defaults The table over the years turned to be very wide, 147 columns and any addition would add a couple of new ones. We need a 28x23 bit matrix right now. This patch changes the formatting, so that we need just 2 columns per new feature and so we have some room for expansion. In addition, the patch changes it to bitfields, which reduces .rodata by 532 bytes (so 5.75x reduction of the variable) and on x86_64-linux grows the cpp_set_lang function by 26 bytes (8.4% growth). 2024-08-20 Jakub Jelinek * init.cc (struct lang_flags): Change all members from char typed fields to unsigned bit-fields. (lang_defaults): Change formatting of the initializer so that it fits to 68 columns rather than 147. Diff: --- libcpp/init.cc | 112 ++--- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/libcpp/init.cc b/libcpp/init.cc index 9ae06a9595d9..2dfd9d7e0623 100644 --- a/libcpp/init.cc +++ b/libcpp/init.cc @@ -77,61 +77,67 @@ END requires. */ struct lang_flags { - char c99; - char cplusplus; - char extended_numbers; - char extended_identifiers; - char c11_identifiers; - char xid_identifiers; - char std; - char digraphs; - char uliterals; - char rliterals; - char user_literals; - char binary_constants; - char digit_separators; - char trigraphs; - char utf8_char_literals; - char va_opt; - char scope; - char dfp_constants; - char size_t_literals; - char elifdef; - char warning_directive; - char delimited_escape_seqs; - char true_false; + unsigned int c99 : 1; + unsigned int cplusplus : 1; + unsigned int extended_numbers : 1; + unsigned int extended_identifiers : 1; + unsigned int c11_identifiers : 1; + unsigned int xid_identifiers : 1; + unsigned int std : 1; + unsigned int digraphs : 1; + unsigned int uliterals : 1; + unsigned int rliterals : 1; + unsigned int user_literals : 1; + unsigned int binary_constants : 1; + unsigned int digit_separators : 1; + unsigned int trigraphs : 1; + unsigned int utf8_char_literals : 1; + unsigned int va_opt : 1; + unsigned int scope : 1; + unsigned int dfp_constants : 1; + unsigned int size_t_literals : 1; + unsigned int elifdef : 1; + unsigned int warning_directive : 1; + unsigned int delimited_escape_seqs : 1; + unsigned int true_false : 1; }; -static const struct lang_flags lang_defaults[] = -{ /* c99 c++ xnum xid c11 xidid std digr ulit rlit udlit bincst digsep trig u8chlit vaopt scope dfp szlit elifdef warndir delim trufal */ - /* GNUC89 */ { 0, 0, 1, 0, 0, 0,0, 1, 0, 0, 0,0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,0 }, - /* GNUC99 */ { 1, 0, 1, 1, 0, 0,0, 1, 1, 1, 0,0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,0 }, - /* GNUC11 */ { 1, 0, 1, 1, 1, 0,0, 1, 1, 1, 0,0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,0 }, - /* GNUC17 */ { 1, 0, 1, 1, 1, 0,0, 1, 1, 1, 0,0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,0 }, - /* GNUC23 */ { 1, 0, 1, 1, 1, 1,0, 1, 1, 1, 0,1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0,1 }, - /* GNUC2Y */ { 1, 0, 1, 1, 1, 1,0, 1, 1, 1, 0,1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0,1 }, - /* STDC89 */ { 0, 0, 0, 0, 0, 0,1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,0 }, - /* STDC94 */ { 0, 0, 0, 0, 0, 0,1, 1, 0, 0, 0,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,0 }, - /* STDC99 */ { 1, 0, 1, 1, 0, 0,1, 1, 0, 0, 0,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,0 }, - /* STDC11 */ { 1, 0, 1, 1, 1, 0,1, 1, 1, 0, 0,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,0 }, - /* STDC17 */ { 1, 0, 1, 1, 1, 0,1, 1, 1, 0, 0,0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,0 }, - /* STDC23 */ { 1, 0, 1, 1, 1, 1,1, 1, 1, 0, 0,1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0,1 }, - /* STDC2Y */ { 1, 0, 1, 1, 1, 1,1, 1, 1, 0, 0,1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0,1 }, - /* GNUCXX */ { 0, 1, 1, 1, 0, 1,0, 1, 0, 0, 0,0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,1 }, - /* CXX98*/ { 0, 1, 0, 1, 0, 1,1, 1, 0, 0, 0
[gcc r15-3315] c++: Allow standard attributes after closing square bracket in new-type-id [PR110345]
https://gcc.gnu.org/g:b748e2eed0df9e691a530a0b8faea9f673bdf2b5 commit r15-3315-gb748e2eed0df9e691a530a0b8faea9f673bdf2b5 Author: Jakub Jelinek Date: Fri Aug 30 09:40:34 2024 +0200 c++: Allow standard attributes after closing square bracket in new-type-id [PR110345] For C++ 26 P2552R3 I went through all the spots (except modules) where attribute-specifier-seq appears in the grammar and tried to construct a testcase in all those spots, for now for [[deprecated]] attribute. The first thing I found is that we aren't parsing standard attributes in noptr-new-declarator - https://eel.is/c++draft/expr.new#1 The following patch parses it there, for the non-outermost arrays applies normally the attributes to the array type, for the outermost where we just set *nelts and don't really build an array type just warns that we ignore those attributes (or, do you think we should just build an array type in that case and just take its element type?). 2024-08-30 Jakub Jelinek PR c++/110345 * parser.cc (make_array_declarator): Add STD_ATTRS argument, set declarator->std_attributes to it. (cp_parser_new_type_id): Warn on non-ignored std_attributes on the array declarator which is being omitted. (cp_parser_direct_new_declarator): Parse standard attributes after closing square bracket, pass it to make_array_declarator. (cp_parser_direct_declarator): Pass std_attrs to make_array_declarator instead of setting declarator->std_attributes manually. * g++.dg/cpp0x/gen-attrs-80.C: New test. * g++.dg/cpp0x/gen-attrs-81.C: New test. Diff: --- gcc/cp/parser.cc | 28 gcc/testsuite/g++.dg/cpp0x/gen-attrs-80.C | 10 ++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-81.C | 11 +++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 918072dbf637..632d3dc5ecf4 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -1689,7 +1689,7 @@ static cp_declarator *make_call_declarator (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, tree, tree, tree, tree, tree, location_t); static cp_declarator *make_array_declarator - (cp_declarator *, tree); + (cp_declarator *, tree, tree); static cp_declarator *make_pointer_declarator (cp_cv_quals, cp_declarator *, tree); static cp_declarator *make_reference_declarator @@ -1904,10 +1904,11 @@ make_call_declarator (cp_declarator *target, } /* Make a declarator for an array of BOUNDS elements, each of which is - defined by ELEMENT. */ + defined by ELEMENT. STD_ATTRS contains attributes that appertain to + the array type. */ cp_declarator * -make_array_declarator (cp_declarator *element, tree bounds) +make_array_declarator (cp_declarator *element, tree bounds, tree std_attrs) { cp_declarator *declarator; @@ -1923,6 +1924,8 @@ make_array_declarator (cp_declarator *element, tree bounds) else declarator->parameter_pack_p = false; + declarator->std_attributes = std_attrs; + return declarator; } @@ -9789,6 +9792,15 @@ cp_parser_new_type_id (cp_parser* parser, tree *nelts) if (*nelts == error_mark_node) *nelts = integer_one_node; + /* FIXME: Maybe build even the outermost array type and strip +it, to diagnose the attributes on it. Problem is that VLAs aren't +pedantically allowed except for this case. */ + if (*nelts + && declarator->std_attributes + && any_nonignored_attribute_p (declarator->std_attributes)) + warning (OPT_Wattributes, "attributes ignored on outermost array " + "type in new expression"); + if (*nelts == NULL_TREE) /* Leave [] in the declarator. */; else if (outer_declarator) @@ -9843,8 +9855,8 @@ cp_parser_new_declarator_opt (cp_parser* parser) /* Parse a direct-new-declarator. direct-new-declarator: - [ expression ] - direct-new-declarator [constant-expression] + [ expression ] attribute-specifier-seq [opt] + direct-new-declarator [constant-expression] attribute-specifier-seq [opt] */ @@ -9891,8 +9903,9 @@ cp_parser_direct_new_declarator (cp_parser* parser) /* Look for the closing `]'. */ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); + tree attrs = cp_parser_std_attribute_spec_seq (parser); /* Add this bound to the declarator. */ - declarator = make_array_declarator (declarator, expression); + declarator = make_array_declarator (declarator, expression, attrs); /* If the next token is not a `[', then there are no more bounds. */ @@ -24339,8 +24352,7 @@ cp_parser_direct_declarator (cp_parser* parser, } attrs = cp_parser_std_attribute_spec_seq (parser)
[gcc r15-3330] c: Add support for unsequenced and reproducible attributes
https://gcc.gnu.org/g:dd346b613886aea9761dbb5e7a8d6c47922750b2 commit r15-3330-gdd346b613886aea9761dbb5e7a8d6c47922750b2 Author: Jakub Jelinek Date: Sat Aug 31 15:58:23 2024 +0200 c: Add support for unsequenced and reproducible attributes C23 added in N2956 ( https://open-std.org/JTC1/SC22/WG14/www/docs/n2956.htm ) two new attributes, which are described as similar to GCC const and pure attributes, but they aren't really same and it seems that even the paper is missing some of the differences. The paper says unsequenced is the same as const on functions without pointer arguments and reproducible is the same as pure on such functions (except that they are function type attributes rather than function declaration ones), but it seems the paper doesn't consider the finiteness GCC relies on (aka non-DECL_LOOPING_CONST_OR_PURE_P) - the paper only talks about using the attributes for CSE etc., not for DCE. The following patch introduces (for now limited) support for those attributes, both as standard C23 attributes and as GNU extensions (the difference is that the patch is then less strict on where it allows them, like other function type attributes they can be specified on function declarations as well and apply to the type, while C23 standard ones must go on the function declarators (i.e. after closing paren after function parameters) or in type specifiers of function type. If function doesn't have any pointer/reference arguments, the patch adds additional internal attribute with " noptr" suffix which then is used by flags_from_decl_or_type to handle those easy cases as ECF_CONST|ECF_LOOPING_CONST_OR_PURE or ECF_PURE|ECF_LOOPING_CONST_OR_PURE The harder cases aren't handled right now, I'd hope they can be handled incrementally. I wonder whether we shouldn't emit a warning for the gcc.dg/c23-attr-{reproducible,unsequenced}-5.c cases, while the standard clearly specifies that composite types should union the attributes and it is what GCC implements for decades, for ?: that feels dangerous for the new attributes, it would be much better to be conservative on say (cond ? unsequenced_function : normal_function) (args) There is no diagnostics on incorrect [[unsequenced]] or [[reproducible]] function definitions, while I think diagnosing non-const static/TLS declarations in the former could be easy, the rest feels hard. E.g. the const/pure discovery can just punt on everything it doesn't understand, but complete diagnostics would need to understand it. 2024-08-31 Jakub Jelinek PR c/116130 gcc/ * doc/extend.texi (unsequenced, reproducible): Document new function type attributes. * calls.cc (flags_from_decl_or_type): Handle "unsequenced noptr" and "reproducible noptr" attributes. gcc/c-family/ * c-attribs.cc (c_common_gnu_attributes): Add entries for "unsequenced", "reproducible", "unsequenced noptr" and "reproducible noptr" attributes. (handle_unsequenced_attribute): New function. (handle_reproducible_attribute): Likewise. * c-common.h (handle_unsequenced_attribute): Declare. (handle_reproducible_attribute): Likewise. * c-lex.cc (c_common_has_attribute): Return 202311 for standard unsequenced and reproducible attributes. gcc/c/ * c-decl.cc (handle_std_unsequenced_attribute): New function. (handle_std_reproducible_attribute): Likewise. (std_attributes): Add entries for "unsequenced" and "reproducible" attributes. (c_warn_type_attributes): Add TYPE argument. Allow unsequenced or reproducible attributes if it is FUNCTION_TYPE. (groktypename): Adjust c_warn_type_attributes caller. (grokdeclarator): Likewise. (finish_declspecs): Likewise. * c-parser.cc (c_parser_declaration_or_fndef): Likewise. * c-tree.h (c_warn_type_attributes): Add TYPE argument. gcc/testsuite/ * c-c++-common/attr-reproducible-1.c: New test. * c-c++-common/attr-reproducible-2.c: New test. * c-c++-common/attr-unsequenced-1.c: New test. * c-c++-common/attr-unsequenced-2.c: New test. * gcc.dg/c23-attr-reproducible-1.c: New test. * gcc.dg/c23-attr-reproducible-2.c: New test. * gcc.dg/c23-attr-reproducible-3.c: New test. * gcc.dg/c23-attr-reproducible-4.c: New test. * gcc.dg/c23-attr-reproducible-5.c: New test. * gcc.dg/c23-attr-reproducible-5-aux.c: New file. * gcc.dg/c23-attr-unsequenced-1.c: New test. * gcc.dg/c23-attr-unsequenced-2.c: New test. * gcc.dg/c23-attr-unsequenced-3.c: New test.
[gcc r15-3331] c++: Add unsequenced C++ testcase
https://gcc.gnu.org/g:afd9558b94eb78ef3e9a8818f2d57f9311e99b4f commit r15-3331-gafd9558b94eb78ef3e9a8818f2d57f9311e99b4f Author: Jakub Jelinek Date: Sat Aug 31 16:03:20 2024 +0200 c++: Add unsequenced C++ testcase This is the testcase I wrote originally and which on top of the https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659154.html patch didn't behave the way I wanted (no warning and no optimizations of [[unsequenced]] function templates which don't have pointer/reference arguments. Posting this separately, because it depends on the above mentioned patch as well as the PR116175 https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659157.html patch. 2024-08-31 Jakub Jelinek * g++.dg/ext/attr-unsequenced-1.C: New test. Diff: --- gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C | 53 +++ 1 file changed, 53 insertions(+) diff --git a/gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C b/gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C new file mode 100644 index ..8e640a8cec1e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C @@ -0,0 +1,53 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-O2 -fdump-tree-optimized" } */ +// { dg-final { scan-tree-dump-times " bar \\\(1, 2, 3\\\);" 1 "optimized" } } +// { dg-final { scan-tree-dump-times " bar \\\(4, 5, 6\\\);" 1 "optimized" } } + +template +[[gnu::noipa]] U +foo (T x, T y, T z) [[gnu::unsequenced]] +{ + *x = 1; + *y = 2; + *z = 3; +} + +template +[[gnu::noipa]] T +bar (T x, T y, T z) [[gnu::unsequenced]] +{ + return x + y + z; +} + +int +baz () [[gnu::unsequenced]] +{ + int x, y, z; + foo (&x, &y, &z); + return x; +} + +int +qux () [[gnu::unsequenced]] +{ + int a = bar (1, 2, 3); + int b = bar (1, 2, 3); + int c = bar (1, 2, 3); + int d = bar (4, 5, 6); + int e = bar (4, 5, 6); + int f = bar (4, 5, 6); + return a + b + c + d + e + f; +} + +template +[[gnu::noipa]] U +corge (T x, T y, T z) [[gnu::unsequenced]] // { dg-warning "'unsequenced' attribute on function type without pointer arguments returning 'void'" } +{ + x += y + z; +} + +void +freddy () +{ + corge (1, 2, 3); +}
[gcc r15-3364] ranger: Fix up range computation for CLZ [PR116486]
https://gcc.gnu.org/g:25d51fb7d098a9ac8880ccb2121d889815680177 commit r15-3364-g25d51fb7d098a9ac8880ccb2121d889815680177 Author: Jakub Jelinek Date: Mon Sep 2 09:44:09 2024 +0200 ranger: Fix up range computation for CLZ [PR116486] The initial CLZ gimple-range-op.cc implementation handled just the case where second argument to .CLZ is equal to prec, but in r15-1014 I've added also handling of the -1 case. As the following testcase shows, incorrectly though for the case where the first argument has [0,0] range. If the second argument is prec, then the result should be [prec,prec] and that was handled correctly, but when the second argument is -1, the result should be [-1,-1] but instead it was incorrectly computed as [prec-1,prec-1] (when second argument is prec, mini is 0 and maxi is prec, while when second argument is -1, mini is -1 and maxi is prec-1). Fixed thusly (the actual handling is then similar to the CTZ [0,0] case). 2024-09-02 Jakub Jelinek PR middle-end/116486 * gimple-range-op.cc (cfn_clz::fold_range): If lh is [0,0] and mini is -1, return [-1,-1] range rather than [prec-1,prec-1]. * gcc.dg/bitint-109.c: New test. Diff: --- gcc/gimple-range-op.cc| 6 -- gcc/testsuite/gcc.dg/bitint-109.c | 25 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index d1c527191f4a..68a7df8d01bc 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -972,8 +972,10 @@ cfn_clz::fold_range (irange &r, tree type, const irange &lh, { // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec, // return [prec, prec] or [-1, -1], otherwise ignore the range. - if (maxi == prec || mini == -1) - mini = maxi; + if (maxi == prec) + mini = prec; + else if (mini == -1) + maxi = -1; } else if (mini >= 0) mini = newmini; diff --git a/gcc/testsuite/gcc.dg/bitint-109.c b/gcc/testsuite/gcc.dg/bitint-109.c new file mode 100644 index ..84c4314cdf9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-109.c @@ -0,0 +1,25 @@ +/* PR middle-end/116486 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-O2 -fno-tree-ccp" } */ + +unsigned u; + +#if __BITINT_MAXWIDTH__ >= 129 +#define N 0x1uwb +#else +#define N 0xuwb +#endif + +int +foo (void) +{ + return __builtin_stdc_first_leading_one (u / N); +} + +int +main () +{ + int x = foo (); + if (x) +__builtin_abort (); +}
[gcc r15-3387] testsuite: Fix optimize_one.c FAIL on i686-linux
https://gcc.gnu.org/g:b64980b0776c8e061696832e74e300e3c720 commit r15-3387-gb64980b0776c8e061696832e74e300e3c720 Author: Jakub Jelinek Date: Mon Sep 2 20:14:49 2024 +0200 testsuite: Fix optimize_one.c FAIL on i686-linux The test FAILs on i686-linux because -mfpmath=sse is used without -msse2 being enabled. 2024-09-02 Jakub Jelinek * gcc.target/i386/optimize_one.c: Add -msse2 to dg-options. Diff: --- gcc/testsuite/gcc.target/i386/optimize_one.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.target/i386/optimize_one.c b/gcc/testsuite/gcc.target/i386/optimize_one.c index 62728d3c5ba4..3a682ed4028f 100644 --- a/gcc/testsuite/gcc.target/i386/optimize_one.c +++ b/gcc/testsuite/gcc.target/i386/optimize_one.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -mfpmath=sse" } */ +/* { dg-options "-O2 -mfpmath=sse -msse2" } */ /* { dg-final { scan-assembler-times "comi" 1 } } */ /* { dg-final { scan-assembler-times "set" 1 } } */
[gcc r15-3408] lower-bitint: Fix up __builtin_{add, sub}_overflow{, _p} bitint lowering [PR116501]
https://gcc.gnu.org/g:d4d75a83007e884bfcd632ea3b3269704496f048 commit r15-3408-gd4d75a83007e884bfcd632ea3b3269704496f048 Author: Jakub Jelinek Date: Tue Sep 3 10:20:44 2024 +0200 lower-bitint: Fix up __builtin_{add,sub}_overflow{,_p} bitint lowering [PR116501] The following testcase is miscompiled. The problem is in the last_ovf step. The second operand has signed _BitInt(513) type but has the MSB clear, so range_to_prec returns 512 for it (i.e. it fits into unsigned _BitInt(512)). Because of that the last step actually doesn't need to get the most significant bit from the second operand, but the code was deciding what to use purely from TYPE_UNSIGNED (type1) - if unsigned, use 0, otherwise sign-extend the last processed bit; but that in this case was set. We don't want to treat the positive operand as if it was negative regardless of the bit below that precision, and precN >= 0 indicates that the operand is in the [0, inf) range. 2024-09-03 Jakub Jelinek PR tree-optimization/116501 * gimple-lower-bitint.cc (bitint_large_huge::lower_addsub_overflow): In the last_ovf case, use build_zero_cst operand not just when TYPE_UNSIGNED (typeN), but also when precN >= 0. * gcc.dg/torture/bitint-73.c: New test. Diff: --- gcc/gimple-lower-bitint.cc | 4 ++-- gcc/testsuite/gcc.dg/torture/bitint-73.c | 20 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index b10593035c36..58deaf253e93 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -4192,7 +4192,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt) else { m_data_cnt = data_cnt; - if (TYPE_UNSIGNED (type0)) + if (TYPE_UNSIGNED (type0) || prec0 >= 0) rhs1 = build_zero_cst (m_limb_type); else { @@ -4210,7 +4210,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt) rhs1 = add_cast (m_limb_type, gimple_assign_lhs (g)); } } - if (TYPE_UNSIGNED (type1)) + if (TYPE_UNSIGNED (type1) || prec1 >= 0) rhs2 = build_zero_cst (m_limb_type); else { diff --git a/gcc/testsuite/gcc.dg/torture/bitint-73.c b/gcc/testsuite/gcc.dg/torture/bitint-73.c new file mode 100644 index ..1e15f3912574 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-73.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/116501 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +_BitInt (4) a; + +int +foo (_BitInt(513) b) +{ + return __builtin_sub_overflow_p (a, b, (_BitInt (511)) 0); +} + +int +main () +{ + if (!foo (0xwb)) +__builtin_abort (); +}
[gcc r15-3476] vrp: Fix up diagnostics wording
https://gcc.gnu.org/g:e9e4777ca2415a73e8db64a406c06a79add621e5 commit r15-3476-ge9e4777ca2415a73e8db64a406c06a79add621e5 Author: Jakub Jelinek Date: Thu Sep 5 11:06:12 2024 +0200 vrp: Fix up diagnostics wording I've noticed non-standard wording of this diagnostics when looking at a miscompilation with --param=vrp-block-limit=0. Diagnostics generally shouldn't start with uppercase letter (unless the upper case would appear also in the middle of a sentence) and shouldn't be separate sentences with dot as separator, ; is IMHO more frequently used. 2024-09-05 Jakub Jelinek * tree-vrp.cc (pass_vrp::execute): Start diagnostics with lowercase u rather than capital U, use semicolon instead of dot. Diff: --- gcc/tree-vrp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc index e184e9af51e..23946c57413 100644 --- a/gcc/tree-vrp.cc +++ b/gcc/tree-vrp.cc @@ -1337,7 +1337,7 @@ public: { use_fvrp = true; warning (OPT_Wdisabled_optimization, - "Using fast VRP algorithm. %d basic blocks" + "using fast VRP algorithm; %d basic blocks" " exceeds %<--param=vrp-block-limit=%d%> limit", n_basic_blocks_for_fn (fun), param_vrp_block_limit);
[gcc r15-3480] libsanitizer: On aarch64 use hint #34 in prologue of libsanitizer functions
https://gcc.gnu.org/g:2379cbb94b2668227c237c94c82e3c49fe39fd0f commit r15-3480-g2379cbb94b2668227c237c94c82e3c49fe39fd0f Author: Jakub Jelinek Date: Thu Sep 5 12:20:57 2024 +0200 libsanitizer: On aarch64 use hint #34 in prologue of libsanitizer functions When gcc is built with -mbranch-protection=standard, running sanitized programs doesn't work properly on bti enabled kernels. This has been fixed upstream with https://github.com/llvm/llvm-project/pull/84061 The following patch cherry picks that from upstream. For trunk we should eventually do a full merge from upstream, but I'm hoping they will first fix up the _BitInt libubsan support mess. 2024-09-05 Jakub Jelinek * sanitizer_common/sanitizer_asm.h: Cherry-pick llvm-project revision 1c792d24e0a228ad49cc004a1c26bbd7cd87f030. * interception/interception.h: Likewise. Diff: --- libsanitizer/interception/interception.h | 4 ++-- libsanitizer/sanitizer_common/sanitizer_asm.h | 14 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h index 58e969378a9..73135b34bee 100644 --- a/libsanitizer/interception/interception.h +++ b/libsanitizer/interception/interception.h @@ -204,11 +204,11 @@ const interpose_substitution substitution_##func_name[] \ ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ASM_TYPE_FUNCTION_STR "\n" \ SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \ - SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \ + C_ASM_STARTPROC "\n" \ C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)), \ "__interceptor_" \ SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n" \ - SANITIZER_STRINGIFY(CFI_ENDPROC) "\n" \ + C_ASM_ENDPROC "\n" \ ".size " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ ); diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h index 3af66a4e449..30e9d15184e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_asm.h +++ b/libsanitizer/sanitizer_common/sanitizer_asm.h @@ -42,6 +42,16 @@ # define CFI_RESTORE(reg) #endif +#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) +# define ASM_STARTPROC CFI_STARTPROC; hint #34 +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34" +#else +# define ASM_STARTPROC CFI_STARTPROC +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) +#endif +#define ASM_ENDPROC CFI_ENDPROC +#define C_ASM_ENDPROC SANITIZER_STRINGIFY(CFI_ENDPROC) + #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__) # define ASM_TAIL_CALL jmp #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ @@ -114,9 +124,9 @@ .globl __interceptor_trampoline_##name; \ ASM_TYPE_FUNCTION(__interceptor_trampoline_##name); \ __interceptor_trampoline_##name: \ - CFI_STARTPROC; \ + ASM_STARTPROC; \ ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name); \ - CFI_ENDPROC; \ + ASM_ENDPROC; \ ASM_SIZE(__interceptor_trampoline_##name) # define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1 # endif // Architecture supports interceptor trampoline
[gcc r14-10644] Don't call clean_symbol_name in create_tmp_var_name [PR116219]
https://gcc.gnu.org/g:6fb41c27b62b5774108455d13f5b7a67c9cbdfa3 commit r14-10644-g6fb41c27b62b5774108455d13f5b7a67c9cbdfa3 Author: Jakub Jelinek Date: Wed Aug 7 20:14:31 2024 +0200 Don't call clean_symbol_name in create_tmp_var_name [PR116219] SRA adds fancy names like offset$D94316$_M_impl$D93629$_M_start where the numbers in there are DECL_UIDs if there are unnamed FIELD_DECLs etc. Because -g0 vs. -g can cause differences between the exact DECL_UID values (add bigger gaps in between them, corresponding decls should still be ordered the same based on DECL_UID) we make sure such decls have DECL_NAMELESS set and depending on exact options either don't dump such names at all or dump_fancy_name sanitizes the D123456$ parts in there to D$. Unfortunately in tons of places we then use get_name to grab either user names or these SRA created names and use that as argument to create_tmp_var{,_name,_raw} to base other artificial temporary names based on that. Those are DECL_NAMELESS too, but unfortunately create_tmp_var_name starting with https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=725494f6e4121eace43b7db1202f8ecbf52a8276 calls clean_symbol_name which replaces the $s in there with _s and thus dump_fancy_name doesn't sanitize it anymore. I don't see any discussion of that commit (originally to TM branch, later merged) on the mailing list, but from DECL_NAME (new_decl) = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (old_decl))); - SET_DECL_ASSEMBLER_NAME (new_decl, NULL_TREE); + SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); snippet elsewhere in that commit it seems create_tmp_var_name was used at that point also to determine function names of clones, so presumably the clean_symbol_name at that point was to ensure the symbol could be emitted into assembly, maybe in case DECL_NAME is something like C++ operators or whatever could have there undesirable characters. Anyway, we don't do that for years anymore, already GCC 4.5 uses for such purposes clone_function_name which starts of DECL_ASSEMBLER_NAME of the old function and appends based on supportable symbol suffix separators the separator and some suffix and/or number, so that part doesn't go through create_tmp_var_name. I don't see problems with having the $ and . etc. characters in the names intended just to make dumps more readable, after all, we already are using those in the SRA created names. Those names shouldn't make it into the assembly in any way, neither debug info nor assembly labels. There is one theoretical case, where the gimplifier promotes automatic vars into TREE_STATIC ones and therefore those can then appear in assembly, just in case it would be on e.g. SRA created names and regimplified later. Because no cases of promotion of DECL_NAMELESS vars to static was observed in {x86_64,i686,powerpc64le}-linux bootstraps/regtests, the code simply uses C.NNN names for DECL_NAMELESS vars like it does for !DECL_NAME vars. Richi mentioned on IRC that the non-cleaned up names might make things harder to feed stuff back to the GIMPLE FE, but if so, I think it should be the dumping for GIMPLE FE purposes that cleans those up (but at that point it should also verify if some such cleaned up names don't collide with others and somehow deal with those). 2024-08-07 Jakub Jelinek PR c++/116219 * gimple-expr.cc (remove_suffix): Formatting fixes. (create_tmp_var_name): Don't call clean_symbol_name. * gimplify.cc (gimplify_init_constructor): When promoting automatic DECL_NAMELESS vars to static, don't preserve their DECL_NAME. (cherry picked from commit 165e3e7c3ba884345647c0f1c9a3a57a03383651) Diff: --- gcc/gimple-expr.cc | 16 ++-- gcc/gimplify.cc| 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc index f8d7185530c..0477c9d5f44 100644 --- a/gcc/gimple-expr.cc +++ b/gcc/gimple-expr.cc @@ -406,14 +406,12 @@ remove_suffix (char *name, int len) { int i; - for (i = 2; i < 7 && len > i; i++) -{ - if (name[len - i] == '.') - { - name[len - i] = '\0'; - break; - } -} + for (i = 2; i < 7 && len > i; i++) +if (name[len - i] == '.') + { + name[len - i] = '\0'; + break; + } } /* Create a new temporary name with PREFIX. Return an identifier. */ @@ -430,8 +428,6 @@ create_tmp_var_name (const char *prefix) char *preftmp = ASTRDUP (prefix); remove_suffix (preftmp, strlen (preftmp)); - clean_symbol_name (preftmp); - prefix = preftmp; } diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 457b33a4293..5753eb90ff5 100644 --- a/gcc/gimplify.cc +++ b
[gcc r14-10645] lower-bitint: Fix up __builtin_{add, sub}_overflow{, _p} bitint lowering [PR116501]
https://gcc.gnu.org/g:73afc3e47e235f3a68abb1c7ce52a9d82003bdab commit r14-10645-g73afc3e47e235f3a68abb1c7ce52a9d82003bdab Author: Jakub Jelinek Date: Tue Sep 3 10:20:44 2024 +0200 lower-bitint: Fix up __builtin_{add,sub}_overflow{,_p} bitint lowering [PR116501] The following testcase is miscompiled. The problem is in the last_ovf step. The second operand has signed _BitInt(513) type but has the MSB clear, so range_to_prec returns 512 for it (i.e. it fits into unsigned _BitInt(512)). Because of that the last step actually doesn't need to get the most significant bit from the second operand, but the code was deciding what to use purely from TYPE_UNSIGNED (type1) - if unsigned, use 0, otherwise sign-extend the last processed bit; but that in this case was set. We don't want to treat the positive operand as if it was negative regardless of the bit below that precision, and precN >= 0 indicates that the operand is in the [0, inf) range. 2024-09-03 Jakub Jelinek PR tree-optimization/116501 * gimple-lower-bitint.cc (bitint_large_huge::lower_addsub_overflow): In the last_ovf case, use build_zero_cst operand not just when TYPE_UNSIGNED (typeN), but also when precN >= 0. * gcc.dg/torture/bitint-73.c: New test. (cherry picked from commit d4d75a83007e884bfcd632ea3b3269704496f048) Diff: --- gcc/gimple-lower-bitint.cc | 4 ++-- gcc/testsuite/gcc.dg/torture/bitint-73.c | 20 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index b10593035c3..58deaf253e9 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -4192,7 +4192,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt) else { m_data_cnt = data_cnt; - if (TYPE_UNSIGNED (type0)) + if (TYPE_UNSIGNED (type0) || prec0 >= 0) rhs1 = build_zero_cst (m_limb_type); else { @@ -4210,7 +4210,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, gimple *stmt) rhs1 = add_cast (m_limb_type, gimple_assign_lhs (g)); } } - if (TYPE_UNSIGNED (type1)) + if (TYPE_UNSIGNED (type1) || prec1 >= 0) rhs2 = build_zero_cst (m_limb_type); else { diff --git a/gcc/testsuite/gcc.dg/torture/bitint-73.c b/gcc/testsuite/gcc.dg/torture/bitint-73.c new file mode 100644 index 000..1e15f391257 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-73.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/116501 */ +/* { dg-do run { target bitint575 } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +_BitInt (4) a; + +int +foo (_BitInt(513) b) +{ + return __builtin_sub_overflow_p (a, b, (_BitInt (511)) 0); +} + +int +main () +{ + if (!foo (0xwb)) +__builtin_abort (); +}
[gcc r14-10646] libsanitizer: On aarch64 use hint #34 in prologue of libsanitizer functions
https://gcc.gnu.org/g:24909512101d59807f6d23a9963d64390eca8f60 commit r14-10646-g24909512101d59807f6d23a9963d64390eca8f60 Author: Jakub Jelinek Date: Thu Sep 5 12:20:57 2024 +0200 libsanitizer: On aarch64 use hint #34 in prologue of libsanitizer functions When gcc is built with -mbranch-protection=standard, running sanitized programs doesn't work properly on bti enabled kernels. This has been fixed upstream with https://github.com/llvm/llvm-project/pull/84061 The following patch cherry picks that from upstream. For trunk we should eventually do a full merge from upstream, but I'm hoping they will first fix up the _BitInt libubsan support mess. 2024-09-05 Jakub Jelinek * sanitizer_common/sanitizer_asm.h: Cherry-pick llvm-project revision 1c792d24e0a228ad49cc004a1c26bbd7cd87f030. * interception/interception.h: Likewise. (cherry picked from commit 2379cbb94b2668227c237c94c82e3c49fe39fd0f) Diff: --- libsanitizer/interception/interception.h | 4 ++-- libsanitizer/sanitizer_common/sanitizer_asm.h | 14 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h index 58e969378a9..73135b34bee 100644 --- a/libsanitizer/interception/interception.h +++ b/libsanitizer/interception/interception.h @@ -204,11 +204,11 @@ const interpose_substitution substitution_##func_name[] \ ".type " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ASM_TYPE_FUNCTION_STR "\n" \ SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n" \ - SANITIZER_STRINGIFY(CFI_STARTPROC) "\n" \ + C_ASM_STARTPROC "\n" \ C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)), \ "__interceptor_" \ SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n" \ - SANITIZER_STRINGIFY(CFI_ENDPROC) "\n" \ + C_ASM_ENDPROC "\n" \ ".size " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", " \ ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n" \ ); diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h index 3af66a4e449..30e9d15184e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_asm.h +++ b/libsanitizer/sanitizer_common/sanitizer_asm.h @@ -42,6 +42,16 @@ # define CFI_RESTORE(reg) #endif +#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT) +# define ASM_STARTPROC CFI_STARTPROC; hint #34 +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) "\nhint #34" +#else +# define ASM_STARTPROC CFI_STARTPROC +# define C_ASM_STARTPROC SANITIZER_STRINGIFY(CFI_STARTPROC) +#endif +#define ASM_ENDPROC CFI_ENDPROC +#define C_ASM_ENDPROC SANITIZER_STRINGIFY(CFI_ENDPROC) + #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__) # define ASM_TAIL_CALL jmp #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ @@ -114,9 +124,9 @@ .globl __interceptor_trampoline_##name; \ ASM_TYPE_FUNCTION(__interceptor_trampoline_##name); \ __interceptor_trampoline_##name: \ - CFI_STARTPROC; \ + ASM_STARTPROC; \ ASM_TAIL_CALL ASM_PREEMPTIBLE_SYM(__interceptor_##name); \ - CFI_ENDPROC; \ + ASM_ENDPROC; \ ASM_SIZE(__interceptor_trampoline_##name) # define ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT 1 # endif // Architecture supports interceptor trampoline
[gcc r15-3513] c++: Partially implement CWG 2867 - Order of initialization for structured bindings [PR115769]
https://gcc.gnu.org/g:964577c31df206d780d5cc7bc07189d44de2719e commit r15-3513-g964577c31df206d780d5cc7bc07189d44de2719e Author: Jakub Jelinek Date: Fri Sep 6 13:50:47 2024 +0200 c++: Partially implement CWG 2867 - Order of initialization for structured bindings [PR115769] The following patch partially implements CWG 2867 - Order of initialization for structured bindings. The DR requires that initialization of e is sequenced before r_i and that r_i initialization is sequenced before r_j for j > i, we already do it that way, the former ordering is a necessity so that the get calls are actually emitted on already initialized variable, the rest just because we implemented it that way, by going through the structured binding vars in ascending order and doing their initialization. The hard part not implemented yet is the lifetime extension of the temporaries from the e initialization to after the get calls (if any). Unlike the range-for lifetime extension patch which I've posted recently where IMO we can just ignore lifetime extension of reference bound temporaries because all the temporaries are extended to the same spot, here lifetime extension of reference bound temporaries should last until the end of lifetime of e, while other temporaries only after all the get calls. The patch just attempts to deal with automatic structured bindings for now, I'll post a patch for static locals incrementally and I don't have a patch for namespace scope structured bindings yet, this patch should just keep existing behavior for both static locals and namespace scope structured bindings. What GCC currently emits is a CLEANUP_POINT_EXPR around the e initialization, followed optionally by nested CLEANUP_STMTs for cleanups like the e dtor if any and dtors of lifetime extended temporaries from reference binding; inside of the CLEANUP_STMT CLEANUP_BODY then the initialization of the individual variables for the tuple case, again with optional CLEANUP_STMT if e.g. lifetime extended temporaries from reference binding are needed in those. The following patch drops that first CLEANUP_POINT_EXPR and instead wraps the whole sequence of the e initialization and the individual variable initialization with get calls after it into a single CLEANUP_POINT_EXPR. If there are any CLEANUP_STMTs needed, they are all emitted first, with the CLEANUP_POINT_EXPR for e initialization and the individual variable initialization inside of those, and a guard variable set after different phases in those expressions guarding the corresponding cleanups, so that they aren't invoked until the respective variables are constructed. This is implemented by cp_finish_decl doing cp_finish_decomp on its own when !processing_template_decl (otherwise we often don't cp_finish_decl or process it at a different time from when we want to call cp_finish_decomp) or unless the decl is erroneous (cp_finish_decl has too many early returns for erroneous cases, and for those we can actually call it even multiple times, for the non-erroneous cases non-processing_template_decl cases we need to call it just once). The two testcases try to construct various temporaries and variables and verify the order in which the temporaries and variables are constructed and destructed. 2024-09-06 Jakub Jelinek PR c++/115769 * cp-tree.h: Partially implement CWG 2867 - Order of initialization for structured bindings. (cp_finish_decomp): Add TEST_P argument defaulted to false. * decl.cc (initialize_local_var): Add DECOMP argument, if true, don't build cleanup and temporarily override stmts_are_full_exprs_p to 0 rather than 1. Formatting fix. (cp_finish_decl): Invoke cp_finish_decomp for structured bindings here, first with test_p. For automatic structured binding bases if the test cp_finish_decomp returned true wrap the initialization together with what non-test cp_finish_decomp emits with a CLEANUP_POINT_EXPR, and if there are any CLEANUP_STMTs needed, emit them around the whole CLEANUP_POINT_EXPR with guard variables for the cleanups. Call cp_finish_decomp using RAII if not called with decomp != NULL otherwise. (cp_finish_decomp): Add TEST_P argument, change return type from void to bool, if TEST_P is true, return true instead of emitting actual code for the tuple case, otherwise return false. * parser.cc (cp_convert_range_for): Don't call cp_finish_decomp after cp_finish_decl. (cp_parser_decomposition_declaration): Set DECL_DECOMP_BASE before cp_finish_decl call. Don't call cp_finish_decomp after
[gcc r15-3525] libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
https://gcc.gnu.org/g:bb8dd0980b39cfd601f88703fd356055727ef24d commit r15-3525-gbb8dd0980b39cfd601f88703fd356055727ef24d Author: Jakub Jelinek Date: Sat Sep 7 09:36:53 2024 +0200 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614] cat abc.C #define A(n) struct T##n {} t##n; #define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) #define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) #define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n##5) C(n##6) C(n##7) C(n##8) C(n##9) #define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n##5) D(n##6) D(n##7) D(n##8) D(n##9) E(1) E(2) E(3) int main () { return 0; } ./xg++ -B ./ -o abc{.o,.C} -flto -flto-partition=1to1 -O2 -g -fdebug-types-section -c ./xgcc -B ./ -o abc{,.o} -flto -flto-partition=1to1 -O2 (not included in testsuite as it takes a while to compile) FAILs with lto-wrapper: fatal error: Too many copied sections: Operation not supported compilation terminated. /usr/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status The following patch fixes that. Most of the 64K+ section support for reading and writing was already there years ago (and especially reading used quite often already) and a further bug fixed in it in the PR104617 fix. Yet, the fix isn't solely about removing the if (new_i - 1 >= SHN_LORESERVE) { *err = ENOTSUP; return "Too many copied sections"; } 5 lines, the missing part was that the function only handled reading of the .symtab_shndx section but not copying/updating of it. If the result has less than 64K-epsilon sections, that actually wasn't needed, but e.g. with -fdebug-types-section one can exceed that pretty easily (reported to us on WebKitGtk build on ppc64le). Updating the section is slightly more complicated, because it basically needs to be done in lock step with updating the .symtab section, if one doesn't need to use SHN_XINDEX in there, the section should (or should be updated to) contain SHN_UNDEF entry, otherwise needs to have whatever would be overwise stored but couldn't fit. But repeating due to that all the symtab decisions what to discard and how to rewrite it would be ugly. So, the patch instead emits the .symtab_shndx section (or sections) last and prepares the content during the .symtab processing and in a second pass when going just through .symtab_shndx sections just uses the saved content. 2024-09-07 Jakub Jelinek PR lto/116614 * simple-object-elf.c (SHN_COMMON): Align comment with neighbouring comments. (SHN_HIRESERVE): Use uppercase hex digits instead of lowercase for consistency. (simple_object_elf_find_sections): Formatting fixes. (simple_object_elf_fetch_attributes): Likewise. (simple_object_elf_attributes_merge): Likewise. (simple_object_elf_start_write): Likewise. (simple_object_elf_write_ehdr): Likewise. (simple_object_elf_write_shdr): Likewise. (simple_object_elf_write_to_file): Likewise. (simple_object_elf_copy_lto_debug_section): Likewise. Don't fail for new_i - 1 >= SHN_LORESERVE, instead arrange in that case to copy over .symtab_shndx sections, though emit those last and compute their section content when processing associated .symtab sections. Handle simple_object_internal_read failure even in the .symtab_shndx reading case. Diff: --- libiberty/simple-object-elf.c | 210 -- 1 file changed, 143 insertions(+), 67 deletions(-) diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index c09c216656c2..5e95297b2fc1 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -128,9 +128,9 @@ typedef struct { #define SHN_UNDEF 0 /* Undefined section */ #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ -#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ +#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ #define SHN_XINDEX 0x /* Section index is held elsewhere */ -#define SHN_HIRESERVE 0x /* End of reserved indices */ +#define SHN_HIRESERVE 0x /* End of reserved indices */ /* 32-bit ELF program header. */ @@ -569,8 +569,8 @@ simple_object_elf_find_sections (simple_object_read *sobj, void *data, int *err) { - struct simple_object_elf_read *eor = -(struct simple_object_elf_read *) sobj->data; + struct simple_object_elf
[gcc r15-3542] testsuite: Fix up pr116588.c test [PR116588]
https://gcc.gnu.org/g:765875e2c18b8f4c346b754a19e287efaec531a5 commit r15-3542-g765875e2c18b8f4c346b754a19e287efaec531a5 Author: Jakub Jelinek Date: Mon Sep 9 09:37:26 2024 +0200 testsuite: Fix up pr116588.c test [PR116588] The test as committed without the tree-vrp.cc change only FAILs with FAIL: gcc.dg/pr116588.c scan-tree-dump-not vrp2 "0 != 0" The DEBUG code in there was just to make it easier to debug, but doesn't actually fail when the test is miscompiled. We don't need such debugging code in simple tests like that, but it is useful if they abort when miscompiled. With this patch without the tree-vrp.cc change I see FAIL: gcc.dg/pr116588.c execution test FAIL: gcc.dg/pr116588.c scan-tree-dump-not vrp2 "0 != 0" and with it it passes. 2024-09-09 Jakub Jelinek PR tree-optimization/116588 * gcc.dg/pr116588.c: Remove -DDEBUG from dg-options. (main): Remove debugging code and simplify. Diff: --- gcc/testsuite/gcc.dg/pr116588.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr116588.c b/gcc/testsuite/gcc.dg/pr116588.c index 6b0678d465ed..481772a54e15 100644 --- a/gcc/testsuite/gcc.dg/pr116588.c +++ b/gcc/testsuite/gcc.dg/pr116588.c @@ -1,7 +1,7 @@ /* PR tree-optimization/116588 */ /* { dg-do run { target bitint575 } } */ /* { dg-require-effective-target int128 } */ -/* { dg-options "-O2 -fno-vect-cost-model -fno-tree-dominator-opts -fno-tree-fre --param=vrp-block-limit=0 -DDEBUG -fdump-tree-vrp2-details" } */ +/* { dg-options "-O2 -fno-vect-cost-model -fno-tree-dominator-opts -fno-tree-fre --param=vrp-block-limit=0 -fdump-tree-vrp2-details" } */ int a; __int128 b, c; @@ -18,15 +18,8 @@ foo (_BitInt (129) e) int main () { - __int128 x = foo (0); -#ifdef DEBUG - for (unsigned i = 0; i < sizeof (x); i++) -__builtin_printf ("%02x", i[(volatile unsigned char *) &x]); - __builtin_printf("\n"); -#else - if (x) -__builtin_abort(); -#endif + if (foo (0)) +__builtin_abort (); } /* { dg-final { scan-tree-dump-not "0 != 0" "vrp2" } } */
[gcc r15-3574] c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449]
https://gcc.gnu.org/g:0008050b9d6046ba4e811a03b406fb5d98707cae commit r15-3574-g0008050b9d6046ba4e811a03b406fb5d98707cae Author: Jakub Jelinek Date: Tue Sep 10 18:32:58 2024 +0200 c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449] The following testcase is miscompiled, because get_member_function_from_ptrfunc emits something like (((FUNCTION.__pfn & 1) != 0) ? ptr + FUNCTION.__delta + FUNCTION.__pfn - 1 : FUNCTION.__pfn) (ptr + FUNCTION.__delta, ...) or so, so FUNCTION tree is used there 5 times. There is if (TREE_SIDE_EFFECTS (function)) function = save_expr (function); but in this case function doesn't have side-effects, just nested ARRAY_REFs. Now, if all the FUNCTION trees would be shared, it would work fine, FUNCTION is evaluated in the first operand of COND_EXPR; but unfortunately that isn't the case, both the BIT_AND_EXPR shortening and conversion to bool done for build_conditional_expr actually unshare_expr that first expression, but none of the other 4 are unshared. With -fsanitize=bounds, .UBSAN_BOUNDS calls are added to the ARRAY_REFs and use save_expr to avoid evaluating the argument multiple times, but because that FUNCTION tree is first used in the second argument of COND_EXPR (i.e. conditionally), the SAVE_EXPR initialization is done just there and then the third argument of COND_EXPR just uses the uninitialized temporary and so does the first argument computation as well. The following patch fixes that by doing save_expr even if !TREE_SIDE_EFFECTS, but to avoid doing that too often only if !nonvirtual and if the expression isn't a simple decl. 2024-09-10 Jakub Jelinek PR c++/116449 * typeck.cc (get_member_function_from_ptrfunc): Use save_expr on instance_ptr and function even if it doesn't have side-effects, as long as it isn't a decl. * g++.dg/ubsan/pr116449.C: New test. Diff: --- gcc/cp/typeck.cc | 19 --- gcc/testsuite/g++.dg/ubsan/pr116449.C | 14 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index e4e260645f65..b6835286cff3 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -4193,10 +4193,23 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, if (!nonvirtual && is_dummy_object (instance_ptr)) nonvirtual = true; - if (TREE_SIDE_EFFECTS (instance_ptr)) - instance_ptr = instance_save_expr = save_expr (instance_ptr); + /* Use save_expr even when instance_ptr doesn't have side-effects, +unless it is a simple decl (save_expr won't do anything on +constants), so that we don't ubsan instrument the expression +multiple times. See PR116449. */ + if (TREE_SIDE_EFFECTS (instance_ptr) + || (!nonvirtual && !DECL_P (instance_ptr))) + { + instance_save_expr = save_expr (instance_ptr); + if (instance_save_expr == instance_ptr) + instance_save_expr = NULL_TREE; + else + instance_ptr = instance_save_expr; + } - if (TREE_SIDE_EFFECTS (function)) + /* See above comment. */ + if (TREE_SIDE_EFFECTS (function) + || (!nonvirtual && !DECL_P (function))) function = save_expr (function); /* Start by extracting all the information from the PMF itself. */ diff --git a/gcc/testsuite/g++.dg/ubsan/pr116449.C b/gcc/testsuite/g++.dg/ubsan/pr116449.C new file mode 100644 index ..f13368a51b00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr116449.C @@ -0,0 +1,14 @@ +// PR c++/116449 +// { dg-do compile } +// { dg-options "-O2 -Wall -fsanitize=undefined" } + +struct C { void foo (int); void bar (); int c[16]; }; +typedef void (C::*P) (); +struct D { P d; }; +static D e[1] = { { &C::bar } }; + +void +C::foo (int x) +{ + (this->*e[c[x]].d) (); +}
[gcc r15-3599] libcpp, c-family: Add (dumb) C23 N3017 #embed support [PR105863]
https://gcc.gnu.org/g:eba6d2aa71a9b59386e5a2453cbe924371626b0b commit r15-3599-geba6d2aa71a9b59386e5a2453cbe924371626b0b Author: Jakub Jelinek Date: Thu Sep 12 11:15:38 2024 +0200 libcpp, c-family: Add (dumb) C23 N3017 #embed support [PR105863] The following patch implements the C23 N3017 "#embed - a scannable, tooling-friendly binary resource inclusion mechanism" paper. The implementation is intentionally dumb, in that it doesn't significantly speed up compilation of larger initializers and doesn't make it possible to use huge #embeds (like several gigabytes large, that is compile time and memory still infeasible). There are 2 reasons for this. One is that I think like it is implemented now in the patch is how we should use it for the smaller #embed sizes, dunno with which boundary, whether 32 bytes or 64 or something like that, certainly handling the single byte cases which is something that can appear anywhere in the source where constant integer literal can appear is desirable and I think for a few bytes it isn't worth it to come up with something smarter and users would like to e.g. see it in -E readably as well (perhaps the slow vs. fast boundary should be determined by command line option). And the other one is to be able to more easily find regressions in behavior caused by the optimizations, so we have something to get back in git to compare against. I'm definitely willing to work on the optimizations (likely introduce a new CPP_* token type to refer to a range of libcpp owned memory (start + size) and similarly some tree which can do the same, and can be at any time e.g. split into 2 subparts + say INTEGER_CST in between if needed say for const unsigned char d[] = { #embed "2GB.dat" prefix (0, 0, ) suffix (, [0x4000] = 42) }; still without having to copy around huge amounts of data; STRING_CST owns the memory it points to and can be only 2GB in size), but would like to do that incrementally. And would like to first include some extensions also not included in this patch, like gnu::offset (off) parameter to allow to skip certain constant amount of bytes at the start of the files, plus gnu::base64 ("base64_encoded_data") parameter to add something which can store more efficiently large amounts of the #embed data in preprocessed source. I've been cross-checking all the tests also against the LLVM implementation https://github.com/llvm/llvm-project/pull/68620 which has been for a few hours even committed to LLVM trunk but reverted afterwards. LLVM now has the support committed and I admit I haven't rechecked whether the behavior on the below mentioned spots have been fixed in it already or not yet. The patch uses --embed-dir= option that clang plans to add above and doesn't use other variants on the search directories yet, plus there are no default directories at least for the time being where to search for embed files. So, #embed "..." works if it is found in the same directory (or relative to the current file's directory) and #embed "/..." or #embed work always, but relative #embed <...> doesn't unless at least one --embed-dir= is specified. There is no reason to differentiate between system and non-system directories, so we don't need -isystem like counterpart, perhaps -iquote like counterpart could be useful in the future, dunno what else. It has --embed-directory=dir and --embed-directory dir as aliases. There are some differences beyond clang ICEs, so I'd like to point them out to make sure there is agreement on the choices in the patch. They are also mentioned in the comments of the llvm pull request. The most important is that the GCC patch (as well as the original thephd.dev LLVM branch on godbolt) expands #embed (or acts as if it is expanded) into a mere sequence of numbers like 123,2,35,26 rather then what clang effectively treats as (unsigned char)123,(unsigned char)2,(unsigned char)35,(unsigned char)26 but only does that when using integrated preprocessor, not when using -save-temps where it acts as GCC. JeanHeyd as the original author agrees that is how it is currently worded in C23. Another difference (not tested in the testsuite, not sure how to check for effective target /dev/urandom nor am sure it is desirable to check that during testsuite) is how to treat character devices, named pipes etc. (block devices are errored on). The original paper uses /dev/urandom in various examples and seems to assume that unlike regular files the devices aren't really cached, so #embed limit(1) prefix(int a = ) suffix(;) #embed limit(1) prefix(int b = ) suffix(;) usually results in a != b. That is what the godbolt thephd.dev branch implements too and what this pat
[gcc r15-3600] libcpp: Add support for gnu::offset #embed/__has_embed parameter
https://gcc.gnu.org/g:44058b847145166715f15e49fa8854f30e852f24 commit r15-3600-g44058b847145166715f15e49fa8854f30e852f24 Author: Jakub Jelinek Date: Thu Sep 12 11:34:06 2024 +0200 libcpp: Add support for gnu::offset #embed/__has_embed parameter The following patch adds on top of the just posted #embed patch a first extension, gnu::offset which allows to seek in the data file (for seekable files, otherwise read and throw away). I think this is useful e.g. when some binary data start with some well known header which shouldn't be included in the data etc. 2024-09-12 Jakub Jelinek libcpp/ * internal.h (struct cpp_embed_params): Add offset member. * directives.cc (EMBED_PARAMS): Add gnu::offset entry. (enum embed_param_kind): Add NUM_EMBED_STD_PARAMS. (_cpp_parse_embed_params): Use NUM_EMBED_STD_PARAMS rather than NUM_EMBED_PARAMS when parsing standard parameters. Parse gnu::offset parameter. * files.cc (struct _cpp_file): Add offset member. (_cpp_stack_embed): Handle params->offset. gcc/ * doc/cpp.texi (Binary Resource Inclusion): Document gnu::offset #embed parameter. gcc/testsuite/ * c-c++-common/cpp/embed-15.c: New test. * c-c++-common/cpp/embed-16.c: New test. * gcc.dg/cpp/embed-5.c: New test. Diff: --- gcc/doc/cpp.texi | 8 ++- gcc/testsuite/c-c++-common/cpp/embed-15.c | 88 gcc/testsuite/c-c++-common/cpp/embed-16.c | 31 ++ gcc/testsuite/gcc.dg/cpp/embed-5.c| 4 ++ libcpp/directives.cc | 40 ++--- libcpp/files.cc | 95 ++- libcpp/internal.h | 2 +- 7 files changed, 244 insertions(+), 24 deletions(-) diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 032b095602d5..612d97e16df8 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -3966,8 +3966,8 @@ treated the same), followed by parameter argument in parentheses, like with currently supported standard parameters @code{limit}, @code{prefix}, @code{suffix} and @code{if_empty}, or implementation defined parameters specified by a unique vendor prefix followed by @code{::} followed by -name of the parameter. GCC will use the @code{gnu} prefix but currently -doesn't support any extensions. +name of the parameter. GCC uses the @code{gnu} prefix for vendor +parameters and currently supports the @code{gnu::offset} parameter. The @code{limit} parameter argument is a constant expression which specifies the maximum number of bytes included by the directive, @@ -3977,6 +3977,10 @@ that sequence is not empty and @code{if_empty} argument is balanced token sequence which is used as expansion for @code{#embed} directive if the resource is empty. +The @code{gnu::offset} parameter argument is a constant expression +which specifies how many bytes to skip from the start of the resource. +@code{limit} is then counted from that position. + The @code{#embed} directive is not supported in the Traditional Mode (@pxref{Traditional Mode}). diff --git a/gcc/testsuite/c-c++-common/cpp/embed-15.c b/gcc/testsuite/c-c++-common/cpp/embed-15.c new file mode 100644 index ..c12aeb31db53 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/embed-15.c @@ -0,0 +1,88 @@ +/* { dg-do run } */ +/* { dg-options "--embed-dir=${srcdir}/c-c++-common/cpp/embed-dir" } */ +/* { dg-additional-options "-std=gnu99" { target c } } */ + +#if __has_embed (__FILE__ gnu::offset (4 + FOOBAR) limit (3)) != __STDC_EMBED_FOUND__ +#error "__has_embed fail" +#endif + +#embed limit(1) gnu::offset (0) prefix(int a = ) suffix (;) +#embed limit(1) __gnu__::offset (1 * 1) prefix(int b = ) suffix (;) +#embed limit(1) gnu::__offset__ (1 + 1) prefix(int c = ) suffix (;) +#embed __limit__(1) __gnu__::__offset__ (1 + (1 \ + + 1)) __prefix__(int d = ) __suffix__ (;) +const unsigned char e[] = { + #embed limit(5) gnu::offset (999) +}; +const unsigned char f[] = { + #embed limit(7) gnu::offset (998) +}; +const unsigned char g[] = { + #embed limit(8) gnu::offset (998) +}; +const unsigned char h[] = { + #embed limit(8) gnu::offset (997) +}; +const unsigned char i[] = { + #embed limit(9) gnu::offset (997) +}; +const unsigned char j[] = { + #embed limit(30) gnu::offset (990) +}; +const unsigned char k[] = { + #embed limit(26) gnu::offset (992) +}; +const unsigned char l[] = { + #embed +}; +const unsigned char m[] = { + #embed __limit__ (1000) __gnu__::__offset__ (32) +}; +#if __has_embed ( limit(5) gnu::offset (999)) != __STDC_EMBED_FOUND__ \ +|| __has_embed ( limit(5) gnu::offset (999)) != __STDC_EMBED_FOUND__ \ +|| __has_embed ( limit(7) gnu::offset (998)) != __STDC_EMBED_FOUND__ \ +|| __has_embed ( limit(8) gnu::offset (998)) != __STDC_EMBED_FOUND__ \ +
[gcc r15-3609] libcpp, v2: Add support for gnu::base64 #embed parameter
https://gcc.gnu.org/g:ce0aecc7df1ff0be24c278dff5575ec28042ee58 commit r15-3609-gce0aecc7df1ff0be24c278dff5575ec28042ee58 Author: Jakub Jelinek Date: Thu Sep 12 18:17:05 2024 +0200 libcpp, v2: Add support for gnu::base64 #embed parameter This patch which adds another #embed extension, gnu::base64. As mentioned in the documentation, this extension is primarily intended for use by the preprocessor, so that for the larger (say 32+ or 64+ bytes long embeds it doesn't have to emit tens of thousands or millions of comma separated string literals which would be very expensive to parse again, but can emit #embed "." __gnu__::__base64__( \ "Tm9uIGVyYW0gbsOpc2NpdXMsIEJydXRlLCBjdW0sIHF1w6Ygc3VtbWlzIGluZ8OpbmlpcyBleHF1" \ "aXNpdMOhcXVlIGRvY3Ryw61uYSBwaGlsw7Nzb3BoaSBHcsOmY28gc2VybcOzbmUgdHJhY3RhdsOt" \ "c3NlbnQsIGVhIExhdMOtbmlzIGzDrXR0ZXJpcyBtYW5kYXLDqW11cywgZm9yZSB1dCBoaWMgbm9z" \ "dGVyIGxhYm9yIGluIHbDoXJpYXMgcmVwcmVoZW5zacOzbmVzIGluY8O6cnJlcmV0LiBuYW0gcXVp" \ "YsO6c2RhbSwgZXQgaWlzIHF1aWRlbSBub24gw6FkbW9kdW0gaW5kw7NjdGlzLCB0b3R1bSBob2Mg" \ "ZMOtc3BsaWNldCBwaGlsb3NvcGjDoXJpLiBxdWlkYW0gYXV0ZW0gbm9uIHRhbSBpZCByZXByZWjD" \ "qW5kdW50LCBzaSByZW3DrXNzaXVzIGFnw6F0dXIsIHNlZCB0YW50dW0gc3TDumRpdW0gdGFtcXVl" \ "IG11bHRhbSDDs3BlcmFtIHBvbsOpbmRhbSBpbiBlbyBub24gYXJiaXRyw6FudHVyLiBlcnVudCDD" \ "qXRpYW0sIGV0IGlpIHF1aWRlbSBlcnVkw610aSBHcsOmY2lzIGzDrXR0ZXJpcywgY29udGVtbsOp" \ "bnRlcyBMYXTDrW5hcywgcXVpIHNlIGRpY2FudCBpbiBHcsOmY2lzIGxlZ8OpbmRpcyDDs3BlcmFt" \ "IG1hbGxlIGNvbnPDum1lcmUuIHBvc3Ryw6ltbyDDoWxpcXVvcyBmdXTDunJvcyBzw7pzcGljb3Is" \ "IHF1aSBtZSBhZCDDoWxpYXMgbMOtdHRlcmFzIHZvY2VudCwgZ2VudXMgaG9jIHNjcmliw6luZGks" \ "IGV0c2kgc2l0IGVsw6lnYW5zLCBwZXJzw7Nuw6YgdGFtZW4gZXQgZGlnbml0w6F0aXMgZXNzZSBu" \ "ZWdlbnQu") with the meaning don't actually load some file, instead base64 decode (RFC4648 with A-Za-z0-9+/ chars and = padding, no newlines in between) the string and use that as data. This is chosen because it should be -pedantic-errors clean, fairly cheap to decode and then in optimizing compiler could be handled as similar binary blob to normal #embed, while the data isn't left somewhere on the disk, so distcc/ccache etc. can move the preprocessed source without issues. It makes no sense to support limit and gnu::offset parameters together with it IMHO, why would somebody waste providing full data and then threw some away? prefix/suffix/if_empty are normally supported though, but not intended to be used by the preprocessor. This patch adds just the extension side, not the actual emitting of this during -E or -E -fdirectives-only for now, that will be included in the upcoming patch. Compared to the earlier posted version of this extension, this patch allows the string concatenation in the parameter argument (but still doesn't allow escapes in the string, why would anyone use them when only A-Za-z0-9+/= are valid). The patch also adds support for parsing this even in -fpreprocessed compilation. 2024-09-12 Jakub Jelinek libcpp/ * internal.h (struct cpp_embed_params): Add base64 member. (_cpp_free_embed_params_tokens): Declare. * directives.cc (DIRECTIVE_TABLE): Add IN_I flag to T_EMBED. (save_token_for_embed, _cpp_free_embed_params_tokens): New functions. (EMBED_PARAMS): Add gnu::base64 entry. (_cpp_parse_embed_params): Parse gnu::base64 parameter. If -fpreprocessed without -fdirectives-only, require #embed to have gnu::base64 parameter. Diagnose conflict between gnu::base64 and limit or gnu::offset parameters. (do_embed): Use _cpp_free_embed_params_tokens. * files.cc (finish_embed, base64_dec_fn): New functions. (base64_dec): New array. (B64D0, B64D1, B64D2, B64D3): Define. (finish_base64_embed): New function. (_cpp_stack_embed): Use finish_embed. Handle params->base64 using finish_base64_embed. * macro.cc (builtin_has_embed): Call _cpp_free_embed_params_tokens. gcc/ * doc/cpp.texi (Binary Resource Inclusion): Document gnu::base64 parameter. gcc/testsuite/ * c-c++-common/cpp/embed-17.c: New test. * c-c++-common/cpp/embed-18.c: New test. * c-c++-common/cpp/embed-19.c: New test. * c-c++-common/cpp/embed-27.c: New test. * gcc.dg/cpp/embed-6.c: New test. * gcc.dg/cpp/embed-7.c: New test. Diff: --- gcc/doc/cpp.texi | 14 +- gcc/testsuite/c-c++-common/cpp/embed-17.c | 116 gcc/testsuite/c-c++-common/cpp/embed-18.c | 54 gcc/testsuite/c-c++-common/cpp/embed-19.c | 5 + gcc/testsuite/c-c++-common/cpp/embed-27.c | 64 + gcc/testsuite/gcc.dg/cpp/embed-6.c|
[gcc r15-3610] c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attribute
https://gcc.gnu.org/g:4026d89d623e322920b052f7ac0d940ef267dc0f commit r15-3610-g4026d89d623e322920b052f7ac0d940ef267dc0f Author: Jakub Jelinek Date: Thu Sep 12 18:22:21 2024 +0200 c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attributes [PR116636] On the following testcase, we emit false positive warnings/errors about using the deprecated or unavailable methods when creating thunks for them, even when nothing (in the testcase so far) actually used those. The following patch temporarily disables that diagnostics when creating the thunks. 2024-09-12 Jakub Jelinek PR c++/116636 * method.cc: Include decl.h. (use_thunk): Temporarily change deprecated_state to UNAVAILABLE_DEPRECATED_SUPPRESS. * g++.dg/warn/deprecated-19.C: New test. Diff: --- gcc/cp/method.cc | 6 ++ gcc/testsuite/g++.dg/warn/deprecated-19.C | 22 ++ 2 files changed, 28 insertions(+) diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 68a776d2c5a6..21c06c744c9a 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "cp-tree.h" +#include "decl.h" #include "stringpool.h" #include "cgraph.h" #include "varasm.h" @@ -283,6 +284,11 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Thunks are always addressable; they only appear in vtables. */ TREE_ADDRESSABLE (thunk_fndecl) = 1; + /* Don't diagnose deprecated or unavailable functions just because they + have thunks emitted for them. */ + auto du = make_temp_override (deprecated_state, +UNAVAILABLE_DEPRECATED_SUPPRESS); + /* Figure out what function is being thunked to. It's referenced in this translation unit. */ TREE_ADDRESSABLE (function) = 1; diff --git a/gcc/testsuite/g++.dg/warn/deprecated-19.C b/gcc/testsuite/g++.dg/warn/deprecated-19.C new file mode 100644 index ..561f1241e005 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/deprecated-19.C @@ -0,0 +1,22 @@ +// PR c++/116636 +// { dg-do compile } +// { dg-options "-pedantic -Wdeprecated" } + +struct A { + virtual int foo () = 0; +}; +struct B : virtual A { + [[deprecated]] int foo () { return 0; } // { dg-message "declared here" } +}; // { dg-warning "C\\\+\\\+11 attributes only available with" "" { target c++98_only } .-1 } +struct C : virtual A { + [[gnu::unavailable]] int foo () { return 0; }// { dg-message "declared here" } +}; // { dg-warning "C\\\+\\\+11 attributes only available with" "" { target c++98_only } .-1 } + +void +bar () +{ + B b; + b.foo ();// { dg-warning "'virtual int B::foo\\\(\\\)' is deprecated" } + C c; + c.foo ();// { dg-error "'virtual int C::foo\\\(\\\)' is unavailable" } +}
[gcc r14-10665] libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
https://gcc.gnu.org/g:c9fd43a8df0e30109794e2480e2d8d05d00763c0 commit r14-10665-gc9fd43a8df0e30109794e2480e2d8d05d00763c0 Author: Jakub Jelinek Date: Sat Sep 7 09:36:53 2024 +0200 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614] cat abc.C #define A(n) struct T##n {} t##n; #define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) #define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) #define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n##5) C(n##6) C(n##7) C(n##8) C(n##9) #define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n##5) D(n##6) D(n##7) D(n##8) D(n##9) E(1) E(2) E(3) int main () { return 0; } ./xg++ -B ./ -o abc{.o,.C} -flto -flto-partition=1to1 -O2 -g -fdebug-types-section -c ./xgcc -B ./ -o abc{,.o} -flto -flto-partition=1to1 -O2 (not included in testsuite as it takes a while to compile) FAILs with lto-wrapper: fatal error: Too many copied sections: Operation not supported compilation terminated. /usr/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status The following patch fixes that. Most of the 64K+ section support for reading and writing was already there years ago (and especially reading used quite often already) and a further bug fixed in it in the PR104617 fix. Yet, the fix isn't solely about removing the if (new_i - 1 >= SHN_LORESERVE) { *err = ENOTSUP; return "Too many copied sections"; } 5 lines, the missing part was that the function only handled reading of the .symtab_shndx section but not copying/updating of it. If the result has less than 64K-epsilon sections, that actually wasn't needed, but e.g. with -fdebug-types-section one can exceed that pretty easily (reported to us on WebKitGtk build on ppc64le). Updating the section is slightly more complicated, because it basically needs to be done in lock step with updating the .symtab section, if one doesn't need to use SHN_XINDEX in there, the section should (or should be updated to) contain SHN_UNDEF entry, otherwise needs to have whatever would be overwise stored but couldn't fit. But repeating due to that all the symtab decisions what to discard and how to rewrite it would be ugly. So, the patch instead emits the .symtab_shndx section (or sections) last and prepares the content during the .symtab processing and in a second pass when going just through .symtab_shndx sections just uses the saved content. 2024-09-07 Jakub Jelinek PR lto/116614 * simple-object-elf.c (SHN_COMMON): Align comment with neighbouring comments. (SHN_HIRESERVE): Use uppercase hex digits instead of lowercase for consistency. (simple_object_elf_find_sections): Formatting fixes. (simple_object_elf_fetch_attributes): Likewise. (simple_object_elf_attributes_merge): Likewise. (simple_object_elf_start_write): Likewise. (simple_object_elf_write_ehdr): Likewise. (simple_object_elf_write_shdr): Likewise. (simple_object_elf_write_to_file): Likewise. (simple_object_elf_copy_lto_debug_section): Likewise. Don't fail for new_i - 1 >= SHN_LORESERVE, instead arrange in that case to copy over .symtab_shndx sections, though emit those last and compute their section content when processing associated .symtab sections. Handle simple_object_internal_read failure even in the .symtab_shndx reading case. (cherry picked from commit bb8dd0980b39cfd601f88703fd356055727ef24d) Diff: --- libiberty/simple-object-elf.c | 210 -- 1 file changed, 143 insertions(+), 67 deletions(-) diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index c09c216656c2..5e95297b2fc1 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -128,9 +128,9 @@ typedef struct { #define SHN_UNDEF 0 /* Undefined section */ #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ -#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ +#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ #define SHN_XINDEX 0x /* Section index is held elsewhere */ -#define SHN_HIRESERVE 0x /* End of reserved indices */ +#define SHN_HIRESERVE 0x /* End of reserved indices */ /* 32-bit ELF program header. */ @@ -569,8 +569,8 @@ simple_object_elf_find_sections (simple_object_read *sobj, void *data, int *err) { - struct simple_object_elf_read *eor =
[gcc r14-10666] c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449]
https://gcc.gnu.org/g:90a9c36dc3ba341cf662ba1d60c939027487fe9a commit r14-10666-g90a9c36dc3ba341cf662ba1d60c939027487fe9a Author: Jakub Jelinek Date: Tue Sep 10 18:32:58 2024 +0200 c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449] The following testcase is miscompiled, because get_member_function_from_ptrfunc emits something like (((FUNCTION.__pfn & 1) != 0) ? ptr + FUNCTION.__delta + FUNCTION.__pfn - 1 : FUNCTION.__pfn) (ptr + FUNCTION.__delta, ...) or so, so FUNCTION tree is used there 5 times. There is if (TREE_SIDE_EFFECTS (function)) function = save_expr (function); but in this case function doesn't have side-effects, just nested ARRAY_REFs. Now, if all the FUNCTION trees would be shared, it would work fine, FUNCTION is evaluated in the first operand of COND_EXPR; but unfortunately that isn't the case, both the BIT_AND_EXPR shortening and conversion to bool done for build_conditional_expr actually unshare_expr that first expression, but none of the other 4 are unshared. With -fsanitize=bounds, .UBSAN_BOUNDS calls are added to the ARRAY_REFs and use save_expr to avoid evaluating the argument multiple times, but because that FUNCTION tree is first used in the second argument of COND_EXPR (i.e. conditionally), the SAVE_EXPR initialization is done just there and then the third argument of COND_EXPR just uses the uninitialized temporary and so does the first argument computation as well. The following patch fixes that by doing save_expr even if !TREE_SIDE_EFFECTS, but to avoid doing that too often only if !nonvirtual and if the expression isn't a simple decl. 2024-09-10 Jakub Jelinek PR c++/116449 * typeck.cc (get_member_function_from_ptrfunc): Use save_expr on instance_ptr and function even if it doesn't have side-effects, as long as it isn't a decl. * g++.dg/ubsan/pr116449.C: New test. (cherry picked from commit 0008050b9d6046ba4e811a03b406fb5d98707cae) Diff: --- gcc/cp/typeck.cc | 19 --- gcc/testsuite/g++.dg/ubsan/pr116449.C | 14 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 21436f836fa6..3d62943f8647 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -4175,10 +4175,23 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, if (!nonvirtual && is_dummy_object (instance_ptr)) nonvirtual = true; - if (TREE_SIDE_EFFECTS (instance_ptr)) - instance_ptr = instance_save_expr = save_expr (instance_ptr); + /* Use save_expr even when instance_ptr doesn't have side-effects, +unless it is a simple decl (save_expr won't do anything on +constants), so that we don't ubsan instrument the expression +multiple times. See PR116449. */ + if (TREE_SIDE_EFFECTS (instance_ptr) + || (!nonvirtual && !DECL_P (instance_ptr))) + { + instance_save_expr = save_expr (instance_ptr); + if (instance_save_expr == instance_ptr) + instance_save_expr = NULL_TREE; + else + instance_ptr = instance_save_expr; + } - if (TREE_SIDE_EFFECTS (function)) + /* See above comment. */ + if (TREE_SIDE_EFFECTS (function) + || (!nonvirtual && !DECL_P (function))) function = save_expr (function); /* Start by extracting all the information from the PMF itself. */ diff --git a/gcc/testsuite/g++.dg/ubsan/pr116449.C b/gcc/testsuite/g++.dg/ubsan/pr116449.C new file mode 100644 index ..f13368a51b00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr116449.C @@ -0,0 +1,14 @@ +// PR c++/116449 +// { dg-do compile } +// { dg-options "-O2 -Wall -fsanitize=undefined" } + +struct C { void foo (int); void bar (); int c[16]; }; +typedef void (C::*P) (); +struct D { P d; }; +static D e[1] = { { &C::bar } }; + +void +C::foo (int x) +{ + (this->*e[c[x]].d) (); +}
[gcc r14-10667] c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attribute
https://gcc.gnu.org/g:5609246b561ab929b24eeb32965911884b58b0df commit r14-10667-g5609246b561ab929b24eeb32965911884b58b0df Author: Jakub Jelinek Date: Thu Sep 12 18:22:21 2024 +0200 c++: Disable deprecated/unavailable diagnostics when creating thunks for methods with such attributes [PR116636] On the following testcase, we emit false positive warnings/errors about using the deprecated or unavailable methods when creating thunks for them, even when nothing (in the testcase so far) actually used those. The following patch temporarily disables that diagnostics when creating the thunks. 2024-09-12 Jakub Jelinek PR c++/116636 * method.cc: Include decl.h. (use_thunk): Temporarily change deprecated_state to UNAVAILABLE_DEPRECATED_SUPPRESS. * g++.dg/warn/deprecated-19.C: New test. (cherry picked from commit 4026d89d623e322920b052f7ac0d940ef267dc0f) Diff: --- gcc/cp/method.cc | 6 ++ gcc/testsuite/g++.dg/warn/deprecated-19.C | 22 ++ 2 files changed, 28 insertions(+) diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc index 08a3d34fb016..a2ca83ce354c 100644 --- a/gcc/cp/method.cc +++ b/gcc/cp/method.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "cp-tree.h" +#include "decl.h" #include "stringpool.h" #include "cgraph.h" #include "varasm.h" @@ -283,6 +284,11 @@ use_thunk (tree thunk_fndecl, bool emit_p) /* Thunks are always addressable; they only appear in vtables. */ TREE_ADDRESSABLE (thunk_fndecl) = 1; + /* Don't diagnose deprecated or unavailable functions just because they + have thunks emitted for them. */ + auto du = make_temp_override (deprecated_state, +UNAVAILABLE_DEPRECATED_SUPPRESS); + /* Figure out what function is being thunked to. It's referenced in this translation unit. */ TREE_ADDRESSABLE (function) = 1; diff --git a/gcc/testsuite/g++.dg/warn/deprecated-19.C b/gcc/testsuite/g++.dg/warn/deprecated-19.C new file mode 100644 index ..e49af4f74d0d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/deprecated-19.C @@ -0,0 +1,22 @@ +// PR c++/116636 +// { dg-do compile { target c++11 } } +// { dg-options "-pedantic -Wdeprecated" } + +struct A { + virtual int foo () = 0; +}; +struct B : virtual A { + [[deprecated]] int foo () { return 0; } // { dg-message "declared here" } +}; +struct C : virtual A { + [[gnu::unavailable]] int foo () { return 0; }// { dg-message "declared here" } +}; + +void +bar () +{ + B b; + b.foo ();// { dg-warning "'virtual int B::foo\\\(\\\)' is deprecated" } + C c; + c.foo ();// { dg-error "'virtual int C::foo\\\(\\\)' is unavailable" } +}
[gcc/redhat/heads/gcc-14-branch] (22 commits) Merge commit 'r14-10667-g5609246b561ab929b24eeb32965911884b
The branch 'redhat/heads/gcc-14-branch' was updated to point to: c7a1c1a4bf73... Merge commit 'r14-10667-g5609246b561ab929b24eeb32965911884b It previously pointed to: b30927153ae4... Merge commit 'r14-10646-g24909512101d59807f6d23a9963d64390e Diff: Summary of changes (added commits): --- c7a1c1a... Merge commit 'r14-10667-g5609246b561ab929b24eeb32965911884b 5609246... c++: Disable deprecated/unavailable diagnostics when creati (*) 90a9c36... c++: Fix get_member_function_from_ptrfunc with -fsanitize=b (*) c9fd43a... libiberty: Fix up > 64K section handling in simple_object_e (*) 78a08bf... Daily bump. (*) 2003f89... libstdc++: Only use std::ios_base_library_init() for ELF [P (*) d5d6d3f... libstdc++: std::string move assignment should not use POCCA (*) f0f00c4... Daily bump. (*) ab884ff... libstdc++: Fix std::chrono::tzdb to work with vanguard form (*) 8a0f0fc... Daily bump. (*) 3951efe... doc: Enhance Intel CPU documentation (*) 9366940... Daily bump. (*) 149d87f... c++: c->B::m access resolved through current inst [PR116320 (*) b5ed381... c++: inherited CTAD fixes [PR116276] (*) 140aab2... libstdc++: use concrete return type for std::forward_like (*) 7e0649a... Daily bump. (*) 0c80216... c++: template depth of lambda in default targ [PR116567] (*) 1e79541... Daily bump. (*) d4d7c4e... Update gcc uk.po (*) aedf6f8... Daily bump. (*) fe66863... c++: vtable referring to "unavailable" virtual fn [PR116606 (*) 6abedee... ipa: Don't disable function parameter analysis for fat LTO (*) (*) This commit already exists in another branch. Because the reference `refs/vendors/redhat/heads/gcc-14-branch' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc r13-9021] testsuite: Fix up pr116034.c test for big/pdp endian [PR116061]
https://gcc.gnu.org/g:e5a9c15266ba70b3a4cbc0f8e6bc8537c9b1c12d commit r13-9021-ge5a9c15266ba70b3a4cbc0f8e6bc8537c9b1c12d Author: Jakub Jelinek Date: Wed Jul 24 18:00:05 2024 +0200 testsuite: Fix up pr116034.c test for big/pdp endian [PR116061] Didn't notice the memmove is into an int variable, so the test was still failing on big endian. 2024-07-24 Jakub Jelinek PR tree-optimization/116034 PR testsuite/116061 * gcc.dg/pr116034.c (g): Change type from int to unsigned short. (foo): Guard memmove call on __SIZEOF_SHORT__ == 2. (cherry picked from commit 69e69847e21a8d951ab5f09fd3421449564dba31) Diff: --- gcc/testsuite/gcc.dg/pr116034.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr116034.c b/gcc/testsuite/gcc.dg/pr116034.c index 9a31de034246..955b4c9e86b8 100644 --- a/gcc/testsuite/gcc.dg/pr116034.c +++ b/gcc/testsuite/gcc.dg/pr116034.c @@ -2,12 +2,13 @@ /* { dg-do run } */ /* { dg-options "-O1 -fno-strict-aliasing" } */ -int g; +unsigned short int g; static inline int foo (_Complex unsigned short c) { - __builtin_memmove (&g, 1 + (char *) &c, 2); + if (__SIZEOF_SHORT__ == 2) +__builtin_memmove (&g, 1 + (char *) &c, 2); return g; }
[gcc r13-9022] i386: Fix up __builtin_ia32_b{extr{, i}_u{32, 64}, zhi_{s, d}i} folding [PR116287]
https://gcc.gnu.org/g:e5839cad7886c0277c111d96cc99c400f6f36b9d commit r13-9022-ge5839cad7886c0277c111d96cc99c400f6f36b9d Author: Jakub Jelinek Date: Fri Aug 9 14:32:51 2024 +0200 i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} folding [PR116287] The GENERIC folding of these builtins have cases where it folds to a constant regardless of the value of the first operand. If so, we need to use omit_one_operand to avoid throwing away side-effects in the first operand if any. The cases which verify the first argument is INTEGER_CST don't need that, INTEGER_CST doesn't have side-effects. 2024-08-09 Jakub Jelinek PR target/116287 * config/i386/i386.cc (ix86_fold_builtin) : When folding into zero without checking whether first argument is constant, use omit_one_operand. (ix86_fold_builtin) : Likewise. * gcc.target/i386/bmi-pr116287.c: New test. * gcc.target/i386/bmi2-pr116287.c: New test. * gcc.target/i386/tbm-pr116287.c: New test. (cherry picked from commit 6e7088dbe3bf87108a89558ffb7df36df3469206) Diff: --- gcc/config/i386/i386.cc | 12 +++ gcc/testsuite/gcc.target/i386/bmi-pr116287.c | 28 ++ gcc/testsuite/gcc.target/i386/bmi2-pr116287.c | 24 ++ gcc/testsuite/gcc.target/i386/tbm-pr116287.c | 29 +++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index a90351ca9c2c..85aa68175aa3 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -18054,9 +18054,11 @@ ix86_fold_builtin (tree fndecl, int n_args, unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0])); unsigned int start = tree_to_uhwi (args[1]); unsigned int len = (start & 0xff00) >> 8; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); start &= 0xff; if (start >= prec || len == 0) - res = 0; + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); else if (!tree_fits_uhwi_p (args[0])) break; else @@ -18065,7 +18067,7 @@ ix86_fold_builtin (tree fndecl, int n_args, len = prec; if (len < HOST_BITS_PER_WIDE_INT) res &= (HOST_WIDE_INT_1U << len) - 1; - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; @@ -18075,15 +18077,17 @@ ix86_fold_builtin (tree fndecl, int n_args, if (tree_fits_uhwi_p (args[1])) { unsigned int idx = tree_to_uhwi (args[1]) & 0xff; + tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl)); if (idx >= TYPE_PRECISION (TREE_TYPE (args[0]))) return args[0]; if (idx == 0) - return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0); + return omit_one_operand (lhs_type, build_zero_cst (lhs_type), +args[0]); if (!tree_fits_uhwi_p (args[0])) break; unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]); res &= ~(HOST_WIDE_INT_M1U << idx); - return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res); + return build_int_cstu (lhs_type, res); } break; diff --git a/gcc/testsuite/gcc.target/i386/bmi-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c new file mode 100644 index ..2212cb458d26 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c @@ -0,0 +1,28 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi } } */ +/* { dg-options "-O2 -mbmi" } */ + +#include + +#include "bmi-check.h" + +static void +bmi_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bextr_u32 (a++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u32 (a++, 0x120) != 0) +abort (); + if (a != 2) +abort (); +#ifdef __x86_64__ + unsigned long long b = 0; + if (__builtin_ia32_bextr_u64 (b++, 0) != 0) +abort (); + if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0) +abort (); + if (b != 2) +abort (); +#endif +} diff --git a/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c new file mode 100644 index ..51c939c39f62 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c @@ -0,0 +1,24 @@ +/* PR target/116287 */ +/* { dg-do run { target bmi2 } } */ +/* { dg-options "-O2 -mbmi2" } */ + +#include + +#include "bmi2-check.h" + +static void +bmi2_test () +{ + unsigned int a = 0; + if (__builtin_ia32_bzhi_si (a++, 0) != 0) +abort (); + if (a != 1) +abort (); +#ifdef __x86_64__ + unsigned long lon
[gcc r13-9023] libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614]
https://gcc.gnu.org/g:9b4a7d907d90ba7b7787433ab66eaf6112c33ffb commit r13-9023-g9b4a7d907d90ba7b7787433ab66eaf6112c33ffb Author: Jakub Jelinek Date: Sat Sep 7 09:36:53 2024 +0200 libiberty: Fix up > 64K section handling in simple_object_elf_copy_lto_debug_section [PR116614] cat abc.C #define A(n) struct T##n {} t##n; #define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n##5) A(n##6) A(n##7) A(n##8) A(n##9) #define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n##5) B(n##6) B(n##7) B(n##8) B(n##9) #define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n##5) C(n##6) C(n##7) C(n##8) C(n##9) #define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n##5) D(n##6) D(n##7) D(n##8) D(n##9) E(1) E(2) E(3) int main () { return 0; } ./xg++ -B ./ -o abc{.o,.C} -flto -flto-partition=1to1 -O2 -g -fdebug-types-section -c ./xgcc -B ./ -o abc{,.o} -flto -flto-partition=1to1 -O2 (not included in testsuite as it takes a while to compile) FAILs with lto-wrapper: fatal error: Too many copied sections: Operation not supported compilation terminated. /usr/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status The following patch fixes that. Most of the 64K+ section support for reading and writing was already there years ago (and especially reading used quite often already) and a further bug fixed in it in the PR104617 fix. Yet, the fix isn't solely about removing the if (new_i - 1 >= SHN_LORESERVE) { *err = ENOTSUP; return "Too many copied sections"; } 5 lines, the missing part was that the function only handled reading of the .symtab_shndx section but not copying/updating of it. If the result has less than 64K-epsilon sections, that actually wasn't needed, but e.g. with -fdebug-types-section one can exceed that pretty easily (reported to us on WebKitGtk build on ppc64le). Updating the section is slightly more complicated, because it basically needs to be done in lock step with updating the .symtab section, if one doesn't need to use SHN_XINDEX in there, the section should (or should be updated to) contain SHN_UNDEF entry, otherwise needs to have whatever would be overwise stored but couldn't fit. But repeating due to that all the symtab decisions what to discard and how to rewrite it would be ugly. So, the patch instead emits the .symtab_shndx section (or sections) last and prepares the content during the .symtab processing and in a second pass when going just through .symtab_shndx sections just uses the saved content. 2024-09-07 Jakub Jelinek PR lto/116614 * simple-object-elf.c (SHN_COMMON): Align comment with neighbouring comments. (SHN_HIRESERVE): Use uppercase hex digits instead of lowercase for consistency. (simple_object_elf_find_sections): Formatting fixes. (simple_object_elf_fetch_attributes): Likewise. (simple_object_elf_attributes_merge): Likewise. (simple_object_elf_start_write): Likewise. (simple_object_elf_write_ehdr): Likewise. (simple_object_elf_write_shdr): Likewise. (simple_object_elf_write_to_file): Likewise. (simple_object_elf_copy_lto_debug_section): Likewise. Don't fail for new_i - 1 >= SHN_LORESERVE, instead arrange in that case to copy over .symtab_shndx sections, though emit those last and compute their section content when processing associated .symtab sections. Handle simple_object_internal_read failure even in the .symtab_shndx reading case. (cherry picked from commit bb8dd0980b39cfd601f88703fd356055727ef24d) Diff: --- libiberty/simple-object-elf.c | 210 -- 1 file changed, 143 insertions(+), 67 deletions(-) diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c index eee07039984d..501b5ba62aac 100644 --- a/libiberty/simple-object-elf.c +++ b/libiberty/simple-object-elf.c @@ -128,9 +128,9 @@ typedef struct { #define SHN_UNDEF 0 /* Undefined section */ #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */ -#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ +#define SHN_COMMON 0xFFF2 /* Associated symbol is in common */ #define SHN_XINDEX 0x /* Section index is held elsewhere */ -#define SHN_HIRESERVE 0x /* End of reserved indices */ +#define SHN_HIRESERVE 0x /* End of reserved indices */ /* 32-bit ELF program header. */ @@ -569,8 +569,8 @@ simple_object_elf_find_sections (simple_object_read *sobj, void *data, int *err) { - struct simple_object_elf_read *eor =
[gcc r13-9019] gimple-fold: Fix up __builtin_clear_padding lowering [PR115527]
https://gcc.gnu.org/g:1880ff0dbd814cf1e7dd53dd810f372a94d66d39 commit r13-9019-g1880ff0dbd814cf1e7dd53dd810f372a94d66d39 Author: Jakub Jelinek Date: Wed Jul 17 11:38:33 2024 +0200 gimple-fold: Fix up __builtin_clear_padding lowering [PR115527] The builtin-clear-padding-6.c testcase fails as clear_padding_type doesn't correctly recompute the buf->size and buf->off members after expanding clearing of an array using a runtime loop. buf->size should be in that case the offset after which it should continue with next members or padding before them modulo UNITS_PER_WORD and buf->off that offset minus buf->size. That is what the code was doing, but with off being the start of the loop cleared array, not its end. So, the last hunk in gimple-fold.cc fixes that. When adding the testcase, I've noticed that the c-c++-common/torture/builtin-clear-padding-* tests, although clearly written as runtime tests to test the builtins at runtime, didn't have { dg-do run } directive and were just compile tests because of that. When adding that to the tests, builtin-clear-padding-1.c was already failing without that clear_padding_type hunk too, but builtin-clear-padding-5.c was still failing even after the change. That is due to a bug in clear_padding_flush which the patch fixes as well - when clear_padding_flush is called with full=true (that happens at the end of the whole __builtin_clear_padding or on those array padding clears done by a runtime loop), it wants to flush all the pending padding clearings rather than just some. If it is at the end of the whole object, it decreases wordsize when needed to make sure the code never writes including RMW cycles to something outside of the object: if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize) > (unsigned HOST_WIDE_INT) buf->sz) { gcc_assert (wordsize > 1); wordsize /= 2; i -= wordsize; continue; } but if it is full==true flush in the middle, this doesn't happen, but we still process just the buffer bytes before the current end. If that end is not on a wordsize boundary, e.g. on the builtin-clear-padding-5.c test the last chunk is 2 bytes, '\0', '\xff', i is 16 and end is 18, nonzero_last might be equal to the end - i, i.e. 2 here, but still all_ones might be true, so in some spots we just didn't emit any clearing in that last chunk. 2024-07-17 Jakub Jelinek PR middle-end/115527 * gimple-fold.cc (clear_padding_flush): Introduce endsize variable and use it instead of wordsize when comparing it against nonzero_last. (clear_padding_type): Increment off by sz. * c-c++-common/torture/builtin-clear-padding-1.c: Add dg-do run directive. * c-c++-common/torture/builtin-clear-padding-2.c: Likewise. * c-c++-common/torture/builtin-clear-padding-3.c: Likewise. * c-c++-common/torture/builtin-clear-padding-4.c: Likewise. * c-c++-common/torture/builtin-clear-padding-5.c: Likewise. * c-c++-common/torture/builtin-clear-padding-6.c: New test. (cherry picked from commit 8b5919bae11754f4b65a17e63663d3143f9615ac) Diff: --- gcc/gimple-fold.cc | 12 ++ .../c-c++-common/torture/builtin-clear-padding-1.c | 1 + .../c-c++-common/torture/builtin-clear-padding-2.c | 1 + .../c-c++-common/torture/builtin-clear-padding-3.c | 1 + .../c-c++-common/torture/builtin-clear-padding-4.c | 4 ++-- .../c-c++-common/torture/builtin-clear-padding-5.c | 1 + .../c-c++-common/torture/builtin-clear-padding-6.c | 28 ++ 7 files changed, 41 insertions(+), 7 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index a61bfcee4e7a..5bdd1d08a265 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -4235,7 +4235,8 @@ clear_padding_flush (clear_padding_struct *buf, bool full) i -= wordsize; continue; } - for (size_t j = i; j < i + wordsize && j < end; j++) + size_t endsize = end - i > wordsize ? wordsize : end - i; + for (size_t j = i; j < i + endsize; j++) { if (buf->buf[j]) { @@ -4264,12 +4265,12 @@ clear_padding_flush (clear_padding_struct *buf, bool full) if (padding_bytes) { if (nonzero_first == 0 - && nonzero_last == wordsize + && nonzero_last == endsize && all_ones) { /* All bits are padding and we had some padding before too. Just extend it. */ - padding_bytes += wordsize; + padding_bytes += endsize; continue; } if (all_ones && nonzero_first == 0) @@ -4309,7 +4310,7 @@ clear_padding_flush (clea
[gcc r13-9020] ssa: Fix up maybe_rewrite_mem_ref_base complex type handling [PR116034]
https://gcc.gnu.org/g:aaa82d63fed5978a0bc7136a3922d280576ce257 commit r13-9020-gaaa82d63fed5978a0bc7136a3922d280576ce257 Author: Jakub Jelinek Date: Tue Jul 23 10:50:29 2024 +0200 ssa: Fix up maybe_rewrite_mem_ref_base complex type handling [PR116034] The folding into REALPART_EXPR is correct, used only when the mem_offset is zero, but for IMAGPART_EXPR it didn't check the exact offset value (just that it is not 0). The following patch fixes that by using IMAGPART_EXPR only if the offset is right and using BITFIELD_REF or whatever else otherwise. 2024-07-23 Jakub Jelinek Andrew Pinski PR tree-optimization/116034 * tree-ssa.cc (maybe_rewrite_mem_ref_base): Only use IMAGPART_EXPR if MEM_REF offset is equal to element type size. * gcc.dg/pr116034.c: New test. (cherry picked from commit b9cefd67a2a464a3c9413e6b3f28e7dc7a9ef162) Diff: --- gcc/testsuite/gcc.dg/pr116034.c | 22 ++ gcc/tree-ssa.cc | 5 - 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/pr116034.c b/gcc/testsuite/gcc.dg/pr116034.c new file mode 100644 index ..9a31de034246 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116034.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/116034 */ +/* { dg-do run } */ +/* { dg-options "-O1 -fno-strict-aliasing" } */ + +int g; + +static inline int +foo (_Complex unsigned short c) +{ + __builtin_memmove (&g, 1 + (char *) &c, 2); + return g; +} + +int +main () +{ + if (__SIZEOF_SHORT__ == 2 + && __CHAR_BIT__ == 8 + && (foo (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ ? 0x100 : 1) + != (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ ? 1 : 0x100))) +__builtin_abort (); +} diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc index b0b3895af1c9..74ede9cc9cf8 100644 --- a/gcc/tree-ssa.cc +++ b/gcc/tree-ssa.cc @@ -1529,7 +1529,10 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming) } else if (TREE_CODE (TREE_TYPE (sym)) == COMPLEX_TYPE && useless_type_conversion_p (TREE_TYPE (*tp), -TREE_TYPE (TREE_TYPE (sym +TREE_TYPE (TREE_TYPE (sym))) + && (integer_zerop (TREE_OPERAND (*tp, 1)) + || tree_int_cst_equal (TREE_OPERAND (*tp, 1), + TYPE_SIZE_UNIT (TREE_TYPE (*tp) { *tp = build1 (integer_zerop (TREE_OPERAND (*tp, 1)) ? REALPART_EXPR : IMAGPART_EXPR,
[gcc r13-9024] c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449]
https://gcc.gnu.org/g:973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3 commit r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3 Author: Jakub Jelinek Date: Tue Sep 10 18:32:58 2024 +0200 c++: Fix get_member_function_from_ptrfunc with -fsanitize=bounds [PR116449] The following testcase is miscompiled, because get_member_function_from_ptrfunc emits something like (((FUNCTION.__pfn & 1) != 0) ? ptr + FUNCTION.__delta + FUNCTION.__pfn - 1 : FUNCTION.__pfn) (ptr + FUNCTION.__delta, ...) or so, so FUNCTION tree is used there 5 times. There is if (TREE_SIDE_EFFECTS (function)) function = save_expr (function); but in this case function doesn't have side-effects, just nested ARRAY_REFs. Now, if all the FUNCTION trees would be shared, it would work fine, FUNCTION is evaluated in the first operand of COND_EXPR; but unfortunately that isn't the case, both the BIT_AND_EXPR shortening and conversion to bool done for build_conditional_expr actually unshare_expr that first expression, but none of the other 4 are unshared. With -fsanitize=bounds, .UBSAN_BOUNDS calls are added to the ARRAY_REFs and use save_expr to avoid evaluating the argument multiple times, but because that FUNCTION tree is first used in the second argument of COND_EXPR (i.e. conditionally), the SAVE_EXPR initialization is done just there and then the third argument of COND_EXPR just uses the uninitialized temporary and so does the first argument computation as well. The following patch fixes that by doing save_expr even if !TREE_SIDE_EFFECTS, but to avoid doing that too often only if !nonvirtual and if the expression isn't a simple decl. 2024-09-10 Jakub Jelinek PR c++/116449 * typeck.cc (get_member_function_from_ptrfunc): Use save_expr on instance_ptr and function even if it doesn't have side-effects, as long as it isn't a decl. * g++.dg/ubsan/pr116449.C: New test. (cherry picked from commit 0008050b9d6046ba4e811a03b406fb5d98707cae) Diff: --- gcc/cp/typeck.cc | 19 --- gcc/testsuite/g++.dg/ubsan/pr116449.C | 14 ++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 470bb2ee5f71..2b29bdc4d70a 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -4178,10 +4178,23 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, if (!nonvirtual && is_dummy_object (instance_ptr)) nonvirtual = true; - if (TREE_SIDE_EFFECTS (instance_ptr)) - instance_ptr = instance_save_expr = save_expr (instance_ptr); + /* Use save_expr even when instance_ptr doesn't have side-effects, +unless it is a simple decl (save_expr won't do anything on +constants), so that we don't ubsan instrument the expression +multiple times. See PR116449. */ + if (TREE_SIDE_EFFECTS (instance_ptr) + || (!nonvirtual && !DECL_P (instance_ptr))) + { + instance_save_expr = save_expr (instance_ptr); + if (instance_save_expr == instance_ptr) + instance_save_expr = NULL_TREE; + else + instance_ptr = instance_save_expr; + } - if (TREE_SIDE_EFFECTS (function)) + /* See above comment. */ + if (TREE_SIDE_EFFECTS (function) + || (!nonvirtual && !DECL_P (function))) function = save_expr (function); /* Start by extracting all the information from the PMF itself. */ diff --git a/gcc/testsuite/g++.dg/ubsan/pr116449.C b/gcc/testsuite/g++.dg/ubsan/pr116449.C new file mode 100644 index ..f13368a51b00 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr116449.C @@ -0,0 +1,14 @@ +// PR c++/116449 +// { dg-do compile } +// { dg-options "-O2 -Wall -fsanitize=undefined" } + +struct C { void foo (int); void bar (); int c[16]; }; +typedef void (C::*P) (); +struct D { P d; }; +static D e[1] = { { &C::bar } }; + +void +C::foo (int x) +{ + (this->*e[c[x]].d) (); +}
[gcc r15-3627] libcpp: Fix up UB in finish_embed
https://gcc.gnu.org/g:4963eb76918295a08a7c216bea986ab8e65c1cf8 commit r15-3627-g4963eb76918295a08a7c216bea986ab8e65c1cf8 Author: Jakub Jelinek Date: Fri Sep 13 16:11:05 2024 +0200 libcpp: Fix up UB in finish_embed Jonathan reported on IRC that certain unnamed proprietary static analyzer is unhappy about the new finish_embed function and it is actually right. On a testcase like: #embed __FILE__ limit (0) if_empty (0) params->if_empty.count is 1, limit is 0, so count is 0 (we need just a single token and one fits into pfile->directive_result). Because count is 0, we don't allocate toks, so it stays NULL, and then in 1301 if (prefix->count) 1302{ 1303 *tok = *prefix->base_run.base; 1304 tok = toks; 1305 tokenrun *cur_run = &prefix->base_run; 1306 while (cur_run) 1307{ 1308 size_t cnt = (cur_run->next ? cur_run->limit 1309: prefix->cur_token) - cur_run->base; 1310 cpp_token *t = cur_run->base; 1311 if (cur_run == &prefix->base_run) 1312{ 1313 t++; 1314 cnt--; 1315} 1316 memcpy (tok, t, cnt * sizeof (cpp_token)); 1317 tok += cnt; 1318 cur_run = cur_run->next; 1319} 1320} the *tok = *prefix->base_run.base; assignment will copy the only token. cur_run is still non-NULL, cnt will be initially 1 and then decremented to 0, but we invoke UB because we do memcpy (NULL, cur_run->base + 1, 0 * sizeof (cpp_token)); and then the loop stops because cur_run->next must be NULL. As we don't really copy anything, toks can be anything non-NULL, so the following patch fixes that by initializing toks also to &pfile->directive_result (just something known to be non-NULL). This should be harmless even for the #embed __FILE__ limit (1) case (no non-empty prefix/suffix) where toks isn't allocated either, but in that case prefix->count will be 0 and in the 1321 for (size_t i = 0; i < limit; ++i) 1322{ 1323 tok->src_loc = params->loc; 1324 tok->type = CPP_NUMBER; 1325 tok->flags = NO_EXPAND; 1326 if (i == 0) 1327tok->flags |= PREV_WHITE; 1328 tok->val.str.text = s; 1329 tok->val.str.len = sprintf ((char *) s, "%d", buffer[i]); 1330 s += tok->val.str.len + 1; 1331 if (tok == &pfile->directive_result) 1332tok = toks; 1333 else 1334tok++; 1335 if (i < limit - 1) 1336{ 1337 tok->src_loc = params->loc; 1338 tok->type = CPP_COMMA; 1339 tok->flags = NO_EXPAND; 1340 tok++; 1341} 1342} loop limit will be 1, so tok is initially &pfile->directive_result, that is stilled in, then tok = toks; (previously setting tok to NULL, now to &pfile->directive_result again) and because 0 < 1 - 1 is false, nothing further will happen and the loop will finish (and as params->suffix.count will be 0, nothing further will use tok). 2024-09-13 Jakub Jelinek * files.cc (finish_embed): Initialize toks to tok rather than NULL. Diff: --- libcpp/files.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcpp/files.cc b/libcpp/files.cc index 8aff0149cbee..031169978e72 100644 --- a/libcpp/files.cc +++ b/libcpp/files.cc @@ -1284,7 +1284,7 @@ finish_embed (cpp_reader *pfile, _cpp_file *file, } uchar *s = len ? _cpp_unaligned_alloc (pfile, len) : NULL; _cpp_buff *tok_buff = NULL; - cpp_token *toks = NULL, *tok = &pfile->directive_result; + cpp_token *tok = &pfile->directive_result, *toks = tok; size_t count = 0; if (limit) count = (params->prefix.count + limit * 2 - 1
[gcc r15-3628] c++: Don't emit deprecated/unavailable attribute diagnostics when creating cdtor thunks [PR116678]
https://gcc.gnu.org/g:b7b67732e20217196f2a13a10fc3df4605b2b2ab commit r15-3628-gb7b67732e20217196f2a13a10fc3df4605b2b2ab Author: Jakub Jelinek Date: Fri Sep 13 16:13:01 2024 +0200 c++: Don't emit deprecated/unavailable attribute diagnostics when creating cdtor thunks [PR116678] Another spot where we mark_used a function (in this case ctor or dtor) even when it is just artificially used inside of thunks (emitted on mingw with -Os for the testcase). 2024-09-13 Jakub Jelinek PR c++/116678 * optimize.cc: Include decl.h. (maybe_thunk_body): Temporarily change deprecated_state to UNAVAILABLE_DEPRECATED_SUPPRESS. * g++.dg/warn/deprecated-20.C: New test. Diff: --- gcc/cp/optimize.cc| 6 ++ gcc/testsuite/g++.dg/warn/deprecated-20.C | 16 2 files changed, 22 insertions(+) diff --git a/gcc/cp/optimize.cc b/gcc/cp/optimize.cc index b8791d8a9635..8429d856728f 100644 --- a/gcc/cp/optimize.cc +++ b/gcc/cp/optimize.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "target.h" #include "cp-tree.h" +#include "decl.h" #include "stringpool.h" #include "cgraph.h" #include "debug.h" @@ -287,6 +288,11 @@ maybe_thunk_body (tree fn, bool force) if (ctor_omit_inherited_parms (fns[0])) return 0; + /* Don't diagnose deprecated or unavailable cdtors just because they + have thunks emitted for them. */ + auto du = make_temp_override (deprecated_state, + UNAVAILABLE_DEPRECATED_SUPPRESS); + DECL_ABSTRACT_P (fn) = false; if (!DECL_WEAK (fn)) { diff --git a/gcc/testsuite/g++.dg/warn/deprecated-20.C b/gcc/testsuite/g++.dg/warn/deprecated-20.C new file mode 100644 index ..1911aeff4e37 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/deprecated-20.C @@ -0,0 +1,16 @@ +// PR c++/116678 +// { dg-do compile } +// { dg-options "-Os -pedantic" } + +struct S +{ + [[deprecated]] S () { s = 1; } // { dg-bogus "'S::S\\\(\\\)' is deprecated" } + S (int x) { s = x; } // { dg-warning "C\\\+\\\+11 attributes only available with" "" { target c++98_only } .-1 } + ~S () {} + int s; +}; + +int +main () +{ +}
[gcc(refs/vendors/redhat/heads/gcc-13-branch)] Merge commit 'r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3' into redhat/gcc-13-branch
https://gcc.gnu.org/g:2fcca36eb1d34066437939cf1b54810a75dd553f commit 2fcca36eb1d34066437939cf1b54810a75dd553f Merge: 03b1a31f9807 973c6ea242ce Author: Jakub Jelinek Date: Fri Sep 13 16:15:02 2024 +0200 Merge commit 'r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb9dbb3' into redhat/gcc-13-branch Diff: gcc/ChangeLog | 627 + gcc/DATESTAMP | 2 +- gcc/c-family/ChangeLog | 10 + gcc/c-family/c-warn.cc | 13 +- gcc/c/ChangeLog| 10 + gcc/common/config/aarch64/aarch64-common.cc| 35 +- gcc/config/aarch64/aarch64-c.cc| 7 +- gcc/config/aarch64/aarch64-cores.def | 2 + gcc/config/aarch64/aarch64-sve-builtins-base.cc| 25 +- gcc/config/aarch64/aarch64-sve.md | 20 +- gcc/config/aarch64/aarch64-tune.md | 2 +- gcc/config/aarch64/aarch64.cc | 52 +- gcc/config/aarch64/aarch64.h | 10 +- gcc/config/aarch64/aarch64.md | 4 +- gcc/config/alpha/alpha.md | 10 +- gcc/config/arm/arm.cc | 87 ++- gcc/config/arm/mve.md | 2 +- gcc/config/avr/avr-dimode.md | 26 +- gcc/config/avr/avr-protos.h| 2 +- gcc/config/avr/avr.cc | 46 +- gcc/config/avr/avr.md | 42 +- gcc/config/i386/avx512dqintrin.h | 16 +- gcc/config/i386/avx512fp16intrin.h | 4 +- gcc/config/i386/avx512vlbwintrin.h | 4 +- gcc/config/i386/avx512vlintrin.h | 2 +- gcc/config/i386/constraints.md | 2 +- gcc/config/i386/i386-options.cc| 77 ++- gcc/config/i386/i386.cc| 48 +- gcc/config/i386/i386.md| 2 +- gcc/config/i386/prfchiintrin.h | 9 + gcc/config/i386/x86-tune-costs.h | 4 +- gcc/config/loongarch/loongarch.cc | 2 +- gcc/config/loongarch/loongarch.h | 7 - gcc/config/pa/pa.cc| 1 + gcc/config/pa/pa.md| 18 - gcc/config/riscv/riscv.cc | 5 +- gcc/config/rs6000/altivec.md | 222 ++-- gcc/config/rs6000/rs6000-logue.cc | 54 +- gcc/config/rs6000/rs6000.cc| 41 +- gcc/config/rs6000/rs6000.md| 21 +- gcc/config/rs6000/vsx.md | 28 +- gcc/config/s390/3931.md| 7 - gcc/config/s390/s390.md| 5 +- gcc/config/s390/vector.md | 6 +- gcc/config/sh/sh.cc| 12 +- gcc/cp/ChangeLog | 17 + gcc/cp/method.cc | 1 + gcc/cp/typeck.cc | 22 +- gcc/cse.cc | 4 +- gcc/doc/invoke.texi| 18 +- gcc/expmed.cc | 4 +- gcc/fortran/ChangeLog | 100 gcc/fortran/dependency.cc | 32 ++ gcc/fortran/expr.cc| 5 + gcc/fortran/gfortran.h | 4 + gcc/fortran/iresolve.cc| 4 + gcc/fortran/trans-array.cc | 52 +- gcc/fortran/trans-expr.cc | 49 +- gcc/fortran/trans-intrinsic.cc | 80 ++- gcc/fortran/trans-stmt.cc | 43 +- gcc/fortran/trans-types.cc | 4 +- gcc/gimple-fold.cc | 12 +- gcc/ipa-icf-gimple.cc | 4 + gcc/ipa-modref.cc | 4 +- gcc/jit/ChangeLog | 9 + gcc/jit/jit-recording.cc | 1 + gcc/opt-suggestions.cc | 2 +- gcc/opts-common.cc | 6 +- gcc/testsuite/ChangeLog| 421 ++ gcc/testsuite/c-c++-common/Warray-compare-3.c | 13 + .../c-c++-common/torture/builtin-clear-padding-1.c | 1 + .../c-c++-common/torture/builtin-clear-padding-2.c | 1 + .../c-c++-common/torture/builtin-clear-padding-3.c | 1 + .../c-c++-common/torture/builtin-clear-padding-4.c | 4 +- .../c-c++-common/torture/builtin-clear-padding-5.c | 1 + .../c-c++-common/torture/builtin-clear-padding-6.c | 28 + gcc/testsuite/c-c++-common/to
[gcc/redhat/heads/gcc-13-branch] (187 commits) Merge commit 'r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb
The branch 'redhat/heads/gcc-13-branch' was updated to point to: 2fcca36eb1d3... Merge commit 'r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb It previously pointed to: 03b1a31f9807... Merge commit 'r13-8838-g7813d94393f60ac641265cb3fc3a446f9f3 Diff: Summary of changes (added commits): --- 2fcca36... Merge commit 'r13-9024-g973c6ea242cea7d95c2888ec6dde39b5cbb 973c6ea... c++: Fix get_member_function_from_ptrfunc with -fsanitize=b (*) 9b4a7d9... libiberty: Fix up > 64K section handling in simple_object_e (*) e5839ca... i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} (*) e5a9c15... testsuite: Fix up pr116034.c test for big/pdp endian [PR116 (*) aaa82d6... ssa: Fix up maybe_rewrite_mem_ref_base complex type handlin (*) 1880ff0... gimple-fold: Fix up __builtin_clear_padding lowering [PR115 (*) ff84211... Daily bump. (*) 934245a... Daily bump. (*) 2d7b4df... Daily bump. (*) 5ceea2a... libstdc++: Fix std::chrono::tzdb to work with vanguard form (*) e9b2f1f... libstdc++: Support link chains in std::chrono::tzdb::locate (*) 2913d33... [libstdc++] define zoneinfo_dir_override on vxworks (*) 04a8e50... Daily bump. (*) 0a16b1b... doc: Enhance Intel CPU documentation (*) 61fd9b0... Daily bump. (*) fbcc672... Daily bump. (*) 750bb0c... Daily bump. (*) 8ad345a... Daily bump. (*) e83df98... ipa: Don't disable function parameter analysis for fat LTO (*) c56dc83... Arm: Fix incorrect tailcall-generation for indirect calls [ (*) 5a081da... Daily bump. (*) cc2c50b... Daily bump. (*) e152aee... i386: Fix vfpclassph non-optimizied intrin (*) f364a43... RISC-V: fix TARGET_PROMOTE_FUNCTION_MODE hook for libcalls (*) 032b6e3... Daily bump. (*) 5e049ad... Check avx upper register for parallel. (*) d9decdc... Daily bump. (*) 85f323c... Daily bump. (*) 9b9e33e... Daily bump. (*) d473609... Daily bump. (*) 2c88e24... Daily bump. (*) 154639f... Daily bump. (*) d4e36c7... Daily bump. (*) 4f26b4f... Daily bump. (*) 891a312... Daily bump. (*) bdb1cb6... Daily bump. (*) ea9c508... Fix testcase failure. (*) aea3742... Align ix86_{move_max,store_max} with vectorizer. (*) 39d5de3... Daily bump. (*) 3e5cf9f... [testsuite] [arm] [vect] adjust mve-vshr test [PR113281] (*) 95c2bc2... Daily bump. (*) 9f54144... Daily bump. (*) e469654... Compare loop bounds in ipa-icf (*) 49bcfb7... Daily bump. (*) 58c8882... AVR: target/116407 - Fix linker error "relocation truncated (*) b8fe699... Daily bump. (*) 2466e10... Daily bump. (*) 959d652... aarch64: Fix bogus cnot optimisation [PR114603] (*) 22c6a11... aarch64: Fix expansion of svsudot [PR114607] (*) 73d22be... Daily bump. (*) 8796e33... Daily bump. (*) a79d7cc... Daily bump. (*) 7b0e478... Daily bump. (*) 617562e... Refine constraint "Bk" to define_special_memory_constraint. (*) 3689565... Daily bump. (*) 3008807... Daily bump. (*) 419c533... Daily bump. (*) 12ba140... c++: local class memfn synth from uneval context [PR113063] (*) 7830d92... Daily bump. (*) 617bbae... Daily bump. (*) 9d36882... Daily bump. (*) f6624ad... hppa: Fix (plus (plus (mult (a) (mem_shadd_constant)) (b)) (*) 73064a2... sh: Don't call make_insn_raw in sh_recog_treg_set_expr [PR1 (*) 87cb011... Daily bump. (*) bf0673e... libgomp: Remove bogus warnings from privatized-ref-2.f90. (*) 7195144... Fortran: Suppress bogus used uninitialized warnings [PR1088 (*) dcc9a85... Daily bump. (*) 991acbd... Daily bump. (*) 4e0846d... Daily bump. (*) 65b8906... Daily bump. (*) 7928ec5... Daily bump. (*) fa6c24e... Daily bump. (*) d80abba... i386: Add non-optimize prefetchi intrins (*) 320a9c5... Daily bump. (*) b2ab34b... i386: Use _mm_setzero_ps/d instead of _mm_avx512_setzero_ps (*) bb15c4c... i386: Fix AVX512 intrin macro typo (*) 69272e4... Daily bump. (*) 920adcb... Daily bump. (*) 4e03c89... Daily bump. (*) f280772... Daily bump. (*) 58b3e55... Daily bump. (*) 46d68bc... libstdc++: Fix std::vector for -std=gnu++14 -fconcept (*) 9a4603d... rs6000: Catch unsupported ABI errors when using -mrop-prote (*) 63b1b3e... rs6000: Error on CPUs and ABIs that don't support the ROP p (*) 77fd352... rs6000: ROP - Emit hashst and hashchk insns on Power8 and l (*) bc51e5a... rs6000: Compute rop_hash_save_offset for non-Altivec compil (*) 9bbdec4... rs6000: Update ELFv2 stack frame comment showing the correc (*) 0575d3b... Daily bump. (*) b352766... Fixup unaligned load/store cost for znver4 (*) dec571e... i386: Change prefetchi output template (*) e504184... [powerpc] [testsuite] reorder dg directives [PR106069] (*) 8a470d7... Daily bump. (*) 4ce7c81... [PR115565] cse: Don't use a valid regno for non-register in (*) 9778ad5... Daily bump. (*) ae6d5dc... Fortran: character array constructor with >= 4 constant ele (*) 44e07e4... Daily bump. (*) a23deb1... Avoid undefined behaviour in build_option_suggestions (*)
[gcc r13-9025] testsuite: Fix up builtin-clear-padding-3.c for -funsigned-char
https://gcc.gnu.org/g:504c8e4dc26501fb68f0ae784b45dba0f68b4f4a commit r13-9025-g504c8e4dc26501fb68f0ae784b45dba0f68b4f4a Author: Jakub Jelinek Date: Thu Jul 18 09:22:10 2024 +0200 testsuite: Fix up builtin-clear-padding-3.c for -funsigned-char As reported on gcc-regression, this test FAILs on aarch64, but my r15-2090 change didn't change anything on the generated assembly, just added the forgotten dg-do run directive to the test, so the test has been failing forever, just we didn't know it. I can actually reproduce it on x86_64 with -funsigned-char too, s2.b.a has int type and -1 is stored to it, so we should compare it against -1 rather than (char) -1; the latter is appropriate for testing char fields into which we've stored -1. 2024-07-18 Jakub Jelinek * c-c++-common/torture/builtin-clear-padding-3.c (main): Compare s2.b.a against -1 rather than (char) -1. (cherry picked from commit 958ee138748fae4371e453eb9b357f576abbe83e) Diff: --- gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c index 27bf8f6dd734..2c673169e134 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-clear-padding-3.c @@ -34,7 +34,7 @@ main () foo (&s1, 0); foo (&s2, 0); __builtin_clear_padding (&s2); - if (s2.b.a != (char) -1) + if (s2.b.a != -1) __builtin_abort (); __builtin_clear_padding (&s2.b.a); __builtin_memset (&s2.b.a + 1, 0, sizeof (union U) - sizeof (s2.b.a));
[gcc r15-1597] c: Fix ICE related to incomplete structures in C23 [PR114930]
https://gcc.gnu.org/g:777cc6a01d1cf783a36d0fa67ab20f0312f35d7a commit r15-1597-g777cc6a01d1cf783a36d0fa67ab20f0312f35d7a Author: Jakub Jelinek Date: Tue Jun 25 08:35:56 2024 +0200 c: Fix ICE related to incomplete structures in C23 [PR114930] Here is a version of the c_update_type_canonical fixes which passed bootstrap/regtest. The non-trivial part is the handling of the case when build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x)) returns a type with NULL TYPE_CANONICAL. That should happen only if TYPE_CANONICAL (t) == t, because otherwise c_update_type_canonical should have been already called on the other type. c, the returned type, is usually x and in that case it should have TYPE_CANONICAL set to itself, or worst for whatever reason x is not the right canonical type (say it has attributes or whatever disqualifies it from check_qualified_type). In that case either it finds some pre-existing type from the variant chain of t which is later in the chain and we haven't processed it yet (but then get_qualified_type moves it right after t in: /* Put the found variant at the head of the variant list so frequently searched variants get found faster. The C++ FE benefits greatly from this. */ tree t = *tp; *tp = TYPE_NEXT_VARIANT (t); TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv); TYPE_NEXT_VARIANT (mv) = t; return t; optimization), or creates a fresh new type using build_variant_type_copy, which again places the new type right after t: /* Add the new type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); TYPE_NEXT_VARIANT (m) = t; TYPE_MAIN_VARIANT (t) = m; At this point we want to make c its own canonical type (i.e. TYPE_CANONICAL (c) = c;), but also need to process pointers to it and only then return back to processing x. Processing the whole chain from c again could be costly, we could have hundreds of types in the chain already processed, and while the loop would just quickly skip them for (tree x = t, l = NULL_TREE; x; l = x, x = TYPE_NEXT_VARIANT (x)) { if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x)) ... else if (x != t) continue; it feels costly. So, this patch instead moves c from right after t to right before x in the chain (that shouldn't change anything, because clearly build_qualified_type didn't find any matches in the chain before x) and continues processing the c at that position, so should handle the x that encountered this in the next iteration. We could avoid some of the moving in the chain if we processed the chain twice, once deal only with x != t && TYPE_STRUCTURAL_EQUALITY_P (x) && TYPE_CANONICAL (t) == t && check_qualified_type (t, x, TYPE_QUALS (x)) types (in that case set TYPE_CANONICAL (x) = x) and once the rest. There is still the theoretical case where build_qualified_type would return a new type and in that case we are back to the moving the type around and needing to handle it though. 2024-06-25 Jakub Jelinek Martin Uecker PR c/114930 PR c/115502 gcc/c/ * c-decl.cc (c_update_type_canonical): Assert t is main variant with 0 TYPE_QUALS. Simplify and don't use check_qualified_type. Deal with the case where build_qualified_type returns TYPE_STRUCTURAL_EQUALITY_P type. gcc/testsuite/ * gcc.dg/pr114574-1.c: Require lto effective target. * gcc.dg/pr114574-2.c: Likewise. * gcc.dg/pr114930.c: New test. * gcc.dg/pr115502.c: New test. Diff: --- gcc/c/c-decl.cc | 38 +++--- gcc/testsuite/gcc.dg/pr114574-1.c | 6 +++--- gcc/testsuite/gcc.dg/pr114574-2.c | 6 +++--- gcc/testsuite/gcc.dg/pr114930.c | 9 + gcc/testsuite/gcc.dg/pr115502.c | 9 + 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 01326570e2b..0eac266471f 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9367,18 +9367,42 @@ is_flexible_array_member_p (bool is_last_field, static void c_update_type_canonical (tree t) { - for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) + gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t && !TYPE_QUALS (t)); + for (tree x = t, l = NULL_TREE; x; l = x, x = TYPE_NEXT_VARIANT (x)) { if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x)) { - if (TYPE_QUALS (x) == TYPE_QUALS (t)) + if (!TYPE_QUALS (x)) TYPE_CANONICAL (x) = TYPE_CANONICAL (t); - else if (TYPE_CANONICAL (t) != t - || check_qualified_type (x, t, TYPE_QUALS (x))) - TYPE_CANONICAL (x) -
[gcc r14-10366] c: Fix ICE related to incomplete structures in C23 [PR114930]
https://gcc.gnu.org/g:37bbd2c1667c70387f5fa6b52f461d57a204229d commit r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a204229d Author: Jakub Jelinek Date: Tue Jun 25 08:35:56 2024 +0200 c: Fix ICE related to incomplete structures in C23 [PR114930] Here is a version of the c_update_type_canonical fixes which passed bootstrap/regtest. The non-trivial part is the handling of the case when build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x)) returns a type with NULL TYPE_CANONICAL. That should happen only if TYPE_CANONICAL (t) == t, because otherwise c_update_type_canonical should have been already called on the other type. c, the returned type, is usually x and in that case it should have TYPE_CANONICAL set to itself, or worst for whatever reason x is not the right canonical type (say it has attributes or whatever disqualifies it from check_qualified_type). In that case either it finds some pre-existing type from the variant chain of t which is later in the chain and we haven't processed it yet (but then get_qualified_type moves it right after t in: /* Put the found variant at the head of the variant list so frequently searched variants get found faster. The C++ FE benefits greatly from this. */ tree t = *tp; *tp = TYPE_NEXT_VARIANT (t); TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv); TYPE_NEXT_VARIANT (mv) = t; return t; optimization), or creates a fresh new type using build_variant_type_copy, which again places the new type right after t: /* Add the new type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); TYPE_NEXT_VARIANT (m) = t; TYPE_MAIN_VARIANT (t) = m; At this point we want to make c its own canonical type (i.e. TYPE_CANONICAL (c) = c;), but also need to process pointers to it and only then return back to processing x. Processing the whole chain from c again could be costly, we could have hundreds of types in the chain already processed, and while the loop would just quickly skip them for (tree x = t, l = NULL_TREE; x; l = x, x = TYPE_NEXT_VARIANT (x)) { if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x)) ... else if (x != t) continue; it feels costly. So, this patch instead moves c from right after t to right before x in the chain (that shouldn't change anything, because clearly build_qualified_type didn't find any matches in the chain before x) and continues processing the c at that position, so should handle the x that encountered this in the next iteration. We could avoid some of the moving in the chain if we processed the chain twice, once deal only with x != t && TYPE_STRUCTURAL_EQUALITY_P (x) && TYPE_CANONICAL (t) == t && check_qualified_type (t, x, TYPE_QUALS (x)) types (in that case set TYPE_CANONICAL (x) = x) and once the rest. There is still the theoretical case where build_qualified_type would return a new type and in that case we are back to the moving the type around and needing to handle it though. 2024-06-25 Jakub Jelinek Martin Uecker PR c/114930 PR c/115502 gcc/c/ * c-decl.cc (c_update_type_canonical): Assert t is main variant with 0 TYPE_QUALS. Simplify and don't use check_qualified_type. Deal with the case where build_qualified_type returns TYPE_STRUCTURAL_EQUALITY_P type. gcc/testsuite/ * gcc.dg/pr114574-1.c: Require lto effective target. * gcc.dg/pr114574-2.c: Likewise. * gcc.dg/pr114930.c: New test. * gcc.dg/pr115502.c: New test. (cherry picked from commit 777cc6a01d1cf783a36d0fa67ab20f0312f35d7a) Diff: --- gcc/c/c-decl.cc | 38 +++--- gcc/testsuite/gcc.dg/pr114574-1.c | 6 +++--- gcc/testsuite/gcc.dg/pr114574-2.c | 6 +++--- gcc/testsuite/gcc.dg/pr114930.c | 9 + gcc/testsuite/gcc.dg/pr115502.c | 9 + 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index e63dab49589..0e52f217618 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9363,18 +9363,42 @@ is_flexible_array_member_p (bool is_last_field, static void c_update_type_canonical (tree t) { - for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) + gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t && !TYPE_QUALS (t)); + for (tree x = t, l = NULL_TREE; x; l = x, x = TYPE_NEXT_VARIANT (x)) { if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x)) { - if (TYPE_QUALS (x) == TYPE_QUALS (t)) + if (!TYPE_QUALS (x)) TYPE_CANONICAL (x) = TYPE_CANONICAL (t); - else if (TYPE_CANONICAL (t) != t - || check_q
[gcc/redhat/heads/gcc-14-branch] (37 commits) Merge commit 'r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a2
The branch 'redhat/heads/gcc-14-branch' was updated to point to: 6eada54ba86... Merge commit 'r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a2 It previously pointed to: 640bb0fa76a... Merge commit 'r14-10330-gd26fa1c73b2c0f7fd2d412ce7b4e84e0f7 Diff: Summary of changes (added commits): --- 6eada54... Merge commit 'r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a2 37bbd2c... c: Fix ICE related to incomplete structures in C23 [PR11493 (*) 78bd4b1... Daily bump. (*) 603b344... Fortran: fix ALLOCATE with SOURCE of deferred character len (*) 9f14748... Fortran: fix passing of optional dummy as actual to optiona (*) b31e190... Fortran: fix for CHARACTER(len=*) dummies with bind(C) [PR1 (*) 4fe3fff... Daily bump. (*) 47cbc76... Daily bump. (*) e6b115b... c++: decltype of capture proxy of ref [PR115504] (*) a00a8d4... c++: alias CTAD and copy deduction guide [PR115198] (*) 33a9c4d... c++: using non-dep array var of unknown bound [PR115358] (*) d5e352a... libstdc++: Fix std::format for chrono::duration with unsign (*) ef8b60d... rs6000: Fix wrong RTL patterns for vector merge high/low wo (*) 15d304d... Daily bump. (*) a8b77a6... libstdc++: Replace viewcvs links in docs with cgit links (*) b70af0b... [libstdc++] [testsuite] defer to check_vect_support* [PR115 (*) c2878a9... aarch64: Add support for -mcpu=grace (*) 6e6f10c... tree-ssa-pre.c/115214(ICE in find_or_generate_expression, a (*) f9cc628... Daily bump. (*) 532357b... Daily bump. (*) f91d9b3... libstdc++: Remove confusing text from status tables for rel (*) b383719... Fix PR c/115587, uninitialized variable in c_parser_omp_loo (*) 4bf93fc... SPARC: fix internal error with -mv8plus on 64-bit Linux (*) b7157f3... c-family: Add Warning property to Wnrvo option [PR115624] (*) faf5994... Daily bump. (*) 2b5e8f9... rs6000: Don't clobber return value when eh_return called [P (*) 1a2329d... Daily bump. (*) 1735b86... Daily bump. (*) 70d9d92... Daily bump. (*) 9421f02... AArch64: Fix cpu features initialization [PR115342] (*) a851931... libstdc++: Fix test on x86_64 and non-simd targets (*) a16f47f... Build: Set gcc_cv_as_mips_explicit_relocs if gcc_cv_as_mips (*) 272e8c9... tree-optimization/115278 - fix DSE in if-conversion wrt vol (*) 65e2586... tree-optimization/115508 - fix ICE with SLP scheduling and (*) 85d32e6... Avoid SLP_REPRESENTATIVE access for VEC_PERM in SLP schedul (*) 30fca2c... Daily bump. (*) e77f314... libstdc++: Fix find_last_set(simd_mask) to ignore padding b (*) (*) This commit already exists in another branch. Because the reference `refs/vendors/redhat/heads/gcc-14-branch' matches your hooks.email-new-commits-only configuration, no separate email is sent for this commit.
[gcc(refs/vendors/redhat/heads/gcc-14-branch)] Merge commit 'r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a204229d' into redhat/gcc-14-branch
https://gcc.gnu.org/g:6eada54ba865eeb9aabfcfbc106c3fbff7abe98a commit 6eada54ba865eeb9aabfcfbc106c3fbff7abe98a Merge: 640bb0fa76a 37bbd2c1667 Author: Jakub Jelinek Date: Mon Jul 1 10:20:55 2024 +0200 Merge commit 'r14-10366-g37bbd2c1667c70387f5fa6b52f461d57a204229d' into redhat/gcc-14-branch Diff: gcc/ChangeLog | 134 +++ gcc/DATESTAMP | 2 +- gcc/c-family/ChangeLog | 8 + gcc/c-family/c.opt | 2 +- gcc/c/ChangeLog| 9 + gcc/c/c-decl.cc| 38 - gcc/c/c-parser.cc | 4 +- gcc/config/aarch64/aarch64-cores.def | 2 + gcc/config/aarch64/aarch64-tune.md | 2 +- gcc/config/rs6000/altivec.md | 80 ++--- gcc/config/rs6000/rs6000-logue.cc | 7 +- gcc/config/rs6000/rs6000.cc| 8 +- gcc/config/rs6000/rs6000.md| 15 ++ gcc/config/rs6000/vsx.md | 28 ++-- gcc/config/sparc/linux64.h | 2 +- gcc/configure | 2 + gcc/configure.ac | 2 + gcc/cp/ChangeLog | 39 + gcc/cp/decl2.cc| 2 + gcc/cp/parser.cc | 8 +- gcc/cp/pt.cc | 6 +- gcc/cp/semantics.cc| 8 - gcc/cp/typeck.cc | 7 - gcc/doc/invoke.texi| 4 +- gcc/fortran/ChangeLog | 31 gcc/fortran/trans-array.cc | 20 ++- gcc/fortran/trans-decl.cc | 4 +- gcc/fortran/trans-stmt.cc | 5 +- gcc/testsuite/ChangeLog| 125 ++ gcc/testsuite/g++.dg/cpp1y/decltype-auto8.C| 22 +++ .../g++.dg/cpp2a/class-deduction-alias22.C | 14 ++ gcc/testsuite/g++.dg/template/array37.C| 14 ++ gcc/testsuite/g++.dg/vect/pr115278.cc | 38 + gcc/testsuite/g++.target/powerpc/pr106069.C| 119 ++ gcc/testsuite/gcc.dg/pr114574-1.c | 6 +- gcc/testsuite/gcc.dg/pr114574-2.c | 6 +- gcc/testsuite/gcc.dg/pr114930.c| 9 + gcc/testsuite/gcc.dg/pr115502.c| 9 + gcc/testsuite/gcc.target/i386/pr115508.c | 15 ++ gcc/testsuite/gcc.target/powerpc/pr114846.c| 20 +++ gcc/testsuite/gcc.target/powerpc/pr115355.c| 37 + .../gcc.target/riscv/rvv/vsetvl/pr115214.c | 52 ++ .../gfortran.dg/allocate_with_source_33.f90| 69 gcc/testsuite/gfortran.dg/bind_c_char_11.f90 | 45 + gcc/testsuite/gfortran.dg/optional_absent_12.f90 | 30 gcc/tree-if-conv.cc| 4 +- gcc/tree-ssa-pre.cc| 10 +- gcc/tree-vect-slp.cc | 29 ++-- libgcc/ChangeLog | 13 ++ libgcc/config/aarch64/cpuinfo.c| 181 + libstdc++-v3/ChangeLog | 65 libstdc++-v3/doc/html/faq.html | 2 +- libstdc++-v3/doc/html/manual/memory.html | 10 +- .../doc/html/manual/mt_allocator_impl.html | 6 +- libstdc++-v3/doc/html/manual/status.html | 16 +- libstdc++-v3/doc/xml/faq.xml | 2 +- libstdc++-v3/doc/xml/manual/allocator.xml | 10 +- libstdc++-v3/doc/xml/manual/mt_allocator.xml | 6 +- libstdc++-v3/doc/xml/manual/status_cxx1998.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxx2011.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxx2014.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxx2017.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxx2020.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxx2023.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxxtr1.xml | 2 +- libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml | 2 +- libstdc++-v3/include/bits/chrono_io.h | 5 +- libstdc++-v3/include/experimental/bits/simd_x86.h | 26 +-- libstdc++-v3/testsuite/20_util/duration/io.cc | 6 + .../experimental/simd/pr115454_find_last_set.cc| 50 ++ 70 files changed, 1301 insertions(+), 265 deletions(-)
[gcc r15-1793] c++: Implement C++26 P0963R3 - Structured binding declaration as a condition [PR115745]
https://gcc.gnu.org/g:f30bdb1f2d79fd787e0c270039179bf80830161f commit r15-1793-gf30bdb1f2d79fd787e0c270039179bf80830161f Author: Jakub Jelinek Date: Tue Jul 2 22:07:30 2024 +0200 c++: Implement C++26 P0963R3 - Structured binding declaration as a condition [PR115745] This C++26 paper allows structured bindings declaration in if/while/for/switch conditions, where the structured binding shouldn't be initialized by array (so in the standard only non-union class types; as extension _Complex will also work and vectors will be diagnosed because of conversion issues) and the decision variable is the artificial variable (e in the standard) itself contextually converted to bool or converted to some integer/enumeration type. The standard requires that the conversion is evaluated before the get calls in case of std::tuple* using class, so the largest part of the patch is making sure this can be done during instantiation without duplicating too much code. In cp_parser_condition, creating a TARGET_EXPR to hold temporarily the bool or int/enum result of the conversion across the get calls is easy, it could be just added in between cp_finish_decl and cp_finish_decomp, but for pt.cc there was no easy spot to add that. In the end, the patch uses DECL_DECOMP_BASE for this. That tree is used primarily for the user vars or var proxies to point back at the DECL_ARTIFICIAL e variable, before this patch it has been NULL_TREE on the base. In some places code was checking if DECL_DECOMP_BASE is NULL_TREE to find out if it is the base or user var/var proxy. The patch introduces DECL_DECOMP_IS_BASE macro for what used to be !DECL_DECOMP_BASE and can stick something else in the base's DECL_DECOMP_BASE as long as it is not a VAR_DECL. The patch uses integer_zero_node to mark if/while/for condition structured binding, integer_one_node to mark switch condition structured binding and finally cp_finish_decomp sets it to TARGET_EXPR if some get method calls are emitted and from there the callers can pick that up. This way I also avoided code duplication between !processing_template_decl parsing and pt.cc. 2024-07-02 Jakub Jelinek PR c++/115745 gcc/cp/ * cp-tree.h: Implement C++26 P0963R3 - Structured binding declaration as a condition. (DECL_DECOMP_BASE): Adjust comment. (DECL_DECOMP_IS_BASE): Define. * parser.cc (cp_parser_selection_statement): Adjust cp_parser_condition caller. (cp_parser_condition): Add KEYWORD argument. Parse C++26 structured bindings in conditions. (cp_parser_c_for, cp_parser_iteration_statement): Adjust cp_parser_condition callers. (cp_parser_simple_declaration): Adjust cp_parser_decomposition_declaration caller. (cp_parser_decomposition_declaration): Add KEYWORD argument. If it is not RID_MAX, diagnose for C++23 and older rather than C++14 and older. Set DECL_DECOMP_BASE to integer_zero_node for structured bindings used in if/while/for conditions or integer_one_node for those used in switch conditions. * decl.cc (poplevel, check_array_initializer): Use DECL_DECOMP_IS_BASE instead of !DECL_DECOMP_BASE. (cp_finish_decomp): Diagnose array initializer for structured bindings used in conditions. If using std::tuple_{size,element}, emit conversion to bool or integer/enumeration of e into a TARGET_EXPR before emitting get method calls. * decl2.cc (mark_used): Use DECL_DECOMP_IS_BASE instead of !DECL_DECOMP_BASE. * module.cc (trees_in::tree_node): Likewise. * typeck.cc (maybe_warn_about_returning_address_of_local): Likewise. * semantics.cc (maybe_convert_cond): For structured bindings with TARGET_EXPR DECL_DECOMP_BASE use that as condition. (finish_switch_cond): Likewise. gcc/testsuite/ * g++.dg/cpp1z/decomp16.C: Adjust expected diagnostics. * g++.dg/cpp26/decomp3.C: New test. * g++.dg/cpp26/decomp4.C: New test. * g++.dg/cpp26/decomp5.C: New test. * g++.dg/cpp26/decomp6.C: New test. * g++.dg/cpp26/decomp7.C: New test. * g++.dg/cpp26/decomp8.C: New test. * g++.dg/cpp26/decomp9.C: New test. * g++.dg/cpp26/decomp10.C: New test. Diff: --- gcc/cp/cp-tree.h | 10 +- gcc/cp/decl.cc| 34 ++- gcc/cp/decl2.cc | 2 +- gcc/cp/module.cc | 2 +- gcc/cp/parser.cc | 46 +++-- gcc/cp/semantics.cc | 17 gcc/cp/typeck.cc | 2 +- gcc/testsui
[gcc r15-1794] c++: Implement C++26 P3144R2 - Deleting a Pointer to an Incomplete Type Should be Ill-formed [PR1157
https://gcc.gnu.org/g:beb7a418aaef2ec8a812712110b007c091a73491 commit r15-1794-gbeb7a418aaef2ec8a812712110b007c091a73491 Author: Jakub Jelinek Date: Tue Jul 2 22:08:45 2024 +0200 c++: Implement C++26 P3144R2 - Deleting a Pointer to an Incomplete Type Should be Ill-formed [PR115747] The following patch implements the C++26 paper which makes delete and delete[] on incomplete class types invalid, previously it has been UB unless the class had trivial destructor and no custom deallocator. The patch uses permerror_opt, so -Wno-delete-incomplete makes it still compile without warnings like before, and -fpermissive makes it warn but not error; in SFINAE contexts it is considered an error in C++26 and later. 2024-07-02 Jakub Jelinek Jason Merrill PR c++/115747 gcc/cp/ * init.cc: Implement C++26 P3144R2 - Deleting a Pointer to an Incomplete Type Should be Ill-formed. (build_vec_delete_1): Emit permerror_at and return error_mark_node for delete [] on incomplete type. (build_delete): Similarly for delete. gcc/testsuite/ * g++.dg/init/delete1.C: Adjust expected diagnostics for C++26. * g++.dg/warn/Wdelete-incomplete-1.C: Likewise. * g++.dg/warn/incomplete1.C: Likewise. * g++.dg/ipa/pr85607.C: Likewise. * g++.dg/cpp26/delete1.C: New test. * g++.dg/cpp26/delete2.C: New test. * g++.dg/cpp26/delete3.C: New test. Diff: --- gcc/cp/init.cc | 38 ++-- gcc/testsuite/g++.dg/cpp26/delete1.C | 36 ++ gcc/testsuite/g++.dg/cpp26/delete2.C | 36 ++ gcc/testsuite/g++.dg/cpp26/delete3.C | 36 ++ gcc/testsuite/g++.dg/init/delete1.C | 7 +++-- gcc/testsuite/g++.dg/ipa/pr85607.C | 7 +++-- gcc/testsuite/g++.dg/warn/Wdelete-incomplete-1.C | 7 +++-- gcc/testsuite/g++.dg/warn/incomplete1.C | 7 +++-- 8 files changed, 160 insertions(+), 14 deletions(-) diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 4a7ed7f5302..826a31c4a84 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4114,7 +4114,24 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type, if (!COMPLETE_TYPE_P (type)) { - if (complain & tf_warning) + if (cxx_dialect > cxx23) + { + if (complain & tf_error) + { + int saved_errorcount = errorcount; + if (permerror_opt (loc, OPT_Wdelete_incomplete, +"operator % used on " +"incomplete type")) + { + cxx_incomplete_type_inform (type); + if (errorcount != saved_errorcount) + return error_mark_node; + } + } + else + return error_mark_node; + } + else if (complain & tf_warning) { auto_diagnostic_group d; if (warning_at (loc, OPT_Wdelete_incomplete, @@ -5178,7 +5195,24 @@ build_delete (location_t loc, tree otype, tree addr, if (!COMPLETE_TYPE_P (type)) { - if (complain & tf_warning) + if (cxx_dialect > cxx23) + { + if (complain & tf_error) + { + int saved_errorcount = errorcount; + if (permerror_opt (loc, OPT_Wdelete_incomplete, +"operator % used on " +"incomplete type")) + { + cxx_incomplete_type_inform (type); + if (errorcount != saved_errorcount) + return error_mark_node; + } + } + else + return error_mark_node; + } + else if (complain & tf_warning) { auto_diagnostic_group d; if (warning_at (loc, OPT_Wdelete_incomplete, diff --git a/gcc/testsuite/g++.dg/cpp26/delete1.C b/gcc/testsuite/g++.dg/cpp26/delete1.C new file mode 100644 index 000..ca7766af1b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/delete1.C @@ -0,0 +1,36 @@ +// C++26 P3144R2 - Deleting a Pointer to an Incomplete Type Should be Ill-formed +// { dg-do compile { target c++26 } } + +struct S; // { dg-message "forward declaration of 'struct S'" } +struct T; // { dg-message "forward declaration of 'struct T'" } +struct U; // { dg-message "forward declaration of 'struct U'" } + +void +foo (S *p, T *q, U *r, S *s, T *t, U *u) +{ + delete p;// { dg-error "operator 'delete' used on incomplete type" } + delete q;// { dg-error "operator 'delete' used on incomplete typ
[gcc r15-1795] c++: Fix ICE on constexpr placement new [PR115754]
https://gcc.gnu.org/g:1250540a98e0a1dfa4d7834672d88d8543ea70b1 commit r15-1795-g1250540a98e0a1dfa4d7834672d88d8543ea70b1 Author: Jakub Jelinek Date: Tue Jul 2 22:09:58 2024 +0200 c++: Fix ICE on constexpr placement new [PR115754] C++26 is making in P2747R2 paper placement new constexpr. While working on a patch for that, I've noticed we ICE starting with GCC 14 on the following testcase. The problem is that e.g. for the void * to sometype * casts checks, we really assume the casts have their operand constant evaluated as prvalue, but on the testcase the cast itself is evaluated with vc_discard and that means op can end up e.g. a VAR_DECL which the later code doesn't like and asserts on. If the result type is void, we don't really need the cast operand for anything, so can use vc_discard for the recursive call, VIEW_CONVERT_EXPR can appear on the lhs, so we need to honor the lval but otherwise the patch uses vc_prvalue. I'd like to get this patch in before the rest of P2747R2 implementation, so that it can be backported to 14.2 later on. 2024-07-02 Jakub Jelinek Jason Merrill PR c++/115754 * constexpr.cc (cxx_eval_constant_expression) : For conversions to void, pass vc_discard to the recursive call and otherwise for tcode other than VIEW_CONVERT_EXPR pass vc_prvalue. * g++.dg/cpp26/pr115754.C: New test. Diff: --- gcc/cp/constexpr.cc | 5 - gcc/testsuite/g++.dg/cpp26/pr115754.C | 36 +++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index bd72533491e..0cdac0af7de 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8103,7 +8103,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, tree oldop = TREE_OPERAND (t, 0); tree op = cxx_eval_constant_expression (ctx, oldop, - lval, + VOID_TYPE_P (TREE_TYPE (t)) + ? vc_discard + : tcode == VIEW_CONVERT_EXPR + ? lval : vc_prvalue, non_constant_p, overflow_p); if (*non_constant_p) return t; diff --git a/gcc/testsuite/g++.dg/cpp26/pr115754.C b/gcc/testsuite/g++.dg/cpp26/pr115754.C new file mode 100644 index 000..45a8efcd9a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/pr115754.C @@ -0,0 +1,36 @@ +// PR c++/115754 +// { dg-do compile { target c++26 } } + +namespace std +{ + using size_t = decltype (sizeof 0); + + template + struct allocator + { +constexpr allocator () noexcept {} + +constexpr T *allocate (size_t n) +{ return static_cast (::operator new (n * sizeof(T))); } + +constexpr void +deallocate (T *p, size_t n) +{ ::operator delete (p); } + }; +} + +constexpr void * +operator new (std::size_t, void *p) noexcept +{ return p; } + +constexpr bool +foo () +{ + std::allocator a; + auto b = a.allocate (1); + ::new (b) int (); + a.deallocate (b, 1); + return true; +} + +constexpr bool a = foo ();
[gcc r15-1906] c++: Implement C++26 CWG2819 - Allow cv void * null pointer value conversion to object types in cons
https://gcc.gnu.org/g:8eab5064d54f41054b6a50d233a1a78a935b1c2a commit r15-1906-g8eab5064d54f41054b6a50d233a1a78a935b1c2a Author: Jakub Jelinek Date: Tue Jul 9 09:37:16 2024 +0200 c++: Implement C++26 CWG2819 - Allow cv void * null pointer value conversion to object types in constant expressions The following patch implements CWG2819 (which wasn't a DR because it changes behavior of C++26 only). 2024-07-09 Jakub Jelinek * constexpr.cc (cxx_eval_constant_expression): CWG2819 - Allow cv void * null pointer value conversion to object types in constant expressions. * g++.dg/cpp26/constexpr-voidptr3.C: New test. * g++.dg/cpp0x/constexpr-cast2.C: Adjust expected diagnostics for C++26. * g++.dg/cpp0x/constexpr-cast4.C: Likewise. Diff: --- gcc/cp/constexpr.cc | 37 ++--- gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C| 4 +-- gcc/testsuite/g++.dg/cpp0x/constexpr-cast4.C| 1 - gcc/testsuite/g++.dg/cpp26/constexpr-voidptr3.C | 13 + 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 0cdac0af7de0..14bbdea2546d 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8157,10 +8157,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, || DECL_NAME (decl) == heap_vec_uninit_identifier)) /* OK */; /* P2738 (C++26): a conversion from a prvalue P of type "pointer to - cv void" to a pointer-to-object type T unless P points to an - object whose type is similar to T. */ + cv void" to a pointer-to-object type T unless P is a null + pointer value or points to an object whose type is similar to + T. */ else if (cxx_dialect > cxx23) { + if (integer_zerop (sop)) + return build_int_cst (type, 0); r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop); if (r) { @@ -8169,26 +8172,16 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, } if (!ctx->quiet) { - if (TREE_CODE (sop) == ADDR_EXPR) - { - auto_diagnostic_group d; - error_at (loc, "cast from %qT is not allowed in a " - "constant expression because " - "pointed-to type %qT is not similar to %qT", - TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)), - TREE_TYPE (type)); - tree obj = build_fold_indirect_ref (sop); - inform (DECL_SOURCE_LOCATION (obj), - "pointed-to object declared here"); - } - else - { - gcc_assert (integer_zerop (sop)); - error_at (loc, "cast from %qT is not allowed in a " - "constant expression because " - "%qE does not point to an object", - TREE_TYPE (op), oldop); - } + gcc_assert (TREE_CODE (sop) == ADDR_EXPR); + auto_diagnostic_group d; + error_at (loc, "cast from %qT is not allowed in a " + "constant expression because " + "pointed-to type %qT is not similar to %qT", + TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)), + TREE_TYPE (type)); + tree obj = build_fold_indirect_ref (sop); + inform (DECL_SOURCE_LOCATION (obj), + "pointed-to object declared here"); } *non_constant_p = true; return t; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C index 3efbd92f0439..71ec08f36137 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-cast2.C @@ -5,9 +5,9 @@ static int i; constexpr void *vp0 = nullptr; constexpr void *vpi = &i; -constexpr int *p1 = (int *) vp0; // { dg-error "cast from .void\\*. is not allowed" } +constexpr int *p1 = (int *) vp0; // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } constexpr int *p2 = (int *) vpi; // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } -constexpr int *p3 = static_cast(vp0); // { dg-error "cast from .void\\*. is not allowed" } +constexpr int *p3 = static_cast(vp0); // { dg-error "cast from .void\\*. is not allowed" "" { target c++23_down } } cons
[gcc r15-1907] c: Rewrite c_parser_omp_tile_sizes to use c_parser_expr_list
https://gcc.gnu.org/g:4f767174b83027091f0e84b4ddb9a6370e549ffd commit r15-1907-g4f767174b83027091f0e84b4ddb9a6370e549ffd Author: Jakub Jelinek Date: Tue Jul 9 10:45:25 2024 +0200 c: Rewrite c_parser_omp_tile_sizes to use c_parser_expr_list The following patch simplifies c_parser_omp_tile_sizes to use c_parser_expr_list, so that it will get CPP_EMBED parsing naturally, without having another spot that needs to be adjusted for it. 2024-07-09 Jakub Jelinek * c-parser.cc (c_parser_omp_tile_sizes): Use c_parser_expr_list. * c-c++-common/gomp/tile-11.c: Adjust expected diagnostics for c. * c-c++-common/gomp/tile-12.c: Likewise. Diff: --- gcc/c/c-parser.cc | 25 + gcc/testsuite/c-c++-common/gomp/tile-11.c | 6 +++--- gcc/testsuite/c-c++-common/gomp/tile-12.c | 6 +++--- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 8c4e697a4e10..12c5ed5d92c7 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -26431,24 +26431,20 @@ c_parser_omp_tile_sizes (c_parser *parser, location_t loc) if (!parens.require_open (parser)) return error_mark_node; - do -{ - if (sizes && !c_parser_require (parser, CPP_COMMA, "expected %<,%>")) - return error_mark_node; - - location_t expr_loc = c_parser_peek_token (parser)->location; - c_expr cexpr = c_parser_expr_no_commas (parser, NULL); - cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); - tree expr = cexpr.value; + vec *sizes_vec += c_parser_expr_list (parser, true, true, NULL, NULL, NULL, NULL); + sizes = build_tree_list_vec (sizes_vec); + release_tree_vector (sizes_vec); + for (tree s = sizes; s; s = TREE_CHAIN (s)) +{ + tree expr = TREE_VALUE (s); if (expr == error_mark_node) { parens.skip_until_found_close (parser); return error_mark_node; } - expr = c_fully_fold (expr, false, NULL); - HOST_WIDE_INT n; if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) || !tree_fits_shwi_p (expr) @@ -26457,17 +26453,14 @@ c_parser_omp_tile_sizes (c_parser *parser, location_t loc) { c_parser_error (parser, "% argument needs positive" " integral constant"); - expr = integer_one_node; + TREE_VALUE (s) = integer_one_node; } - - sizes = tree_cons (NULL_TREE, expr, sizes); } - while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); parens.require_close (parser); gcc_assert (sizes); tree c = build_omp_clause (loc, OMP_CLAUSE_SIZES); - OMP_CLAUSE_SIZES_LIST (c) = nreverse (sizes); + OMP_CLAUSE_SIZES_LIST (c) = sizes; return c; } diff --git a/gcc/testsuite/c-c++-common/gomp/tile-11.c b/gcc/testsuite/c-c++-common/gomp/tile-11.c index 7659fc5a072b..bf38bbe5dae6 100644 --- a/gcc/testsuite/c-c++-common/gomp/tile-11.c +++ b/gcc/testsuite/c-c++-common/gomp/tile-11.c @@ -21,9 +21,9 @@ test (void) for (int i = 0; i < 100; ++i) dummy (i); - #pragma omp tile sizes(1,2 /* { dg-error "expected ',' before end of line" } */ - for (int i = 0; i < 100; ++i) -dummy (i); + #pragma omp tile sizes(1,2 /* { dg-error "expected '\\\)' before end of line" "" { target c } } */ + for (int i = 0; i < 100; ++i) /* { dg-error "not enough nested loops" "" { target c } } */ +dummy (i); /* { dg-error "expected ',' before end of line" "" { target c++ } .-2 } */ #pragma omp tile sizes /* { dg-error "expected '\\\(' before end of line" } */ for (int i = 0; i < 100; ++i) diff --git a/gcc/testsuite/c-c++-common/gomp/tile-12.c b/gcc/testsuite/c-c++-common/gomp/tile-12.c index 8408d53b641e..f36bbdb0ef68 100644 --- a/gcc/testsuite/c-c++-common/gomp/tile-12.c +++ b/gcc/testsuite/c-c++-common/gomp/tile-12.c @@ -35,9 +35,9 @@ test (void) dummy (i); #pragma omp parallel for - #pragma omp tile sizes(1,2 /* { dg-error "expected ',' before end of line" } */ - for (int i = 0; i < 100; ++i) -dummy (i); + #pragma omp tile sizes(1,2 /* { dg-error "expected '\\\)' before end of line" "" { target c } } */ + for (int i = 0; i < 100; ++i) /* { dg-error "not enough nested loops" "" { target c } } */ +dummy (i); /* { dg-error "expected ',' before end of line" "" { target c++ } .-2 } */ #pragma omp parallel for #pragma omp tile sizes /* { dg-error "expected '\\\(' before end of line" } */
[gcc r15-2039] varasm: Add support for emitting binary data with the new gas .base64 directive
https://gcc.gnu.org/g:9964edfb4abdec25f8be48e667afcae30ce03a37 commit r15-2039-g9964edfb4abdec25f8be48e667afcae30ce03a37 Author: Jakub Jelinek Date: Mon Jul 15 09:48:38 2024 +0200 varasm: Add support for emitting binary data with the new gas .base64 directive Nick has implemented a new .base64 directive in gas (to be shipped in the upcoming binutils 2.43; big thanks for that). See https://sourceware.org/bugzilla/show_bug.cgi?id=31964 The following patch adjusts default_elf_asm_output_ascii (i.e. ASM_OUTPUT_ASCII elfos.h implementation) to use it if it detects binary data and gas supports it. Without this patch, we emit stuff like: .string "\177ELF\002\001\001\003" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "\002" .string ">" ... .string "\324\001\236 0FS\202\002E\n0@\203\004\005&\202\021\337)\021\203C\020A\300\220I\004\t\b\206(\234\0132l\004b\300\bK\006\220$0\303\020P$\233\211\002D\f" etc., with this patch more compact .base64 "f0VMRgIBAQMAAAIAPgABABf3AABAAACneB0AAEAAOAAOAEAALAArAAYEQABAAEAAAEAAQAAAEAMQAwgAAwQAAABQAwAAAFADQAAAUANcABwAAQABBABAAEAAADBwOQAAMHA5EAEFAIA5gHkA" .base64 "AACAeQAAxSSgAgDFJKACAAAQAQQAsNkCAACwGQMAALAZAwDMtc0AAMy1zQAAABABBgAAAGhmpwMAaHbnAwBoducDAOAMAQAA4MEeEAIGkH2nAwCQjecDAJCN5wMAQAIAAABAAggABAQAAABwAwAAAHADQAAAcANAAABAAEAACAAA" .base64 "AAAEBLADsANAAACwA0AAACAAIAAEAAcEaGanAwBoducDAGh25wMQAAgAU+V0ZAQAAABwAwAAAHADQAAAcANAAABAAEAACABQ5XRkBAw/WAMADD+YAwAMP5gDAPy7CgAA/LsKAAAEAFHldGQG" .base64 "ABAAUuV0ZAQAAABoZqcDAGh25wMAaHbnAwCYGQAAAJgZAQAvbGliNjQvbGQtbGludXgteDg2LTY0LnNvLjIAAAQwBQAAAEdOVQACgADABAEAAQABwAQJAAIAAcAEAwAEEAEAAABHTlUAAAMCAAOAAACsqAAAgS0AAOJWAAAjNwAAXjAAF1gAAHsxAABBBwAA" .base64 "G0kAALGmAACwoACQhOw1AACNYgAAAFQox3UAALZAiIUAALGeAABBlAAAWEsAAPmRAACmOgAAADh3lCBymgAAaosAAMIjAAAKMQAAMkIAADU05ZwAAFIdAAAIGQAAAMFbAAAoTQAAGDcAAIRgAAA6HgAAlxwAAADOlgAAAEhPAAARiwAAMGgAAOVtAADMFgCrjgAAYl4AACZVAAA/HgBqPwAA" The patch attempts to juggle between readability and compactness, so if it detects some hunk of the initializer that would be shorter to be emitted as .string/.ascii directive, it does so, but if it previously used .base64 directive it switches mode only if there is a 16+ char ASCII-ish string. On my #embed testcase from yesterday unsigned char a[] = { #embed "cc1plus" }; without this patch it emits 2.4GB of assembly, while with this patch 649M. Compile times (trunk, so yes,rtl,extra checking) are: time ./xgcc -B ./ -S -std=c23 -O2 embed-11.c real0m13.647s user0m7.157s sys 0m2.597s time ./xgcc -B ./ -c -std=c23 -O2 embed-11.c real0m28.649s user0m26.653s sys 0m1.958s without the patch and time ./xgcc -B ./ -S -std=c23 -O2 embed-11.c real0m4.283s user0m2.288s sys 0m0.859s time ./xgcc -B ./ -c -std=c23 -O2 embed-11.c real0m6.888s user0m5.876s sys 0m1.002s with the patch, so that feels like significant improvement. The resulting embed-11.o is identical between the two ways of expressing the mostly binary data in the assembly. But note that there are portions like: .base64 "nAAvZRcAIgAOAFAzMwEABgCEQBgAEgAOAFBHcAIA7AAAX19nbXB6X2dldF9zaQBtcGZyX3NldF9zaV8yZXhwAG1wZnJfY29zaABtcGZyX3RhbmgAbXBmcl9zZXRfbmFuAG1wZnJfc3ViAG1wZnJfdGFuAG1wZnJfc3RydG9mcgBfX2dtcHpfc3ViX3VpAF9fZ21wX2dldF9tZW1vcnlfZnVuY3Rpb25zAF9fZ21wel9zZXRfdWkAbXBmcl9wb3cAX19nbXB6X3N1YgBfX2dtcHpfZml0c19zbG9uZ19wAG1wZnJfYXRh" .base64 "bjIAX19nbXB6X2RpdmV4YWN0AG1wZnJfc2V0X2VtaW4AX19nbXB6X3NldABfX2dtcHpfbXVsAG1wZnJfY2xlYXIAbXBmcl9sb2cAbXBmcl9hdGFuaABfX2dtcHpfc3dhcABtcGZyX2FzaW5oAG1wZnJfYXNpbgBtcGZyX2NsZWFycwBfX2dtcHpfbXVsXzJleHAAX19nbXB6X2FkZG11bABtcGZyX3NpbmgAX19nbXB6X2FkZF91aQBfX2dtcHFfY2xlYXIAX19nbW9uX3N0YXJ0X18AbXBmcl9hY29zAG1wZnJfc2V0X2VtYXgAbXBmcl9jb3MAbXBmcl9zaW4A
[gcc r15-2090] gimple-fold: Fix up __builtin_clear_padding lowering [PR115527]
https://gcc.gnu.org/g:8b5919bae11754f4b65a17e63663d3143f9615ac commit r15-2090-g8b5919bae11754f4b65a17e63663d3143f9615ac Author: Jakub Jelinek Date: Wed Jul 17 11:38:33 2024 +0200 gimple-fold: Fix up __builtin_clear_padding lowering [PR115527] The builtin-clear-padding-6.c testcase fails as clear_padding_type doesn't correctly recompute the buf->size and buf->off members after expanding clearing of an array using a runtime loop. buf->size should be in that case the offset after which it should continue with next members or padding before them modulo UNITS_PER_WORD and buf->off that offset minus buf->size. That is what the code was doing, but with off being the start of the loop cleared array, not its end. So, the last hunk in gimple-fold.cc fixes that. When adding the testcase, I've noticed that the c-c++-common/torture/builtin-clear-padding-* tests, although clearly written as runtime tests to test the builtins at runtime, didn't have { dg-do run } directive and were just compile tests because of that. When adding that to the tests, builtin-clear-padding-1.c was already failing without that clear_padding_type hunk too, but builtin-clear-padding-5.c was still failing even after the change. That is due to a bug in clear_padding_flush which the patch fixes as well - when clear_padding_flush is called with full=true (that happens at the end of the whole __builtin_clear_padding or on those array padding clears done by a runtime loop), it wants to flush all the pending padding clearings rather than just some. If it is at the end of the whole object, it decreases wordsize when needed to make sure the code never writes including RMW cycles to something outside of the object: if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize) > (unsigned HOST_WIDE_INT) buf->sz) { gcc_assert (wordsize > 1); wordsize /= 2; i -= wordsize; continue; } but if it is full==true flush in the middle, this doesn't happen, but we still process just the buffer bytes before the current end. If that end is not on a wordsize boundary, e.g. on the builtin-clear-padding-5.c test the last chunk is 2 bytes, '\0', '\xff', i is 16 and end is 18, nonzero_last might be equal to the end - i, i.e. 2 here, but still all_ones might be true, so in some spots we just didn't emit any clearing in that last chunk. 2024-07-17 Jakub Jelinek PR middle-end/115527 * gimple-fold.cc (clear_padding_flush): Introduce endsize variable and use it instead of wordsize when comparing it against nonzero_last. (clear_padding_type): Increment off by sz. * c-c++-common/torture/builtin-clear-padding-1.c: Add dg-do run directive. * c-c++-common/torture/builtin-clear-padding-2.c: Likewise. * c-c++-common/torture/builtin-clear-padding-3.c: Likewise. * c-c++-common/torture/builtin-clear-padding-4.c: Likewise. * c-c++-common/torture/builtin-clear-padding-5.c: Likewise. * c-c++-common/torture/builtin-clear-padding-6.c: New test. Diff: --- gcc/gimple-fold.cc | 12 ++ .../c-c++-common/torture/builtin-clear-padding-1.c | 1 + .../c-c++-common/torture/builtin-clear-padding-2.c | 1 + .../c-c++-common/torture/builtin-clear-padding-3.c | 1 + .../c-c++-common/torture/builtin-clear-padding-4.c | 4 ++-- .../c-c++-common/torture/builtin-clear-padding-5.c | 1 + .../c-c++-common/torture/builtin-clear-padding-6.c | 28 ++ 7 files changed, 41 insertions(+), 7 deletions(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index 7c534d56bf1b..ed9508e4c912 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -4242,7 +4242,8 @@ clear_padding_flush (clear_padding_struct *buf, bool full) i -= wordsize; continue; } - for (size_t j = i; j < i + wordsize && j < end; j++) + size_t endsize = end - i > wordsize ? wordsize : end - i; + for (size_t j = i; j < i + endsize; j++) { if (buf->buf[j]) { @@ -4271,12 +4272,12 @@ clear_padding_flush (clear_padding_struct *buf, bool full) if (padding_bytes) { if (nonzero_first == 0 - && nonzero_last == wordsize + && nonzero_last == endsize && all_ones) { /* All bits are padding and we had some padding before too. Just extend it. */ - padding_bytes += wordsize; + padding_bytes += endsize; continue; } if (all_ones && nonzero_first == 0) @@ -4316,7 +4317,7 @@ clear_padding_flush (clear_padding_struct *buf, bool full) if (nonzero_first == wordsize)
[gcc r15-2092] testsuite: Add dg-do run to another test
https://gcc.gnu.org/g:2790800c61fb5748cd336e09a691848dd3e74090 commit r15-2092-g2790800c61fb5748cd336e09a691848dd3e74090 Author: Jakub Jelinek Date: Wed Jul 17 11:40:58 2024 +0200 testsuite: Add dg-do run to another test This is another test which clearly has been written with the assumption that it will be executed, but it isn't. It works fine when it is executed on both x86_64-linux and i686-linux. 2024-07-17 Jakub Jelinek * c-c++-common/torture/builtin-convertvector-1.c: Add dg-do run directive. Diff: --- gcc/testsuite/c-c++-common/torture/builtin-convertvector-1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/c-c++-common/torture/builtin-convertvector-1.c b/gcc/testsuite/c-c++-common/torture/builtin-convertvector-1.c index fababf1a9eb3..5ce5890685ab 100644 --- a/gcc/testsuite/c-c++-common/torture/builtin-convertvector-1.c +++ b/gcc/testsuite/c-c++-common/torture/builtin-convertvector-1.c @@ -1,3 +1,4 @@ +/* { dg-do run } */ /* { dg-skip-if "double support is incomplete" { "avr-*-*" } } */ extern
[gcc r15-2091] varasm: Fix bootstrap after the .base64 changes [PR115958]
https://gcc.gnu.org/g:74bcef4cf16b35fe64767c1e8e529bdd229841a3 commit r15-2091-g74bcef4cf16b35fe64767c1e8e529bdd229841a3 Author: Jakub Jelinek Date: Wed Jul 17 11:40:03 2024 +0200 varasm: Fix bootstrap after the .base64 changes [PR115958] Apparently there is a -Wsign-compare warning if ptrdiff_t has precision of int, then (t - s + 1 + 2) / 3 * 4 has int type while cnt unsigned int. This doesn't warn if ptrdiff_t has larger precision, say on x86_64 it is 64-bit and so (t - s + 1 + 2) / 3 * 4 has long type and cnt unsigned int. And it doesn't warn when using older binutils (in my tests I've used new binutils on x86_64 and old binutils on i686). Anyway, earlier condition guarantees that t - s is at most 256-ish and t >= s by construction, so we can just cast it to (unsigned) to avoid the warning. 2024-07-17 Jakub Jelinek PR other/115958 * varasm.cc (default_elf_asm_output_ascii): Cast t - s to unsigned to avoid -Wsign-compare warnings. Diff: --- gcc/varasm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/varasm.cc b/gcc/varasm.cc index fe0a6b873ef4..ecd91a683237 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -8543,7 +8543,7 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) { if (t == p && t != s) { - if (cnt <= (t - s + 1 + 2) / 3 * 4 + if (cnt <= ((unsigned) (t - s) + 1 + 2) / 3 * 4 && (!prev_base64 || (t - s) >= 16) && ((t - s) > 1 || cnt <= 2)) { @@ -8569,7 +8569,7 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) break; } } - if (cnt > (t - s + 2) / 3 * 4 && (t - s) >= 3) + if (cnt > ((unsigned) (t - s) + 2) / 3 * 4 && (t - s) >= 3) { if (bytes_in_chunk > 0) {
[gcc r15-2100] varasm: Shorten assembly of strings with larger zero regions
https://gcc.gnu.org/g:d8a75353dded30a7ecdef2807ad101a02743d4a9 commit r15-2100-gd8a75353dded30a7ecdef2807ad101a02743d4a9 Author: Jakub Jelinek Date: Wed Jul 17 17:30:24 2024 +0200 varasm: Shorten assembly of strings with larger zero regions When not using .base64 directive, we emit for long sequences of zeros .string "foobarbaz" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" .string "" The following patch changes that to .string "foobarbaz" .zero 12 It keeps emitting .string "" if there is just one zero or two zeros where the first one is preceded by non-zeros, so we can have .string "foobarbaz" .string "" or .base64 "VG8gYmUgb3Igbm90IHRvIGJlLCB0aGF0IGlzIHRoZSBxdWVzdGlvbg==" .string "" but not 2 .string "" in a row. On a testcase I have with around 310440 0-255 unsigned char character constants mostly derived from cc1plus start but with too long sequences of 0s which broke transformation to STRING_CST adjusted to have at most 126 consecutive 0s, I see: 1504498 bytes long assembly without this patch on i686-linux (without .base64 support in binutils) 1155071 bytes long assembly with this patch on i686-linux (without .base64 support in binutils) 431390 bytes long assembly without this patch on x86_64-linux (with .base64 support in binutils) 427593 bytes long assembly with this patch on x86_64-linux (with .base64 support in binutils) All 4 assemble to identical *.o file when using x86_64-linux .base64 supporting gas, and the former 2 when using older x86_64-linux gas assemble to identical content as well. 2024-07-17 Jakub Jelinek * varasm.cc (default_elf_asm_output_ascii): Use ASM_OUTPUT_SKIP instead of 2 or more default_elf_asm_output_limited_string (f, "") calls and adjust base64 heuristics correspondingly. Diff: --- gcc/varasm.cc | 24 +--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/gcc/varasm.cc b/gcc/varasm.cc index ecd91a683237..beb88709033f 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -8538,6 +8538,7 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) if (s >= last_base64) { unsigned cnt = 0; + unsigned char prev_c = ' '; const char *t; for (t = s; t < limit && (t - s) < (long) ELF_STRING_LIMIT - 1; t++) { @@ -8560,7 +8561,13 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) break; case 1: if (c == 0) - cnt += 2 + strlen (STRING_ASM_OP) + 1; + { + if (prev_c == 0 + && t + 1 < limit + && (t + 1 - s) < (long) ELF_STRING_LIMIT - 1) + break; + cnt += 2 + strlen (STRING_ASM_OP) + 1; + } else cnt += 4; break; @@ -8568,6 +8575,7 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) cnt += 2; break; } + prev_c = c; } if (cnt > ((unsigned) (t - s) + 2) / 3 * 4 && (t - s) >= 3) { @@ -8633,8 +8641,18 @@ default_elf_asm_output_ascii (FILE *f, const char *s, unsigned int len) bytes_in_chunk = 0; } - default_elf_asm_output_limited_string (f, s); - s = p; + if (p == s && p + 1 < limit && p[1] == '\0') + { + for (p = s + 2; p < limit && *p == '\0'; p++) + continue; + ASM_OUTPUT_SKIP (f, (unsigned HOST_WIDE_INT) (p - s)); + s = p - 1; + } + else + { + default_elf_asm_output_limited_string (f, s); + s = p; + } } else {