summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepesh Varatharajan <Deepesh.Varatharajan@windriver.com>2025-06-16 05:18:21 -0700
committerSteve Sakoman <steve@sakoman.com>2025-06-20 08:38:12 -0700
commit3f2cf790b2f325f497088bd7f28971ea27e5e555 (patch)
tree9e39b8adcb542890615f2a230fac6065ea7c8dd7
parentf2648ee38086e8632f319d41008c001b1a2454c0 (diff)
downloadpoky-3f2cf790b2f325f497088bd7f28971ea27e5e555.tar.gz
gcc: Upgrade to GCC 13.4
This is a bugfix release in GCC13 release series 100+ bugfixes https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED&resolution=FIXED&target_milestone=13.4 Dropped the following patches: 0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch https://github.com/gcc-mirror/gcc/commit/179dc0f0fe01012675c1b430591b9891ce96c26e gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch https://github.com/gcc-mirror/gcc/commit/5ceea2ac106d6dd1aa8175670b15a801316cf1c9 #GCC 13.3 #GCC 13.4 #Diff No. of expected passes            148863 149440 +577 No. of unexpected failures        14 14 0 No. of expected failures          1415 1414 -1 No. of unresolved testcases       25384 25660 +276 No. of unsupported tests          2692 2689 -3 (From OE-Core rev: 7af83314fea5948937403b5d59ba5df6fecdd81a) Signed-off-by: Deepesh Varatharajan <Deepesh.Varatharajan@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/conf/distro/include/maintainers.inc2
-rw-r--r--meta/recipes-devtools/gcc/gcc-13.4.inc (renamed from meta/recipes-devtools/gcc/gcc-13.3.inc)8
-rw-r--r--meta/recipes-devtools/gcc/gcc-cross-canadian_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-cross-canadian_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc-cross_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-cross_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc-crosssdk_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-crosssdk_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc-runtime_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-runtime_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc-sanitizers_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-sanitizers_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc-source_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc-source_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/gcc/0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch113
-rw-r--r--meta/recipes-devtools/gcc/gcc/gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch549
-rw-r--r--meta/recipes-devtools/gcc/gcc_13.4.bb (renamed from meta/recipes-devtools/gcc/gcc_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/libgcc-initial_13.4.bb (renamed from meta/recipes-devtools/gcc/libgcc-initial_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/libgcc_13.4.bb (renamed from meta/recipes-devtools/gcc/libgcc_13.3.bb)0
-rw-r--r--meta/recipes-devtools/gcc/libgfortran_13.4.bb (renamed from meta/recipes-devtools/gcc/libgfortran_13.3.bb)0
14 files changed, 4 insertions, 668 deletions
diff --git a/meta/conf/distro/include/maintainers.inc b/meta/conf/distro/include/maintainers.inc
index 9548fcd258..3a51ad2139 100644
--- a/meta/conf/distro/include/maintainers.inc
+++ b/meta/conf/distro/include/maintainers.inc
@@ -190,7 +190,7 @@ RECIPE_MAINTAINER:pn-gcc-cross-canadian-${TRANSLATED_TARGET_ARCH} = "Khem Raj <r
190RECIPE_MAINTAINER:pn-gcc-crosssdk-${SDK_SYS} = "Khem Raj <raj.khem@gmail.com>" 190RECIPE_MAINTAINER:pn-gcc-crosssdk-${SDK_SYS} = "Khem Raj <raj.khem@gmail.com>"
191RECIPE_MAINTAINER:pn-gcc-runtime = "Khem Raj <raj.khem@gmail.com>" 191RECIPE_MAINTAINER:pn-gcc-runtime = "Khem Raj <raj.khem@gmail.com>"
192RECIPE_MAINTAINER:pn-gcc-sanitizers = "Khem Raj <raj.khem@gmail.com>" 192RECIPE_MAINTAINER:pn-gcc-sanitizers = "Khem Raj <raj.khem@gmail.com>"
193RECIPE_MAINTAINER:pn-gcc-source-13.3.0 = "Khem Raj <raj.khem@gmail.com>" 193RECIPE_MAINTAINER:pn-gcc-source-13.4.0 = "Khem Raj <raj.khem@gmail.com>"
194RECIPE_MAINTAINER:pn-gconf = "Ross Burton <ross.burton@arm.com>" 194RECIPE_MAINTAINER:pn-gconf = "Ross Burton <ross.burton@arm.com>"
195RECIPE_MAINTAINER:pn-gcr = "Alexander Kanavin <alex.kanavin@gmail.com>" 195RECIPE_MAINTAINER:pn-gcr = "Alexander Kanavin <alex.kanavin@gmail.com>"
196RECIPE_MAINTAINER:pn-gdb = "Khem Raj <raj.khem@gmail.com>" 196RECIPE_MAINTAINER:pn-gdb = "Khem Raj <raj.khem@gmail.com>"
diff --git a/meta/recipes-devtools/gcc/gcc-13.3.inc b/meta/recipes-devtools/gcc/gcc-13.4.inc
index 8b6c2a5938..eefae13530 100644
--- a/meta/recipes-devtools/gcc/gcc-13.3.inc
+++ b/meta/recipes-devtools/gcc/gcc-13.4.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
5PV = "13.3.0" 5PV = "13.4.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
9BINV = "13.3.0" 9BINV = "13.4.0"
10 10
11FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc:${FILE_DIRNAME}/gcc/backport:" 11FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc:${FILE_DIRNAME}/gcc/backport:"
12 12
@@ -66,10 +66,8 @@ SRC_URI = "${BASEURI} \
66 file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \ 66 file://0024-Avoid-hardcoded-build-paths-into-ppc-libgcc.patch \
67 file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \ 67 file://0025-gcc-testsuite-tweaks-for-mips-OE.patch \
68 file://0027-Fix-gcc-vect-module-testcases.patch \ 68 file://0027-Fix-gcc-vect-module-testcases.patch \
69 file://0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch \
70 file://gcc.git-ab884fffe3fc82a710bea66ad651720d71c938b8.patch \
71" 69"
72SRC_URI[sha256sum] = "0845e9621c9543a13f484e94584a49ffc0129970e9914624235fc1d061a0c083" 70SRC_URI[sha256sum] = "9c4ce6dbb040568fdc545588ac03c5cbc95a8dbf0c7aa490170843afb59ca8f5"
73 71
74S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}" 72S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/${SOURCEDIR}"
75B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}" 73B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}"
diff --git a/meta/recipes-devtools/gcc/gcc-cross-canadian_13.3.bb b/meta/recipes-devtools/gcc/gcc-cross-canadian_13.4.bb
index bf53c5cd78..bf53c5cd78 100644
--- a/meta/recipes-devtools/gcc/gcc-cross-canadian_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-cross-canadian_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc-cross_13.3.bb b/meta/recipes-devtools/gcc/gcc-cross_13.4.bb
index b43cca0c52..b43cca0c52 100644
--- a/meta/recipes-devtools/gcc/gcc-cross_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-cross_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc-crosssdk_13.3.bb b/meta/recipes-devtools/gcc/gcc-crosssdk_13.4.bb
index 40a6c4feff..40a6c4feff 100644
--- a/meta/recipes-devtools/gcc/gcc-crosssdk_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-crosssdk_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc-runtime_13.3.bb b/meta/recipes-devtools/gcc/gcc-runtime_13.4.bb
index dd430b57eb..dd430b57eb 100644
--- a/meta/recipes-devtools/gcc/gcc-runtime_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-runtime_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc-sanitizers_13.3.bb b/meta/recipes-devtools/gcc/gcc-sanitizers_13.4.bb
index 8bda2ccad6..8bda2ccad6 100644
--- a/meta/recipes-devtools/gcc/gcc-sanitizers_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-sanitizers_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc-source_13.3.bb b/meta/recipes-devtools/gcc/gcc-source_13.4.bb
index b890fa33ea..b890fa33ea 100644
--- a/meta/recipes-devtools/gcc/gcc-source_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc-source_13.4.bb
diff --git a/meta/recipes-devtools/gcc/gcc/0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch b/meta/recipes-devtools/gcc/gcc/0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch
deleted file mode 100644
index 745b38f7f1..0000000000
--- a/meta/recipes-devtools/gcc/gcc/0028-gcc-Fix-c-tweak-for-Wrange-loop-construct.patch
+++ /dev/null
@@ -1,113 +0,0 @@
1From 66aa69e2add2b8641a652768b0eac30f00427145 Mon Sep 17 00:00:00 2001
2From: Sunil Dora <sunilkumar.dora@windriver.com>
3Date: Wed, 11 Dec 2024 09:48:16 -0800
4Subject: [PATCH] gcc: Fix c++: tweak for Wrange-loop-construct
5
6This 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
8to types that can be copied trivially, whereas "trivially constructible" is the correct check
9for types that can be trivially default-constructed.
10
11This change ensures the warning is more accurate and aligns with the proper type traits.
12
13LLVM accepted a similar fix:
14https://github.com/llvm/llvm-project/issues/47355
15
16PR c++/116731 [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116731]
17
18Upstream-Status: Backport [https://gcc.gnu.org/g:179dc0f0fe01012675c1b430591b9891ce96c26e]
19
20Signed-off-by: Marek Polacek <polacek@redhat.com>
21Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
22---
23 gcc/cp/parser.cc | 7 ++-
24 .../g++.dg/warn/Wrange-loop-construct3.C | 57 +++++++++++++++++++
25 2 files changed, 61 insertions(+), 3 deletions(-)
26 create mode 100644 gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C
27
28diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
29index 4e67da6ff..5dd94357d 100644
30--- a/gcc/cp/parser.cc
31+++ b/gcc/cp/parser.cc
32@@ -13854,11 +13854,12 @@ 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 list = build_tree_list (NULL_TREE, TREE_TYPE (expr));
41 if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
42 || (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64
43- && trivially_copyable_p (type)))
44+ && is_trivially_xible (INIT_EXPR, type, list)))
45 return;
46
47 /* If we can initialize a reference directly, suggest that to avoid the
48diff --git a/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C
49new file mode 100644
50index 000000000..3d9d0c908
51--- /dev/null
52+++ b/gcc/testsuite/g++.dg/warn/Wrange-loop-construct3.C
53@@ -0,0 +1,57 @@
54+// PR c++/116731
55+// { dg-do compile { target c++11 } }
56+// { dg-options "-Wrange-loop-construct" }
57+
58+void
59+f0 ()
60+{
61+ struct S {
62+ char a[64];
63+ S& operator=(const S&) { return *this; };
64+ };
65+
66+ S arr[8];
67+ for (const auto r : arr)
68+ (void) r;
69+}
70+
71+void
72+f1 ()
73+{
74+ struct S {
75+ char a[65];
76+ S& operator=(const S&) { return *this; };
77+ };
78+
79+ S arr[8];
80+ for (const auto r : arr) // { dg-warning "creates a copy" }
81+ (void) r;
82+}
83+
84+void
85+f2 ()
86+{
87+ struct S {
88+ char a[64];
89+ S& operator=(const S&) { return *this; };
90+ ~S() { }
91+ };
92+
93+ S arr[8];
94+ for (const auto r : arr) // { dg-warning "creates a copy" }
95+ (void) r;
96+}
97+
98+void
99+f3 ()
100+{
101+ struct S {
102+ char a[65];
103+ S& operator=(const S&) { return *this; };
104+ ~S() { }
105+ };
106+
107+ S arr[8];
108+ for (const auto r : arr) // { dg-warning "creates a copy" }
109+ (void) r;
110+}
111--
1122.43.0
113
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 @@
1From ab884fffe3fc82a710bea66ad651720d71c938b8 Mon Sep 17 00:00:00 2001
2From: Jonathan Wakely <jwakely@redhat.com>
3Date: Tue, 30 Apr 2024 09:52:13 +0100
4Subject: [PATCH] libstdc++: Fix std::chrono::tzdb to work with vanguard format
5
6I found some issues in the std::chrono::tzdb parser by testing the
7tzdata "vanguard" format, which uses new features that aren't enabled in
8the "main" and "rearguard" data formats.
9
10Since 2024a the keyword "minimum" is no longer valid for the FROM and TO
11fields in a Rule line, which means that "m" is now a valid abbreviation
12for "maximum". Previously we expected either "mi" or "ma". For backwards
13compatibility, a FROM field beginning with "mi" is still supported and
14is treated as 1900. The "maximum" keyword is only allowed in TO now,
15because it makes no sense in FROM. To support these changes the
16minmax_year and minmax_year2 classes for parsing FROM and TO are
17replaced with a single years_from_to class that reads both fields.
18
19The vanguard format makes use of %z in Zone FORMAT fields, which caused
20an exception to be thrown from ZoneInfo::set_abbrev because no % or /
21characters were expected when a Zone doesn't use a named Rule. The
22ZoneInfo::to(sys_info&) function now uses format_abbrev_str to replace
23any %z with the current offset. Although format_abbrev_str also checks
24for %s and STD/DST formats, those only make sense when a named Rule is
25in effect, so won't occur when ZoneInfo::to(sys_info&) is used.
26
27Since making this change on trunk, the tzdata-2024b release started
28using %z in the main format, not just vanguard. This makes a backport to
29release branches necessary (see PR 116657).
30
31This change also implements a feature that has always been missing from
32time_zone::_M_get_sys_info: finding the Rule that is active before the
33specified time point, so that we can correctly handle %s in the FORMAT
34for the first new sys_info that gets created. This requires implementing
35a poorly documented feature of zic, to get the LETTERS field from a
36later transition, as described at
37https://mm.icann.org/pipermail/tz/2024-April/058891.html
38In order for this to work we need to be able to distinguish an empty
39letters field (as used by CE%sT where the variable part is either empty
40or "S") from "the letters field is not known for this transition". The
41tzdata file uses "-" for an empty letters field, which libstdc++ was
42previously replacing with "" when the Rule was parsed. Instead, we now
43preserve the "-" in the Rule object, so that "" can be used for the case
44where we don't know the letters (and so need to decide it).
45
46(cherry picked from commit 0ca8d56f2085715f27ee536c6c344bc47af49cdd)
47
48Upstream-Status: Backport [https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=5ceea2ac106d6dd1aa8175670b15a801316cf1c9]
49
50Signed-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
58diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
59index 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
414diff --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
415new file mode 100644
416index 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+}
526diff --git a/libstdc++-v3/testsuite/std/time/tzdb/1.cc b/libstdc++-v3/testsuite/std/time/tzdb/1.cc
527index 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--
5482.43.5
549
diff --git a/meta/recipes-devtools/gcc/gcc_13.3.bb b/meta/recipes-devtools/gcc/gcc_13.4.bb
index 255fe552bd..255fe552bd 100644
--- a/meta/recipes-devtools/gcc/gcc_13.3.bb
+++ b/meta/recipes-devtools/gcc/gcc_13.4.bb
diff --git a/meta/recipes-devtools/gcc/libgcc-initial_13.3.bb b/meta/recipes-devtools/gcc/libgcc-initial_13.4.bb
index a259082b47..a259082b47 100644
--- a/meta/recipes-devtools/gcc/libgcc-initial_13.3.bb
+++ b/meta/recipes-devtools/gcc/libgcc-initial_13.4.bb
diff --git a/meta/recipes-devtools/gcc/libgcc_13.3.bb b/meta/recipes-devtools/gcc/libgcc_13.4.bb
index fdcd6cc0da..fdcd6cc0da 100644
--- a/meta/recipes-devtools/gcc/libgcc_13.3.bb
+++ b/meta/recipes-devtools/gcc/libgcc_13.4.bb
diff --git a/meta/recipes-devtools/gcc/libgfortran_13.3.bb b/meta/recipes-devtools/gcc/libgfortran_13.4.bb
index 71dd8b4bdc..71dd8b4bdc 100644
--- a/meta/recipes-devtools/gcc/libgfortran_13.3.bb
+++ b/meta/recipes-devtools/gcc/libgfortran_13.4.bb