[gcc r15-6362] RISC-V: Make vector strided store alias all other memories
https://gcc.gnu.org/g:46194b912780452e80c1ef9867cbcff1050231a2 commit r15-6362-g46194b912780452e80c1ef9867cbcff1050231a2 Author: Pan Li Date: Thu Dec 19 08:58:20 2024 +0800 RISC-V: Make vector strided store alias all other memories Almost the same as the RVV strided load, the vector strided store doesn't involve the (mem:BLK (scratch)) to alias all other memories. It will make the alias analysis only consider the base address of strided store. PR target/118075 gcc/ChangeLog: * config/riscv/vector.md: Add the (mem:BLK (scratch)) as the lhs of strided store define insn. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pr118075-run-1.c: New test. Signed-off-by: Pan Li Diff: --- gcc/config/riscv/vector.md | 19 - .../gcc.target/riscv/rvv/base/pr118075-run-1.c | 24 ++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 58406f3d17cd..ff8f552b802b 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -2396,18 +2396,17 @@ (set_attr "mode" "")]) (define_insn "@pred_strided_store" - [(set (match_operand:V_VLS 0 "memory_operand" "+m,m") - (if_then_else:V_VLS - (unspec: - [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1") -(match_operand 4 "vector_length_operand"" rK, rK") -(match_operand 5 "const_int_operand""i,i") + [(set (mem:BLK (scratch)) + (unspec:BLK + [(match_operand:V_VLS 0 "memory_operand" " +m, m") + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1, vmWc1") +(match_operand 4 "vector_length_operand"" rK,rK") +(match_operand 5 "const_int_operand""i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (unspec:V_VLS - [(match_operand 2 "" "") -(match_operand:V_VLS 3 "register_operand" " vr, vr")] UNSPEC_STRIDED) - (match_dup 0)))] + (match_operand 2 "" "") + (match_operand:V_VLS 3 "register_operand" " vr,vr")] UNSPEC_STRIDED))] "TARGET_VECTOR" "@ vsse.v\t%3,%0,%z2%p1 diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr118075-run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr118075-run-1.c new file mode 100644 index ..120573a1e8c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr118075-run-1.c @@ -0,0 +1,24 @@ +/* { dg-do run { target { riscv_v && rv64 } } } */ +/* { dg-additional-options "-std=c99 -O3 -march=rv64gcv_zvl256b -mrvv-vector-bits=zvl" } */ + +int a; +int b[14]; +char c[14][14]; + +int main() { + for (long f = 0; f < 14; ++f) +for (long g = 0; g < 4; ++g) + c[f][g] = 1; + + for (short f = 0; f < 12; f += 1) +c[f][f] = b[f]; + + for (long f = 0; f < 4; ++f) +for (long g = 0; g < 14; ++g) + a ^= c[f][g]; + + if (a != 0) +__builtin_abort (); + + return 0; +}
[gcc r15-6363] RISC-V: Adjust the strided store testcases check times on options
https://gcc.gnu.org/g:d0635492172781ac1af73e671e19a53471a30038 commit r15-6363-gd0635492172781ac1af73e671e19a53471a30038 Author: Pan Li Date: Thu Dec 19 09:03:59 2024 +0800 RISC-V: Adjust the strided store testcases check times on options The vsse* dump check times changes on options (O2, O3) after we add (mem:BLK (scratch)) to the define_insn of strided load. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c: Adjust the vsse check times based on optimization option. * gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c: Ditto. * gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c: Ditto. Signed-off-by: Pan Li Diff: --- .../gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c | 3 ++- .../gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c | 3 ++- .../gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c index e4f6a40873be..2be8854a0b64 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-f64.c @@ -10,4 +10,5 @@ DEF_STRIDED_LD_ST_FORM_1(double) /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_LOAD " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_STORE " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-assembler-times {vlse64.v} 1 } } */ -/* { dg-final { scan-assembler-times {vsse64.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 1 { target { any-opts "-O2" } } } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 2 { target { any-opts "-O3" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c index afbce2263681..13003e2ccdcb 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-i64.c @@ -10,4 +10,5 @@ DEF_STRIDED_LD_ST_FORM_1(int64_t) /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_LOAD " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_STORE " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-assembler-times {vlse64.v} 1 } } */ -/* { dg-final { scan-assembler-times {vsse64.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 1 { target { any-opts "-O2" } } } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 2 { target { any-opts "-O3" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c index a66eb5bcfd41..5df2caa793b4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/strided/strided_ld_st-1-u64.c @@ -10,4 +10,5 @@ DEF_STRIDED_LD_ST_FORM_1(uint64_t) /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_LOAD " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-rtl-dump-times ".MASK_LEN_STRIDED_STORE " 2 "expand" { target { any-opts "-O2" } } } } */ /* { dg-final { scan-assembler-times {vlse64.v} 1 } } */ -/* { dg-final { scan-assembler-times {vsse64.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 1 { target { any-opts "-O2" } } } } */ +/* { dg-final { scan-assembler-times {vsse64.v} 2 { target { any-opts "-O3" } } } } */
[gcc r15-6375] c++: optimize constraint subsumption [PR118069]
https://gcc.gnu.org/g:7eac34a6c793540606a50e20c4c56bd98476d3a1 commit r15-6375-g7eac34a6c793540606a50e20c4c56bd98476d3a1 Author: Patrick Palka Date: Thu Dec 19 12:00:31 2024 -0500 c++: optimize constraint subsumption [PR118069] Since atomic constraints are interned the subsumption machinery can safely use pointer instead of structural hashing for them. This speeds up compilation of the testcase in the PR from ~3s to ~2s. PR c++/118069 gcc/cp/ChangeLog: * constraint.cc (atom_hasher): Define here, instead of ... * cp-tree.h (atom_hasher): ... here. * logic.cc (clause::m_set): Use pointer instead of structural hashing. Reviewed-by: Jason Merrill Diff: --- gcc/cp/constraint.cc | 21 + gcc/cp/cp-tree.h | 21 - gcc/cp/logic.cc | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 2af1bbc016b9..c75982d80093 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -512,6 +512,27 @@ normalize_concept_check (tree check, tree args, norm_info info) return norm; } +/* A structural hasher for ATOMIC_CONSTRs. */ + +struct atom_hasher : default_hash_traits +{ + static hashval_t hash (tree t) + { +++comparing_specializations; +hashval_t val = hash_atomic_constraint (t); +--comparing_specializations; +return val; + } + + static bool equal (tree t1, tree t2) + { +++comparing_specializations; +bool eq = atomic_constraints_identical_p (t1, t2); +--comparing_specializations; +return eq; + } +}; + /* Used by normalize_atom to cache ATOMIC_CONSTRs. */ static GTY((deletable)) hash_table *atom_cache; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6833035664b0..32e6b014b67e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8715,27 +8715,6 @@ extern void diagnose_constraints (location_t, tree, tree); extern void note_failed_type_completion_for_satisfaction (tree); -/* A structural hasher for ATOMIC_CONSTRs. */ - -struct atom_hasher : default_hash_traits -{ - static hashval_t hash (tree t) - { -++comparing_specializations; -hashval_t val = hash_atomic_constraint (t); ---comparing_specializations; -return val; - } - - static bool equal (tree t1, tree t2) - { -++comparing_specializations; -bool eq = atomic_constraints_identical_p (t1, t2); ---comparing_specializations; -return eq; - } -}; - /* in logic.cc */ extern bool subsumes(tree, tree); diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc index a385fb719eca..6b4bf1dfb7dc 100644 --- a/gcc/cp/logic.cc +++ b/gcc/cp/logic.cc @@ -203,7 +203,7 @@ struct clause } std::list m_terms; /* The list of terms. */ - hash_set m_set; /* The set of atomic constraints. */ + hash_set m_set; /* The set of atomic constraints. */ iterator m_current; /* The current term. */ };
[gcc r15-6374] c++: integer overflow during constraint subsumption [PR118069]
https://gcc.gnu.org/g:875f14e15d49dce7de501a6357a3d5811b5c36d4 commit r15-6374-g875f14e15d49dce7de501a6357a3d5811b5c36d4 Author: Patrick Palka Date: Thu Dec 19 12:00:29 2024 -0500 c++: integer overflow during constraint subsumption [PR118069] For the testcase in the PR we hang during constraint subsumption ultimately because one of the constraints is complex enough that its conjunctive normal form is calculated to have more than 2^31 clauses, which causes the size calculation (through an int) to overflow and so the optimization in subsumes_constraints_nonnull if (dnf_size (lhs) <= cnf_size (rhs)) // iterate over DNF of LHS else // iterate over CNF of RHS incorrectly decides to loop over the CNF (>> billions of clauses) instead of the DNF (thousands of clauses). I haven't verified that the result of cnf_size is correct for the problematic constraint but integer overflow is definitely plausible given that CNF/DNF can be exponentially larger than the original constraint in the worst case. This patch fixes this by using 64-bit saturating arithmetic during these size calculations (via new add/mul_sat_hwi functions) so that overflow is less likely and if it does occur we handle it gracefully. It should be highly unlikely that both the DNF and CNF sizes overflow, and if they do then it doesn't matter which form we select, subsumption will take forever either way. The testcase now compiles in ~3 seconds on my machine after this change. PR c++/118069 gcc/ChangeLog: * hwint.h (add_sat_hwi): New function. (mul_sat_hwi): Likewise. gcc/cp/ChangeLog: * logic.cc (dnf_size_r): Use HOST_WIDE_INT instead of int, and handle overflow gracefully via add_sat_hwi and mul_sat_hwi. (cnf_size_r): Likewise. (dnf_size): Use HOST_WIDE_INT instead of int. (cnf_size): Likewise. Reviewed-by: Jason Merrill Diff: --- gcc/cp/logic.cc | 68 +++-- gcc/hwint.h | 26 ++ 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc index fab2c357dc4e..a385fb719eca 100644 --- a/gcc/cp/logic.cc +++ b/gcc/cp/logic.cc @@ -349,7 +349,7 @@ atomic_p (tree t) distributing. In general, a conjunction for which this flag is set is considered a disjunction for the purpose of counting. */ -static std::pair +static std::pair dnf_size_r (tree t) { if (atomic_p (t)) @@ -360,9 +360,9 @@ dnf_size_r (tree t) the results. */ tree lhs = TREE_OPERAND (t, 0); tree rhs = TREE_OPERAND (t, 1); - std::pair p1 = dnf_size_r (lhs); - std::pair p2 = dnf_size_r (rhs); - int n1 = p1.first, n2 = p2.first; + auto p1 = dnf_size_r (lhs); + auto p2 = dnf_size_r (rhs); + HOST_WIDE_INT n1 = p1.first, n2 = p2.first; bool d1 = p1.second, d2 = p2.second; if (disjunction_p (t)) @@ -376,22 +376,24 @@ dnf_size_r (tree t) { if (disjunction_p (rhs) || (conjunction_p (rhs) && d2)) /* Both P and Q are disjunctions. */ - return std::make_pair (n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (n1, n2), d1 | d2); else /* Only LHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); gcc_unreachable (); } if (conjunction_p (lhs)) { if ((disjunction_p (rhs) && d1) || (conjunction_p (rhs) && d1 && d2)) /* Both P and Q are disjunctions. */ - return std::make_pair (n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (n1, n2), d1 | d2); if (disjunction_p (rhs) || (conjunction_p (rhs) && d1 != d2) || (atomic_p (rhs) && d1)) /* Either LHS or RHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); else /* Neither LHS nor RHS is a disjunction. */ return std::make_pair (2, false); @@ -400,7 +402,8 @@ dnf_size_r (tree t) { if (disjunction_p (rhs) || (conjunction_p (rhs) && d2)) /* Only RHS is a disjunction. */ - return std::make_pair (1 + n1 + n2, d1 | d2); + return std::make_pair (add_sat_hwi (1, add_sat_hwi (n1, n2)), + d1 | d2); else /* Neither LHS nor RHS is a disjunction. */ return std::make_pair (2, false); @@ -418,22 +421,22 @@ dnf_size_r (tree t) { if (disjunction_p (rhs) || (conjunction_p (rhs) && d2))
[gcc r14-11105] arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801]
https://gcc.gnu.org/g:0631c5770e8162dbe67c73dee0327313c19822c2 commit r14-11105-g0631c5770e8162dbe67c73dee0327313c19822c2 Author: Christophe Lyon Date: Sun Nov 24 18:08:48 2024 + arm: [MVE intrinsics] Fix support for predicate constants [PR target/114801] In this PR, we have to handle a case where MVE predicates are supplied as a const_int, where individual predicates have illegal boolean values (such as 0xc for a 4-bit boolean predicate). To avoid the ICE, fix the constant (any non-zero value is converted to all 1s) and emit a warning. On MVE, V8BI and V4BI multi-bit masks are interpreted byte-by-byte at instruction level, but end-users should describe lanes rather than bytes (so all bytes of a true-predicated lane should be '1'), see the section on MVE intrinsics in the Arm ACLE specification. Since force_lowpart_subreg cannot handle const_int (because they have VOID mode), use gen_lowpart on them, force_lowpart_subreg otherwise. 2024-11-20 Christophe Lyon Jakub Jelinek PR target/114801 gcc/ * config/arm/arm-mve-builtins.cc (function_expander::add_input_operand): Handle CONST_INT predicates. gcc/testsuite/ * gcc.target/arm/mve/pr108443.c: Update predicate constant. * gcc.target/arm/mve/pr108443-run.c: Likewise. * gcc.target/arm/mve/pr114801.c: New test. (cherry picked from commit 2089009210a1774c37e527ead8bbcaaa1a7a9d2d) Diff: --- gcc/config/arm/arm-mve-builtins.cc | 32 +++- gcc/testsuite/gcc.target/arm/mve/pr108443-run.c | 2 +- gcc/testsuite/gcc.target/arm/mve/pr108443.c | 4 +-- gcc/testsuite/gcc.target/arm/mve/pr114801.c | 39 + 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc index e1826ae40527..ec856f7d6168 100644 --- a/gcc/config/arm/arm-mve-builtins.cc +++ b/gcc/config/arm/arm-mve-builtins.cc @@ -2107,7 +2107,37 @@ function_expander::add_input_operand (insn_code icode, rtx x) mode = GET_MODE (x); } else if (VALID_MVE_PRED_MODE (mode)) -x = gen_lowpart (mode, x); +{ + if (CONST_INT_P (x)) + { + if (mode == V8BImode || mode == V4BImode) + { + /* In V8BI or V4BI each element has 2 or 4 bits, if those bits +aren't all the same, gen_lowpart might ICE. Canonicalize all +the 2 or 4 bits to all ones if any of them is non-zero. V8BI +and V4BI multi-bit masks are interpreted byte-by-byte at +instruction level, but such constants should describe lanes, +rather than bytes. See the section on MVE intrinsics in the +Arm ACLE specification. */ + unsigned HOST_WIDE_INT xi = UINTVAL (x); + xi |= ((xi & 0x) << 1) | ((xi & 0x) >> 1); + if (mode == V4BImode) + xi |= ((xi & 0x) << 2) | ((xi & 0x) >> 2); + if (xi != UINTVAL (x)) + warning_at (location, 0, "constant predicate argument %d" + " (%wx) does not map to %d lane numbers," + " converted to %wx", + opno, UINTVAL (x) & 0x, + mode == V8BImode ? 8 : 4, + xi & 0x); + + x = gen_int_mode (xi, HImode); + } + x = gen_lowpart (mode, x); + } + else + x = force_lowpart_subreg (mode, x, GET_MODE (x)); +} m_ops.safe_grow (m_ops.length () + 1, true); create_input_operand (&m_ops.last (), x, mode); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c index cb4b45bd3056..b894f019b8bb 100644 --- a/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c +++ b/gcc/testsuite/gcc.target/arm/mve/pr108443-run.c @@ -16,7 +16,7 @@ __attribute__ ((noipa)) partial_write (uint32_t *a, uint32x4_t v, unsigned short int main (void) { - unsigned short p = 0x00CC; + unsigned short p = 0x00FF; uint32_t a[] = {0, 0, 0, 0}; uint32_t b[] = {0, 0, 0, 0}; uint32x4_t v = vdupq_n_u32 (0xU); diff --git a/gcc/testsuite/gcc.target/arm/mve/pr108443.c b/gcc/testsuite/gcc.target/arm/mve/pr108443.c index c5fbfa4a1bb7..0c0e2dd6eb8f 100644 --- a/gcc/testsuite/gcc.target/arm/mve/pr108443.c +++ b/gcc/testsuite/gcc.target/arm/mve/pr108443.c @@ -7,8 +7,8 @@ void __attribute__ ((noipa)) partial_write_cst (uint32_t *a, uint32x4_t v) { - vstrwq_p_u32 (a, v, 0x00CC); + vstrwq_p_u32 (a, v, 0x00FF); } -/* { dg-final { scan-assembler {mov\tr[0-9]+, #204} } } */ +/* { dg-final { scan-assembler {mov\tr[0-9]+, #255} } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/pr114801.c b/gcc/testsuite/gcc.target/arm/mve/pr
[gcc r15-6370] libstdc++: Define P1206R7 range-key-type and range-mapped-type aliases
https://gcc.gnu.org/g:fb1f1c763055abea556959b42a2f1d5e548c1452 commit r15-6370-gfb1f1c763055abea556959b42a2f1d5e548c1452 Author: Patrick Palka Date: Thu Dec 19 11:31:06 2024 -0500 libstdc++: Define P1206R7 range-key-type and range-mapped-type aliases libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (__detail::__range_key_type): Define as per P1206R7. (__detail::__range_mapped_type): Likewise. Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/bits/ranges_base.h | 8 1 file changed, 8 insertions(+) diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index a2c743ff56bc..c8cd4e87b12c 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -1087,6 +1087,14 @@ namespace __detail concept __container_compatible_range = ranges::input_range<_Rg> && convertible_to, _Tp>; + + template +using __range_key_type + = remove_const_t::first_type>; + + template +using __range_mapped_type + = typename ranges::range_value_t<_Range>::second_type; } /// @endcond #endif
[gcc r15-6371] libstdc++: Implement C++23 (P0429R9)
https://gcc.gnu.org/g:92381894b36b39030e6a264d3da2204b20f08d6c commit r15-6371-g92381894b36b39030e6a264d3da2204b20f08d6c Author: Patrick Palka Date: Thu Dec 19 11:31:09 2024 -0500 libstdc++: Implement C++23 (P0429R9) This implements the C++23 container adaptors std::flat_map and std::flat_multimap from P0429R9. The implementation is shared as much as possible between the two adaptors via a common base class that's parameterized according to key uniqueness. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header . * include/Makefile.in: Regenerate. * include/bits/alloc_traits.h (__not_allocator_like): New concept. * include/bits/stl_function.h (__transparent_comparator): Likewise. * include/bits/stl_iterator_base_types.h (__has_input_iter_cat): Likewise. * include/bits/uses_allocator.h (__allocator_for): Likewise. * include/bits/utility.h (sorted_unique_t): Define for C++23. (sorted_unique): Likewise. (sorted_equivalent_t): Likewise. (sorted_equivalent): Likewise. * include/bits/version.def (flat_map): Define. * include/bits/version.h: Regenerate. * include/precompiled/stdc++.h: Include . * include/std/flat_map: New file. * src/c++23/std.cc.in: Export . * testsuite/23_containers/flat_map/1.cc: New test. * testsuite/23_containers/flat_multimap/1.cc: New test. Co-authored-by: Jonathan Wakely Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/Makefile.am |1 + libstdc++-v3/include/Makefile.in |1 + libstdc++-v3/include/bits/alloc_traits.h |3 + libstdc++-v3/include/bits/stl_function.h |6 + .../include/bits/stl_iterator_base_types.h |6 + libstdc++-v3/include/bits/uses_allocator.h |5 + libstdc++-v3/include/bits/utility.h|8 + libstdc++-v3/include/bits/version.def |8 + libstdc++-v3/include/bits/version.h| 10 + libstdc++-v3/include/precompiled/stdc++.h |1 + libstdc++-v3/include/std/flat_map | 1570 libstdc++-v3/src/c++23/std.cc.in | 11 + libstdc++-v3/testsuite/23_containers/flat_map/1.cc | 178 +++ .../testsuite/23_containers/flat_multimap/1.cc | 153 ++ 14 files changed, 1961 insertions(+) diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 6efd3cd5f1c8..b606bcd49359 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -70,6 +70,7 @@ std_headers = \ ${std_srcdir}/deque \ ${std_srcdir}/execution \ ${std_srcdir}/filesystem \ + ${std_srcdir}/flat_map \ ${std_srcdir}/format \ ${std_srcdir}/forward_list \ ${std_srcdir}/fstream \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 3b5f93ce185d..d277f87905b9 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -426,6 +426,7 @@ std_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/deque \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/execution \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/filesystem \ +@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/flat_map \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/format \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/forward_list \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/fstream \ diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index 76d5646afe57..5d8a952ec1bf 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -957,6 +957,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Alloc::value_type; __a.deallocate(__a.allocate(1u), 1u); }; + + template +concept __not_allocator_like = !__allocator_like<_Alloc>; #endif /// @endcond #endif // C++11 diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h index 8c77471fbf54..a472c3d79f3a 100644 --- a/libstdc++-v3/include/bits/stl_function.h +++ b/libstdc++-v3/include/bits/stl_function.h @@ -1426,6 +1426,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using __has_is_transparent_t = typename __has_is_transparent<_Func, _SfinaeType>::type; + +#if __cpp_concepts + template +concept __transparent_comparator + = requires { typename _Func::is_transparent; }; +#endif #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h index 710e367c9786..a58358e1059b 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -253,6 +253,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
[gcc r15-6372] libstdc++: Implement C++23 (P1222R4)
https://gcc.gnu.org/g:e3fab34506430e78d286d4aaf66c0dec9a28c187 commit r15-6372-ge3fab34506430e78d286d4aaf66c0dec9a28c187 Author: Patrick Palka Date: Thu Dec 19 11:31:19 2024 -0500 libstdc++: Implement C++23 (P1222R4) This implements the C++23 container adaptors std::flat_set and std::flat_multiset from P1222R4. The implementation is essentially an simpler and pared down version of std::flat_map. libstdc++-v3/ChangeLog: * include/Makefile.am: Add new header . * include/Makefile.in: Regenerate. * include/bits/version.def (__cpp_flat_set): Define. * include/bits/version.h: Regenerate * include/precompiled/stdc++.h: Include . * include/std/flat_set: New file. * src/c++23/std.cc.in: Export . * testsuite/23_containers/flat_multiset/1.cc: New test. * testsuite/23_containers/flat_set/1.cc: New test. Co-authored-by: Jonathan Wakely Reviewed-by: Jonathan Wakely Diff: --- libstdc++-v3/include/Makefile.am |1 + libstdc++-v3/include/Makefile.in |1 + libstdc++-v3/include/bits/version.def |8 + libstdc++-v3/include/bits/version.h| 10 + libstdc++-v3/include/precompiled/stdc++.h |1 + libstdc++-v3/include/std/flat_set | 1041 libstdc++-v3/src/c++23/std.cc.in | 11 + .../testsuite/23_containers/flat_multiset/1.cc | 140 +++ libstdc++-v3/testsuite/23_containers/flat_set/1.cc | 155 +++ 9 files changed, 1368 insertions(+) diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index b606bcd49359..3e1e42e79737 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -71,6 +71,7 @@ std_headers = \ ${std_srcdir}/execution \ ${std_srcdir}/filesystem \ ${std_srcdir}/flat_map \ + ${std_srcdir}/flat_set \ ${std_srcdir}/format \ ${std_srcdir}/forward_list \ ${std_srcdir}/fstream \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index d277f87905b9..4c461afb7513 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -427,6 +427,7 @@ std_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/execution \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/filesystem \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/flat_map \ +@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/flat_set \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/format \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/forward_list \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/fstream \ diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 171ee2780e8d..3b31cff51943 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1671,6 +1671,14 @@ ftms = { }; }; +ftms = { + name = flat_set; + values = { +v = 202207; +cxxmin = 23; + }; +}; + ftms = { name = formatters; values = { diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 5e1858855eb6..ef27ae5e4fae 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1845,6 +1845,16 @@ #endif /* !defined(__cpp_lib_flat_map) && defined(__glibcxx_want_flat_map) */ #undef __glibcxx_want_flat_map +#if !defined(__cpp_lib_flat_set) +# if (__cplusplus >= 202100L) +# define __glibcxx_flat_set 202207L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_flat_set) +# define __cpp_lib_flat_set 202207L +# endif +# endif +#endif /* !defined(__cpp_lib_flat_set) && defined(__glibcxx_want_flat_set) */ +#undef __glibcxx_want_flat_set + #if !defined(__cpp_lib_formatters) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED # define __glibcxx_formatters 202302L diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h index 67ee00d073bb..3312a7a4dd4d 100644 --- a/libstdc++-v3/include/precompiled/stdc++.h +++ b/libstdc++-v3/include/precompiled/stdc++.h @@ -226,6 +226,7 @@ #if __cplusplus > 202002L #include #include +#include #include #include #include diff --git a/libstdc++-v3/include/std/flat_set b/libstdc++-v3/include/std/flat_set new file mode 100644 index ..3e1347a6a0ae --- /dev/null +++ b/libstdc++-v3/include/std/flat_set @@ -0,0 +1,1041 @@ +// -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY o
[gcc r15-6373] OpenMP: Add 'nec' as to the 'vendor' context-selector list
https://gcc.gnu.org/g:a104766914e98ded9b991f1dac9ad22e815a3acc commit r15-6373-ga104766914e98ded9b991f1dac9ad22e815a3acc Author: Tobias Burnus Date: Thu Dec 19 17:27:41 2024 +0100 OpenMP: Add 'nec' as to the 'vendor' context-selector list For unknown vendors using in a context selector such as match(implementation={vendor(...)}) GCC prints a warning like: warning: unknown property 'nec' of 'vendor' selector While all known vendors (including the vendor 'unknown') are silently accepted, only "gnu" counts as matched by GCC. The list of known vendors is published in OpenMP's additional definition document (or, previously, the context definitions document). While the initial list did not contain 'nec', it was added quite early but GCC missed this addition, which this commit rectifies. Some history: * GCC added the list in r10-3744-g94e7f906ca5c73 (Oct 2019) * At spec level, 'pgi' was replaced by 'nvidia' in Nov 2019, but GCC (since r10-4639-gd0ec7c935f0c96, Nov 2019) and LLVM recognize both vendor names. * 'nec' was then added in Dec 2019 and is present in "Context Definitions for the OpenMP API Specification Version 5.0 – Version 1.0", but only this commit adds it. * 'hpe' (as alias for 'cray') was added to the spec in Nov 2020 but to GCC only in r14-6720-gd0603dfe9d3bc7 (Dec 2023). gcc/ * omp-general.cc (vendor_properties): Add "nec". Diff: --- gcc/omp-general.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 9837ca021f0d..78c38a6d7152 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1163,7 +1163,7 @@ static const char *const kind_properties[] = { "host", "nohost", "cpu", "gpu", "fpga", "any", NULL }; static const char *const vendor_properties[] = { "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "hpe", "ibm", "intel", -"llvm", "nvidia", "pgi", "ti", "unknown", NULL }; +"llvm", "nec", "nvidia", "pgi", "ti", "unknown", NULL }; static const char *const extension_properties[] = { NULL }; static const char *const atomic_default_mem_order_properties[] =
[gcc r15-6369] c++: ICE in TARGET_EXPR evaluation in cp_fold_r [PR117980]
https://gcc.gnu.org/g:fa99002538bc91c869f3b1fd9af7f14e410e1e1a commit r15-6369-gfa99002538bc91c869f3b1fd9af7f14e410e1e1a Author: Marek Polacek Date: Tue Dec 10 18:43:56 2024 -0500 c++: ICE in TARGET_EXPR evaluation in cp_fold_r [PR117980] This ICE started with the recent prvalue optimization (r15-6052). In cp_fold_r we have: if (tree &init = TARGET_EXPR_INITIAL (stmt)) { cp_walk_tree (&init, cp_fold_r, data, NULL); // ... tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt)); What can happen here is that originally the TARGET_EXPR is: TARGET_EXPR >> &TARGET_EXPR }> but after the first cp_walk_tree we fold the D.2707 TARGET_EXPR into: TARGET_EXPR and then we pass the EXPR_STMT to maybe_constant_init, with D.2707 as the object. But their types don't match anymore, so we crash. We'd have to pass D.2707.it as the object for it to work. This patch adjusts cxx_eval_outermost_constant_expr to take the object's type if available. constexpr-prvalue3.C is reduced from a large std::ranges libstdc++ test. PR c++/117980 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_outermost_constant_expr): If there's an object to initialize, take its type. Don't set the type in the constexpr dtor case. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-prvalue2.C: New test. * g++.dg/cpp0x/constexpr-prvalue3.C: New test. Co-authored-by: Jason Merrill Diff: --- gcc/cp/constexpr.cc | 9 - gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C | 15 ++ gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C | 26 + 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index c16597dfaece..d699020ff9db 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8870,15 +8870,14 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, /* Turn off -frounding-math for manifestly constant evaluation. */ warning_sentinel rm (flag_rounding_math, ctx.manifestly_const_eval == mce_true); - tree type = initialized_type (t); + tree type = (object + ? cv_unqualified (TREE_TYPE (object)) + : initialized_type (t)); tree r = t; bool is_consteval = false; if (VOID_TYPE_P (type)) { - if (constexpr_dtor) - /* Used for destructors of array elements. */ - type = TREE_TYPE (object); - else + if (!constexpr_dtor) { if (cxx_dialect < cxx20) return t; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C new file mode 100644 index ..46053231cf83 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue2.C @@ -0,0 +1,15 @@ +// PR c++/117980 +// { dg-do compile { target c++11 } } +// { dg-options "-O" } + +struct S { + constexpr S(S &); // { dg-warning "used but never defined" } + ~S(); +}; +struct B { + S s; +}; +struct A { + B b; +}; +void fn(B b) { A{b}; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C new file mode 100644 index ..a2eb12c02d74 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-prvalue3.C @@ -0,0 +1,26 @@ +// PR c++/117980 +// { dg-do compile { target c++11 } } +// { dg-options "-O" } + +struct _Safe_iterator { + _Safe_iterator(); + ~_Safe_iterator(); +}; +template +struct vector { + vector(int) {} + constexpr _Safe_iterator end() { +return _Safe_iterator(); + } +}; +template struct sentinel { + It it; +}; +template +struct subrange { + subrange(sentinel<_Safe_iterator>) {} +}; +void test01() { + vector v{0}; + subrange>{sentinel<_Safe_iterator>{v.end()}}; +}
[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Correction assertion même type
https://gcc.gnu.org/g:9eff4d8000bb1cb1e54b76d474ff45c6d339981f commit 9eff4d8000bb1cb1e54b76d474ff45c6d339981f Author: Mikael Morin Date: Thu Dec 19 15:19:50 2024 +0100 Correction assertion même type Diff: --- gcc/fortran/trans-expr.cc | 34 +++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 774c43ba9062..8b4fd2876788 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -819,9 +819,27 @@ gfc_get_vptr_from_expr (tree expr) return NULL_TREE; } + +static int +descriptor_rank (tree descriptor) +{ + tree dim = gfc_get_descriptor_dimension (descriptor); + tree dim_type = TREE_TYPE (dim); + gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE); + tree idx_type = TYPE_DOMAIN (dim_type); + gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE); + gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type))); + tree idx_max = TYPE_MAX_VALUE (idx_type); + if (idx_max == NULL_TREE) +return GFC_MAX_DIMENSIONS; + wide_int max = wi::to_wide (idx_max); + return max.to_shwi () + 1; +} + + void gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc, -bool lhs_type) +bool) { tree tmp, tmp2, type; @@ -837,8 +855,18 @@ gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc, tmp = gfc_get_descriptor_dimension (lhs_desc); tmp2 = gfc_get_descriptor_dimension (rhs_desc); - gcc_assert (TREE_TYPE (tmp) == TREE_TYPE (tmp2)); - type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2); + int rank = descriptor_rank (lhs_desc); + int rank2 = descriptor_rank (rhs_desc); + if (rank == GFC_MAX_DIMENSIONS && rank2 != GFC_MAX_DIMENSIONS) +type = TREE_TYPE (tmp2); + else if (rank2 == GFC_MAX_DIMENSIONS && rank != GFC_MAX_DIMENSIONS) +type = TREE_TYPE (tmp); + else +{ + gcc_assert (TREE_TYPE (tmp) == TREE_TYPE (tmp2)); + type = TREE_TYPE (tmp); +} + tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp, gfc_index_zero_node, NULL_TREE, NULL_TREE); tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
[gcc r15-6364] testsuite: Fix toplevel-asm-1.c failure for riscv
https://gcc.gnu.org/g:b117201385d3e8b0ee3fca396b77b2539f90bd40 commit r15-6364-gb117201385d3e8b0ee3fca396b77b2539f90bd40 Author: Jakub Jelinek Date: Thu Dec 19 11:36:29 2024 +0100 testsuite: Fix toplevel-asm-1.c failure for riscv On Wed, Dec 18, 2024 at 01:19:43PM +0100, Andreas Schwab wrote: > On Dez 12 2024, Jakub Jelinek wrote: > > > The intent was to test %cN because %N doesn't DTRT on various targets. > > I have a patch to add %ccN support which should then work even on riscv > > hopefully, but unfortunately it hasn't been fully reviewed yet. > > That didn't change toplevel-asm-1, so the failure remains. Yes, I've only committed what was approved. The following patch ought to fix this (and if there are other targets which don't really support %cN for SYMBOL_REFs even with -fno-pic, they can be added there too; I think it is useful to test %cN on the targets where it works though). 2024-12-19 Jakub Jelinek * c-c++-common/toplevel-asm-1.c: Use %cc3 %cc4 instead of %c3 %c4 on riscv. Diff: --- gcc/testsuite/c-c++-common/toplevel-asm-1.c | 5 + 1 file changed, 5 insertions(+) diff --git a/gcc/testsuite/c-c++-common/toplevel-asm-1.c b/gcc/testsuite/c-c++-common/toplevel-asm-1.c index 12623fcd6668..d6766b00e724 100644 --- a/gcc/testsuite/c-c++-common/toplevel-asm-1.c +++ b/gcc/testsuite/c-c++-common/toplevel-asm-1.c @@ -8,7 +8,12 @@ enum E { E0, E1 = sizeof (struct S) + 15 }; int v[42]; void foo (void) {} +/* Not all targets can use %cN even in non-pic code. */ +#if defined(__riscv) +asm ("# %0 %1 %2 %cc3 %cc4 %5 %% %=" +#else asm ("# %0 %1 %2 %c3 %c4 %5 %% %=" +#endif :: "i" (sizeof (struct S)), "i" (__builtin_offsetof (struct S, c)), "i" (E1),
[gcc(refs/users/aoliva/heads/testme)] add options to control ifcombine
https://gcc.gnu.org/g:03732dab7bf226b51b26f729405e42b4722f4b56 commit 03732dab7bf226b51b26f729405e42b4722f4b56 Author: Alexandre Oliva Date: Thu Dec 19 00:19:34 2024 -0300 add options to control ifcombine Introduce flags to disable ifcombine as a whole, or its new components. Disable the potentially quadratic noncontiguous ifcombine at -O1. Adjust the tests that expected it with -O to use -O2 instead. for gcc/ChangeLog * common.opt (fcombine-conditionals): New. (fcombine-field-conditionals): New. (fcombine-noncontiguous-conditionals): New. * doc/invoke.texi: Document them. * tree-ssa-ifcombine.cc (ifcombine_ifandif): Don't call fold_truth_andor if -fno-combine-field-conditionals. (tree_ssa_ifcombine_bb): Quit after the first attempt under -fno-combine-noncontiguous-conditionals. (pass_tree_ifcombine::gate): New. for gcc/testsuite/ChangeLog * gcc.dg/field-merge-1.c: Bump to -O2. * gcc.dg/field-merge-2.c: Likewise. * gcc.dg/field-merge-3.c: Likewise. * gcc.dg/field-merge-4.c: Likewise. * gcc.dg/field-merge-5.c: Likewise. * gcc.dg/field-merge-6.c: Likewise. * gcc.dg/field-merge-7.c: Likewise. * gcc.dg/field-merge-8.c: Likewise. * gcc.dg/field-merge-9.c: Likewise. * gcc.dg/field-merge-10.c: Likewise. * gcc.dg/field-merge-11.c: Likewise. * gcc.dg/field-merge-13.c: Likewise. * gcc.dg/field-merge-14.c: Likewise. * gcc.dg/field-merge-15.c: Likewise. * gcc.dg/field-merge-16.c: Likewise. Diff: --- gcc/common.opt| 12 gcc/doc/invoke.texi | 30 gcc/testsuite/gcc.dg/field-merge-1.c | 2 +- gcc/testsuite/gcc.dg/field-merge-10.c | 2 +- gcc/testsuite/gcc.dg/field-merge-11.c | 2 +- gcc/testsuite/gcc.dg/field-merge-13.c | 2 +- gcc/testsuite/gcc.dg/field-merge-14.c | 2 +- gcc/testsuite/gcc.dg/field-merge-15.c | 2 +- gcc/testsuite/gcc.dg/field-merge-16.c | 2 +- gcc/testsuite/gcc.dg/field-merge-2.c | 2 +- gcc/testsuite/gcc.dg/field-merge-3.c | 2 +- gcc/testsuite/gcc.dg/field-merge-4.c | 2 +- gcc/testsuite/gcc.dg/field-merge-5.c | 2 +- gcc/testsuite/gcc.dg/field-merge-6.c | 2 +- gcc/testsuite/gcc.dg/field-merge-7.c | 2 +- gcc/testsuite/gcc.dg/field-merge-8.c | 2 +- gcc/testsuite/gcc.dg/field-merge-9.c | 2 +- gcc/tree-ssa-ifcombine.cc | 37 +++ 18 files changed, 82 insertions(+), 27 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index 1b72826d44b1..adf3ca3f6b17 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1241,6 +1241,18 @@ fcode-hoisting Common Var(flag_code_hoisting) Optimization Enable code hoisting. +fcombine-conditionals +Common Var(flag_tree_ifcombine) Init(-1) Optimization +Combine conditionals, with the ifcombine optimization pass. + +fcombine-field-conditionals +Common Var(flag_tree_ifcombine_fieldmerge) Init(-1) Optimization +Combine conditionals involving separate fields. + +fcombine-noncontiguous-conditionals +Common Var(flag_tree_ifcombine_noncontig) Init(-1) Optimization +Combine conditionals from noncontiguous blocks. + fcombine-stack-adjustments Common Var(flag_combine_stack_adjustments) Optimization Looks for opportunities to reduce stack adjustments and stack references. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8ed5536365f7..317b1dd233a6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -570,6 +570,8 @@ Objective-C and Objective-C++ Dialects}. -fassociative-math -fauto-profile -fauto-profile[=@var{path}] -fauto-inc-dec -fbranch-probabilities -fcaller-saves +-fcombine-conditionals -fcombine-field-conditionals +-fcombine-noncontiguous-conditionals -fcombine-stack-adjustments -fconserve-stack -ffold-mem-offsets -fcompare-elim -fcprop-registers -fcrossjumping @@ -12633,6 +12635,8 @@ complexity than at @option{-O}. @c Please keep the following list alphabetized. @gccoptlist{-fauto-inc-dec -fbranch-count-reg +-fcombine-conditionals +-fcombine-field-conditionals -fcombine-stack-adjustments -fcompare-elim -fcprop-registers @@ -12693,6 +12697,7 @@ also turns on the following optimization flags: @gccoptlist{-falign-functions -falign-jumps -falign-labels -falign-loops -fcaller-saves +-fcombine-noncontiguous-conditionals -fcode-hoisting -fcrossjumping -fcse-follow-jumps -fcse-skip-blocks @@ -13676,6 +13681,31 @@ those which have no call-preserved registers to use instead. Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}. +@opindex fcombine-conditionals +@opindex fno-combine-conditionals +@item -fcombine-conditionals +Enable combination of conditionals from blocks without side effects. + +It has no effect when n
[gcc/aoliva/heads/testme] add options to control ifcombine
The branch 'aoliva/heads/testme' was updated to point to: 03732dab7bf2... add options to control ifcombine It previously pointed to: 942a25fa89d7... add options to control ifcombine Diff: !!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST): --- 942a25f... add options to control ifcombine Summary of changes (added commits): --- 03732da... add options to control ifcombine
[gcc r15-6367] libgomp.texi: Update 'arch' context-selector description
https://gcc.gnu.org/g:570d4e4c68535ee4e5b2d82ad02a65fa1ec04112 commit r15-6367-g570d4e4c68535ee4e5b2d82ad02a65fa1ec04112 Author: Tobias Burnus Date: Thu Dec 19 16:06:21 2024 +0100 libgomp.texi: Update 'arch' context-selector description * libgomp.texi (OpenMP Context Selectors): Document that 'kind' also accepts 'cpu'/'any' on host and 'any'/'nohost' on 'nohost' devices. Diff: --- libgomp/libgomp.texi | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 6b8000c696f6..4e0ed993b2ca 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -6687,9 +6687,10 @@ smaller number. On non-host devices, the value of the @c has to be implemented; cf. also PR target/105640. @c For offload devices, add *additionally* gcc/config/*/t-omp-device. -For the host compiler, @code{kind} always matches @code{host}; for the -offloading architectures AMD GCN and Nvidia PTX, @code{kind} always matches -@code{gpu}. For the x86 family of computers, AMD GCN and Nvidia PTX +For the host compiler, @code{kind} always matches @code{host}, @code{cpu} +and @code{any}; for the offloading architectures AMD GCN and Nvidia PTX, +@code{kind} always matches @code{nohost}, @code{gpu} and @code{any}. +For the x86 family of computers, AMD GCN and Nvidia PTX the following traits are supported in addition; while OpenMP is supported on more architectures, GCC currently does not match any @code{arch} or @code{isa} traits for those.
[gcc r15-6368] Fix comment typos in tree-assume.cc
https://gcc.gnu.org/g:fc95e8776cf4b11bbffc593167105883165b9e4c commit r15-6368-gfc95e8776cf4b11bbffc593167105883165b9e4c Author: Andrew Carlotti Date: Wed Dec 18 16:16:51 2024 + Fix comment typos in tree-assume.cc gcc/ChangeLog: * tree-assume.cc: Fix comment typos. Diff: --- gcc/tree-assume.cc | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gcc/tree-assume.cc b/gcc/tree-assume.cc index 883338bcef1e..9a934f21dc03 100644 --- a/gcc/tree-assume.cc +++ b/gcc/tree-assume.cc @@ -36,16 +36,16 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfg.h" #include "gimple-pretty-print.h" -// An assume query utilizes the current range query to implelemtn the assume +// An assume query utilizes the current range query to implement the assume // keyword. // For any return value of 1 from the function, it attempts to determine -// which paths leads to a 1 value being returned. On those paths, what +// which paths lead to a 1 value being returned. On those paths, it determines // the ranges of any ssa_names listed in bitmap P (usually the parm list for -// the function) are, and combined them all. +// the function), and combines them all. // These ranges are then set as the global ranges for those parms in this // function. -// Other functions which then refer to this function in an assume builtin -// will then pick up these ranges for the paramters via the inferred range +// Other functions which refer to this function in an assume builtin +// will then pick up these ranges for the parameters via the inferred range // mechanism. // See gimple-range-infer.cc::gimple_infer_range::check_assume_func () // @@ -57,11 +57,11 @@ along with GCC; see the file COPYING3. If not see // // a small temporary assume function consisting of // assume_f1 (int x) { return x == 1 || x == 4; } -// is constructed by the front end, and optimzed, at the very end of +// is constructed by the front end, and optimized, at the very end of // optimization, instead of generating code, we instead invoke the assume pass // which uses this query to set the the global value of parm x to [1,1][4,4] // -// Meanwhile., my_Fund has been rewritten to be: +// Meanwhile., my_func has been rewritten to be: // // my_func (int x_2) // { @@ -70,12 +70,12 @@ along with GCC; see the file COPYING3. If not see // if (x_2 == 3) // // When ranger is processing the assume_builtin_call, it looks up the global -// value of the paramter in assume_f1, which is [1,1][4,4]. It then registers +// value of the parameter in assume_f1, which is [1,1][4,4]. It then registers // and inferred range at this statement setting the value x_2 to [1,1][4,4] // -// Any uses of x_2 after this statement will now utilzie this inferred range. +// Any uses of x_2 after this statement will now utilize this inferred range. // -// When VRP precoesses if (x_2 == 3), it picks up the inferred range, and +// When VRP processes if (x_2 == 3), it picks up the inferred range, and // determines that x_2 can never be 3, and will rewrite the branch to // if (0 != 0) @@ -109,7 +109,7 @@ assume_query::assume_query (function *f, bitmap p) : m_parm_list (p), m_func (f) { basic_block exit_bb = EXIT_BLOCK_PTR_FOR_FN (f); - // If there is more than one precessor to the exit block, bail. + // If there is more than one predecessor to the exit block, bail. if (!single_pred_p (exit_bb)) return; @@ -130,7 +130,7 @@ assume_query::assume_query (function *f, bitmap p) : m_parm_list (p), if (!irange::supports_p (lhs_type)) return; - // Only values of interest are when the return value is 1. The defintion + // Only values of interest are when the return value is 1. The definition // of the return value must be in the same block, or we have // complicated flow control we don't understand, and just return. unsigned prec = TYPE_PRECISION (lhs_type); @@ -169,7 +169,7 @@ assume_query::assume_query (function *f, bitmap p) : m_parm_list (p), } } -// This function Will update all the current value of interesting parameters. +// This function will update all the current values of interesting parameters. // It tries, in order: //a) a range found via path calculations. //b) range of the parm at SRC point in the IL. (either edge or stmt) @@ -423,9 +423,9 @@ public: bool gate (function *fun) final override { return fun->assume_function; } unsigned int execute (function *fun) final override { - // Create a bitmap of all the paramters in this function. - // Invoke the assume_query to detemine what values these parameters - // have when the function returns TRUE, and set the globals value of + // Create a bitmap of all the parameters in this function. + // Invoke the assume_query to determine what values these parameters + // have when the fu
[gcc r14-11104] Fix comment typos in tree-assume.cc
https://gcc.gnu.org/g:87f9c0e4ae2ad7f5f4fde2438ba57af7ea45cafc commit r14-11104-g87f9c0e4ae2ad7f5f4fde2438ba57af7ea45cafc Author: Andrew Carlotti Date: Wed Dec 18 16:16:51 2024 + Fix comment typos in tree-assume.cc gcc/ChangeLog: * tree-assume.cc: Fix comment typos. Diff: --- gcc/tree-assume.cc | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gcc/tree-assume.cc b/gcc/tree-assume.cc index 897b5ce3bafe..10c1343492c0 100644 --- a/gcc/tree-assume.cc +++ b/gcc/tree-assume.cc @@ -36,16 +36,16 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "tree-cfg.h" -// An assume query utilizes the current range query to implelemtn the assume +// An assume query utilizes the current range query to implement the assume // keyword. // For any return value of 1 from the function, it attempts to determine -// which paths leads to a 1 value being returned. On those paths, what +// which paths lead to a 1 value being returned. On those paths, it determines // the ranges of any ssa_names listed in bitmap P (usually the parm list for -// the function) are, and combined them all. +// the function), and combines them all. // These ranges are then set as the global ranges for those parms in this // function. -// Other functions which then refer to this function in an assume builtin -// will then pick up these ranges for the paramters via the inferred range +// Other functions which refer to this function in an assume builtin +// will then pick up these ranges for the parameters via the inferred range // mechanism. // See gimple-range-infer.cc::gimple_infer_range::check_assume_func () // @@ -57,11 +57,11 @@ along with GCC; see the file COPYING3. If not see // // a small temporary assume function consisting of // assume_f1 (int x) { return x == 1 || x == 4; } -// is constructed by the front end, and optimzed, at the very end of +// is constructed by the front end, and optimized, at the very end of // optimization, instead of generating code, we instead invoke the assume pass // which uses this query to set the the global value of parm x to [1,1][4,4] // -// Meanwhile., my_Fund has been rewritten to be: +// Meanwhile., my_func has been rewritten to be: // // my_func (int x_2) // { @@ -70,12 +70,12 @@ along with GCC; see the file COPYING3. If not see // if (x_2 == 3) // // When ranger is processing the assume_builtin_call, it looks up the global -// value of the paramter in assume_f1, which is [1,1][4,4]. It then registers +// value of the parameter in assume_f1, which is [1,1][4,4]. It then registers // and inferred range at this statement setting the value x_2 to [1,1][4,4] // -// Any uses of x_2 after this statement will now utilzie this inferred range. +// Any uses of x_2 after this statement will now utilize this inferred range. // -// When VRP precoesses if (x_2 == 3), it picks up the inferred range, and +// When VRP processes if (x_2 == 3), it picks up the inferred range, and // determines that x_2 can never be 3, and will rewrite the branch to // if (0 != 0) @@ -110,7 +110,7 @@ assume_query::assume_query (gimple_ranger *ranger, function *f, bitmap p) : m_ranger (ranger), m_parm_list (p), m_func (f) { basic_block exit_bb = EXIT_BLOCK_PTR_FOR_FN (f); - // If there is more than one precessor to the exit block, bail. + // If there is more than one predecessor to the exit block, bail. if (!single_pred_p (exit_bb)) return; @@ -131,7 +131,7 @@ assume_query::assume_query (gimple_ranger *ranger, function *f, bitmap p) if (!irange::supports_p (lhs_type)) return; - // Only values of interest are when the return value is 1. The defintion + // Only values of interest are when the return value is 1. The definition // of the return value must be in the same block, or we have // complicated flow control we don't understand, and just return. unsigned prec = TYPE_PRECISION (lhs_type); @@ -173,7 +173,7 @@ assume_query::assume_query (gimple_ranger *ranger, function *f, bitmap p) } } -// This function Will update all the current value of interesting parameters. +// This function will update all the current values of interesting parameters. // It tries, in order: //a) a range found via path calculations. //b) range of the parm at SRC point in the IL. (either edge or stmt) @@ -341,9 +341,9 @@ public: bool gate (function *fun) final override { return fun->assume_function; } unsigned int execute (function *fun) final override { - // Create a bitmap of all the paramters in this function. - // Invoke the assume_query to detemine what values these parameters - // have when the function returns TRUE, and set the globals value of + // Create a bitmap of all the parameters in this function. + // Invoke the assume_query to determine what values these parameters + // have when the
[gcc r15-6365] testsuite: arm: C++26 uses __equal() instead of operator==()
https://gcc.gnu.org/g:898f333413d2ec9c446ab61fab303126ae5be4ac commit r15-6365-g898f333413d2ec9c446ab61fab303126ae5be4ac Author: Torbjörn SVENSSON Date: Wed Dec 18 20:54:00 2024 +0100 testsuite: arm: C++26 uses __equal() instead of operator==() Update test case to align with used function in C++26. gcc/testsuite/ChangeLog: * g++.dg/abi/arm_rtti1.C: Check for expected symbol in C++26. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/g++.dg/abi/arm_rtti1.C | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/g++.dg/abi/arm_rtti1.C b/gcc/testsuite/g++.dg/abi/arm_rtti1.C index 74f00033d9aa..5ebae26e6703 100644 --- a/gcc/testsuite/g++.dg/abi/arm_rtti1.C +++ b/gcc/testsuite/g++.dg/abi/arm_rtti1.C @@ -2,7 +2,8 @@ // { dg-options "-O2" } // Check that, even when optimizing, we emit an out-of-line call to // the type-info comparison function. -// { dg-final { scan-assembler _ZNKSt9type_infoeqERKS_ } } +// { dg-final { scan-assembler _ZNKSt9type_infoeqERKS_ { target { ! c++26 } } } } +// { dg-final { scan-assembler _ZNKSt9type_info7__equalERKS_ { target { c++26 } } } } #include
[gcc r15-6366] testsuite: arm: Use effective-target for memset-inline* tests
https://gcc.gnu.org/g:8462a5fdbfe12194b44072b5e64809b02dd2432d commit r15-6366-g8462a5fdbfe12194b44072b5e64809b02dd2432d Author: Torbjörn SVENSSON Date: Thu Oct 24 10:40:27 2024 +0200 testsuite: arm: Use effective-target for memset-inline* tests Split tests into 2 parts: - The first part checkes the assmbler generated. - The second part does the run test and this part now requires effective-target arm_neon_hw. gcc/testsuite/ChangeLog: * gcc.target/arm/memset-inline-4.c: Only check assembler output. * gcc.target/arm/memset-inline-5.c: Likewise. * gcc.target/arm/memset-inline-6.c: Likewise. * gcc.target/arm/memset-inline-8.c: Likewise. * gcc.target/arm/memset-inline-9.c: Likewise. * gcc.target/arm/memset-inline-4-exe.c: New test. * gcc.target/arm/memset-inline-5-exe.c: Likewise. * gcc.target/arm/memset-inline-6-exe.c: Likewise. * gcc.target/arm/memset-inline-8-exe.c: Likewise. * gcc.target/arm/memset-inline-9-exe.c: Likewise. Signed-off-by: Torbjörn SVENSSON Diff: --- gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-4.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-5.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-6.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-8.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-9-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-9.c | 2 +- 10 files changed, 40 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c new file mode 100644 index ..fef6c4365e2b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-4.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-4.c b/gcc/testsuite/gcc.target/arm/memset-inline-4.c index 5d7223ef2c00..6eb2a9d18a33 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-4.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-4.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-options "-save-temps -O2 -fno-inline" } */ /* { dg-add-options "arm_neon" } */ diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c new file mode 100644 index ..a52a527ea135 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-5.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-5.c b/gcc/testsuite/gcc.target/arm/memset-inline-5.c index 6e7ae65eef47..0f55c7b8c885 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-5.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-5.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-options "-save-temps -O2 -fno-inline" } */ /* { dg-add-options "arm_neon" } */ diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c new file mode 100644 index ..8e58d6810239 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-6.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-6.c b/gcc/testsuite/gcc.target/arm/memset-inline-6.c index ae226346d489..49ed68cbf351 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-6.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-6.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-options "-save-temps -O2 -fn
[gcc r14-11103] testsuite: arm: Use effective-target for memset-inline* tests
https://gcc.gnu.org/g:4bbb74c75c0a5bb8d4c5be57c22594b3e130b8de commit r14-11103-g4bbb74c75c0a5bb8d4c5be57c22594b3e130b8de Author: Torbjörn SVENSSON Date: Thu Oct 24 10:40:27 2024 +0200 testsuite: arm: Use effective-target for memset-inline* tests Split tests into 2 parts: - The first part checkes the assmbler generated. - The second part does the run test and this part now requires effective-target arm_neon_hw. gcc/testsuite/ChangeLog: * gcc.target/arm/memset-inline-4.c: Only check assembler output. * gcc.target/arm/memset-inline-5.c: Likewise. * gcc.target/arm/memset-inline-6.c: Likewise. * gcc.target/arm/memset-inline-8.c: Likewise. * gcc.target/arm/memset-inline-9.c: Likewise. * gcc.target/arm/memset-inline-4-exe.c: New test. * gcc.target/arm/memset-inline-5-exe.c: Likewise. * gcc.target/arm/memset-inline-6-exe.c: Likewise. * gcc.target/arm/memset-inline-8-exe.c: Likewise. * gcc.target/arm/memset-inline-9-exe.c: Likewise. Signed-off-by: Torbjörn SVENSSON (cherry picked from commit 8462a5fdbfe12194b44072b5e64809b02dd2432d) Diff: --- gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-4.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-5.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-6.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-8-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-8.c | 2 +- gcc/testsuite/gcc.target/arm/memset-inline-9-exe.c | 7 +++ gcc/testsuite/gcc.target/arm/memset-inline-9.c | 2 +- 10 files changed, 40 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c new file mode 100644 index ..fef6c4365e2b --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-4-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-4.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-4.c b/gcc/testsuite/gcc.target/arm/memset-inline-4.c index fc5f4aeed85e..5d3eb1d53ad0 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-4.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-4.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-require-effective-target arm_neon_hw } */ /* { dg-options "-save-temps -O2 -fno-inline" } */ diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c new file mode 100644 index ..a52a527ea135 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-5-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-5.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-5.c b/gcc/testsuite/gcc.target/arm/memset-inline-5.c index 683290771cfa..567e6d0ca8a6 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-5.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-5.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ /* { dg-require-effective-target arm_neon_hw } */ /* { dg-options "-save-temps -O2 -fno-inline" } */ diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c b/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c new file mode 100644 index ..8e58d6810239 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/memset-inline-6-exe.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ +/* { dg-skip-if "Don't inline memset using neon instructions" { ! arm_tune_string_ops_prefer_neon } } */ +/* { dg-require-effective-target arm_neon_hw } */ +/* { dg-options "-save-temps -O2 -fno-inline" } */ +/* { dg-add-options "arm_neon" } */ + +#include "./memset-inline-6.c" diff --git a/gcc/testsuite/gcc.target/arm/memset-inline-6.c b/gcc/testsuite/gcc.target/arm/memset-inline-6.c index 66c242eebbe8..ccaf25e3f9d2 100644 --- a/gcc/testsuite/gcc.target/arm/memset-inline-6.c +++ b/gcc/testsuite/gcc.target/arm/memset-inline-6.c @@ -1,4 +1,4 @@ -/* { dg-do run } */ +/* { dg-do compile } */ /* { dg-skip-if "Don't inline memset usin
[gcc r15-6376] libstdc++: Add fancy pointer support to std::map and std::set [PR57272]
https://gcc.gnu.org/g:23df3c3a4aa33a08e82ac8b98d7ff6e7f1b65b63 commit r15-6376-g23df3c3a4aa33a08e82ac8b98d7ff6e7f1b65b63 Author: François Dumont Date: Mon Jul 22 21:54:36 2024 +0200 libstdc++: Add fancy pointer support to std::map and std::set [PR57272] The fancy allocator pointer type support is added to std::map, std::multimap, std::multiset and std::set through the underlying std::_Rb_tree class. To respect ABI a new parralel hierarchy of node types has been added. This change introduces new class template parameterized on the allocator's void_pointer type, __rb_tree::_Node_base, and new class templates parameterized on the allocator's pointer type, __rb_tree::_Node, __rb_tree::_Iterator. The iterator class template is used for both iterator and const_iterator. Whether std::_Rb_tree should use the old _Rb_tree_node or new __rb_tree::_Node type family internally is controlled by a new __rb_tree::_Node_traits traits template. Because std::pointer_traits and std::__to_address are not defined for C++98, there is no way to support fancy pointers in C++98. For C++98 the _Node_traits traits always choose the old _Rb_tree_node family. In case anybody is currently using std::_Rb_tree with an allocator that has a fancy pointer, this change would be an ABI break, because their std::_Rb_tree instantiations would start to (correctly) use the fancy pointer type. If the fancy pointer just contains a single pointer and so has the same size, layout, and object representation as a raw pointer, the code might still work (despite being an ODR violation). But if their fancy pointer has a different representation, they would need to recompile all their code using that allocator with std::_Rb_tree. Because std::_Rb_tree will never use fancy pointers in C++98 mode, recompiling everything to use fancy pointers isn't even possible if mixing C++98 and C++11 code that uses std::_Rb_tree. To alleviate this problem, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=0 will force std::_Rb_tree to have the old, non-conforming behaviour and use raw pointers internally. For testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE=9001 will force std::_Rb_tree to always use the new node types. This macro is currently undocumented, which needs to be fixed. As _Rb_tree is using _Base_ptr to represent the tree this change also simplifies the implementation by removing all the const pointer types and associated methods. libstdc++-v3/ChangeLog: PR libstdc++/57272 * include/bits/stl_tree.h [_GLIBCXX_USE_ALLOC_PTR_FOR_RB_TREE]: New macro to control usage of the code required to support fancy allocator pointer type. (_Rb_tree_node_base::_Const_Base_ptr): Remove. (_Rb_tree_node_base::_S_minimum, _Rb_tree_node_base::_S_maximum): Remove overloads for _Const_Base_ptr. (_Rb_tree_node_base::_M_base_ptr()): New. (_Rb_tree_node::_Link_type): Remove. (_Rb_tree_node::_M_node_ptr()): New. (__rb_tree::_Node_base<>): New. (__rb_tree::_Header<>): New. (__rb_tree::_Node<>): New. (_Rb_tree_increment(const _Rb_tree_node_base*)): Remove declaration. (_Rb_tree_decrement(const _Rb_tree_node_base*)): Remove declaration. (_Rb_tree_iterator<>::_Self): Remove. (_Rb_tree_iterator<>::_Link_type): Rename into... (_Rb_tree_iterator<>::_Node_ptr): ...this. (_Rb_tree_const_iterator<>::_Link_type): Rename into... (_Rb_tree_const_iterator<>::_Node_ptr): ...this. (_Rb_tree_const_iterator<>::_M_const_cast): Remove. (_Rb_tree_const_iterator<>::_M_node): Change type into _Base_ptr. (__rb_tree::_Iterator<>): New. (__rb_tree::_Node_traits<>): New. (_Rb_tree<>::_Node_base, _Rb_tree::_Node): New. (_Rb_tree<>::_Link_type): Rename into... (_Rb_tree<>::_Node_ptr): ...this. (_Rb_tree<>::_Const_Base_ptr, _Rb_tree<>::_Const_Node_ptr): Remove. (_Rb_tree<>::_M_mbegin): Remove. (_Rb_tree<>::_M_begin_node()): New. (_S_key(const _Node&)): New. (_S_key(_Base_ptr)): New, call latter. (_S_key(_Node_ptr)): Likewise. (_Rb_tree<>::_S_left(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_right(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_maximum(_Const_Base_ptr)): Remove. (_Rb_tree<>::_S_minimum(_Const_Base_ptr)): Remove. * testsuite/23_containers/map/allocator/ext_ptr.cc: New test case. * testsuite/23_containers/multimap/allocator/ext_ptr.cc: New test case. * testsuite/23_containers/multiset/allocator/ext_ptr.cc: New test case.
[gcc r15-6378] c++/modules: Detect exposures of TU-local entities
https://gcc.gnu.org/g:9016c5ac94c55714d001309ef640710f9d512254 commit r15-6378-g9016c5ac94c55714d001309ef640710f9d512254 Author: Nathaniel Shead Date: Tue Oct 8 20:50:38 2024 +1100 c++/modules: Detect exposures of TU-local entities Currently, the modules streaming code implements some checks for declarations in the CMI that reference (some kinds of) internal-linkage entities, and errors if so. This patch expands on that support to implement the logic for exposures of TU-local entities as defined in [basic.link] since P1815. This will cause some code that previously errored in modules to start compiling; for instance, template specialisations of internal linkage functions. However, some code that previously appeared valid will with this patch no longer compile, notably some kinds of usages of internal linkage functions included from the GMF. This appears to be related to P2808 and FR-025, however as yet there doesn't appear to be consensus for changing these rules so I've implemented them as-is. This patch leaves a couple of things out. In particular, a couple of the rules for what is a TU-local entity currently seem to me to be redundant; I've left them as FIXMEs to be handled once I can find testcases that aren't adequately supported by the other logic here. Additionally, there are some exceptions for when naming a TU-local entity is not always an exposure; I've left support for this to a follow-up patch for easier review, as it has broader implications for streaming. TU-local lambdas are also not yet properly implemented, due to other bugs with regards to LAMBDA_TYPE_EXTRA_SCOPE not being set in all cases that it probably should be (see also PR c++/116568). We can revisit this once that issue has been fixed. Finally, this patch makes a couple of small adjustments to the modules streaming logic to prune any leftover TU-local deps (that aren't erroneous exposures). This is required for this patch to ensure that later stages don't get confused by any leftover TU-local entities floating around. gcc/cp/ChangeLog: * tree.cc (decl_linkage): Treat DECL_SELF_REFERENCE_P like DECL_IMPLICIT_TYPEDEF_P. * name-lookup.cc (do_namespace_alias): Fix linkage. * module.cc (DB_IS_INTERNAL_BIT): Rename to... (DB_TU_LOCAL_BIT): ...this. (DB_REFS_INTERNAL_BIT): Rename to... (DB_EXPOSURE_BIT): ...this. (depset::hash::is_internal): Rename to... (depset::hash::is_tu_local): ...this. (depset::hash::refs_internal): Rename to... (depset::hash::is_exposure): ...this. (depset::hash::is_tu_local_entity): New function. (depset::hash::has_tu_local_tmpl_arg): New function. (depset::hash::is_tu_local_value): New function. (depset::hash::make_dependency): Check for TU-local entities. (depset::hash::add_dependency): Make current an exposure whenever it references a TU-local entity. (depset::hash::add_binding_entity): Don't create bindings for any TU-local entity. (depset::hash::finalize_dependencies): Rename flags and adjust diagnostic messages to report exposures of TU-local entities. (depset::tarjan::connect): Don't include any TU-local depsets. (depset::hash::connect): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/block-decl-2.C: Adjust messages. * g++.dg/modules/internal-1.C: Adjust messages, remove XFAILs. * g++.dg/modules/linkage-2.C: Adjust messages, remove XFAILS. * g++.dg/modules/internal-3.C: New test. * g++.dg/modules/internal-4_a.H: New test. * g++.dg/modules/internal-4_b.C: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill Diff: --- gcc/cp/module.cc| 382 +++- gcc/cp/name-lookup.cc | 2 +- gcc/cp/tree.cc | 10 +- gcc/testsuite/g++.dg/modules/block-decl-2.C | 2 +- gcc/testsuite/g++.dg/modules/internal-1.C | 15 +- gcc/testsuite/g++.dg/modules/internal-3.C | 18 ++ gcc/testsuite/g++.dg/modules/internal-4_a.H | 4 + gcc/testsuite/g++.dg/modules/internal-4_b.C | 128 ++ gcc/testsuite/g++.dg/modules/linkage-2.C| 5 +- 9 files changed, 491 insertions(+), 75 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index f2a4fb16c078..09158b0f0e62 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2352,10 +2352,8 @@ private: DB_KIND_BITS = EK_BITS, DB_DEFN_BIT = DB_KIND_BIT + DB_KIND_BITS, DB_IS_PENDING_BIT, /* Is a maybe-pending entity. */ -DB_IS_INTERNAL_BIT,/* It is an (erron
[gcc r15-6381] c++/modules: Check linkage for exported declarations
https://gcc.gnu.org/g:fde64d1180408128a2f33e5326a3a7876926e2a3 commit r15-6381-gfde64d1180408128a2f33e5326a3a7876926e2a3 Author: Nathaniel Shead Date: Fri Sep 6 23:53:08 2024 +1000 c++/modules: Check linkage for exported declarations By [module.interface] p3, if an exported declaration is not within a header unit, it shall not declare a name with internal linkage. Unfortunately we cannot just do this within set_originating_module, since at the locations its called the linkage for declarations are not always fully determined yet. We could move the calls but this causes the checking assertion to fail as the originating module declaration may have moved, and in general for some kinds of declarations it's not always obvious where it should be moved to. This patch instead introduces a new function to check that the linkage of a declaration within a module is correct, to be called for all declarations once their linkage is fully determined. As a drive-by fix this patch also improves the source location of namespace aliases to point at the identifier rather than the terminating semicolon. gcc/cp/ChangeLog: * cp-tree.h (check_module_decl_linkage): Declare. * decl2.cc (finish_static_data_member_decl): Check linkage. * module.cc (set_originating_module): Adjust comment. (check_module_decl_linkage): New function. * name-lookup.cc (do_namespace_alias): Build alias with specified location, check linkage. (pushtag): Check linkage. (push_namespace): Slightly clarify error message. * name-lookup.h (do_namespace_alias): Add location parameter. * parser.cc (cp_parser_namespace_alias_definition): Pass identifier location to do_namespace_alias. (cp_parser_alias_declaration): Check linkage. (cp_parser_init_declarator): Check linkage. (cp_parser_function_definition_after_declarator): Check linkage. (cp_parser_save_member_function_body): Check linkage. * pt.cc (finish_concept_definition): Mark as public, check linkage. libcc1/ChangeLog: * libcp1plugin.cc (plugin_add_namespace_alias): Call do_namespace_alias with input_location. gcc/testsuite/ChangeLog: * g++.dg/modules/export-3.C: Adjust error message. * g++.dg/modules/export-6.C: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill Diff: --- gcc/cp/cp-tree.h| 1 + gcc/cp/decl2.cc | 1 + gcc/cp/module.cc| 29 +++--- gcc/cp/name-lookup.cc | 20 ++ gcc/cp/name-lookup.h| 2 +- gcc/cp/parser.cc| 9 - gcc/cp/pt.cc| 2 ++ gcc/testsuite/g++.dg/modules/export-3.C | 2 +- gcc/testsuite/g++.dg/modules/export-6.C | 36 + libcc1/libcp1plugin.cc | 2 +- 10 files changed, 93 insertions(+), 11 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c60d0ac014e6..6de8f64b5eea 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7531,6 +7531,7 @@ extern void set_originating_module (tree, bool friend_p = false); extern tree get_originating_module_decl (tree) ATTRIBUTE_PURE; extern int get_originating_module (tree, bool for_mangle = false) ATTRIBUTE_PURE; extern unsigned get_importing_module (tree, bool = false) ATTRIBUTE_PURE; +extern void check_module_decl_linkage (tree); /* Where current instance of the decl got declared/defined/instantiated. */ extern void set_instantiating_module (tree); diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index bc3a9d0e922c..b6e93c1dfca0 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -1019,6 +1019,7 @@ finish_static_data_member_decl (tree decl, } cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags); + check_module_decl_linkage (decl); } /* DECLARATOR and DECLSPECS correspond to a class member. The other diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index c1886e6c3b6e..b15f5b2496f7 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -20153,11 +20153,34 @@ set_originating_module (tree decl, bool friend_p ATTRIBUTE_UNUSED) DECL_MODULE_ATTACH_P (decl) = true; } - if (!module_exporting_p ()) + /* It is ill-formed to export a declaration with internal linkage. However, + at the point this function is called we don't yet always know whether this + declaration has internal linkage; instead we defer this check for callers + to do once visibility has been determined. */ + if (module_exporting_p ()) +DECL_MODULE_EXPORT_P (decl) = true; +} + +/* Checks whether DECL within a module unit has valid linkage for i
[gcc r15-6380] c++/modules: Support unnamed namespaces in header units
https://gcc.gnu.org/g:eebd8dfdc4f4a7f54b42f74c2e7f54f957930ecd commit r15-6380-geebd8dfdc4f4a7f54b42f74c2e7f54f957930ecd Author: Nathaniel Shead Date: Fri Sep 6 23:46:47 2024 +1000 c++/modules: Support unnamed namespaces in header units A header unit may contain unnamed namespaces, and those declarations are exported (as with any declaration in a header unit). This patch ensures that such declarations are correctly handled. The change to 'make_namespace_finish' is required so that if an unnamed namespace is first seen by an import it is correctly handled within 'add_imported_namespace'. I don't see any particular reason why handling of unnamed namespaces here had to be handled separately outside that function since these are the only two callers. gcc/cp/ChangeLog: * module.cc (depset::hash::add_binding_entity): Also walk unnamed namespaces. (module_state::write_namespaces): Adjust assertion. * name-lookup.cc (push_namespace): Move anon using-directive handling to... (make_namespace_finish): ...here. gcc/testsuite/ChangeLog: * g++.dg/modules/internal-9_a.H: New test. * g++.dg/modules/internal-9_b.C: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill Diff: --- gcc/cp/module.cc| 7 +++ gcc/cp/name-lookup.cc | 10 +- gcc/testsuite/g++.dg/modules/internal-9_a.H | 28 gcc/testsuite/g++.dg/modules/internal-9_b.C | 29 + 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 6774d472f191..c1886e6c3b6e 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -13903,15 +13903,15 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) return (flags & WMB_Using ? flags & WMB_Export : DECL_MODULE_EXPORT_P (decl)); } - else if (DECL_NAME (decl) && !data->met_namespace) + else if (!data->met_namespace) { /* Namespace, walk exactly once. */ - gcc_checking_assert (TREE_PUBLIC (decl)); data->met_namespace = true; if (data->hash->add_namespace_entities (decl, data->partitions)) { /* It contains an exported thing, so it is exported. */ gcc_checking_assert (DECL_MODULE_PURVIEW_P (decl)); + gcc_checking_assert (TREE_PUBLIC (decl) || header_module_p ()); DECL_MODULE_EXPORT_P (decl) = true; } @@ -16329,8 +16329,7 @@ module_state::write_namespaces (elf_out *to, vec spaces, tree ns = b->get_entity (); gcc_checking_assert (TREE_CODE (ns) == NAMESPACE_DECL); - /* P1815 may have something to say about this. */ - gcc_checking_assert (TREE_PUBLIC (ns)); + gcc_checking_assert (TREE_PUBLIC (ns) || header_module_p ()); unsigned flags = 0; if (TREE_PUBLIC (ns)) diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 35e7dc81377a..7737b0fbf732 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -9121,6 +9121,11 @@ make_namespace_finish (tree ns, tree *slot, bool from_import = false) if (DECL_NAMESPACE_INLINE_P (ns) || !DECL_NAME (ns)) emit_debug_info_using_namespace (ctx, ns, true); + + /* An unnamed namespace implicitly has a using-directive inserted so + that its contents are usable in the surrounding context. */ + if (!DECL_NAMESPACE_INLINE_P (ns) && !DECL_NAME (ns)) +add_using_namespace (NAMESPACE_LEVEL (ctx)->using_directives, ns); } /* Push into the scope of the NAME namespace. If NAME is NULL_TREE, @@ -9257,11 +9262,6 @@ push_namespace (tree name, bool make_inline) gcc_checking_assert (slot); } make_namespace_finish (ns, slot); - - /* Add the anon using-directive here, we don't do it in -make_namespace_finish. */ - if (!DECL_NAMESPACE_INLINE_P (ns) && !name) - add_using_namespace (current_binding_level->using_directives, ns); } } diff --git a/gcc/testsuite/g++.dg/modules/internal-9_a.H b/gcc/testsuite/g++.dg/modules/internal-9_a.H new file mode 100644 index ..57fe60bb3c05 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/internal-9_a.H @@ -0,0 +1,28 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +static int x = 123; +static void f() {} +template static void t() {} + +namespace { + int y = 456; + void g() {}; + template void u() {} + + namespace ns { int in_ns = 456; } + + struct A {}; + template struct B {}; + + enum E { X }; + enum class F { Y }; + + template using U = int; + +#if __cplusplus >= 202002L + template concept C = true; +#endif +} + +namespace ns2 = ns; diff --git a/gcc/testsuite/g++.dg/modules/internal-9_b.C b/gcc/testsuite/g++.dg/modules/internal-9_b.C new file mode
[gcc r15-6382] c++/modules: Validate external linkage definitions in header units [PR116401]
https://gcc.gnu.org/g:71732eafedbd30355e752bf873d355fbcd0e076f commit r15-6382-g71732eafedbd30355e752bf873d355fbcd0e076f Author: Nathaniel Shead Date: Sun Sep 8 01:37:28 2024 +1000 c++/modules: Validate external linkage definitions in header units [PR116401] [module.import] p6 says "A header unit shall not contain a definition of a non-inline function or variable whose name has external linkage." This patch implements this requirement, and cleans up some issues in the testsuite where this was already violated. To handle deduction guides we mark them as inline, since although we give them a definition for implementation reasons, by the standard they have no definition, and so we should not error in this case. PR c++/116401 gcc/cp/ChangeLog: * decl.cc (grokfndecl): Mark deduction guides as 'inline'. * module.cc (check_module_decl_linkage): Implement checks for non-inline external linkage definitions in headers. gcc/testsuite/ChangeLog: * g++.dg/modules/macro-4_c.H: Add missing 'inline'. * g++.dg/modules/pr106761.h: Likewise. * g++.dg/modules/pr98843_b.H: Likewise. * g++.dg/modules/pr99468.H: Likewise. * g++.dg/modules/pragma-1_a.H: Likewise. * g++.dg/modules/tpl-ary-1.h: Likewise. * g++.dg/modules/hdr-2.H: New test. Signed-off-by: Nathaniel Shead Reviewed-by: Jason Merrill Diff: --- gcc/cp/decl.cc| 3 + gcc/cp/module.cc | 16 +++ gcc/testsuite/g++.dg/modules/hdr-2.H | 172 ++ gcc/testsuite/g++.dg/modules/macro-4_c.H | 2 +- gcc/testsuite/g++.dg/modules/pr106761.h | 2 +- gcc/testsuite/g++.dg/modules/pr98843_b.H | 2 +- gcc/testsuite/g++.dg/modules/pr99468.H| 2 +- gcc/testsuite/g++.dg/modules/pragma-1_a.H | 2 +- gcc/testsuite/g++.dg/modules/tpl-ary-1.h | 2 +- 9 files changed, 197 insertions(+), 6 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 9d251348a438..42e83f880f92 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -11072,6 +11072,9 @@ grokfndecl (tree ctype, have one: the restriction that you can't repeat a deduction guide makes them more like a definition anyway. */ DECL_INITIAL (decl) = void_node; + /* But to ensure that external-linkage deduction guides in header units +don't fall afoul of [module.import] p6, mark them as inline. */ + DECL_DECLARED_INLINE_P (decl) = true; break; default: break; diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index b15f5b2496f7..b9cf16433b5d 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -20170,6 +20170,22 @@ check_module_decl_linkage (tree decl) if (!module_has_cmi_p ()) return; + /* A header unit shall not contain a definition of a non-inline function + or variable (not template) whose name has external linkage. */ + if (header_module_p () + && !processing_template_decl + && ((TREE_CODE (decl) == FUNCTION_DECL + && !DECL_DECLARED_INLINE_P (decl)) + || (TREE_CODE (decl) == VAR_DECL + && !DECL_INLINE_VAR_P (decl))) + && decl_defined_p (decl) + && !(DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INSTANTIATION (decl)) + && decl_linkage (decl) == lk_external) +error_at (DECL_SOURCE_LOCATION (decl), + "external linkage definition of %qD in header module must " + "be declared %", decl); + /* An internal-linkage declaration cannot be generally be exported. But it's OK to export any declaration from a header unit, including internal linkage declarations. */ diff --git a/gcc/testsuite/g++.dg/modules/hdr-2.H b/gcc/testsuite/g++.dg/modules/hdr-2.H new file mode 100644 index ..097546d56674 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/hdr-2.H @@ -0,0 +1,172 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi !{} } +// external linkage variables or functions in header units must +// not have non-inline definitions + +int x_err; // { dg-error "external linkage definition" } +int y_err = 123; // { dg-error "external linkage definition" } +void f_err() {} // { dg-error "external linkage definition" } + +struct Err { + Err(); + void m(); + static void s(); + static int x; + static int y; +}; +Err::Err() = default; // { dg-error "external linkage definition" } +void Err::m() {} // { dg-error "external linkage definition" } +void Err::s() {} // { dg-error "external linkage definition" } +int Err::x; // { dg-error "external linkage definition" } +int Err::y = 123; // { dg-error "external linkage definition" } + +// No definition, OK +extern int y_decl; +void f_decl(); + +template struct DeductionGuide {}; +DeductionGuide() -> DeductionGuide; + +struct NoDefStatics { + enum E { V }; + stati
[gcc r15-6379] c++/modules: Ignore TU-local entities where necessary
https://gcc.gnu.org/g:0c2ae384326108fad5ca2713ad3c9b768162fe73 commit r15-6379-g0c2ae384326108fad5ca2713ad3c9b768162fe73 Author: Nathaniel Shead Date: Fri Oct 11 22:16:02 2024 +1100 c++/modules: Ignore TU-local entities where necessary [basic.link] p14 lists a number of circumstances where a declaration naming a TU-local entity is not an exposure, notably the bodies of non-inline templates and friend declarations in classes. This patch ensures that these references do not error when exporting the module. We do need to still error on instantiation from a different module, however, in case this refers to a TU-local entity. As such this patch adds a new tree TU_LOCAL_ENTITY which is used purely as a placeholder to poison any attempted template instantiations that refer to it. This is also streamed for friend decls so that merging (based on the index of an entity into the friend decl list) doesn't break and to prevent complicating the logic; I imagine this shouldn't ever come up though. We also add a new warning, '-Wtemplate-names-tu-local', to handle the case where someone accidentally refers to a TU-local value from within a non-inline function template. This will compile without errors as-is, but any attempt to instantiate the decl will fail; this warning can be used to ensure that this doesn't happen. The warning is silenced for any declarations with explicit instantiations, since uses of those instantiations would not be exposures. The main piece that this patch doesn't yet attempt to solve is ADL: as specified, if ADL adds an overload set that includes a translation-unit local entity when instantiating a template, that overload set is now poisoned and counts as an exposure. Unfortunately, we don't currently differentiate between decls that are hidden due to not being exported, or decls that are hidden due to being hidden friends, so this patch instead just keeps the current (wrong) behaviour of non-exported entities not being visible to ADL at all. Additionally, this patch doesn't attempt to ignore non-ODR uses of constants in constexpr functions or templates. The obvious approach of folding them early in 'mark_use' doesn't seem to work (for a variety of reasons), so this leaves this to a later patch to implement, as it's at least no worse than the current behaviour and easy enough to workaround. For completeness this patch adds a new xtreme-header testcase to ensure that we have no regressions with regards to exposures of TU-local declarations in the standard library header files. A more restrictive test would be to do 'export extern "C++"' here, but unfortunately the system headers on some targets declare TU-local entities, so we'll make do with checking that at least the C++ standard library headers don't refer to such entities. gcc/c-family/ChangeLog: * c.opt: New warning '-Wtemplate-names-tu-local'. gcc/cp/ChangeLog: * cp-objcp-common.cc (cp_tree_size): Add TU_LOCAL_ENTITY. * cp-tree.def (TU_LOCAL_ENTITY): New tree code. * cp-tree.h (DECL_TEMPLATE_INSTANTIATIONS): Update comment. (struct tree_tu_local_entity): New type. (TU_LOCAL_ENTITY_NAME): New accessor. (TU_LOCAL_ENTITY_LOCATION): New accessor. (enum cp_tree_node_structure_enum): Add TS_CP_TU_LOCAL_ENTITY. (union GTY): Add tu_local_entity field. * module.cc (enum tree_tag): New flag DB_REFS_TU_LOCAL_BIT. (depset::has_defn): Override for TU-local entities. (depset::refs_tu_local): New accessor. (depset::hash::ignore_tu_local): New field. (depset::hash::hash): Initialize it. (trees_out::tree_tag::tt_tu_local): New flag. (trees_out::writing_local_entities): New field. (trees_out::is_initial_scan): New function. (trees_out::tu_local_count): New counter. (trees_out::trees_out): Initialize writing_local_entities. (dumper::impl::nested_name): Handle TU_LOCAL_ENTITY. (trees_out::instrument): Report TU-local entity counts. (trees_out::decl_value): Early exit for TU-local entities. (trees_in::decl_value): Handle typedefs of TU-local entities. (trees_out::decl_node): Adjust assertion to cope with early exit of TU-local deps. Always write TU-local entities by value. (trees_out::type_node): Handle TU-local types. (trees_out::has_tu_local_dep): New function. (trees_out::find_tu_local_decl): New function. (trees_out::tree_node): Intercept TU-local entities and write placeholder values for them instead of normal streaming. (trees_in::tree_node): Handle TU-local ent
[gcc r15-6383] Fortran: Fix caf_stop_numeric and reporting exceptions from caf [PR57598]
https://gcc.gnu.org/g:a25cc26884663244c3b936af785854abee8949dd commit r15-6383-ga25cc26884663244c3b936af785854abee8949dd Author: Andre Vehreschild Date: Wed Dec 18 12:43:39 2024 +0100 Fortran: Fix caf_stop_numeric and reporting exceptions from caf [PR57598] Caf_stop_numeric always exited with code 0, which is wrong. It shall behave like regular stop. Add reporting exceptions to caf's stop handlers. For this the existing library routine had to be exported. libgfortran/ChangeLog: PR fortran/57598 * caf/single.c (_gfortran_caf_stop_numeric): Report exceptions on stop. And fix send_by_ref. (_gfortran_caf_stop_str): Same. (_gfortran_caf_error_stop_str): Same. (_gfortran_caf_error_stop): Same. * gfortran.map: Add report_exception for export. * libgfortran.h (report_exception): Add to internal export. * runtime/stop.c (report_exception): Same. Diff: --- libgfortran/caf/single.c | 19 +++ libgfortran/gfortran.map | 1 + libgfortran/libgfortran.h | 3 +++ libgfortran/runtime/stop.c | 7 +-- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index 41da970e8308..0ffbffa1d2ba 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -263,13 +263,17 @@ _gfortran_caf_sync_images (int count __attribute__ ((unused)), *stat = 0; } +extern void _gfortran_report_exception (void); void _gfortran_caf_stop_numeric(int stop_code, bool quiet) { if (!quiet) -fprintf (stderr, "STOP %d\n", stop_code); - exit (0); +{ + _gfortran_report_exception (); + fprintf (stderr, "STOP %d\n", stop_code); +} + exit (stop_code); } @@ -278,6 +282,7 @@ _gfortran_caf_stop_str(const char *string, size_t len, bool quiet) { if (!quiet) { + _gfortran_report_exception (); fputs ("STOP ", stderr); while (len--) fputc (*(string++), stderr); @@ -292,6 +297,7 @@ _gfortran_caf_error_stop_str (const char *string, size_t len, bool quiet) { if (!quiet) { + _gfortran_report_exception (); fputs ("ERROR STOP ", stderr); while (len--) fputc (*(string++), stderr); @@ -373,7 +379,10 @@ void _gfortran_caf_error_stop (int error, bool quiet) { if (!quiet) -fprintf (stderr, "ERROR STOP %d\n", error); +{ + _gfortran_report_exception (); + fprintf (stderr, "ERROR STOP %d\n", error); +} exit (error); } @@ -2131,14 +2140,16 @@ send_by_ref (caf_reference_t *ref, size_t *i, size_t *src_index, /* Assume that the rank and the dimensions fit for copying src to dst. */ GFC_DESCRIPTOR_DTYPE (dst) = GFC_DESCRIPTOR_DTYPE (src); + GFC_DESCRIPTOR_SPAN (dst) = GFC_DESCRIPTOR_SPAN (src); stride_dst = 1; + dst->offset = 0; for (size_t d = 0; d < src_rank; ++d) { extent_dst = GFC_DIMENSION_EXTENT (src->dim[d]); GFC_DIMENSION_LBOUND (dst->dim[d]) = 1; GFC_DIMENSION_UBOUND (dst->dim[d]) = extent_dst; GFC_DIMENSION_STRIDE (dst->dim[d]) = stride_dst; - dst->offset = -extent_dst; + dst->offset -= stride_dst; stride_dst *= extent_dst; } /* Null the data-pointer to make register_component allocate diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map index f58edc52e3c2..851df211 100644 --- a/libgfortran/gfortran.map +++ b/libgfortran/gfortran.map @@ -1997,4 +1997,5 @@ GFORTRAN_15 { _gfortran_sminloc1_8_m2; _gfortran_sminloc1_8_m4; _gfortran_sminloc1_8_m8; +_gfortran_report_exception; } GFORTRAN_14; diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index aaa9222c43b6..cf3dda07d3d1 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -986,6 +986,9 @@ internal_proto(filename_from_unit); /* stop.c */ +extern void report_exception (void); +iexport_proto (report_exception); + extern _Noreturn void stop_string (const char *, size_t, bool); export_proto(stop_string); diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c index 2eefe21a9e90..3ac5beff6bba 100644 --- a/libgfortran/runtime/stop.c +++ b/libgfortran/runtime/stop.c @@ -38,7 +38,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see inexact - and we optionally ignore underflow, cf. thread starting at http://mailman.j3-fortran.org/pipermail/j3/2013-June/006452.html. */ -static void +extern void report_exception (void); +iexport_proto (report_exception); + +void report_exception (void) { struct iovec iov[8]; @@ -108,7 +111,7 @@ report_exception (void) estr_writev (iov, iovcnt); } - +iexport (report_exception); /* A numeric STOP statement