diff options
17 files changed, 4 insertions, 1742 deletions
diff --git a/meta/conf/distro/include/maintainers.inc b/meta/conf/distro/include/maintainers.inc index f1bff80586..9fe11282d9 100644 --- a/meta/conf/distro/include/maintainers.inc +++ b/meta/conf/distro/include/maintainers.inc | |||
| @@ -194,7 +194,7 @@ RECIPE_MAINTAINER:pn-gcc-cross-canadian-${TRANSLATED_TARGET_ARCH} = "Khem Raj <r | |||
| 194 | RECIPE_MAINTAINER:pn-gcc-crosssdk-${SDK_SYS} = "Khem Raj <raj.khem@gmail.com>" | 194 | RECIPE_MAINTAINER:pn-gcc-crosssdk-${SDK_SYS} = "Khem Raj <raj.khem@gmail.com>" |
| 195 | RECIPE_MAINTAINER:pn-gcc-runtime = "Khem Raj <raj.khem@gmail.com>" | 195 | RECIPE_MAINTAINER:pn-gcc-runtime = "Khem Raj <raj.khem@gmail.com>" |
| 196 | RECIPE_MAINTAINER:pn-gcc-sanitizers = "Khem Raj <raj.khem@gmail.com>" | 196 | RECIPE_MAINTAINER:pn-gcc-sanitizers = "Khem Raj <raj.khem@gmail.com>" |
| 197 | RECIPE_MAINTAINER:pn-gcc-source-14.2.0 = "Khem Raj <raj.khem@gmail.com>" | 197 | RECIPE_MAINTAINER:pn-gcc-source-14.3.0 = "Khem Raj <raj.khem@gmail.com>" |
| 198 | RECIPE_MAINTAINER:pn-gconf = "Ross Burton <ross.burton@arm.com>" | 198 | RECIPE_MAINTAINER:pn-gconf = "Ross Burton <ross.burton@arm.com>" |
| 199 | RECIPE_MAINTAINER:pn-gcr = "Unassigned <unassigned@yoctoproject.org>" | 199 | RECIPE_MAINTAINER:pn-gcr = "Unassigned <unassigned@yoctoproject.org>" |
| 200 | RECIPE_MAINTAINER:pn-gdb = "Khem Raj <raj.khem@gmail.com>" | 200 | RECIPE_MAINTAINER:pn-gdb = "Khem Raj <raj.khem@gmail.com>" |
diff --git a/meta/recipes-devtools/gcc/gcc-14.2.inc b/meta/recipes-devtools/gcc/gcc-14.3.inc index fa9003f604..ca2f2e2a13 100644 --- a/meta/recipes-devtools/gcc/gcc-14.2.inc +++ b/meta/recipes-devtools/gcc/gcc-14.3.inc | |||
| @@ -2,11 +2,11 @@ require gcc-common.inc | |||
| 2 | 2 | ||
| 3 | # Third digit in PV should be incremented after a minor release | 3 | # Third digit in PV should be incremented after a minor release |
| 4 | 4 | ||
| 5 | PV = "14.2.0" | 5 | PV = "14.3.0" |
| 6 | 6 | ||
| 7 | # BINV should be incremented to a revision after a minor gcc release | 7 | # BINV should be incremented to a revision after a minor gcc release |
| 8 | 8 | ||
| 9 | BINV = "14.2.0" | 9 | BINV = "14.3.0" |
| 10 | 10 | ||
| 11 | FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc:${FILE_DIRNAME}/gcc/backport:" | 11 | FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc:${FILE_DIRNAME}/gcc/backport:" |
| 12 | 12 | ||
| @@ -40,7 +40,7 @@ LIC_FILES_CHKSUM = "\ | |||
| 40 | RELEASE ?= "${PV}" | 40 | RELEASE ?= "${PV}" |
| 41 | BASEURI ?= "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.xz" | 41 | BASEURI ?= "${GNU_MIRROR}/gcc/gcc-${PV}/gcc-${PV}.tar.xz" |
| 42 | SOURCEDIR ?= "gcc-${PV}" | 42 | SOURCEDIR ?= "gcc-${PV}" |
| 43 | SRC_URI[sha256sum] = "a7b39bc69cbf9e25826c5a60ab26477001f7c08d85cec04bc0e29cabed6f3cc9" | 43 | SRC_URI[sha256sum] = "e0dc77297625631ac8e50fa92fffefe899a4eb702592da5c32ef04e2293aca3a" |
| 44 | 44 | ||
| 45 | SRC_URI = "${BASEURI} \ | 45 | SRC_URI = "${BASEURI} \ |
| 46 | file://0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \ | 46 | file://0001-gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \ |
| @@ -68,11 +68,6 @@ SRC_URI = "${BASEURI} \ | |||
| 68 | file://0023-Fix-install-path-of-linux64.h.patch \ | 68 | file://0023-Fix-install-path-of-linux64.h.patch \ |
| 69 | file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \ | 69 | file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \ |
| 70 | file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \ | 70 | file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \ |
| 71 | file://0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch \ | ||
| 72 | file://0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch \ | ||
| 73 | file://gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch \ | ||
| 74 | file://0001-arm-Fix-LDRD-register-overlap-PR117675.patch \ | ||
| 75 | file://0028-fix-incorrect-preprocessor-line-numbers.patch \ | ||
| 76 | " | 71 | " |
| 77 | 72 | ||
| 78 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" | 73 | S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" |
diff --git a/meta/recipes-devtools/gcc/gcc-cross-canadian_14.2.bb b/meta/recipes-devtools/gcc/gcc-cross-canadian_14.3.bb index bf53c5cd78..bf53c5cd78 100644 --- a/meta/recipes-devtools/gcc/gcc-cross-canadian_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-cross-canadian_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-cross_14.2.bb b/meta/recipes-devtools/gcc/gcc-cross_14.3.bb index b43cca0c52..b43cca0c52 100644 --- a/meta/recipes-devtools/gcc/gcc-cross_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-cross_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-crosssdk_14.2.bb b/meta/recipes-devtools/gcc/gcc-crosssdk_14.3.bb index 40a6c4feff..40a6c4feff 100644 --- a/meta/recipes-devtools/gcc/gcc-crosssdk_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-crosssdk_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-runtime_14.2.bb b/meta/recipes-devtools/gcc/gcc-runtime_14.3.bb index dd430b57eb..dd430b57eb 100644 --- a/meta/recipes-devtools/gcc/gcc-runtime_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-runtime_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-sanitizers_14.2.bb b/meta/recipes-devtools/gcc/gcc-sanitizers_14.3.bb index 8bda2ccad6..8bda2ccad6 100644 --- a/meta/recipes-devtools/gcc/gcc-sanitizers_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-sanitizers_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc-source_14.2.bb b/meta/recipes-devtools/gcc/gcc-source_14.3.bb index be11fa2fcc..be11fa2fcc 100644 --- a/meta/recipes-devtools/gcc/gcc-source_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc-source_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch b/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch deleted file mode 100644 index e3d887a135..0000000000 --- a/meta/recipes-devtools/gcc/gcc/0001-arm-Fix-LDRD-register-overlap-PR117675.patch +++ /dev/null | |||
| @@ -1,148 +0,0 @@ | |||
| 1 | From 9366c328518766d896155388726055624716c0af Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Wilco Dijkstra <wilco.dijkstra@arm.com> | ||
| 3 | Date: Tue, 10 Dec 2024 14:22:48 +0000 | ||
| 4 | Subject: [PATCH] arm: Fix LDRD register overlap [PR117675] | ||
| 5 | |||
| 6 | The register indexed variants of LDRD have complex register overlap constraints | ||
| 7 | which makes them hard to use without using output_move_double (which can't be | ||
| 8 | used for atomics as it doesn't guarantee to emit atomic LDRD/STRD when required). | ||
| 9 | Add a new predicate and constraint for plain LDRD/STRD with base or base+imm. | ||
| 10 | This blocks register indexing and fixes PR117675. | ||
| 11 | |||
| 12 | gcc: | ||
| 13 | PR target/117675 | ||
| 14 | * config/arm/arm.cc (arm_ldrd_legitimate_address): New function. | ||
| 15 | * config/arm/arm-protos.h (arm_ldrd_legitimate_address): New prototype. | ||
| 16 | * config/arm/constraints.md: Add new Uo constraint. | ||
| 17 | * config/arm/predicates.md (arm_ldrd_memory_operand): Add new predicate. | ||
| 18 | * config/arm/sync.md (arm_atomic_loaddi2_ldrd): Use | ||
| 19 | arm_ldrd_memory_operand and Uo. | ||
| 20 | |||
| 21 | gcc/testsuite: | ||
| 22 | PR target/117675 | ||
| 23 | * gcc.target/arm/pr117675.c: Add new test. | ||
| 24 | |||
| 25 | (cherry picked from commit 21fbfae2e55e1a153820acc6fbd922e66f67e65b) | ||
| 26 | |||
| 27 | Upstream-Status: Backport [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117675] | ||
| 28 | --- | ||
| 29 | gcc/config/arm/arm-protos.h | 1 + | ||
| 30 | gcc/config/arm/arm.cc | 24 ++++++++++++++++++++++++ | ||
| 31 | gcc/config/arm/constraints.md | 8 +++++++- | ||
| 32 | gcc/config/arm/predicates.md | 4 ++++ | ||
| 33 | gcc/config/arm/sync.md | 2 +- | ||
| 34 | gcc/testsuite/gcc.target/arm/pr117675.c | 17 +++++++++++++++++ | ||
| 35 | 6 files changed, 54 insertions(+), 2 deletions(-) | ||
| 36 | create mode 100644 gcc/testsuite/gcc.target/arm/pr117675.c | ||
| 37 | |||
| 38 | --- a/gcc/config/arm/arm-protos.h | ||
| 39 | +++ b/gcc/config/arm/arm-protos.h | ||
| 40 | @@ -202,6 +202,7 @@ extern rtx arm_load_tp (rtx); | ||
| 41 | extern bool arm_coproc_builtin_available (enum unspecv); | ||
| 42 | extern bool arm_coproc_ldc_stc_legitimate_address (rtx); | ||
| 43 | extern rtx arm_stack_protect_tls_canary_mem (bool); | ||
| 44 | +extern bool arm_ldrd_legitimate_address (rtx); | ||
| 45 | |||
| 46 | |||
| 47 | #if defined TREE_CODE | ||
| 48 | --- a/gcc/config/arm/arm.cc | ||
| 49 | +++ b/gcc/config/arm/arm.cc | ||
| 50 | @@ -34523,6 +34523,30 @@ arm_coproc_ldc_stc_legitimate_address (r | ||
| 51 | return false; | ||
| 52 | } | ||
| 53 | |||
| 54 | +/* Return true if OP is a valid memory operand for LDRD/STRD without any | ||
| 55 | + register overlap restrictions. Allow [base] and [base, imm] for now. */ | ||
| 56 | +bool | ||
| 57 | +arm_ldrd_legitimate_address (rtx op) | ||
| 58 | +{ | ||
| 59 | + if (!MEM_P (op)) | ||
| 60 | + return false; | ||
| 61 | + | ||
| 62 | + op = XEXP (op, 0); | ||
| 63 | + if (REG_P (op)) | ||
| 64 | + return true; | ||
| 65 | + | ||
| 66 | + if (GET_CODE (op) != PLUS) | ||
| 67 | + return false; | ||
| 68 | + if (!REG_P (XEXP (op, 0)) || !CONST_INT_P (XEXP (op, 1))) | ||
| 69 | + return false; | ||
| 70 | + | ||
| 71 | + HOST_WIDE_INT val = INTVAL (XEXP (op, 1)); | ||
| 72 | + | ||
| 73 | + if (TARGET_ARM) | ||
| 74 | + return IN_RANGE (val, -255, 255); | ||
| 75 | + return IN_RANGE (val, -1020, 1020) && (val & 3) == 0; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | /* Return the diagnostic message string if conversion from FROMTYPE to | ||
| 79 | TOTYPE is not allowed, NULL otherwise. */ | ||
| 80 | |||
| 81 | --- a/gcc/config/arm/constraints.md | ||
| 82 | +++ b/gcc/config/arm/constraints.md | ||
| 83 | @@ -39,7 +39,7 @@ | ||
| 84 | ;; in all states: Pg | ||
| 85 | |||
| 86 | ;; The following memory constraints have been used: | ||
| 87 | -;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us, Up, Uf, Ux, Ul | ||
| 88 | +;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us, Uo, Up, Uf, Ux, Ul, Uz | ||
| 89 | ;; in ARM state: Uq | ||
| 90 | ;; in Thumb state: Uu, Uw | ||
| 91 | ;; in all states: Q | ||
| 92 | @@ -585,6 +585,12 @@ | ||
| 93 | (and (match_code "mem") | ||
| 94 | (match_test "arm_coproc_ldc_stc_legitimate_address (op)"))) | ||
| 95 | |||
| 96 | +(define_memory_constraint "Uo" | ||
| 97 | + "@internal | ||
| 98 | + A memory operand for Arm/Thumb-2 LDRD/STRD" | ||
| 99 | + (and (match_code "mem") | ||
| 100 | + (match_test "arm_ldrd_legitimate_address (op)"))) | ||
| 101 | + | ||
| 102 | ;; We used to have constraint letters for S and R in ARM state, but | ||
| 103 | ;; all uses of these now appear to have been removed. | ||
| 104 | |||
| 105 | --- a/gcc/config/arm/predicates.md | ||
| 106 | +++ b/gcc/config/arm/predicates.md | ||
| 107 | @@ -849,6 +849,10 @@ | ||
| 108 | (and (match_operand 0 "memory_operand") | ||
| 109 | (match_code "reg" "0"))) | ||
| 110 | |||
| 111 | +;; True if the operand is memory reference suitable for a ldrd/strd. | ||
| 112 | +(define_predicate "arm_ldrd_memory_operand" | ||
| 113 | + (match_test "arm_ldrd_legitimate_address (op)")) | ||
| 114 | + | ||
| 115 | ;; Predicates for parallel expanders based on mode. | ||
| 116 | (define_special_predicate "vect_par_constant_high" | ||
| 117 | (match_code "parallel") | ||
| 118 | --- a/gcc/config/arm/sync.md | ||
| 119 | +++ b/gcc/config/arm/sync.md | ||
| 120 | @@ -161,7 +161,7 @@ | ||
| 121 | (define_insn "arm_atomic_loaddi2_ldrd" | ||
| 122 | [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 123 | (unspec_volatile:DI | ||
| 124 | - [(match_operand:DI 1 "memory_operand" "m")] | ||
| 125 | + [(match_operand:DI 1 "arm_ldrd_memory_operand" "Uo")] | ||
| 126 | VUNSPEC_LDRD_ATOMIC))] | ||
| 127 | "ARM_DOUBLEWORD_ALIGN && TARGET_HAVE_LPAE" | ||
| 128 | "ldrd\t%0, %H0, %1" | ||
| 129 | --- /dev/null | ||
| 130 | +++ b/gcc/testsuite/gcc.target/arm/pr117675.c | ||
| 131 | @@ -0,0 +1,17 @@ | ||
| 132 | +/* { dg-do compile } */ | ||
| 133 | +/* { dg-options "-O2 -marm" } */ | ||
| 134 | +/* { dg-require-effective-target arm_arch_v7ve_neon_ok } */ | ||
| 135 | +/* { dg-add-options arm_arch_v7ve_neon } */ | ||
| 136 | +/* { dg-final { check-function-bodies "**" "" "" } } */ | ||
| 137 | + | ||
| 138 | +/* | ||
| 139 | +** f1: | ||
| 140 | +** add r0, r0, r1 | ||
| 141 | +** ldrd r0, r1, \[r0\] | ||
| 142 | +** bx lr | ||
| 143 | +*/ | ||
| 144 | +long long f1 (char *p, int i) | ||
| 145 | +{ | ||
| 146 | + return __atomic_load_n ((long long *)(p + i), __ATOMIC_RELAXED); | ||
| 147 | +} | ||
| 148 | + | ||
diff --git a/meta/recipes-devtools/gcc/gcc/0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch b/meta/recipes-devtools/gcc/gcc/0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch deleted file mode 100644 index c9bc863eea..0000000000 --- a/meta/recipes-devtools/gcc/gcc/0026-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch +++ /dev/null | |||
| @@ -1,114 +0,0 @@ | |||
| 1 | From 05106fea707f010779369c5d6e89787953d2976f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Sunil Dora <sunilkumar.dora@windriver.com> | ||
| 3 | Date: Wed, 11 Dec 2024 10:04:56 -0800 | ||
| 4 | Subject: [PATCH] gcc: Fix c++: tweak for Wrange-loop-construct | ||
| 5 | |||
| 6 | This commit updates the warning to use a check for "trivially constructible" instead of | ||
| 7 | "trivially copyable." The original check was incorrect, as "trivially copyable" only applies | ||
| 8 | to types that can be copied trivially, whereas "trivially constructible" is the correct check | ||
| 9 | for types that can be trivially default-constructed. | ||
| 10 | |||
| 11 | This change ensures the warning is more accurate and aligns with the proper type traits. | ||
| 12 | |||
| 13 | LLVM accepted a similar fix: | ||
| 14 | https://github.com/llvm/llvm-project/issues/47355 | ||
| 15 | |||
| 16 | PR c++/116731 [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116731] | ||
| 17 | |||
| 18 | Upstream-Status: Backport [https://gcc.gnu.org/g:6ac4e2f4b2ca9980670e7d3815a9140730df1005] | ||
| 19 | |||
| 20 | Signed-off-by: Marek Polacek <polacek@redhat.com> | ||
| 21 | Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com> | ||
| 22 | --- | ||
| 23 | gcc/cp/parser.cc | 8 ++- | ||
| 24 | .../g++.dg/warn/Wrange-loop-construct3.C | 57 +++++++++++++++++++ | ||
| 25 | 2 files changed, 62 insertions(+), 3 deletions(-) | ||
| 26 | create mode 100644 gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C | ||
| 27 | |||
| 28 | diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc | ||
| 29 | index 7e81c1010..8206489a2 100644 | ||
| 30 | --- a/gcc/cp/parser.cc | ||
| 31 | +++ b/gcc/cp/parser.cc | ||
| 32 | @@ -14301,11 +14301,13 @@ warn_for_range_copy (tree decl, tree expr) | ||
| 33 | else if (!CP_TYPE_CONST_P (type)) | ||
| 34 | return; | ||
| 35 | |||
| 36 | - /* Since small trivially copyable types are cheap to copy, we suppress the | ||
| 37 | - warning for them. 64B is a common size of a cache line. */ | ||
| 38 | + /* Since small trivially constructible types are cheap to construct, we | ||
| 39 | + suppress the warning for them. 64B is a common size of a cache line. */ | ||
| 40 | + tree vec = make_tree_vec (1); | ||
| 41 | + TREE_VEC_ELT (vec, 0) = TREE_TYPE (expr); | ||
| 42 | if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST | ||
| 43 | || (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64 | ||
| 44 | - && trivially_copyable_p (type))) | ||
| 45 | + && is_trivially_xible (INIT_EXPR, type, vec))) | ||
| 46 | return; | ||
| 47 | |||
| 48 | /* If we can initialize a reference directly, suggest that to avoid the | ||
| 49 | diff --git a/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C | ||
| 50 | new file mode 100644 | ||
| 51 | index 000000000..3d9d0c908 | ||
| 52 | --- /dev/null | ||
| 53 | +++ b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C | ||
| 54 | @@ -0,0 +1,57 @@ | ||
| 55 | +// PR c++/116731 | ||
| 56 | +// { dg-do compile { target c++11 } } | ||
| 57 | +// { dg-options "-Wrange-loop-construct" } | ||
| 58 | + | ||
| 59 | +void | ||
| 60 | +f0 () | ||
| 61 | +{ | ||
| 62 | + struct S { | ||
| 63 | + char a[64]; | ||
| 64 | + S& operator=(const S&) { return *this; }; | ||
| 65 | + }; | ||
| 66 | + | ||
| 67 | + S arr[8]; | ||
| 68 | + for (const auto r : arr) | ||
| 69 | + (void) r; | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +void | ||
| 73 | +f1 () | ||
| 74 | +{ | ||
| 75 | + struct S { | ||
| 76 | + char a[65]; | ||
| 77 | + S& operator=(const S&) { return *this; }; | ||
| 78 | + }; | ||
| 79 | + | ||
| 80 | + S arr[8]; | ||
| 81 | + for (const auto r : arr) // { dg-warning "creates a copy" } | ||
| 82 | + (void) r; | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +void | ||
| 86 | +f2 () | ||
| 87 | +{ | ||
| 88 | + struct S { | ||
| 89 | + char a[64]; | ||
| 90 | + S& operator=(const S&) { return *this; }; | ||
| 91 | + ~S() { } | ||
| 92 | + }; | ||
| 93 | + | ||
| 94 | + S arr[8]; | ||
| 95 | + for (const auto r : arr) // { dg-warning "creates a copy" } | ||
| 96 | + (void) r; | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +void | ||
| 100 | +f3 () | ||
| 101 | +{ | ||
| 102 | + struct S { | ||
| 103 | + char a[65]; | ||
| 104 | + S& operator=(const S&) { return *this; }; | ||
| 105 | + ~S() { } | ||
| 106 | + }; | ||
| 107 | + | ||
| 108 | + S arr[8]; | ||
| 109 | + for (const auto r : arr) // { dg-warning "creates a copy" } | ||
| 110 | + (void) r; | ||
| 111 | +} | ||
| 112 | -- | ||
| 113 | 2.43.0 | ||
| 114 | |||
diff --git a/meta/recipes-devtools/gcc/gcc/0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch b/meta/recipes-devtools/gcc/gcc/0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch deleted file mode 100644 index 5bede60816..0000000000 --- a/meta/recipes-devtools/gcc/gcc/0027-gcc-backport-patch-to-fix-data-relocation-to-ENDBR-s.patch +++ /dev/null | |||
| @@ -1,447 +0,0 @@ | |||
| 1 | From 4e7735a8d87559bbddfe3a985786996e22241f8d Mon Sep 17 00:00:00 2001 | ||
| 2 | From: liuhongt <hongtao.liu@intel.com> | ||
| 3 | Date: Mon, 12 Aug 2024 14:35:31 +0800 | ||
| 4 | Subject: [PATCH] Move ix86_align_loops into a separate pass and insert the | ||
| 5 | pass after pass_endbr_and_patchable_area. | ||
| 6 | |||
| 7 | gcc/ChangeLog: | ||
| 8 | |||
| 9 | PR target/116174 | ||
| 10 | * config/i386/i386.cc (ix86_align_loops): Move this to .. | ||
| 11 | * config/i386/i386-features.cc (ix86_align_loops): .. here. | ||
| 12 | (class pass_align_tight_loops): New class. | ||
| 13 | (make_pass_align_tight_loops): New function. | ||
| 14 | * config/i386/i386-passes.def: Insert pass_align_tight_loops | ||
| 15 | after pass_insert_endbr_and_patchable_area. | ||
| 16 | * config/i386/i386-protos.h (make_pass_align_tight_loops): New | ||
| 17 | declare. | ||
| 18 | |||
| 19 | gcc/testsuite/ChangeLog: | ||
| 20 | |||
| 21 | * gcc.target/i386/pr116174.c: New test. | ||
| 22 | |||
| 23 | (cherry picked from commit c3c83d22d212a35cb1bfb8727477819463f0dcd8) | ||
| 24 | |||
| 25 | Upstream-Status: Backport [https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=4e7735a8d87559bbddfe3a985786996e22241f8d] | ||
| 26 | |||
| 27 | Signed-off-by: Bin Lan <bin.lan.cn@windriver.com> | ||
| 28 | --- | ||
| 29 | gcc/config/i386/i386-features.cc | 191 +++++++++++++++++++++++ | ||
| 30 | gcc/config/i386/i386-passes.def | 3 + | ||
| 31 | gcc/config/i386/i386-protos.h | 1 + | ||
| 32 | gcc/config/i386/i386.cc | 146 ----------------- | ||
| 33 | gcc/testsuite/gcc.target/i386/pr116174.c | 12 ++ | ||
| 34 | 5 files changed, 207 insertions(+), 146 deletions(-) | ||
| 35 | create mode 100644 gcc/testsuite/gcc.target/i386/pr116174.c | ||
| 36 | |||
| 37 | diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc | ||
| 38 | index e3e004d55267..7de19d423637 100644 | ||
| 39 | --- a/gcc/config/i386/i386-features.cc | ||
| 40 | +++ b/gcc/config/i386/i386-features.cc | ||
| 41 | @@ -3253,6 +3253,197 @@ make_pass_remove_partial_avx_dependency (gcc::context *ctxt) | ||
| 42 | return new pass_remove_partial_avx_dependency (ctxt); | ||
| 43 | } | ||
| 44 | |||
| 45 | +/* When a hot loop can be fit into one cacheline, | ||
| 46 | + force align the loop without considering the max skip. */ | ||
| 47 | +static void | ||
| 48 | +ix86_align_loops () | ||
| 49 | +{ | ||
| 50 | + basic_block bb; | ||
| 51 | + | ||
| 52 | + /* Don't do this when we don't know cache line size. */ | ||
| 53 | + if (ix86_cost->prefetch_block == 0) | ||
| 54 | + return; | ||
| 55 | + | ||
| 56 | + loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | ||
| 57 | + profile_count count_threshold = cfun->cfg->count_max / param_align_threshold; | ||
| 58 | + FOR_EACH_BB_FN (bb, cfun) | ||
| 59 | + { | ||
| 60 | + rtx_insn *label = BB_HEAD (bb); | ||
| 61 | + bool has_fallthru = 0; | ||
| 62 | + edge e; | ||
| 63 | + edge_iterator ei; | ||
| 64 | + | ||
| 65 | + if (!LABEL_P (label)) | ||
| 66 | + continue; | ||
| 67 | + | ||
| 68 | + profile_count fallthru_count = profile_count::zero (); | ||
| 69 | + profile_count branch_count = profile_count::zero (); | ||
| 70 | + | ||
| 71 | + FOR_EACH_EDGE (e, ei, bb->preds) | ||
| 72 | + { | ||
| 73 | + if (e->flags & EDGE_FALLTHRU) | ||
| 74 | + has_fallthru = 1, fallthru_count += e->count (); | ||
| 75 | + else | ||
| 76 | + branch_count += e->count (); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + if (!fallthru_count.initialized_p () || !branch_count.initialized_p ()) | ||
| 80 | + continue; | ||
| 81 | + | ||
| 82 | + if (bb->loop_father | ||
| 83 | + && bb->loop_father->latch != EXIT_BLOCK_PTR_FOR_FN (cfun) | ||
| 84 | + && (has_fallthru | ||
| 85 | + ? (!(single_succ_p (bb) | ||
| 86 | + && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) | ||
| 87 | + && optimize_bb_for_speed_p (bb) | ||
| 88 | + && branch_count + fallthru_count > count_threshold | ||
| 89 | + && (branch_count > fallthru_count * param_align_loop_iterations)) | ||
| 90 | + /* In case there'no fallthru for the loop. | ||
| 91 | + Nops inserted won't be executed. */ | ||
| 92 | + : (branch_count > count_threshold | ||
| 93 | + || (bb->count > bb->prev_bb->count * 10 | ||
| 94 | + && (bb->prev_bb->count | ||
| 95 | + <= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count / 2))))) | ||
| 96 | + { | ||
| 97 | + rtx_insn* insn, *end_insn; | ||
| 98 | + HOST_WIDE_INT size = 0; | ||
| 99 | + bool padding_p = true; | ||
| 100 | + basic_block tbb = bb; | ||
| 101 | + unsigned cond_branch_num = 0; | ||
| 102 | + bool detect_tight_loop_p = false; | ||
| 103 | + | ||
| 104 | + for (unsigned int i = 0; i != bb->loop_father->num_nodes; | ||
| 105 | + i++, tbb = tbb->next_bb) | ||
| 106 | + { | ||
| 107 | + /* Only handle continuous cfg layout. */ | ||
| 108 | + if (bb->loop_father != tbb->loop_father) | ||
| 109 | + { | ||
| 110 | + padding_p = false; | ||
| 111 | + break; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + FOR_BB_INSNS (tbb, insn) | ||
| 115 | + { | ||
| 116 | + if (!NONDEBUG_INSN_P (insn)) | ||
| 117 | + continue; | ||
| 118 | + size += ix86_min_insn_size (insn); | ||
| 119 | + | ||
| 120 | + /* We don't know size of inline asm. | ||
| 121 | + Don't align loop for call. */ | ||
| 122 | + if (asm_noperands (PATTERN (insn)) >= 0 | ||
| 123 | + || CALL_P (insn)) | ||
| 124 | + { | ||
| 125 | + size = -1; | ||
| 126 | + break; | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + if (size == -1 || size > ix86_cost->prefetch_block) | ||
| 131 | + { | ||
| 132 | + padding_p = false; | ||
| 133 | + break; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + FOR_EACH_EDGE (e, ei, tbb->succs) | ||
| 137 | + { | ||
| 138 | + /* It could be part of the loop. */ | ||
| 139 | + if (e->dest == bb) | ||
| 140 | + { | ||
| 141 | + detect_tight_loop_p = true; | ||
| 142 | + break; | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + if (detect_tight_loop_p) | ||
| 147 | + break; | ||
| 148 | + | ||
| 149 | + end_insn = BB_END (tbb); | ||
| 150 | + if (JUMP_P (end_insn)) | ||
| 151 | + { | ||
| 152 | + /* For decoded icache: | ||
| 153 | + 1. Up to two branches are allowed per Way. | ||
| 154 | + 2. A non-conditional branch is the last micro-op in a Way. | ||
| 155 | + */ | ||
| 156 | + if (onlyjump_p (end_insn) | ||
| 157 | + && (any_uncondjump_p (end_insn) | ||
| 158 | + || single_succ_p (tbb))) | ||
| 159 | + { | ||
| 160 | + padding_p = false; | ||
| 161 | + break; | ||
| 162 | + } | ||
| 163 | + else if (++cond_branch_num >= 2) | ||
| 164 | + { | ||
| 165 | + padding_p = false; | ||
| 166 | + break; | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + if (padding_p && detect_tight_loop_p) | ||
| 173 | + { | ||
| 174 | + emit_insn_before (gen_max_skip_align (GEN_INT (ceil_log2 (size)), | ||
| 175 | + GEN_INT (0)), label); | ||
| 176 | + /* End of function. */ | ||
| 177 | + if (!tbb || tbb == EXIT_BLOCK_PTR_FOR_FN (cfun)) | ||
| 178 | + break; | ||
| 179 | + /* Skip bb which already fits into one cacheline. */ | ||
| 180 | + bb = tbb; | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + loop_optimizer_finalize (); | ||
| 186 | + free_dominance_info (CDI_DOMINATORS); | ||
| 187 | +} | ||
| 188 | + | ||
| 189 | +namespace { | ||
| 190 | + | ||
| 191 | +const pass_data pass_data_align_tight_loops = | ||
| 192 | +{ | ||
| 193 | + RTL_PASS, /* type */ | ||
| 194 | + "align_tight_loops", /* name */ | ||
| 195 | + OPTGROUP_NONE, /* optinfo_flags */ | ||
| 196 | + TV_MACH_DEP, /* tv_id */ | ||
| 197 | + 0, /* properties_required */ | ||
| 198 | + 0, /* properties_provided */ | ||
| 199 | + 0, /* properties_destroyed */ | ||
| 200 | + 0, /* todo_flags_start */ | ||
| 201 | + 0, /* todo_flags_finish */ | ||
| 202 | +}; | ||
| 203 | + | ||
| 204 | +class pass_align_tight_loops : public rtl_opt_pass | ||
| 205 | +{ | ||
| 206 | +public: | ||
| 207 | + pass_align_tight_loops (gcc::context *ctxt) | ||
| 208 | + : rtl_opt_pass (pass_data_align_tight_loops, ctxt) | ||
| 209 | + {} | ||
| 210 | + | ||
| 211 | + /* opt_pass methods: */ | ||
| 212 | + bool gate (function *) final override | ||
| 213 | + { | ||
| 214 | + return optimize && optimize_function_for_speed_p (cfun); | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + unsigned int execute (function *) final override | ||
| 218 | + { | ||
| 219 | + timevar_push (TV_MACH_DEP); | ||
| 220 | +#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN | ||
| 221 | + ix86_align_loops (); | ||
| 222 | +#endif | ||
| 223 | + timevar_pop (TV_MACH_DEP); | ||
| 224 | + return 0; | ||
| 225 | + } | ||
| 226 | +}; // class pass_align_tight_loops | ||
| 227 | + | ||
| 228 | +} // anon namespace | ||
| 229 | + | ||
| 230 | +rtl_opt_pass * | ||
| 231 | +make_pass_align_tight_loops (gcc::context *ctxt) | ||
| 232 | +{ | ||
| 233 | + return new pass_align_tight_loops (ctxt); | ||
| 234 | +} | ||
| 235 | + | ||
| 236 | /* This compares the priority of target features in function DECL1 | ||
| 237 | and DECL2. It returns positive value if DECL1 is higher priority, | ||
| 238 | negative value if DECL2 is higher priority and 0 if they are the | ||
| 239 | diff --git a/gcc/config/i386/i386-passes.def b/gcc/config/i386/i386-passes.def | ||
| 240 | index 7d96766f7b96..e500f15c9971 100644 | ||
| 241 | --- a/gcc/config/i386/i386-passes.def | ||
| 242 | +++ b/gcc/config/i386/i386-passes.def | ||
| 243 | @@ -31,5 +31,8 @@ along with GCC; see the file COPYING3. If not see | ||
| 244 | INSERT_PASS_BEFORE (pass_cse2, 1, pass_stv, true /* timode_p */); | ||
| 245 | |||
| 246 | INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_insert_endbr_and_patchable_area); | ||
| 247 | + /* pass_align_tight_loops must be after pass_insert_endbr_and_patchable_area. | ||
| 248 | + PR116174. */ | ||
| 249 | + INSERT_PASS_BEFORE (pass_shorten_branches, 1, pass_align_tight_loops); | ||
| 250 | |||
| 251 | INSERT_PASS_AFTER (pass_combine, 1, pass_remove_partial_avx_dependency); | ||
| 252 | diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h | ||
| 253 | index 46214a63974d..36c7b1aed42b 100644 | ||
| 254 | --- a/gcc/config/i386/i386-protos.h | ||
| 255 | +++ b/gcc/config/i386/i386-protos.h | ||
| 256 | @@ -419,6 +419,7 @@ extern rtl_opt_pass *make_pass_insert_endbr_and_patchable_area | ||
| 257 | (gcc::context *); | ||
| 258 | extern rtl_opt_pass *make_pass_remove_partial_avx_dependency | ||
| 259 | (gcc::context *); | ||
| 260 | +extern rtl_opt_pass *make_pass_align_tight_loops (gcc::context *); | ||
| 261 | |||
| 262 | extern bool ix86_has_no_direct_extern_access; | ||
| 263 | |||
| 264 | diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc | ||
| 265 | index 6f89891d3cb5..288c69467d62 100644 | ||
| 266 | --- a/gcc/config/i386/i386.cc | ||
| 267 | +++ b/gcc/config/i386/i386.cc | ||
| 268 | @@ -23444,150 +23444,6 @@ ix86_split_stlf_stall_load () | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 272 | -/* When a hot loop can be fit into one cacheline, | ||
| 273 | - force align the loop without considering the max skip. */ | ||
| 274 | -static void | ||
| 275 | -ix86_align_loops () | ||
| 276 | -{ | ||
| 277 | - basic_block bb; | ||
| 278 | - | ||
| 279 | - /* Don't do this when we don't know cache line size. */ | ||
| 280 | - if (ix86_cost->prefetch_block == 0) | ||
| 281 | - return; | ||
| 282 | - | ||
| 283 | - loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | ||
| 284 | - profile_count count_threshold = cfun->cfg->count_max / param_align_threshold; | ||
| 285 | - FOR_EACH_BB_FN (bb, cfun) | ||
| 286 | - { | ||
| 287 | - rtx_insn *label = BB_HEAD (bb); | ||
| 288 | - bool has_fallthru = 0; | ||
| 289 | - edge e; | ||
| 290 | - edge_iterator ei; | ||
| 291 | - | ||
| 292 | - if (!LABEL_P (label)) | ||
| 293 | - continue; | ||
| 294 | - | ||
| 295 | - profile_count fallthru_count = profile_count::zero (); | ||
| 296 | - profile_count branch_count = profile_count::zero (); | ||
| 297 | - | ||
| 298 | - FOR_EACH_EDGE (e, ei, bb->preds) | ||
| 299 | - { | ||
| 300 | - if (e->flags & EDGE_FALLTHRU) | ||
| 301 | - has_fallthru = 1, fallthru_count += e->count (); | ||
| 302 | - else | ||
| 303 | - branch_count += e->count (); | ||
| 304 | - } | ||
| 305 | - | ||
| 306 | - if (!fallthru_count.initialized_p () || !branch_count.initialized_p ()) | ||
| 307 | - continue; | ||
| 308 | - | ||
| 309 | - if (bb->loop_father | ||
| 310 | - && bb->loop_father->latch != EXIT_BLOCK_PTR_FOR_FN (cfun) | ||
| 311 | - && (has_fallthru | ||
| 312 | - ? (!(single_succ_p (bb) | ||
| 313 | - && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) | ||
| 314 | - && optimize_bb_for_speed_p (bb) | ||
| 315 | - && branch_count + fallthru_count > count_threshold | ||
| 316 | - && (branch_count > fallthru_count * param_align_loop_iterations)) | ||
| 317 | - /* In case there'no fallthru for the loop. | ||
| 318 | - Nops inserted won't be executed. */ | ||
| 319 | - : (branch_count > count_threshold | ||
| 320 | - || (bb->count > bb->prev_bb->count * 10 | ||
| 321 | - && (bb->prev_bb->count | ||
| 322 | - <= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count / 2))))) | ||
| 323 | - { | ||
| 324 | - rtx_insn* insn, *end_insn; | ||
| 325 | - HOST_WIDE_INT size = 0; | ||
| 326 | - bool padding_p = true; | ||
| 327 | - basic_block tbb = bb; | ||
| 328 | - unsigned cond_branch_num = 0; | ||
| 329 | - bool detect_tight_loop_p = false; | ||
| 330 | - | ||
| 331 | - for (unsigned int i = 0; i != bb->loop_father->num_nodes; | ||
| 332 | - i++, tbb = tbb->next_bb) | ||
| 333 | - { | ||
| 334 | - /* Only handle continuous cfg layout. */ | ||
| 335 | - if (bb->loop_father != tbb->loop_father) | ||
| 336 | - { | ||
| 337 | - padding_p = false; | ||
| 338 | - break; | ||
| 339 | - } | ||
| 340 | - | ||
| 341 | - FOR_BB_INSNS (tbb, insn) | ||
| 342 | - { | ||
| 343 | - if (!NONDEBUG_INSN_P (insn)) | ||
| 344 | - continue; | ||
| 345 | - size += ix86_min_insn_size (insn); | ||
| 346 | - | ||
| 347 | - /* We don't know size of inline asm. | ||
| 348 | - Don't align loop for call. */ | ||
| 349 | - if (asm_noperands (PATTERN (insn)) >= 0 | ||
| 350 | - || CALL_P (insn)) | ||
| 351 | - { | ||
| 352 | - size = -1; | ||
| 353 | - break; | ||
| 354 | - } | ||
| 355 | - } | ||
| 356 | - | ||
| 357 | - if (size == -1 || size > ix86_cost->prefetch_block) | ||
| 358 | - { | ||
| 359 | - padding_p = false; | ||
| 360 | - break; | ||
| 361 | - } | ||
| 362 | - | ||
| 363 | - FOR_EACH_EDGE (e, ei, tbb->succs) | ||
| 364 | - { | ||
| 365 | - /* It could be part of the loop. */ | ||
| 366 | - if (e->dest == bb) | ||
| 367 | - { | ||
| 368 | - detect_tight_loop_p = true; | ||
| 369 | - break; | ||
| 370 | - } | ||
| 371 | - } | ||
| 372 | - | ||
| 373 | - if (detect_tight_loop_p) | ||
| 374 | - break; | ||
| 375 | - | ||
| 376 | - end_insn = BB_END (tbb); | ||
| 377 | - if (JUMP_P (end_insn)) | ||
| 378 | - { | ||
| 379 | - /* For decoded icache: | ||
| 380 | - 1. Up to two branches are allowed per Way. | ||
| 381 | - 2. A non-conditional branch is the last micro-op in a Way. | ||
| 382 | - */ | ||
| 383 | - if (onlyjump_p (end_insn) | ||
| 384 | - && (any_uncondjump_p (end_insn) | ||
| 385 | - || single_succ_p (tbb))) | ||
| 386 | - { | ||
| 387 | - padding_p = false; | ||
| 388 | - break; | ||
| 389 | - } | ||
| 390 | - else if (++cond_branch_num >= 2) | ||
| 391 | - { | ||
| 392 | - padding_p = false; | ||
| 393 | - break; | ||
| 394 | - } | ||
| 395 | - } | ||
| 396 | - | ||
| 397 | - } | ||
| 398 | - | ||
| 399 | - if (padding_p && detect_tight_loop_p) | ||
| 400 | - { | ||
| 401 | - emit_insn_before (gen_max_skip_align (GEN_INT (ceil_log2 (size)), | ||
| 402 | - GEN_INT (0)), label); | ||
| 403 | - /* End of function. */ | ||
| 404 | - if (!tbb || tbb == EXIT_BLOCK_PTR_FOR_FN (cfun)) | ||
| 405 | - break; | ||
| 406 | - /* Skip bb which already fits into one cacheline. */ | ||
| 407 | - bb = tbb; | ||
| 408 | - } | ||
| 409 | - } | ||
| 410 | - } | ||
| 411 | - | ||
| 412 | - loop_optimizer_finalize (); | ||
| 413 | - free_dominance_info (CDI_DOMINATORS); | ||
| 414 | -} | ||
| 415 | - | ||
| 416 | /* Implement machine specific optimizations. We implement padding of returns | ||
| 417 | for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window. */ | ||
| 418 | static void | ||
| 419 | @@ -23611,8 +23467,6 @@ ix86_reorg (void) | ||
| 420 | #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN | ||
| 421 | if (TARGET_FOUR_JUMP_LIMIT) | ||
| 422 | ix86_avoid_jump_mispredicts (); | ||
| 423 | - | ||
| 424 | - ix86_align_loops (); | ||
| 425 | #endif | ||
| 426 | } | ||
| 427 | } | ||
| 428 | diff --git a/gcc/testsuite/gcc.target/i386/pr116174.c b/gcc/testsuite/gcc.target/i386/pr116174.c | ||
| 429 | new file mode 100644 | ||
| 430 | index 000000000000..8877d0b51af1 | ||
| 431 | --- /dev/null | ||
| 432 | +++ b/gcc/testsuite/gcc.target/i386/pr116174.c | ||
| 433 | @@ -0,0 +1,12 @@ | ||
| 434 | +/* { dg-do compile { target *-*-linux* } } */ | ||
| 435 | +/* { dg-options "-O2 -fcf-protection=branch" } */ | ||
| 436 | + | ||
| 437 | +char * | ||
| 438 | +foo (char *dest, const char *src) | ||
| 439 | +{ | ||
| 440 | + while ((*dest++ = *src++) != '\0') | ||
| 441 | + /* nothing */; | ||
| 442 | + return --dest; | ||
| 443 | +} | ||
| 444 | + | ||
| 445 | +/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n" } } */ | ||
| 446 | -- | ||
| 447 | 2.43.5 | ||
diff --git a/meta/recipes-devtools/gcc/gcc/0028-fix-incorrect-preprocessor-line-numbers.patch b/meta/recipes-devtools/gcc/gcc/0028-fix-incorrect-preprocessor-line-numbers.patch deleted file mode 100644 index 5185236a3d..0000000000 --- a/meta/recipes-devtools/gcc/gcc/0028-fix-incorrect-preprocessor-line-numbers.patch +++ /dev/null | |||
| @@ -1,475 +0,0 @@ | |||
| 1 | From 8cbe033a8a88fe6437cc5d343ae0ddf8dd3455c8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jakub Jelinek <jakub@redhat.com> | ||
| 3 | Date: Thu, 8 May 2025 11:14:24 +0200 | ||
| 4 | Subject: libcpp: Further fixes for incorrect line numbers in large files | ||
| 5 | [PR120061] | ||
| 6 | MIME-Version: 1.0 | ||
| 7 | Content-Type: text/plain; charset=UTF-8 | ||
| 8 | Content-Transfer-Encoding: 8bit | ||
| 9 | |||
| 10 | The backport of the PR108900 fix to 14 branch broke building chromium | ||
| 11 | because static_assert (__LINE__ == expected_line_number, ""); now triggers | ||
| 12 | as the __LINE__ values are off by one. | ||
| 13 | This isn't the case on the trunk and 15 branch because we've switched | ||
| 14 | to 64-bit location_t and so one actually needs far longer header files | ||
| 15 | to trigger it. | ||
| 16 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c11 | ||
| 17 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c12 | ||
| 18 | contain (large) testcases in patch form which show on the 14 branch | ||
| 19 | that the first one used to fail before the PR108900 backport and now | ||
| 20 | works correctly, while the second one attempts to match the chromium | ||
| 21 | behavior and it used to pass before the PR108900 backport and now it | ||
| 22 | FAILs. | ||
| 23 | The two testcases show rare problematic cases, because | ||
| 24 | do_include_common -> parse_include -> check_eol -> check_eol_1 -> | ||
| 25 | cpp_get_token_1 -> _cpp_lex_token -> _cpp_lex_direct -> linemap_line_start | ||
| 26 | triggers there | ||
| 27 | /* Allocate the new line_map. However, if the current map only has a | ||
| 28 | single line we can sometimes just increase its column_bits instead. */ | ||
| 29 | if (line_delta < 0 | ||
| 30 | || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) | ||
| 31 | || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits)) | ||
| 32 | || ( /* We can't reuse the map if the line offset is sufficiently | ||
| 33 | large to cause overflow when computing location_t values. */ | ||
| 34 | (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) | ||
| 35 | >= (((uint64_t) 1) | ||
| 36 | << (CHAR_BIT * sizeof (linenum_type) - column_bits))) | ||
| 37 | || range_bits < map->m_range_bits) | ||
| 38 | map = linemap_check_ordinary | ||
| 39 | (const_cast <line_map *> | ||
| 40 | (linemap_add (set, LC_RENAME, | ||
| 41 | ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), | ||
| 42 | ORDINARY_MAP_FILE_NAME (map), | ||
| 43 | to_line))); | ||
| 44 | and so creates a new ordinary map on the line right after the | ||
| 45 | (problematic) #include line. | ||
| 46 | Now, in the spot that r14-11679-g8a884140c2bcb7 patched, | ||
| 47 | pfile->line_table->highest_location in all 3 tests (also | ||
| 48 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c13 | ||
| 49 | ) is before the decrement the start of the line after the #include line and so | ||
| 50 | the decrement is really desirable in that case to put highest_location | ||
| 51 | [jakub@tucnak gcc-15]$ git log -1 --format=%B r15-9638-gbfcb5da69a41f7a5e41faab39b763d9d7c8bd2ea | cat | ||
| 52 | libcpp: Further fixes for incorrect line numbers in large files [PR120061] | ||
| 53 | |||
| 54 | The backport of the PR108900 fix to 14 branch broke building chromium | ||
| 55 | because static_assert (__LINE__ == expected_line_number, ""); now triggers | ||
| 56 | as the __LINE__ values are off by one. | ||
| 57 | This isn't the case on the trunk and 15 branch because we've switched | ||
| 58 | to 64-bit location_t and so one actually needs far longer header files | ||
| 59 | to trigger it. | ||
| 60 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c11 | ||
| 61 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c12 | ||
| 62 | contain (large) testcases in patch form which show on the 14 branch | ||
| 63 | that the first one used to fail before the PR108900 backport and now | ||
| 64 | works correctly, while the second one attempts to match the chromium | ||
| 65 | behavior and it used to pass before the PR108900 backport and now it | ||
| 66 | FAILs. | ||
| 67 | The two testcases show rare problematic cases, because | ||
| 68 | do_include_common -> parse_include -> check_eol -> check_eol_1 -> | ||
| 69 | cpp_get_token_1 -> _cpp_lex_token -> _cpp_lex_direct -> linemap_line_start | ||
| 70 | triggers there | ||
| 71 | /* Allocate the new line_map. However, if the current map only has a | ||
| 72 | single line we can sometimes just increase its column_bits instead. */ | ||
| 73 | if (line_delta < 0 | ||
| 74 | || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map) | ||
| 75 | || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits)) | ||
| 76 | || ( /* We can't reuse the map if the line offset is sufficiently | ||
| 77 | large to cause overflow when computing location_t values. */ | ||
| 78 | (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) | ||
| 79 | >= (((uint64_t) 1) | ||
| 80 | << (CHAR_BIT * sizeof (linenum_type) - column_bits))) | ||
| 81 | || range_bits < map->m_range_bits) | ||
| 82 | map = linemap_check_ordinary | ||
| 83 | (const_cast <line_map *> | ||
| 84 | (linemap_add (set, LC_RENAME, | ||
| 85 | ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), | ||
| 86 | ORDINARY_MAP_FILE_NAME (map), | ||
| 87 | to_line))); | ||
| 88 | and so creates a new ordinary map on the line right after the | ||
| 89 | (problematic) #include line. | ||
| 90 | Now, in the spot that r14-11679-g8a884140c2bcb7 patched, | ||
| 91 | pfile->line_table->highest_location in all 3 tests (also | ||
| 92 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120061#c13 | ||
| 93 | ) is before the decrement the start of the line after the #include line and so | ||
| 94 | the decrement is really desirable in that case to put highest_location | ||
| 95 | somewhere on the line where the #include actually is. | ||
| 96 | But at the same time it is also undesirable, because if we do decrement it, | ||
| 97 | then linemap_add LC_ENTER called from _cpp_do_file_change will then | ||
| 98 | /* Generate a start_location above the current highest_location. | ||
| 99 | If possible, make the low range bits be zero. */ | ||
| 100 | location_t start_location = set->highest_location + 1; | ||
| 101 | unsigned range_bits = 0; | ||
| 102 | if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS) | ||
| 103 | range_bits = set->default_range_bits; | ||
| 104 | start_location += (1 << range_bits) - 1; | ||
| 105 | start_location &= ~((1 << range_bits) - 1); | ||
| 106 | |||
| 107 | linemap_assert (!LINEMAPS_ORDINARY_USED (set) | ||
| 108 | || (start_location | ||
| 109 | >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))); | ||
| 110 | and we can end up with the new LC_ENTER ordinary map having the same | ||
| 111 | start_location as the preceding LC_RENAME one. | ||
| 112 | Next thing that happens is computation of included_from: | ||
| 113 | if (reason == LC_ENTER) | ||
| 114 | { | ||
| 115 | if (set->depth == 0) | ||
| 116 | map->included_from = 0; | ||
| 117 | else | ||
| 118 | /* The location of the end of the just-closed map. */ | ||
| 119 | map->included_from | ||
| 120 | = (((map[0].start_location - 1 - map[-1].start_location) | ||
| 121 | & ~((1 << map[-1].m_column_and_range_bits) - 1)) | ||
| 122 | + map[-1].start_location); | ||
| 123 | The normal case (e.g. with the testcase included at the start of this comment) is | ||
| 124 | that map[-1] starts somewhere earlier and so map->included_from computation above | ||
| 125 | nicely computes location_t which expands to the start of the #include line. | ||
| 126 | With r14-11679 reverted, for #c11 as well as #c12 | ||
| 127 | map[0].start_location == map[-1].start_location above, and so it is | ||
| 128 | ((location_t) -1 & ~((1 << map[-1].m_column_and_range_bits) - 1))) | ||
| 129 | + map[-1].start_location, | ||
| 130 | which happens to be start of the #include line. | ||
| 131 | For #c11 map[0].start_location is 0x500003a0 and map[-1] has | ||
| 132 | m_column_and_range_bits 7 and map[-2] has m_column_and_range_bits 12 and | ||
| 133 | map[0].included_from is set to 0x50000320. | ||
| 134 | For #c12 map[0].start_location is 0x606c0402 and map[-2].start_location is | ||
| 135 | 0x606c0400 and m_column_and_range_bits is 0 for all 3 maps. | ||
| 136 | map[0].included_from is set to 0x606c0401. | ||
| 137 | The last important part is again in linemap_add when doing LC_LEAVE: | ||
| 138 | /* (MAP - 1) points to the map we are leaving. The | ||
| 139 | map from which (MAP - 1) got included should be the map | ||
| 140 | that comes right before MAP in the same file. */ | ||
| 141 | from = linemap_included_from_linemap (set, map - 1); | ||
| 142 | |||
| 143 | /* A TO_FILE of NULL is special - we use the natural values. */ | ||
| 144 | if (to_file == NULL) | ||
| 145 | { | ||
| 146 | to_file = ORDINARY_MAP_FILE_NAME (from); | ||
| 147 | to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 148 | sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); | ||
| 149 | } | ||
| 150 | Here it wants to compute the right to_line which ought to be the line after | ||
| 151 | the #include directive. | ||
| 152 | On the #c11 testcase that doesn't work correctly though, because | ||
| 153 | map[-1].included_from is 0x50000320, from[0] for that is LC_ENTER with | ||
| 154 | start_location 0x4080 and m_column_and_range_bits 12 but note that we've | ||
| 155 | earlier computed map[-1].start_location + (-1 & 0xffffff80) and so only | ||
| 156 | decreased by 7 bits, so to_line is still on the line with #include and not | ||
| 157 | after it. In the #c12 that doesn't happen, all the ordinary maps involved | ||
| 158 | there had 0 m_column_and_range_bits and so this computes correct line. | ||
| 159 | |||
| 160 | Below is a fix for the trunk including testcases using the | ||
| 161 | location_overflow_plugin hack to simulate the bugs without needing huge | ||
| 162 | files (in the 14 case it is just 330KB and almost 10MB, but in the 15 | ||
| 163 | case it would need to be far bigger). | ||
| 164 | The pre- r15-9018 trunk has | ||
| 165 | FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 | ||
| 166 | and current trunk | ||
| 167 | FAIL: gcc.dg/plugin/location-overflow-test-pr116047.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*6[^\n\r]*== 6 | ||
| 168 | FAIL: gcc.dg/plugin/location-overflow-test-pr120061.c -fplugin=./location_overflow_plugin.so scan-file static_assert[^\n\r]*5[^\n\r]*== 5 | ||
| 169 | and with the patch everything PASSes. | ||
| 170 | |||
| 171 | The patch reverts the r14-11679 change, because it is incorrect, | ||
| 172 | we really need to decrement it even when crossing ordinary map | ||
| 173 | boundaries, so that the location is not on the line after the #include | ||
| 174 | line but somewhere on the #include line. It also patches two spots | ||
| 175 | in linemap_add mentioned above to make sure we get correct locations | ||
| 176 | both in the included_from location_t when doing LC_ENTER (second | ||
| 177 | line-map.cc hunk) and when doing LC_LEAVE to compute the right to_line | ||
| 178 | (first line-map.cc hunk), both in presence of an added LC_RENAME | ||
| 179 | with the same start_location as the following LC_ENTER (i.e. the | ||
| 180 | problematic cases). | ||
| 181 | The LC_ENTER hunk is mostly to ensure included_form location_t is | ||
| 182 | at the start of the #include line (column 0), without it we can | ||
| 183 | decrease include_from not enough and end up at some random column | ||
| 184 | in the middle of the line, because it is masking away | ||
| 185 | map[-1].m_column_and_range_bits bits even when in the end the resulting | ||
| 186 | include_from location_t will be found in map[-2] map with perhaps | ||
| 187 | different m_column_and_range_bits. That alone doesn't fix the bug | ||
| 188 | though. | ||
| 189 | The more important is the LC_LEAVE hunk and the problem there is | ||
| 190 | caused by linemap_line_start not actually doing | ||
| 191 | r = set->highest_line + (line_delta << map->m_column_and_range_bits); | ||
| 192 | when adding a new map (the LC_RENAME one because we need to switch to | ||
| 193 | different number of directly encoded ranges, or columns, etc.). | ||
| 194 | So, in the original PR108900 case that | ||
| 195 | to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 196 | doesn't do the right thing, from there is the last < 0x50000000 map | ||
| 197 | with m_column_and_range_bits 12, from[1] is the first one above it | ||
| 198 | and map[-1].included_from is the correct location of column 0 on | ||
| 199 | the #include line, but as the new LC_RENAME map has been created without | ||
| 200 | actually increasing highest_location to be on the new line (we've just | ||
| 201 | set to_line of the new LC_RENAME map to the correct line), | ||
| 202 | to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 203 | stays on the same source line. I've tried to just replace that with | ||
| 204 | to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; | ||
| 205 | i.e. just find out the #include line from map[-1].included_from and | ||
| 206 | add 1 to it, unfortunately that breaks the | ||
| 207 | c-c++-common/cpp/line-4.c | ||
| 208 | test where we expect to stay on the same 0 line for LC_LEAVE from | ||
| 209 | <command line> and gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/trad/builtins.c | ||
| 210 | and c-c++-common/analyzer/named-constants-via-macros-traditional.c tests | ||
| 211 | all with -traditional-cpp preprocessing where to_line is also off-by-one | ||
| 212 | from the expected one. | ||
| 213 | So, this patch instead conditionalizes it, uses the | ||
| 214 | to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; | ||
| 215 | way only if from[1] is a LC_RENAME map (rather than the usual | ||
| 216 | LC_ENTER one), that should limit it to the problematic cases of when | ||
| 217 | parse_include peeked after EOL and had to create LC_RENAME map with | ||
| 218 | the same start_location as the LC_ENTER after it. | ||
| 219 | |||
| 220 | Some further justification for the LC_ENTER hunk, using the | ||
| 221 | https://gcc.gnu.org/pipermail/gcc-patches/2025-May/682774.html testcase | ||
| 222 | (old is 14 before r14-11679, vanilla current 14 and new with the 14 patch) | ||
| 223 | I get | ||
| 224 | $ /usr/src/gcc-14/obj/gcc/cc1.old -quiet -std=c23 pr116047.c -nostdinc | ||
| 225 | In file included from pr116047-1.h:327677:21, | ||
| 226 | from pr116047.c:4: | ||
| 227 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 228 | 1 | a b c; | ||
| 229 | | ^ | ||
| 230 | pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ | ||
| 231 | 1 | a b c; | ||
| 232 | | ^ | ||
| 233 | pr116047-1.h:327677:1: error: static assertion failed: "" | ||
| 234 | 327677 | #include "pr116047-2.h" | ||
| 235 | | ^~~~~~~~~~~~~ | ||
| 236 | $ /usr/src/gcc-14/obj/gcc/cc1.vanilla -quiet -std=c23 pr116047.c -nostdinc | ||
| 237 | In file included from pr116047-1.h:327678, | ||
| 238 | from pr116047.c:4: | ||
| 239 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 240 | 1 | a b c; | ||
| 241 | | ^ | ||
| 242 | pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ | ||
| 243 | 1 | a b c; | ||
| 244 | | ^ | ||
| 245 | $ /usr/src/gcc-14/obj/gcc/cc1.new -quiet -std=c23 pr116047.c -nostdinc | ||
| 246 | In file included from pr116047-1.h:327677, | ||
| 247 | from pr116047.c:4: | ||
| 248 | pr116047-2.h:1:1: error: unknown type name ‘a’ | ||
| 249 | 1 | a b c; | ||
| 250 | | ^ | ||
| 251 | pr116047-2.h:1:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘c’ | ||
| 252 | 1 | a b c; | ||
| 253 | | ^ | ||
| 254 | |||
| 255 | pr116047-1.h has on lines 327677+327678: | ||
| 256 | #include "pr116047-2.h" | ||
| 257 | static_assert (__LINE__ == 327678, ""); | ||
| 258 | so the static_assert failure is something that was dealt mainly in the | ||
| 259 | LC_LEAVE hunk and files.cc reversion, but please have a look at the | ||
| 260 | In file included from lines. | ||
| 261 | 14.2 emits correct line (#include "pr116047-2.h" is indeed on line | ||
| 262 | 327677) but some random column in there (which is not normally printed | ||
| 263 | for smaller headers; 21 is the . before extension in the filename). | ||
| 264 | Current trunk emits incorrect line (327678 instead of 327677, clearly | ||
| 265 | it didn't decrement). | ||
| 266 | And the patched compiler emits the right line with no column, as would | ||
| 267 | be printed if I remove e.g. 300000 newlines from the file. | ||
| 268 | |||
| 269 | 2025-05-08 Jakub Jelinek <jakub@redhat.com> | ||
| 270 | |||
| 271 | PR preprocessor/108900 | ||
| 272 | PR preprocessor/116047 | ||
| 273 | PR preprocessor/120061 | ||
| 274 | * files.cc (_cpp_stack_file): Revert 2025-03-28 change. | ||
| 275 | * line-map.cc (linemap_add): Use | ||
| 276 | SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; instead of | ||
| 277 | SOURCE_LINE (from, from[1].start_location); to compute to_line | ||
| 278 | for LC_LEAVE if from[1].reason is LC_RENAME. For LC_ENTER | ||
| 279 | included_from computation, look at map[-2] or even lower if map[-1] | ||
| 280 | has the same start_location as map[0]. | ||
| 281 | |||
| 282 | * gcc.dg/plugin/plugin.exp: Add location-overflow-test-pr116047.c | ||
| 283 | and location-overflow-test-pr120061.c. | ||
| 284 | * gcc.dg/plugin/location_overflow_plugin.c (plugin_init): Don't error | ||
| 285 | on unknown values, instead just break. | ||
| 286 | * gcc.dg/plugin/location-overflow-test-pr116047.c: New test. | ||
| 287 | * gcc.dg/plugin/location-overflow-test-pr116047-1.h: New test. | ||
| 288 | * gcc.dg/plugin/location-overflow-test-pr116047-2.h: New test. | ||
| 289 | * gcc.dg/plugin/location-overflow-test-pr120061.c: New test. | ||
| 290 | * gcc.dg/plugin/location-overflow-test-pr120061-1.h: New test. | ||
| 291 | * gcc.dg/plugin/location-overflow-test-pr120061-2.h: New test. | ||
| 292 | |||
| 293 | Upstream-Status: Backport [https://gcc.gnu.org/cgit/gcc/commit/?id=edf745dc519ddbfef127e2789bf11bfbacd300b7] | ||
| 294 | Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com> | ||
| 295 | --- | ||
| 296 | .../plugin/location-overflow-test-pr116047-1.h | 6 +++ | ||
| 297 | .../plugin/location-overflow-test-pr116047-2.h | 1 + | ||
| 298 | .../plugin/location-overflow-test-pr116047.c | 5 +++ | ||
| 299 | .../plugin/location-overflow-test-pr120061-1.h | 6 +++ | ||
| 300 | .../plugin/location-overflow-test-pr120061-2.h | 1 + | ||
| 301 | .../plugin/location-overflow-test-pr120061.c | 6 +++ | ||
| 302 | .../gcc.dg/plugin/location_overflow_plugin.c | 2 +- | ||
| 303 | gcc/testsuite/gcc.dg/plugin/plugin.exp | 4 +- | ||
| 304 | libcpp/line-map.cc | 48 ++++++++++++++++++---- | ||
| 305 | 10 files changed, 69 insertions(+), 18 deletions(-) | ||
| 306 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h | ||
| 307 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h | ||
| 308 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c | ||
| 309 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h | ||
| 310 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h | ||
| 311 | create mode 100644 gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c | ||
| 312 | |||
| 313 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h | ||
| 314 | new file mode 100644 | ||
| 315 | index 000000000000..3dd6434a938b | ||
| 316 | --- /dev/null | ||
| 317 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h | ||
| 318 | @@ -0,0 +1,6 @@ | ||
| 319 | + | ||
| 320 | + | ||
| 321 | + | ||
| 322 | + | ||
| 323 | +#include "location-overflow-test-pr116047-2.h" | ||
| 324 | +static_assert (__LINE__ == 6, ""); | ||
| 325 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h | ||
| 326 | new file mode 100644 | ||
| 327 | index 000000000000..048f715b4656 | ||
| 328 | --- /dev/null | ||
| 329 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h | ||
| 330 | @@ -0,0 +1 @@ | ||
| 331 | +int i; | ||
| 332 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c | ||
| 333 | new file mode 100644 | ||
| 334 | index 000000000000..33f2c4ce8def | ||
| 335 | --- /dev/null | ||
| 336 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c | ||
| 337 | @@ -0,0 +1,5 @@ | ||
| 338 | +/* PR preprocessor/116047 */ | ||
| 339 | +/* { dg-do preprocess } */ | ||
| 340 | +/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x4fff8080" } */ | ||
| 341 | +#include "location-overflow-test-pr116047-1.h" | ||
| 342 | +/* { dg-final { scan-file location-overflow-test-pr116047.i "static_assert\[^\n\r]\*6\[^\n\r]\*== 6" } } */ | ||
| 343 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h | ||
| 344 | new file mode 100644 | ||
| 345 | index 000000000000..ebf7704f568e | ||
| 346 | --- /dev/null | ||
| 347 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h | ||
| 348 | @@ -0,0 +1,6 @@ | ||
| 349 | + | ||
| 350 | + | ||
| 351 | + | ||
| 352 | + | ||
| 353 | +#include "location-overflow-test-pr120061-2.h" | ||
| 354 | + | ||
| 355 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h | ||
| 356 | new file mode 100644 | ||
| 357 | index 000000000000..048f715b4656 | ||
| 358 | --- /dev/null | ||
| 359 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h | ||
| 360 | @@ -0,0 +1 @@ | ||
| 361 | +int i; | ||
| 362 | diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c | ||
| 363 | new file mode 100644 | ||
| 364 | index 000000000000..e8e803898da3 | ||
| 365 | --- /dev/null | ||
| 366 | +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c | ||
| 367 | @@ -0,0 +1,6 @@ | ||
| 368 | +/* PR preprocessor/120061 */ | ||
| 369 | +/* { dg-do preprocess } */ | ||
| 370 | +/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x61000000" } */ | ||
| 371 | +#include "location-overflow-test-pr120061-1.h" | ||
| 372 | +static_assert (__LINE__ == 5, ""); | ||
| 373 | +/* { dg-final { scan-file location-overflow-test-pr120061.i "static_assert\[^\n\r]\*5\[^\n\r]\*== 5" } } */ | ||
| 374 | diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c | ||
| 375 | index d0a6b0755648..6f4497a1cb16 100644 | ||
| 376 | --- a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c | ||
| 377 | +++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.c | ||
| 378 | @@ -101,7 +101,7 @@ plugin_init (struct plugin_name_args *plugin_info, | ||
| 379 | break; | ||
| 380 | |||
| 381 | default: | ||
| 382 | - error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument"); | ||
| 383 | + break; | ||
| 384 | } | ||
| 385 | |||
| 386 | return 0; | ||
| 387 | diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp | ||
| 388 | index 933f9a5850bc..438c6d87aad9 100644 | ||
| 389 | --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp | ||
| 390 | +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp | ||
| 391 | @@ -126,7 +126,9 @@ set plugin_test_list [list \ | ||
| 392 | { location_overflow_plugin.c \ | ||
| 393 | location-overflow-test-1.c \ | ||
| 394 | location-overflow-test-2.c \ | ||
| 395 | - location-overflow-test-pr83173.c } \ | ||
| 396 | + location-overflow-test-pr83173.c \ | ||
| 397 | + location-overflow-test-pr116047.c \ | ||
| 398 | + location-overflow-test-pr120061.c } \ | ||
| 399 | { must_tail_call_plugin.c \ | ||
| 400 | must-tail-call-1.c \ | ||
| 401 | must-tail-call-2.c } \ | ||
| 402 | diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc | ||
| 403 | index d5200b317eee..1e659638d9f7 100644 | ||
| 404 | --- a/libcpp/line-map.cc | ||
| 405 | +++ b/libcpp/line-map.cc | ||
| 406 | @@ -618,8 +618,8 @@ linemap_add (line_maps *set, enum lc_reason reason, | ||
| 407 | #include "included", inside the same "includer" file. */ | ||
| 408 | |||
| 409 | linemap_assert (!MAIN_FILE_P (map - 1)); | ||
| 410 | - /* (MAP - 1) points to the map we are leaving. The | ||
| 411 | - map from which (MAP - 1) got included should be the map | ||
| 412 | + /* (MAP - 1) points to the map we are leaving. The | ||
| 413 | + map from which (MAP - 1) got included should be usually the map | ||
| 414 | that comes right before MAP in the same file. */ | ||
| 415 | from = linemap_included_from_linemap (set, map - 1); | ||
| 416 | |||
| 417 | @@ -627,7 +627,24 @@ linemap_add (line_maps *set, enum lc_reason reason, | ||
| 418 | if (to_file == NULL) | ||
| 419 | { | ||
| 420 | to_file = ORDINARY_MAP_FILE_NAME (from); | ||
| 421 | - to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 422 | + /* Compute the line on which the map resumes, for #include this | ||
| 423 | + should be the line after the #include line. Usually FROM is | ||
| 424 | + the map right before LC_ENTER map - the first map of the included | ||
| 425 | + file, and in that case SOURCE_LINE (from, from[1].start_location); | ||
| 426 | + computes the right line (and does handle even some special cases | ||
| 427 | + (e.g. where for returning from <command line> we still want to | ||
| 428 | + be at line 0 or some -traditional-cpp cases). In rare cases | ||
| 429 | + FROM can be followed by LC_RENAME created by linemap_line_start | ||
| 430 | + for line right after #include line. If that happens, | ||
| 431 | + start_location of the FROM[1] map will be the same as | ||
| 432 | + start_location of FROM[2] LC_ENTER, but FROM[1] start_location | ||
| 433 | + might not have advance enough for moving to a full next line. | ||
| 434 | + In that case compute the line of #include line and add 1 to it | ||
| 435 | + to advance to the next line. See PR120061. */ | ||
| 436 | + if (from[1].reason == LC_RENAME) | ||
| 437 | + to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; | ||
| 438 | + else | ||
| 439 | + to_line = SOURCE_LINE (from, from[1].start_location); | ||
| 440 | sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); | ||
| 441 | } | ||
| 442 | else | ||
| 443 | @@ -657,11 +674,26 @@ linemap_add (line_maps *set, enum lc_reason reason, | ||
| 444 | if (set->depth == 0) | ||
| 445 | map->included_from = 0; | ||
| 446 | else | ||
| 447 | - /* The location of the end of the just-closed map. */ | ||
| 448 | - map->included_from | ||
| 449 | - = (((map[0].start_location - 1 - map[-1].start_location) | ||
| 450 | - & ~((1 << map[-1].m_column_and_range_bits) - 1)) | ||
| 451 | - + map[-1].start_location); | ||
| 452 | + { | ||
| 453 | + /* Compute location from whence this line map was included. | ||
| 454 | + For #include this should be preferrably column 0 of the | ||
| 455 | + line on which #include directive appears. | ||
| 456 | + map[-1] is the just closed map and usually included_from | ||
| 457 | + falls within that map. In rare cases linemap_line_start | ||
| 458 | + can insert a new LC_RENAME map for the line immediately | ||
| 459 | + after #include line, in that case map[-1] will have the | ||
| 460 | + same start_location as the new one and so included_from | ||
| 461 | + would not be from map[-1] but likely map[-2]. If that | ||
| 462 | + happens, mask off map[-2] m_column_and_range_bits bits | ||
| 463 | + instead of map[-1]. See PR120061. */ | ||
| 464 | + int i = -1; | ||
| 465 | + while (map[i].start_location == map[0].start_location) | ||
| 466 | + --i; | ||
| 467 | + map->included_from | ||
| 468 | + = (((map[0].start_location - 1 - map[i].start_location) | ||
| 469 | + & ~((1 << map[i].m_column_and_range_bits) - 1)) | ||
| 470 | + + map[i].start_location); | ||
| 471 | + } | ||
| 472 | set->depth++; | ||
| 473 | if (set->trace_includes) | ||
| 474 | trace_include (set, map); | ||
| 475 | -- | ||
diff --git a/meta/recipes-devtools/gcc/gcc/gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch b/meta/recipes-devtools/gcc/gcc/gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch deleted file mode 100644 index e5abdcc703..0000000000 --- a/meta/recipes-devtools/gcc/gcc/gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch +++ /dev/null | |||
| @@ -1,549 +0,0 @@ | |||
| 1 | From ab884fffe3fc82a710bea66ad651720d71c938b8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jonathan Wakely <jwakely@redhat.com> | ||
| 3 | Date: Tue, 30 Apr 2024 09:52:13 +0100 | ||
| 4 | Subject: [PATCH] libstdc++: Fix std::chrono::tzdb to work with vanguard format | ||
| 5 | |||
| 6 | I found some issues in the std::chrono::tzdb parser by testing the | ||
| 7 | tzdata "vanguard" format, which uses new features that aren't enabled in | ||
| 8 | the "main" and "rearguard" data formats. | ||
| 9 | |||
| 10 | Since 2024a the keyword "minimum" is no longer valid for the FROM and TO | ||
| 11 | fields in a Rule line, which means that "m" is now a valid abbreviation | ||
| 12 | for "maximum". Previously we expected either "mi" or "ma". For backwards | ||
| 13 | compatibility, a FROM field beginning with "mi" is still supported and | ||
| 14 | is treated as 1900. The "maximum" keyword is only allowed in TO now, | ||
| 15 | because it makes no sense in FROM. To support these changes the | ||
| 16 | minmax_year and minmax_year2 classes for parsing FROM and TO are | ||
| 17 | replaced with a single years_from_to class that reads both fields. | ||
| 18 | |||
| 19 | The vanguard format makes use of %z in Zone FORMAT fields, which caused | ||
| 20 | an exception to be thrown from ZoneInfo::set_abbrev because no % or / | ||
| 21 | characters were expected when a Zone doesn't use a named Rule. The | ||
| 22 | ZoneInfo::to(sys_info&) function now uses format_abbrev_str to replace | ||
| 23 | any %z with the current offset. Although format_abbrev_str also checks | ||
| 24 | for %s and STD/DST formats, those only make sense when a named Rule is | ||
| 25 | in effect, so won't occur when ZoneInfo::to(sys_info&) is used. | ||
| 26 | |||
| 27 | Since making this change on trunk, the tzdata-2024b release started | ||
| 28 | using %z in the main format, not just vanguard. This makes a backport to | ||
| 29 | release branches necessary (see PR 116657). | ||
| 30 | |||
| 31 | This change also implements a feature that has always been missing from | ||
| 32 | time_zone::_M_get_sys_info: finding the Rule that is active before the | ||
| 33 | specified time point, so that we can correctly handle %s in the FORMAT | ||
| 34 | for the first new sys_info that gets created. This requires implementing | ||
| 35 | a poorly documented feature of zic, to get the LETTERS field from a | ||
| 36 | later transition, as described at | ||
| 37 | https://mm.icann.org/pipermail/tz/2024-April/058891.html | ||
| 38 | In order for this to work we need to be able to distinguish an empty | ||
| 39 | letters field (as used by CE%sT where the variable part is either empty | ||
| 40 | or "S") from "the letters field is not known for this transition". The | ||
| 41 | tzdata file uses "-" for an empty letters field, which libstdc++ was | ||
| 42 | previously replacing with "" when the Rule was parsed. Instead, we now | ||
| 43 | preserve the "-" in the Rule object, so that "" can be used for the case | ||
| 44 | where we don't know the letters (and so need to decide it). | ||
| 45 | |||
| 46 | (cherry picked from commit 0ca8d56f2085715f27ee536c6c344bc47af49cdd) | ||
| 47 | |||
| 48 | Upstream-Status: Backport [https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=5ceea2ac106d6dd1aa8175670b15a801316cf1c9] | ||
| 49 | |||
| 50 | Signed-off-by: Markus Volk <f_l_k@t-online.de> | ||
| 51 | --- | ||
| 52 | libstdc++-v3/src/c++20/tzdb.cc | 265 +++++++++++------- | ||
| 53 | .../std/time/time_zone/sys_info_abbrev.cc | 106 +++++++ | ||
| 54 | libstdc++-v3/testsuite/std/time/tzdb/1.cc | 6 +- | ||
| 55 | 3 files changed, 274 insertions(+), 103 deletions(-) | ||
| 56 | create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc | ||
| 57 | |||
| 58 | diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc | ||
| 59 | index c7c7cc9deee6..7e8cce7ce8cf 100644 | ||
| 60 | --- a/libstdc++-v3/src/c++20/tzdb.cc | ||
| 61 | +++ b/libstdc++-v3/src/c++20/tzdb.cc | ||
| 62 | @@ -342,51 +342,103 @@ namespace std::chrono | ||
| 63 | friend istream& operator>>(istream&, on_day&); | ||
| 64 | }; | ||
| 65 | |||
| 66 | - // Wrapper for chrono::year that reads a year, or one of the keywords | ||
| 67 | - // "minimum" or "maximum", or an unambiguous prefix of a keyword. | ||
| 68 | - struct minmax_year | ||
| 69 | + // Wrapper for two chrono::year values, which reads the FROM and TO | ||
| 70 | + // fields of a Rule line. The FROM field is a year and TO is a year or | ||
| 71 | + // one of the keywords "maximum" or "only" (or an abbreviation of those). | ||
| 72 | + // For backwards compatibility, the keyword "minimum" is recognized | ||
| 73 | + // for FROM and interpreted as 1900. | ||
| 74 | + struct years_from_to | ||
| 75 | { | ||
| 76 | - year& y; | ||
| 77 | + year& from; | ||
| 78 | + year& to; | ||
| 79 | |||
| 80 | - friend istream& operator>>(istream& in, minmax_year&& y) | ||
| 81 | + friend istream& operator>>(istream& in, years_from_to&& yy) | ||
| 82 | { | ||
| 83 | - if (ws(in).peek() == 'm') // keywords "minimum" or "maximum" | ||
| 84 | + string s; | ||
| 85 | + auto c = ws(in).peek(); | ||
| 86 | + if (c == 'm') [[unlikely]] // keyword "minimum" | ||
| 87 | { | ||
| 88 | - string s; | ||
| 89 | - in >> s; // extract the rest of the word, but only look at s[1] | ||
| 90 | - if (s[1] == 'a') | ||
| 91 | - y.y = year::max(); | ||
| 92 | - else if (s[1] == 'i') | ||
| 93 | - y.y = year::min(); | ||
| 94 | - else | ||
| 95 | - in.setstate(ios::failbit); | ||
| 96 | + in >> s; // extract the rest of the word | ||
| 97 | + yy.from = year(1900); | ||
| 98 | + } | ||
| 99 | + else if (int num = 0; in >> num) [[likely]] | ||
| 100 | + yy.from = year{num}; | ||
| 101 | + | ||
| 102 | + c = ws(in).peek(); | ||
| 103 | + if (c == 'm') // keyword "maximum" | ||
| 104 | + { | ||
| 105 | + in >> s; // extract the rest of the word | ||
| 106 | + yy.to = year::max(); | ||
| 107 | + } | ||
| 108 | + else if (c == 'o') // keyword "only" | ||
| 109 | + { | ||
| 110 | + in >> s; // extract the rest of the word | ||
| 111 | + yy.to = yy.from; | ||
| 112 | } | ||
| 113 | else if (int num = 0; in >> num) | ||
| 114 | - y.y = year{num}; | ||
| 115 | + yy.to = year{num}; | ||
| 116 | + | ||
| 117 | return in; | ||
| 118 | } | ||
| 119 | }; | ||
| 120 | |||
| 121 | - // As above for minmax_year, but also supports the keyword "only", | ||
| 122 | - // meaning that the TO year is the same as the FROM year. | ||
| 123 | - struct minmax_year2 | ||
| 124 | + bool | ||
| 125 | + select_std_or_dst_abbrev(string& abbrev, minutes save) | ||
| 126 | { | ||
| 127 | - minmax_year to; | ||
| 128 | - year from; | ||
| 129 | + if (size_t pos = abbrev.find('/'); pos != string::npos) | ||
| 130 | + { | ||
| 131 | + // Select one of "STD/DST" for standard or daylight. | ||
| 132 | + if (save == 0min) | ||
| 133 | + abbrev.erase(pos); | ||
| 134 | + else | ||
| 135 | + abbrev.erase(0, pos + 1); | ||
| 136 | + return true; | ||
| 137 | + } | ||
| 138 | + return false; | ||
| 139 | + } | ||
| 140 | |||
| 141 | - friend istream& operator>>(istream& in, minmax_year2&& y) | ||
| 142 | - { | ||
| 143 | - if (ws(in).peek() == 'o') // keyword "only" | ||
| 144 | - { | ||
| 145 | - string s; | ||
| 146 | - in >> s; // extract the whole keyword | ||
| 147 | - y.to.y = y.from; | ||
| 148 | - } | ||
| 149 | - else | ||
| 150 | - in >> std::move(y.to); | ||
| 151 | - return in; | ||
| 152 | - } | ||
| 153 | - }; | ||
| 154 | + // Set the sys_info::abbrev string by expanding any placeholders. | ||
| 155 | + void | ||
| 156 | + format_abbrev_str(sys_info& info, string_view letters = {}) | ||
| 157 | + { | ||
| 158 | + if (size_t pos = info.abbrev.find('%'); pos != string::npos) | ||
| 159 | + { | ||
| 160 | + if (info.abbrev[pos + 1] == 's') | ||
| 161 | + { | ||
| 162 | + // Expand "%s" to the variable part, given by Rule::letters. | ||
| 163 | + if (letters == "-") | ||
| 164 | + info.abbrev.erase(pos, 2); | ||
| 165 | + else | ||
| 166 | + info.abbrev.replace(pos, 2, letters); | ||
| 167 | + } | ||
| 168 | + else if (info.abbrev[pos + 1] == 'z') | ||
| 169 | + { | ||
| 170 | + // Expand "%z" to the UT offset as +/-hh, +/-hhmm, or +/-hhmmss. | ||
| 171 | + hh_mm_ss<seconds> t(info.offset); | ||
| 172 | + string z(1, "+-"[t.is_negative()]); | ||
| 173 | + long val = t.hours().count(); | ||
| 174 | + int digits = 2; | ||
| 175 | + if (int m = t.minutes().count()) | ||
| 176 | + { | ||
| 177 | + digits = 4; | ||
| 178 | + val *= 100; | ||
| 179 | + val += m; | ||
| 180 | + if (int s = t.seconds().count()) | ||
| 181 | + { | ||
| 182 | + digits = 6; | ||
| 183 | + val *= 100; | ||
| 184 | + val += s; | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + auto sval = std::to_string(val); | ||
| 188 | + z += string(digits - sval.size(), '0'); | ||
| 189 | + z += sval; | ||
| 190 | + info.abbrev.replace(pos, 2, z); | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + else | ||
| 194 | + select_std_or_dst_abbrev(info.abbrev, info.save); | ||
| 195 | + } | ||
| 196 | |||
| 197 | // A time zone information record. | ||
| 198 | // Zone NAME STDOFF RULES FORMAT [UNTIL] | ||
| 199 | @@ -462,6 +514,7 @@ namespace std::chrono | ||
| 200 | info.offset = offset(); | ||
| 201 | info.save = minutes(m_save); | ||
| 202 | info.abbrev = format(); | ||
| 203 | + format_abbrev_str(info); // expand %z | ||
| 204 | return true; | ||
| 205 | } | ||
| 206 | |||
| 207 | @@ -469,12 +522,9 @@ namespace std::chrono | ||
| 208 | friend class time_zone; | ||
| 209 | |||
| 210 | void | ||
| 211 | - set_abbrev(const string& abbrev) | ||
| 212 | + set_abbrev(string abbrev) | ||
| 213 | { | ||
| 214 | - // In practice, the FORMAT field never needs expanding here. | ||
| 215 | - if (abbrev.find_first_of("/%") != abbrev.npos) | ||
| 216 | - __throw_runtime_error("std::chrono::time_zone: invalid data"); | ||
| 217 | - m_buf = abbrev; | ||
| 218 | + m_buf = std::move(abbrev); | ||
| 219 | m_pos = 0; | ||
| 220 | m_expanded = true; | ||
| 221 | } | ||
| 222 | @@ -544,9 +594,7 @@ namespace std::chrono | ||
| 223 | |||
| 224 | // Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S | ||
| 225 | |||
| 226 | - in >> quoted(rule.name) | ||
| 227 | - >> minmax_year{rule.from} | ||
| 228 | - >> minmax_year2{rule.to, rule.from}; | ||
| 229 | + in >> quoted(rule.name) >> years_from_to{rule.from, rule.to}; | ||
| 230 | |||
| 231 | if (char type; in >> type && type != '-') | ||
| 232 | in.setstate(ios::failbit); | ||
| 233 | @@ -557,7 +605,7 @@ namespace std::chrono | ||
| 234 | if (save_time.indicator != at_time::Wall) | ||
| 235 | { | ||
| 236 | // We don't actually store the save_time.indicator, because we | ||
| 237 | - // assume that it's always deducable from the actual offset value. | ||
| 238 | + // assume that it's always deducible from the offset value. | ||
| 239 | auto expected = save_time.time == 0s | ||
| 240 | ? at_time::Standard | ||
| 241 | : at_time::Daylight; | ||
| 242 | @@ -567,8 +615,6 @@ namespace std::chrono | ||
| 243 | rule.save = save_time.time; | ||
| 244 | |||
| 245 | in >> rule.letters; | ||
| 246 | - if (rule.letters == "-") | ||
| 247 | - rule.letters.clear(); | ||
| 248 | return in; | ||
| 249 | } | ||
| 250 | |||
| 251 | @@ -719,58 +765,6 @@ namespace std::chrono | ||
| 252 | #endif // TZDB_DISABLED | ||
| 253 | }; | ||
| 254 | |||
| 255 | -#ifndef TZDB_DISABLED | ||
| 256 | - namespace | ||
| 257 | - { | ||
| 258 | - bool | ||
| 259 | - select_std_or_dst_abbrev(string& abbrev, minutes save) | ||
| 260 | - { | ||
| 261 | - if (size_t pos = abbrev.find('/'); pos != string::npos) | ||
| 262 | - { | ||
| 263 | - // Select one of "STD/DST" for standard or daylight. | ||
| 264 | - if (save == 0min) | ||
| 265 | - abbrev.erase(pos); | ||
| 266 | - else | ||
| 267 | - abbrev.erase(0, pos + 1); | ||
| 268 | - return true; | ||
| 269 | - } | ||
| 270 | - return false; | ||
| 271 | - } | ||
| 272 | - | ||
| 273 | - // Set the sys_info::abbrev string by expanding any placeholders. | ||
| 274 | - void | ||
| 275 | - format_abbrev_str(sys_info& info, string_view letters = {}) | ||
| 276 | - { | ||
| 277 | - if (size_t pos = info.abbrev.find("%s"); pos != string::npos) | ||
| 278 | - { | ||
| 279 | - // Expand "%s" to the variable part, given by Rule::letters. | ||
| 280 | - info.abbrev.replace(pos, 2, letters); | ||
| 281 | - } | ||
| 282 | - else if (size_t pos = info.abbrev.find("%z"); pos != string::npos) | ||
| 283 | - { | ||
| 284 | - // Expand "%z" to the UT offset as +/-hh, +/-hhmm, or +/-hhmmss. | ||
| 285 | - hh_mm_ss<seconds> t(info.offset); | ||
| 286 | - string z(1, "+-"[t.is_negative()]); | ||
| 287 | - long val = t.hours().count(); | ||
| 288 | - if (minutes m = t.minutes(); m != m.zero()) | ||
| 289 | - { | ||
| 290 | - val *= 100; | ||
| 291 | - val += m.count(); | ||
| 292 | - if (seconds s = t.seconds(); s != s.zero()) | ||
| 293 | - { | ||
| 294 | - val *= 100; | ||
| 295 | - val += s.count(); | ||
| 296 | - } | ||
| 297 | - } | ||
| 298 | - z += std::to_string(val); | ||
| 299 | - info.abbrev.replace(pos, 2, z); | ||
| 300 | - } | ||
| 301 | - else | ||
| 302 | - select_std_or_dst_abbrev(info.abbrev, info.save); | ||
| 303 | - } | ||
| 304 | - } | ||
| 305 | -#endif // TZDB_DISABLED | ||
| 306 | - | ||
| 307 | // Implementation of std::chrono::time_zone::get_info(const sys_time<D>&) | ||
| 308 | sys_info | ||
| 309 | time_zone::_M_get_sys_info(sys_seconds tp) const | ||
| 310 | @@ -839,12 +833,72 @@ namespace std::chrono | ||
| 311 | info.abbrev = ri.format(); | ||
| 312 | |||
| 313 | string_view letters; | ||
| 314 | - if (i != infos.begin()) | ||
| 315 | + if (i != infos.begin() && i[-1].expanded()) | ||
| 316 | + letters = i[-1].next_letters(); | ||
| 317 | + | ||
| 318 | + if (letters.empty()) | ||
| 319 | { | ||
| 320 | - if (i[-1].expanded()) | ||
| 321 | - letters = i[-1].next_letters(); | ||
| 322 | - // XXX else need to find Rule active before this time and use it | ||
| 323 | - // to know the initial offset, save, and letters. | ||
| 324 | + sys_seconds t = info.begin - seconds(1); | ||
| 325 | + const year_month_day date(chrono::floor<days>(t)); | ||
| 326 | + | ||
| 327 | + // Try to find a Rule active before this time, to get initial | ||
| 328 | + // SAVE and LETTERS values. There may not be a Rule for the period | ||
| 329 | + // before the first DST transition, so find the earliest DST->STD | ||
| 330 | + // transition and use the LETTERS from that. | ||
| 331 | + const Rule* active_rule = nullptr; | ||
| 332 | + sys_seconds active_rule_start = sys_seconds::min(); | ||
| 333 | + const Rule* first_std = nullptr; | ||
| 334 | + for (const auto& rule : rules) | ||
| 335 | + { | ||
| 336 | + if (rule.save == minutes(0)) | ||
| 337 | + { | ||
| 338 | + if (!first_std) | ||
| 339 | + first_std = &rule; | ||
| 340 | + else if (rule.from < first_std->from) | ||
| 341 | + first_std = &rule; | ||
| 342 | + else if (rule.from == first_std->from) | ||
| 343 | + { | ||
| 344 | + if (rule.start_time(rule.from, {}) | ||
| 345 | + < first_std->start_time(first_std->from, {})) | ||
| 346 | + first_std = &rule; | ||
| 347 | + } | ||
| 348 | + } | ||
| 349 | + | ||
| 350 | + year y = date.year(); | ||
| 351 | + | ||
| 352 | + if (y > rule.to) // rule no longer applies at time t | ||
| 353 | + continue; | ||
| 354 | + if (y < rule.from) // rule doesn't apply yet at time t | ||
| 355 | + continue; | ||
| 356 | + | ||
| 357 | + sys_seconds rule_start; | ||
| 358 | + | ||
| 359 | + seconds offset{}; // appropriate for at_time::Universal | ||
| 360 | + if (rule.when.indicator == at_time::Wall) | ||
| 361 | + offset = info.offset; | ||
| 362 | + else if (rule.when.indicator == at_time::Standard) | ||
| 363 | + offset = ri.offset(); | ||
| 364 | + | ||
| 365 | + // Time the rule takes effect this year: | ||
| 366 | + rule_start = rule.start_time(y, offset); | ||
| 367 | + | ||
| 368 | + if (rule_start >= t && rule.from < y) | ||
| 369 | + { | ||
| 370 | + // Try this rule in the previous year. | ||
| 371 | + rule_start = rule.start_time(--y, offset); | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + if (active_rule_start < rule_start && rule_start < t) | ||
| 375 | + { | ||
| 376 | + active_rule_start = rule_start; | ||
| 377 | + active_rule = &rule; | ||
| 378 | + } | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + if (active_rule) | ||
| 382 | + letters = active_rule->letters; | ||
| 383 | + else if (first_std) | ||
| 384 | + letters = first_std->letters; | ||
| 385 | } | ||
| 386 | |||
| 387 | const Rule* curr_rule = nullptr; | ||
| 388 | @@ -2069,9 +2123,11 @@ namespace std::chrono | ||
| 389 | istringstream in2(std::move(rules)); | ||
| 390 | in2 >> rules_time; | ||
| 391 | inf.m_save = duration_cast<minutes>(rules_time.time); | ||
| 392 | + // If the FORMAT is "STD/DST" then we can choose the right one | ||
| 393 | + // now, so that we store a shorter string. | ||
| 394 | select_std_or_dst_abbrev(fmt, inf.m_save); | ||
| 395 | } | ||
| 396 | - inf.set_abbrev(fmt); | ||
| 397 | + inf.set_abbrev(std::move(fmt)); | ||
| 398 | } | ||
| 399 | |||
| 400 | // YEAR [MONTH [DAY [TIME]]] | ||
| 401 | @@ -2082,7 +2138,12 @@ namespace std::chrono | ||
| 402 | abbrev_month m{January}; | ||
| 403 | int d = 1; | ||
| 404 | at_time t{}; | ||
| 405 | + // XXX DAY should support ON format, e.g. lastSun or Sun>=8 | ||
| 406 | in >> m >> d >> t; | ||
| 407 | + // XXX UNTIL field should be interpreted | ||
| 408 | + // "using the rules in effect just before the transition" | ||
| 409 | + // so might need to store as year_month_day and hh_mm_ss and only | ||
| 410 | + // convert to a sys_time once we know the offset in effect. | ||
| 411 | inf.m_until = sys_days(year(y)/m.m/day(d)) + seconds(t.time); | ||
| 412 | } | ||
| 413 | else | ||
| 414 | diff --git a/libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc b/libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc | ||
| 415 | new file mode 100644 | ||
| 416 | index 000000000000..f1a8fff02f58 | ||
| 417 | --- /dev/null | ||
| 418 | +++ b/libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc | ||
| 419 | @@ -0,0 +1,106 @@ | ||
| 420 | +// { dg-do run { target c++20 } } | ||
| 421 | +// { dg-require-effective-target tzdb } | ||
| 422 | +// { dg-require-effective-target cxx11_abi } | ||
| 423 | +// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } } | ||
| 424 | + | ||
| 425 | +#include <chrono> | ||
| 426 | +#include <fstream> | ||
| 427 | +#include <testsuite_hooks.h> | ||
| 428 | + | ||
| 429 | +static bool override_used = false; | ||
| 430 | + | ||
| 431 | +namespace __gnu_cxx | ||
| 432 | +{ | ||
| 433 | + const char* zoneinfo_dir_override() { | ||
| 434 | + override_used = true; | ||
| 435 | + return "./"; | ||
| 436 | + } | ||
| 437 | +} | ||
| 438 | + | ||
| 439 | +using namespace std::chrono; | ||
| 440 | + | ||
| 441 | +void | ||
| 442 | +test_format() | ||
| 443 | +{ | ||
| 444 | + std::ofstream("tzdata.zi") << R"(# version test_1 | ||
| 445 | +Zone Africa/Bissau -1:2:20 - LMT 1912 Ja 1 1u | ||
| 446 | + -1 - %z 1975 | ||
| 447 | + 0 - GMT | ||
| 448 | +Zon Some/Zone 1:2:3 - %z 1900 | ||
| 449 | + 1:23:45 - %z 1950 | ||
| 450 | +Zo Another/Zone 1:2:3 - AZ0 1901 | ||
| 451 | + 1 Roolz A%sZ 2000 | ||
| 452 | + 1 Roolz SAZ/DAZ 2005 | ||
| 453 | + 1 Roolz %z | ||
| 454 | +Rule Roolz 1950 max - April 1 2 1 D | ||
| 455 | +Rul Roolz 1950 max - Oct 1 1 0 S | ||
| 456 | +Z Strange/Zone 1 - X%sX 1980 | ||
| 457 | + 1 - FOO/BAR 1990 | ||
| 458 | + 2:00 - %zzz 1995 | ||
| 459 | + 0:9 - %zzz 1996 | ||
| 460 | + 0:8:7 - %zzz 1997 | ||
| 461 | + 0:6:5.5 - %zzz 1998 | ||
| 462 | +)"; | ||
| 463 | + | ||
| 464 | + const auto& db = reload_tzdb(); | ||
| 465 | + VERIFY( override_used ); // If this fails then XFAIL for the target. | ||
| 466 | + VERIFY( db.version == "test_1" ); | ||
| 467 | + | ||
| 468 | + // Test formatting %z as | ||
| 469 | + auto tz = locate_zone("Africa/Bissau"); | ||
| 470 | + auto inf = tz->get_info(sys_days(1974y/1/1)); | ||
| 471 | + VERIFY( inf.abbrev == "-01" ); | ||
| 472 | + | ||
| 473 | + tz = locate_zone("Some/Zone"); | ||
| 474 | + inf = tz->get_info(sys_days(1899y/1/1)); | ||
| 475 | + VERIFY( inf.abbrev == "+010203" ); | ||
| 476 | + inf = tz->get_info(sys_days(1955y/1/1)); | ||
| 477 | + VERIFY( inf.abbrev == "+012345" ); | ||
| 478 | + | ||
| 479 | + tz = locate_zone("Another/Zone"); | ||
| 480 | + // Test formatting %s as the LETTER/S field from the active Rule. | ||
| 481 | + inf = tz->get_info(sys_days(1910y/January/1)); | ||
| 482 | + VERIFY( inf.abbrev == "ASZ" ); | ||
| 483 | + inf = tz->get_info(sys_days(1950y/January/1)); | ||
| 484 | + VERIFY( inf.abbrev == "ASZ" ); | ||
| 485 | + inf = tz->get_info(sys_days(1950y/June/1)); | ||
| 486 | + VERIFY( inf.abbrev == "ADZ" ); | ||
| 487 | + inf = tz->get_info(sys_days(1999y/January/1)); | ||
| 488 | + VERIFY( inf.abbrev == "ASZ" ); | ||
| 489 | + inf = tz->get_info(sys_days(1999y/July/1)); | ||
| 490 | + VERIFY( inf.abbrev == "ADZ" ); | ||
| 491 | + // Test formatting STD/DST according to the active Rule. | ||
| 492 | + inf = tz->get_info(sys_days(2000y/January/2)); | ||
| 493 | + VERIFY( inf.abbrev == "SAZ" ); | ||
| 494 | + inf = tz->get_info(sys_days(2001y/January/1)); | ||
| 495 | + VERIFY( inf.abbrev == "SAZ" ); | ||
| 496 | + inf = tz->get_info(sys_days(2001y/July/1)); | ||
| 497 | + VERIFY( inf.abbrev == "DAZ" ); | ||
| 498 | + // Test formatting %z as the offset determined by the active Rule. | ||
| 499 | + inf = tz->get_info(sys_days(2005y/January/2)); | ||
| 500 | + VERIFY( inf.abbrev == "+01" ); | ||
| 501 | + inf = tz->get_info(sys_days(2006y/January/1)); | ||
| 502 | + VERIFY( inf.abbrev == "+01" ); | ||
| 503 | + inf = tz->get_info(sys_days(2006y/July/1)); | ||
| 504 | + VERIFY( inf.abbrev == "+02" ); | ||
| 505 | + | ||
| 506 | + // Test formatting %z, %s and S/D for a Zone with no associated Rules. | ||
| 507 | + tz = locate_zone("Strange/Zone"); | ||
| 508 | + inf = tz->get_info(sys_days(1979y/January/1)); | ||
| 509 | + VERIFY( inf.abbrev == "XX" ); // No Rule means nothing to use for %s. | ||
| 510 | + inf = tz->get_info(sys_days(1981y/July/1)); | ||
| 511 | + VERIFY( inf.abbrev == "FOO" ); // Always standard time means first string. | ||
| 512 | + inf = tz->get_info(sys_days(1994y/July/1)); | ||
| 513 | + VERIFY( inf.abbrev == "+02zz" ); | ||
| 514 | + inf = tz->get_info(sys_days(1995y/July/1)); | ||
| 515 | + VERIFY( inf.abbrev == "+0009zz" ); | ||
| 516 | + inf = tz->get_info(sys_days(1996y/July/1)); | ||
| 517 | + VERIFY( inf.abbrev == "+000807zz" ); | ||
| 518 | + inf = tz->get_info(sys_days(1997y/July/1)); | ||
| 519 | + VERIFY( inf.abbrev == "+000606zz" ); | ||
| 520 | +} | ||
| 521 | + | ||
| 522 | +int main() | ||
| 523 | +{ | ||
| 524 | + test_format(); | ||
| 525 | +} | ||
| 526 | diff --git a/libstdc++-v3/testsuite/std/time/tzdb/1.cc b/libstdc++-v3/testsuite/std/time/tzdb/1.cc | ||
| 527 | index 796f3a8b4256..7a31c1c20ba7 100644 | ||
| 528 | --- a/libstdc++-v3/testsuite/std/time/tzdb/1.cc | ||
| 529 | +++ b/libstdc++-v3/testsuite/std/time/tzdb/1.cc | ||
| 530 | @@ -39,11 +39,15 @@ test_locate() | ||
| 531 | const tzdb& db = get_tzdb(); | ||
| 532 | const time_zone* tz = db.locate_zone("GMT"); | ||
| 533 | VERIFY( tz != nullptr ); | ||
| 534 | - VERIFY( tz->name() == "Etc/GMT" ); | ||
| 535 | VERIFY( tz == std::chrono::locate_zone("GMT") ); | ||
| 536 | VERIFY( tz == db.locate_zone("Etc/GMT") ); | ||
| 537 | VERIFY( tz == db.locate_zone("Etc/GMT+0") ); | ||
| 538 | |||
| 539 | + // Since 2022f GMT is now a Zone and Etc/GMT a link instead of vice versa, | ||
| 540 | + // but only when using the vanguard format. As of 2024a, the main and | ||
| 541 | + // rearguard formats still have Etc/GMT as a Zone and GMT as a link. | ||
| 542 | + VERIFY( tz->name() == "GMT" || tz->name() == "Etc/GMT" ); | ||
| 543 | + | ||
| 544 | VERIFY( db.locate_zone(db.current_zone()->name()) == db.current_zone() ); | ||
| 545 | } | ||
| 546 | |||
| 547 | -- | ||
| 548 | 2.43.5 | ||
| 549 | |||
diff --git a/meta/recipes-devtools/gcc/gcc_14.2.bb b/meta/recipes-devtools/gcc/gcc_14.3.bb index 255fe552bd..255fe552bd 100644 --- a/meta/recipes-devtools/gcc/gcc_14.2.bb +++ b/meta/recipes-devtools/gcc/gcc_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgcc-initial_14.2.bb b/meta/recipes-devtools/gcc/libgcc-initial_14.3.bb index a259082b47..a259082b47 100644 --- a/meta/recipes-devtools/gcc/libgcc-initial_14.2.bb +++ b/meta/recipes-devtools/gcc/libgcc-initial_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgcc_14.2.bb b/meta/recipes-devtools/gcc/libgcc_14.3.bb index fdcd6cc0da..fdcd6cc0da 100644 --- a/meta/recipes-devtools/gcc/libgcc_14.2.bb +++ b/meta/recipes-devtools/gcc/libgcc_14.3.bb | |||
diff --git a/meta/recipes-devtools/gcc/libgfortran_14.2.bb b/meta/recipes-devtools/gcc/libgfortran_14.3.bb index 71dd8b4bdc..71dd8b4bdc 100644 --- a/meta/recipes-devtools/gcc/libgfortran_14.2.bb +++ b/meta/recipes-devtools/gcc/libgfortran_14.3.bb | |||
