Compare commits
No commits in common. "c8" and "c9-beta" have entirely different histories.
@ -1,3 +1,4 @@
|
||||
b7245af5eab1d4055b6590b6e4f5fb3b7f6c24bf SOURCES/gcc-8.5.0-20210514.tar.xz
|
||||
3bdb3cc01fa7690a0e20ea5cfffcbe690f7665eb SOURCES/nvptx-newlib-aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24.tar.xz
|
||||
ce8eb83be0ac37fb5d5388df455a980fe37b4f13 SOURCES/nvptx-tools-c28050f60193b3b95a18866a96f03334e874e78f.tar.xz
|
||||
fdeaf702eb50579d38faf7dc2aadbf5e27a2c432 SOURCES/gcc-11.5.0-20240719.tar.xz
|
||||
bbffc5a2b05e4f0c97e882f96c448504491dc4ed SOURCES/isl-0.18.tar.bz2
|
||||
6ec33952e824e837fef0e829c93d39d6a507082f SOURCES/newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz
|
||||
0e0c6f8d68ab0878f02287ac082c1077c831cd81 SOURCES/nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
SOURCES/gcc-8.5.0-20210514.tar.xz
|
||||
SOURCES/nvptx-newlib-aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24.tar.xz
|
||||
SOURCES/nvptx-tools-c28050f60193b3b95a18866a96f03334e874e78f.tar.xz
|
||||
SOURCES/gcc-11.5.0-20240719.tar.xz
|
||||
SOURCES/isl-0.18.tar.bz2
|
||||
SOURCES/newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz
|
||||
SOURCES/nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz
|
||||
|
||||
63
SOURCES/gcc-RHEL-105072-1.patch
Normal file
63
SOURCES/gcc-RHEL-105072-1.patch
Normal file
@ -0,0 +1,63 @@
|
||||
commit 90986c5f0aa61cd22a9132486304ba5d12aae6c4
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 22 13:30:23 2021 +0100
|
||||
|
||||
libgcc: Remove tbase member from struct unw_eh_callback_data
|
||||
|
||||
It is always a null pointer.
|
||||
|
||||
libgcc/ChangeLog
|
||||
|
||||
* unwind-dw2-fde-dip.c (struct unw_eh_callback_data): Remove
|
||||
tbase member.
|
||||
(base_from_cb_data): Adjust.
|
||||
(_Unwind_IteratePhdrCallback): Likewise.
|
||||
(_Unwind_Find_FDE): Likewise.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index 5095b6830bf79e2e..4a4d990f455e5c11 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -104,7 +104,6 @@ static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases
|
||||
struct unw_eh_callback_data
|
||||
{
|
||||
_Unwind_Ptr pc;
|
||||
- void *tbase;
|
||||
void *dbase;
|
||||
void *func;
|
||||
const fde *ret;
|
||||
@@ -154,7 +153,7 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
|
||||
return 0;
|
||||
|
||||
case DW_EH_PE_textrel:
|
||||
- return (_Unwind_Ptr) data->tbase;
|
||||
+ return 0;
|
||||
case DW_EH_PE_datarel:
|
||||
return (_Unwind_Ptr) data->dbase;
|
||||
default:
|
||||
@@ -431,7 +430,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
As soon as GLIBC will provide API so to notify that a library has been
|
||||
removed, we could cache this (and thus use search_object). */
|
||||
ob.pc_begin = NULL;
|
||||
- ob.tbase = data->tbase;
|
||||
+ ob.tbase = NULL;
|
||||
ob.dbase = data->dbase;
|
||||
ob.u.single = (fde *) eh_frame;
|
||||
ob.s.i = 0;
|
||||
@@ -461,7 +460,6 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
return ret;
|
||||
|
||||
data.pc = (_Unwind_Ptr) pc;
|
||||
- data.tbase = NULL;
|
||||
data.dbase = NULL;
|
||||
data.func = NULL;
|
||||
data.ret = NULL;
|
||||
@@ -472,7 +470,7 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
|
||||
if (data.ret)
|
||||
{
|
||||
- bases->tbase = data.tbase;
|
||||
+ bases->tbase = NULL;
|
||||
bases->dbase = data.dbase;
|
||||
bases->func = data.func;
|
||||
}
|
||||
51
SOURCES/gcc-RHEL-105072-10.patch
Normal file
51
SOURCES/gcc-RHEL-105072-10.patch
Normal file
@ -0,0 +1,51 @@
|
||||
commit 94ccaf62c378c3737f7e4b6a80e1160157119171
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Mon Sep 19 18:10:02 2022 +0200
|
||||
|
||||
Avoid depending on destructor order
|
||||
|
||||
In some scenarios (e.g., when mixing gcc and clang code), it can
|
||||
happen that frames are deregistered after the lookup structure
|
||||
has already been destroyed. That in itself would be fine, but
|
||||
it triggers an assert in __deregister_frame_info_bases that
|
||||
expects to find the frame.
|
||||
|
||||
To avoid that, we now remember that the btree as already been
|
||||
destroyed and disable the assert in that case.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
* unwind-dw2-fde.c: (release_register_frames) Remember
|
||||
when the btree has been destroyed.
|
||||
(__deregister_frame_info_bases) Disable the assert when
|
||||
shutting down.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index f38efd3c09efc3e9..b0d07ccd53b30f4c 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -48,6 +48,7 @@ typedef __UINTPTR_TYPE__ uintptr_type;
|
||||
#include "unwind-dw2-btree.h"
|
||||
|
||||
static struct btree registered_frames;
|
||||
+static bool in_shutdown;
|
||||
|
||||
static void
|
||||
release_registered_frames (void) __attribute__ ((destructor (110)));
|
||||
@@ -57,6 +58,7 @@ release_registered_frames (void)
|
||||
/* Release the b-tree and all frames. Frame releases that happen later are
|
||||
* silently ignored */
|
||||
btree_destroy (®istered_frames);
|
||||
+ in_shutdown = true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -282,7 +284,7 @@ __deregister_frame_info_bases (const void *begin)
|
||||
__gthread_mutex_unlock (&object_mutex);
|
||||
#endif
|
||||
|
||||
- gcc_assert (ob);
|
||||
+ gcc_assert (in_shutdown || ob);
|
||||
return (void *) ob;
|
||||
}
|
||||
|
||||
42
SOURCES/gcc-RHEL-105072-11.patch
Normal file
42
SOURCES/gcc-RHEL-105072-11.patch
Normal file
@ -0,0 +1,42 @@
|
||||
commit 386ebf75f4c0342b1f823f4e4aba07abda3288d1
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Fri Sep 23 15:57:13 2022 +0200
|
||||
|
||||
fix assert in __deregister_frame_info_bases
|
||||
|
||||
When using the atomic fast path deregistering can fail during
|
||||
program shutdown if the lookup structures are already destroyed.
|
||||
The assert in __deregister_frame_info_bases takes that into
|
||||
account. In the non-fast-path case however is not aware of
|
||||
program shutdown, which caused a compiler error on such platforms.
|
||||
We fix that by introducing a constant for in_shutdown in
|
||||
non-fast-path builds.
|
||||
We also drop the destructor priority, as it is not supported on
|
||||
all platforms and we no longer rely upon the priority anyway.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
* unwind-dw2-fde.c: Introduce a constant for in_shutdown
|
||||
for the non-fast-path case. Drop destructor priority.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index b0d07ccd53b30f4c..27fea89dc314ccd0 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -51,7 +51,7 @@ static struct btree registered_frames;
|
||||
static bool in_shutdown;
|
||||
|
||||
static void
|
||||
-release_registered_frames (void) __attribute__ ((destructor (110)));
|
||||
+release_registered_frames (void) __attribute__ ((destructor));
|
||||
static void
|
||||
release_registered_frames (void)
|
||||
{
|
||||
@@ -67,6 +67,8 @@ static void
|
||||
init_object (struct object *ob);
|
||||
|
||||
#else
|
||||
+/* Without fast path frame deregistration must always succeed. */
|
||||
+static const int in_shutdown = 0;
|
||||
|
||||
/* The unseen_objects list contains objects that have been registered
|
||||
but not yet categorized in any way. The seen_objects list has had
|
||||
1811
SOURCES/gcc-RHEL-105072-12.patch
Normal file
1811
SOURCES/gcc-RHEL-105072-12.patch
Normal file
File diff suppressed because it is too large
Load Diff
48
SOURCES/gcc-RHEL-105072-13.patch
Normal file
48
SOURCES/gcc-RHEL-105072-13.patch
Normal file
@ -0,0 +1,48 @@
|
||||
commit acdb24166d13d87c374e578d2ad5d58249171930
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Oct 17 11:09:17 2022 +0200
|
||||
|
||||
libgcc: Move cfa_how into potential padding in struct frame_state_reg_info
|
||||
|
||||
On many architectures, there is a padding gap after the how array
|
||||
member, and cfa_how can be moved there. This reduces the size of the
|
||||
struct and the amount of memory that uw_frame_state_for has to clear.
|
||||
|
||||
There is no measurable performance benefit from this on x86-64 (even
|
||||
though the memset goes from 120 to 112 bytes), but it seems to be a
|
||||
good idea to do anyway.
|
||||
|
||||
libgcc/
|
||||
|
||||
* unwind-dw2.h (struct frame_state_reg_info): Move cfa_how member
|
||||
and reduce its size.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2.h b/libgcc/unwind-dw2.h
|
||||
index 22241b1f0d14cffc..437c785efa4f297d 100644
|
||||
--- a/libgcc/unwind-dw2.h
|
||||
+++ b/libgcc/unwind-dw2.h
|
||||
@@ -50,6 +50,12 @@ typedef struct
|
||||
} reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
|
||||
unsigned char how[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
|
||||
|
||||
+ enum {
|
||||
+ CFA_UNSET,
|
||||
+ CFA_REG_OFFSET,
|
||||
+ CFA_EXP
|
||||
+ } cfa_how : 8;
|
||||
+
|
||||
/* Used to implement DW_CFA_remember_state. */
|
||||
struct frame_state_reg_info *prev;
|
||||
|
||||
@@ -58,11 +64,6 @@ typedef struct
|
||||
_Unwind_Sword cfa_offset;
|
||||
_Unwind_Word cfa_reg;
|
||||
const unsigned char *cfa_exp;
|
||||
- enum {
|
||||
- CFA_UNSET,
|
||||
- CFA_REG_OFFSET,
|
||||
- CFA_EXP
|
||||
- } cfa_how;
|
||||
} regs;
|
||||
|
||||
/* The PC described by the current frame state. */
|
||||
99
SOURCES/gcc-RHEL-105072-14.patch
Normal file
99
SOURCES/gcc-RHEL-105072-14.patch
Normal file
@ -0,0 +1,99 @@
|
||||
commit e724b0480bfa5ec04f39be8c7290330b495c59de
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Nov 4 10:18:03 2022 +0100
|
||||
|
||||
libgcc: Special-case BFD ld unwind table encodings in find_fde_tail
|
||||
|
||||
BFD ld (and the other linkers) only produce one encoding of these
|
||||
values. It is not necessary to use the general
|
||||
read_encoded_value_with_base decoding routine. This avoids the
|
||||
data-dependent branches in its implementation.
|
||||
|
||||
libgcc/
|
||||
|
||||
* unwind-dw2-fde-dip.c (find_fde_tail): Special-case encoding
|
||||
values actually used by BFD ld.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index 25f2e44c5823cf64..d4821d7d19950f15 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -396,10 +396,21 @@ find_fde_tail (_Unwind_Ptr pc,
|
||||
if (hdr->version != 1)
|
||||
return NULL;
|
||||
|
||||
- p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
- base_from_cb_data (hdr->eh_frame_ptr_enc,
|
||||
- dbase),
|
||||
- p, &eh_frame);
|
||||
+ if (__builtin_expect (hdr->eh_frame_ptr_enc == (DW_EH_PE_sdata4
|
||||
+ | DW_EH_PE_pcrel), 1))
|
||||
+ {
|
||||
+ /* Specialized version of read_encoded_value_with_base, based on what
|
||||
+ BFD ld generates. */
|
||||
+ signed value __attribute__ ((mode (SI)));
|
||||
+ memcpy (&value, p, sizeof (value));
|
||||
+ p += sizeof (value);
|
||||
+ dbase = value; /* No adjustment because pcrel has base 0. */
|
||||
+ }
|
||||
+ else
|
||||
+ p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
+ base_from_cb_data (hdr->eh_frame_ptr_enc,
|
||||
+ dbase),
|
||||
+ p, &eh_frame);
|
||||
|
||||
/* We require here specific table encoding to speed things up.
|
||||
Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
|
||||
@@ -409,10 +420,20 @@ find_fde_tail (_Unwind_Ptr pc,
|
||||
{
|
||||
_Unwind_Ptr fde_count;
|
||||
|
||||
- p = read_encoded_value_with_base (hdr->fde_count_enc,
|
||||
- base_from_cb_data (hdr->fde_count_enc,
|
||||
- dbase),
|
||||
- p, &fde_count);
|
||||
+ if (__builtin_expect (hdr->fde_count_enc == DW_EH_PE_udata4, 1))
|
||||
+ {
|
||||
+ /* Specialized version of read_encoded_value_with_base, based on
|
||||
+ what BFD ld generates. */
|
||||
+ unsigned value __attribute__ ((mode (SI)));
|
||||
+ memcpy (&value, p, sizeof (value));
|
||||
+ p += sizeof (value);
|
||||
+ fde_count = value;
|
||||
+ }
|
||||
+ else
|
||||
+ p = read_encoded_value_with_base (hdr->fde_count_enc,
|
||||
+ base_from_cb_data (hdr->fde_count_enc,
|
||||
+ dbase),
|
||||
+ p, &fde_count);
|
||||
/* Shouldn't happen. */
|
||||
if (fde_count == 0)
|
||||
return NULL;
|
||||
@@ -454,8 +475,25 @@ find_fde_tail (_Unwind_Ptr pc,
|
||||
f = (fde *) (table[mid].fde + data_base);
|
||||
f_enc = get_fde_encoding (f);
|
||||
f_enc_size = size_of_encoded_value (f_enc);
|
||||
- read_encoded_value_with_base (f_enc & 0x0f, 0,
|
||||
- &f->pc_begin[f_enc_size], &range);
|
||||
+
|
||||
+ /* BFD ld uses DW_EH_PE_sdata4 | DW_EH_PE_pcrel on non-FDPIC targets,
|
||||
+ so optimize for that.
|
||||
+
|
||||
+ This optimization is not valid for FDPIC targets. f_enc & 0x0f as
|
||||
+ passed to read_encoded_value_with_base masks away the base flags,
|
||||
+ but they are implicit for FDPIC. */
|
||||
+#ifndef __FDPIC__
|
||||
+ if (__builtin_expect (f_enc == (DW_EH_PE_sdata4 | DW_EH_PE_pcrel),
|
||||
+ 1))
|
||||
+ {
|
||||
+ signed value __attribute__ ((mode (SI)));
|
||||
+ memcpy (&value, &f->pc_begin[f_enc_size], sizeof (value));
|
||||
+ range = value;
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ read_encoded_value_with_base (f_enc & 0x0f, 0,
|
||||
+ &f->pc_begin[f_enc_size], &range);
|
||||
_Unwind_Ptr func = table[mid].initial_loc + data_base;
|
||||
if (pc < table[mid].initial_loc + data_base + range)
|
||||
{
|
||||
337
SOURCES/gcc-RHEL-105072-15.patch
Normal file
337
SOURCES/gcc-RHEL-105072-15.patch
Normal file
@ -0,0 +1,337 @@
|
||||
commit 1c118c9970600117700cc12284587e0238de6bbe
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Tue Nov 22 08:41:54 2022 +0100
|
||||
|
||||
speed up end_fde_sort using radix sort
|
||||
|
||||
When registering a dynamic unwinding frame the fde list is sorted.
|
||||
Previously, we split the list into a sorted and an unsorted part,
|
||||
sorted the later using heap sort, and merged both. That can be
|
||||
quite slow due to the large number of (expensive) comparisons.
|
||||
|
||||
This patch replaces that logic with a radix sort instead. The
|
||||
radix sort uses the same amount of memory as the old logic,
|
||||
using the second list as auxiliary space, and it includes two
|
||||
techniques to speed up sorting: First, it computes the pointer
|
||||
addresses for blocks of values, reducing the decoding overhead.
|
||||
And it recognizes when the data has reached a sorted state,
|
||||
allowing for early termination. When running out of memory
|
||||
we fall back to pure heap sort, as before.
|
||||
|
||||
For this test program
|
||||
|
||||
\#include <cstdio>
|
||||
int main(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
compiled with g++ -O -o hello -static hello.c we get with
|
||||
perf stat -r 200 on a 5950X the following performance numbers:
|
||||
|
||||
old logic:
|
||||
|
||||
0,20 msec task-clock
|
||||
930.834 cycles
|
||||
3.079.765 instructions
|
||||
0,00030478 +- 0,00000237 seconds time elapsed
|
||||
|
||||
new logic:
|
||||
|
||||
0,10 msec task-clock
|
||||
473.269 cycles
|
||||
1.239.077 instructions
|
||||
0,00021119 +- 0,00000168 seconds time elapsed
|
||||
|
||||
libgcc/ChangeLog:
|
||||
* unwind-dw2-fde.c: Use radix sort instead of split+sort+merge.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index 27fea89dc314ccd0..a0d9bfb9f7d34ec1 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -456,22 +456,52 @@ fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
|
||||
|
||||
typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
|
||||
|
||||
+// The extractor functions compute the pointer values for a block of
|
||||
+// fdes. The block processing hides the call overhead.
|
||||
|
||||
-/* This is a special mix of insertion sort and heap sort, optimized for
|
||||
- the data sets that actually occur. They look like
|
||||
- 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130.
|
||||
- I.e. a linearly increasing sequence (coming from functions in the text
|
||||
- section), with additionally a few unordered elements (coming from functions
|
||||
- in gnu_linkonce sections) whose values are higher than the values in the
|
||||
- surrounding linear sequence (but not necessarily higher than the values
|
||||
- at the end of the linear sequence!).
|
||||
- The worst-case total run time is O(N) + O(n log (n)), where N is the
|
||||
- total number of FDEs and n is the number of erratic ones. */
|
||||
+static void
|
||||
+fde_unencoded_extract (struct object *ob __attribute__ ((unused)),
|
||||
+ _Unwind_Ptr *target, const fde **x, int count)
|
||||
+{
|
||||
+ for (int index = 0; index < count; ++index)
|
||||
+ memcpy (target + index, x[index]->pc_begin, sizeof (_Unwind_Ptr));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+fde_single_encoding_extract (struct object *ob, _Unwind_Ptr *target,
|
||||
+ const fde **x, int count)
|
||||
+{
|
||||
+ _Unwind_Ptr base;
|
||||
+
|
||||
+ base = base_from_object (ob->s.b.encoding, ob);
|
||||
+ for (int index = 0; index < count; ++index)
|
||||
+ read_encoded_value_with_base (ob->s.b.encoding, base, x[index]->pc_begin,
|
||||
+ target + index);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+fde_mixed_encoding_extract (struct object *ob, _Unwind_Ptr *target,
|
||||
+ const fde **x, int count)
|
||||
+{
|
||||
+ for (int index = 0; index < count; ++index)
|
||||
+ {
|
||||
+ int encoding = get_fde_encoding (x[index]);
|
||||
+ read_encoded_value_with_base (encoding, base_from_object (encoding, ob),
|
||||
+ x[index]->pc_begin, target + index);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+typedef void (*fde_extractor_t) (struct object *, _Unwind_Ptr *, const fde **,
|
||||
+ int);
|
||||
+
|
||||
+// Data is is sorted using radix sort if possible, using an temporary
|
||||
+// auxiliary data structure of the same size as the input. When running
|
||||
+// out of memory do in-place heap sort.
|
||||
|
||||
struct fde_accumulator
|
||||
{
|
||||
struct fde_vector *linear;
|
||||
- struct fde_vector *erratic;
|
||||
+ struct fde_vector *aux;
|
||||
};
|
||||
|
||||
static inline int
|
||||
@@ -485,8 +515,8 @@ start_fde_sort (struct fde_accumulator *accu, size_t count)
|
||||
if ((accu->linear = malloc (size)))
|
||||
{
|
||||
accu->linear->count = 0;
|
||||
- if ((accu->erratic = malloc (size)))
|
||||
- accu->erratic->count = 0;
|
||||
+ if ((accu->aux = malloc (size)))
|
||||
+ accu->aux->count = 0;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@@ -500,59 +530,6 @@ fde_insert (struct fde_accumulator *accu, const fde *this_fde)
|
||||
accu->linear->array[accu->linear->count++] = this_fde;
|
||||
}
|
||||
|
||||
-/* Split LINEAR into a linear sequence with low values and an erratic
|
||||
- sequence with high values, put the linear one (of longest possible
|
||||
- length) into LINEAR and the erratic one into ERRATIC. This is O(N).
|
||||
-
|
||||
- Because the longest linear sequence we are trying to locate within the
|
||||
- incoming LINEAR array can be interspersed with (high valued) erratic
|
||||
- entries. We construct a chain indicating the sequenced entries.
|
||||
- To avoid having to allocate this chain, we overlay it onto the space of
|
||||
- the ERRATIC array during construction. A final pass iterates over the
|
||||
- chain to determine what should be placed in the ERRATIC array, and
|
||||
- what is the linear sequence. This overlay is safe from aliasing. */
|
||||
-
|
||||
-static inline void
|
||||
-fde_split (struct object *ob, fde_compare_t fde_compare,
|
||||
- struct fde_vector *linear, struct fde_vector *erratic)
|
||||
-{
|
||||
- static const fde *marker;
|
||||
- size_t count = linear->count;
|
||||
- const fde *const *chain_end = ▮
|
||||
- size_t i, j, k;
|
||||
-
|
||||
- /* This should optimize out, but it is wise to make sure this assumption
|
||||
- is correct. Should these have different sizes, we cannot cast between
|
||||
- them and the overlaying onto ERRATIC will not work. */
|
||||
- gcc_assert (sizeof (const fde *) == sizeof (const fde **));
|
||||
-
|
||||
- for (i = 0; i < count; i++)
|
||||
- {
|
||||
- const fde *const *probe;
|
||||
-
|
||||
- for (probe = chain_end;
|
||||
- probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
|
||||
- probe = chain_end)
|
||||
- {
|
||||
- chain_end = (const fde *const*) erratic->array[probe - linear->array];
|
||||
- erratic->array[probe - linear->array] = NULL;
|
||||
- }
|
||||
- erratic->array[i] = (const fde *) chain_end;
|
||||
- chain_end = &linear->array[i];
|
||||
- }
|
||||
-
|
||||
- /* Each entry in LINEAR which is part of the linear sequence we have
|
||||
- discovered will correspond to a non-NULL entry in the chain we built in
|
||||
- the ERRATIC array. */
|
||||
- for (i = j = k = 0; i < count; i++)
|
||||
- if (erratic->array[i])
|
||||
- linear->array[j++] = linear->array[i];
|
||||
- else
|
||||
- erratic->array[k++] = linear->array[i];
|
||||
- linear->count = j;
|
||||
- erratic->count = k;
|
||||
-}
|
||||
-
|
||||
#define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
|
||||
|
||||
/* Convert a semi-heap to a heap. A semi-heap is a heap except possibly
|
||||
@@ -615,59 +592,116 @@ frame_heapsort (struct object *ob, fde_compare_t fde_compare,
|
||||
#undef SWAP
|
||||
}
|
||||
|
||||
-/* Merge V1 and V2, both sorted, and put the result into V1. */
|
||||
+// Radix sort data in V1 using V2 as aux memory. Runtime O(n).
|
||||
static inline void
|
||||
-fde_merge (struct object *ob, fde_compare_t fde_compare,
|
||||
- struct fde_vector *v1, struct fde_vector *v2)
|
||||
+fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
|
||||
+ struct fde_vector *v1, struct fde_vector *v2)
|
||||
{
|
||||
- size_t i1, i2;
|
||||
- const fde * fde2;
|
||||
-
|
||||
- i2 = v2->count;
|
||||
- if (i2 > 0)
|
||||
+#define FANOUTBITS 8
|
||||
+#define FANOUT (1 << FANOUTBITS)
|
||||
+#define BLOCKSIZE 128
|
||||
+ const unsigned rounds
|
||||
+ = (__CHAR_BIT__ * sizeof (_Unwind_Ptr) + FANOUTBITS - 1) / FANOUTBITS;
|
||||
+ const fde **a1 = v1->array, **a2 = v2->array;
|
||||
+ _Unwind_Ptr ptrs[BLOCKSIZE + 1];
|
||||
+ unsigned n = v1->count;
|
||||
+ for (unsigned round = 0; round != rounds; ++round)
|
||||
{
|
||||
- i1 = v1->count;
|
||||
- do
|
||||
+ unsigned counts[FANOUT] = {0};
|
||||
+ unsigned violations = 0;
|
||||
+
|
||||
+ // Count the number of elements per bucket and check if we are already
|
||||
+ // sorted.
|
||||
+ _Unwind_Ptr last = 0;
|
||||
+ for (unsigned i = 0; i < n;)
|
||||
+ {
|
||||
+ unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
|
||||
+ fde_extractor (ob, ptrs + 1, a1 + i, chunk);
|
||||
+ ptrs[0] = last;
|
||||
+ for (unsigned j = 0; j < chunk; ++j)
|
||||
+ {
|
||||
+ unsigned b = (ptrs[j + 1] >> (round * FANOUTBITS)) & (FANOUT - 1);
|
||||
+ counts[b]++;
|
||||
+ // Use summation instead of an if to eliminate branches.
|
||||
+ violations += ptrs[j + 1] < ptrs[j];
|
||||
+ }
|
||||
+ i += chunk;
|
||||
+ last = ptrs[chunk];
|
||||
+ }
|
||||
+
|
||||
+ // Stop if we are already sorted.
|
||||
+ if (!violations)
|
||||
+ {
|
||||
+ // The sorted data is in a1 now.
|
||||
+ a2 = a1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ // Compute the prefix sum.
|
||||
+ unsigned sum = 0;
|
||||
+ for (unsigned i = 0; i != FANOUT; ++i)
|
||||
+ {
|
||||
+ unsigned s = sum;
|
||||
+ sum += counts[i];
|
||||
+ counts[i] = s;
|
||||
+ }
|
||||
+
|
||||
+ // Place all elements.
|
||||
+ for (unsigned i = 0; i < n;)
|
||||
{
|
||||
- i2--;
|
||||
- fde2 = v2->array[i2];
|
||||
- while (i1 > 0 && fde_compare (ob, v1->array[i1-1], fde2) > 0)
|
||||
+ unsigned chunk = ((n - i) <= BLOCKSIZE) ? (n - i) : BLOCKSIZE;
|
||||
+ fde_extractor (ob, ptrs, a1 + i, chunk);
|
||||
+ for (unsigned j = 0; j < chunk; ++j)
|
||||
{
|
||||
- v1->array[i1+i2] = v1->array[i1-1];
|
||||
- i1--;
|
||||
+ unsigned b = (ptrs[j] >> (round * FANOUTBITS)) & (FANOUT - 1);
|
||||
+ a2[counts[b]++] = a1[i + j];
|
||||
}
|
||||
- v1->array[i1+i2] = fde2;
|
||||
+ i += chunk;
|
||||
}
|
||||
- while (i2 > 0);
|
||||
- v1->count += v2->count;
|
||||
+
|
||||
+ // Swap a1 and a2.
|
||||
+ const fde **tmp = a1;
|
||||
+ a1 = a2;
|
||||
+ a2 = tmp;
|
||||
}
|
||||
+#undef BLOCKSIZE
|
||||
+#undef FANOUT
|
||||
+#undef FANOUTBITS
|
||||
+
|
||||
+ // The data is in a2 now, move in place if needed.
|
||||
+ if (a2 != v1->array)
|
||||
+ memcpy (v1->array, a2, sizeof (const fde *) * n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
|
||||
{
|
||||
- fde_compare_t fde_compare;
|
||||
-
|
||||
gcc_assert (!accu->linear || accu->linear->count == count);
|
||||
|
||||
- if (ob->s.b.mixed_encoding)
|
||||
- fde_compare = fde_mixed_encoding_compare;
|
||||
- else if (ob->s.b.encoding == DW_EH_PE_absptr)
|
||||
- fde_compare = fde_unencoded_compare;
|
||||
- else
|
||||
- fde_compare = fde_single_encoding_compare;
|
||||
-
|
||||
- if (accu->erratic)
|
||||
+ if (accu->aux)
|
||||
{
|
||||
- fde_split (ob, fde_compare, accu->linear, accu->erratic);
|
||||
- gcc_assert (accu->linear->count + accu->erratic->count == count);
|
||||
- frame_heapsort (ob, fde_compare, accu->erratic);
|
||||
- fde_merge (ob, fde_compare, accu->linear, accu->erratic);
|
||||
- free (accu->erratic);
|
||||
+ fde_extractor_t fde_extractor;
|
||||
+ if (ob->s.b.mixed_encoding)
|
||||
+ fde_extractor = fde_mixed_encoding_extract;
|
||||
+ else if (ob->s.b.encoding == DW_EH_PE_absptr)
|
||||
+ fde_extractor = fde_unencoded_extract;
|
||||
+ else
|
||||
+ fde_extractor = fde_single_encoding_extract;
|
||||
+
|
||||
+ fde_radixsort (ob, fde_extractor, accu->linear, accu->aux);
|
||||
+ free (accu->aux);
|
||||
}
|
||||
else
|
||||
{
|
||||
- /* We've not managed to malloc an erratic array,
|
||||
+ fde_compare_t fde_compare;
|
||||
+ if (ob->s.b.mixed_encoding)
|
||||
+ fde_compare = fde_mixed_encoding_compare;
|
||||
+ else if (ob->s.b.encoding == DW_EH_PE_absptr)
|
||||
+ fde_compare = fde_unencoded_compare;
|
||||
+ else
|
||||
+ fde_compare = fde_single_encoding_compare;
|
||||
+
|
||||
+ /* We've not managed to malloc an aux array,
|
||||
so heap sort in the linear one. */
|
||||
frame_heapsort (ob, fde_compare, accu->linear);
|
||||
}
|
||||
143
SOURCES/gcc-RHEL-105072-16.patch
Normal file
143
SOURCES/gcc-RHEL-105072-16.patch
Normal file
@ -0,0 +1,143 @@
|
||||
commit 6e56633daae79f514b0e71f4d9849bcd8d9ce71f
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Fri Dec 9 18:23:44 2022 +0100
|
||||
|
||||
initialize fde objects lazily
|
||||
|
||||
When registering an unwind frame with __register_frame_info_bases
|
||||
we currently initialize that fde object eagerly. This has the
|
||||
advantage that it is immutable afterwards and we can safely
|
||||
access it from multiple threads, but it has the disadvantage
|
||||
that we pay the initialization cost even if the application
|
||||
never throws an exception.
|
||||
|
||||
This commit changes the logic to initialize the objects lazily.
|
||||
The objects themselves are inserted into the b-tree when
|
||||
registering the frame, but the sorted fde_vector is
|
||||
not constructed yet. Only on the first time that an
|
||||
exception tries to pass through the registered code the
|
||||
object is initialized. We notice that with a double checking,
|
||||
first doing a relaxed load of the sorted bit and then re-checking
|
||||
under a mutex when the object was not initialized yet.
|
||||
|
||||
Note that the check must implicitly be safe concering a concurrent
|
||||
frame deregistration, as trying the deregister a frame that is
|
||||
on the unwinding path of a concurrent exception is inherently racy.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
* unwind-dw2-fde.c: Initialize fde object lazily when
|
||||
the first exception tries to pass through.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index a0d9bfb9f7d34ec1..efcf9490469ad1a0 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -63,8 +63,6 @@ release_registered_frames (void)
|
||||
|
||||
static void
|
||||
get_pc_range (const struct object *ob, uintptr_type *range);
|
||||
-static void
|
||||
-init_object (struct object *ob);
|
||||
|
||||
#else
|
||||
/* Without fast path frame deregistration must always succeed. */
|
||||
@@ -76,6 +74,7 @@ static const int in_shutdown = 0;
|
||||
by decreasing value of pc_begin. */
|
||||
static struct object *unseen_objects;
|
||||
static struct object *seen_objects;
|
||||
+#endif
|
||||
|
||||
#ifdef __GTHREAD_MUTEX_INIT
|
||||
static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
|
||||
@@ -103,7 +102,6 @@ init_object_mutex_once (void)
|
||||
static __gthread_mutex_t object_mutex;
|
||||
#endif
|
||||
#endif
|
||||
-#endif
|
||||
|
||||
/* Called from crtbegin.o to register the unwind info for an object. */
|
||||
|
||||
@@ -126,10 +124,7 @@ __register_frame_info_bases (const void *begin, struct object *ob,
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- // Initialize eagerly to avoid locking later
|
||||
- init_object (ob);
|
||||
-
|
||||
- // And register the frame
|
||||
+ // Register the frame in the b-tree
|
||||
uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
@@ -180,10 +175,7 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
|
||||
ob->s.b.encoding = DW_EH_PE_omit;
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- // Initialize eagerly to avoid locking later
|
||||
- init_object (ob);
|
||||
-
|
||||
- // And register the frame
|
||||
+ // Register the frame in the b-tree
|
||||
uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
@@ -926,7 +918,15 @@ init_object (struct object* ob)
|
||||
accu.linear->orig_data = ob->u.single;
|
||||
ob->u.sort = accu.linear;
|
||||
|
||||
+#ifdef ATOMIC_FDE_FAST_PATH
|
||||
+ // We must update the sorted bit with an atomic operation
|
||||
+ struct object tmp;
|
||||
+ tmp.s.b = ob->s.b;
|
||||
+ tmp.s.b.sorted = 1;
|
||||
+ __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELEASE);
|
||||
+#else
|
||||
ob->s.b.sorted = 1;
|
||||
+#endif
|
||||
}
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
@@ -1164,6 +1164,21 @@ search_object (struct object* ob, void *pc)
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef ATOMIC_FDE_FAST_PATH
|
||||
+
|
||||
+// Check if the object was already initialized
|
||||
+static inline bool
|
||||
+is_object_initialized (struct object *ob)
|
||||
+{
|
||||
+ // We have to use acquire atomics for the read, which
|
||||
+ // is a bit involved as we read from a bitfield
|
||||
+ struct object tmp;
|
||||
+ __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_ACQUIRE);
|
||||
+ return tmp.s.b.sorted;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
const fde *
|
||||
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
{
|
||||
@@ -1175,6 +1190,21 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
if (!ob)
|
||||
return NULL;
|
||||
|
||||
+ // Initialize the object lazily
|
||||
+ if (!is_object_initialized (ob))
|
||||
+ {
|
||||
+ // Check again under mutex
|
||||
+ init_object_mutex_once ();
|
||||
+ __gthread_mutex_lock (&object_mutex);
|
||||
+
|
||||
+ if (!ob->s.b.sorted)
|
||||
+ {
|
||||
+ init_object (ob);
|
||||
+ }
|
||||
+
|
||||
+ __gthread_mutex_unlock (&object_mutex);
|
||||
+ }
|
||||
+
|
||||
f = search_object (ob, pc);
|
||||
#else
|
||||
|
||||
703
SOURCES/gcc-RHEL-105072-17.patch
Normal file
703
SOURCES/gcc-RHEL-105072-17.patch
Normal file
@ -0,0 +1,703 @@
|
||||
commit 8fdef16cd5d1b89359db3cd9a9768ab2d1b5081f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jan 3 16:47:32 2023 +0100
|
||||
|
||||
libgcc: Specialize execute_cfa_program in DWARF unwinder for alignments [redo]
|
||||
|
||||
The parameters fs->data_align and fs->code_align always have fixed
|
||||
values for a particular target in GCC-generated code. Specialize
|
||||
execute_cfa_program for these values, to avoid multiplications.
|
||||
|
||||
gcc/c-family/
|
||||
|
||||
* c-cppbuiltin.cc (c_cpp_builtins): Define
|
||||
__LIBGCC_DWARF_CIE_DATA_ALIGNMENT__.
|
||||
|
||||
libgcc/
|
||||
|
||||
* unwind-dw2-execute_cfa.h: New file. Extracted from
|
||||
the execute_cfa_program function in unwind-dw2.c.
|
||||
* unwind-dw2.c (execute_cfa_program_generic): New function.
|
||||
(execute_cfa_program_specialized): Likewise.
|
||||
(execute_cfa_program): Call execute_cfa_program_specialized
|
||||
or execute_cfa_program_generic, as appropriate.
|
||||
|
||||
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
|
||||
index 11e015bdb87b0f9b..a5369eb51b07f0ab 100644
|
||||
--- a/gcc/c-family/c-cppbuiltin.c
|
||||
+++ b/gcc/c-family/c-cppbuiltin.c
|
||||
@@ -1408,6 +1408,9 @@ c_cpp_builtins (cpp_reader *pfile)
|
||||
#endif
|
||||
builtin_define_with_int_value ("__LIBGCC_DWARF_FRAME_REGISTERS__",
|
||||
DWARF_FRAME_REGISTERS);
|
||||
+ builtin_define_with_int_value ("__LIBGCC_DWARF_CIE_DATA_ALIGNMENT__",
|
||||
+ DWARF_CIE_DATA_ALIGNMENT);
|
||||
+
|
||||
#ifdef EH_RETURN_STACKADJ_RTX
|
||||
cpp_define (pfile, "__LIBGCC_EH_RETURN_STACKADJ_RTX__");
|
||||
#endif
|
||||
diff --git a/libgcc/unwind-dw2-execute_cfa.h b/libgcc/unwind-dw2-execute_cfa.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..dd97b7866686a361
|
||||
--- /dev/null
|
||||
+++ b/libgcc/unwind-dw2-execute_cfa.h
|
||||
@@ -0,0 +1,322 @@
|
||||
+/* DWARF2 exception handling CFA execution engine.
|
||||
+ Copyright (C) 1997-2022 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is part of GCC.
|
||||
+
|
||||
+ GCC is free software; you can redistribute it and/or modify it
|
||||
+ under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3, or (at your option)
|
||||
+ any later version.
|
||||
+
|
||||
+ GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
+ License for more details.
|
||||
+
|
||||
+ Under Section 7 of GPL version 3, you are granted additional
|
||||
+ permissions described in the GCC Runtime Library Exception, version
|
||||
+ 3.1, as published by the Free Software Foundation.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License and
|
||||
+ a copy of the GCC Runtime Library Exception along with this program;
|
||||
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
+ <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This file is included from unwind-dw2.c to specialize the code for certain
|
||||
+ values of DATA_ALIGN and CODE_ALIGN. These macros must be defined prior to
|
||||
+ including this file. */
|
||||
+
|
||||
+{
|
||||
+ struct frame_state_reg_info *unused_rs = NULL;
|
||||
+
|
||||
+ /* Don't allow remember/restore between CIE and FDE programs. */
|
||||
+ fs->regs.prev = NULL;
|
||||
+
|
||||
+ /* The comparison with the return address uses < rather than <= because
|
||||
+ we are only interested in the effects of code before the call; for a
|
||||
+ noreturn function, the return address may point to unrelated code with
|
||||
+ a different stack configuration that we are not interested in. We
|
||||
+ assume that the call itself is unwind info-neutral; if not, or if
|
||||
+ there are delay instructions that adjust the stack, these must be
|
||||
+ reflected at the point immediately before the call insn.
|
||||
+ In signal frames, return address is after last completed instruction,
|
||||
+ so we add 1 to return address to make the comparison <=. */
|
||||
+ while (insn_ptr < insn_end
|
||||
+ && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
|
||||
+ {
|
||||
+ unsigned char insn = *insn_ptr++;
|
||||
+ _uleb128_t reg, utmp;
|
||||
+ _sleb128_t offset, stmp;
|
||||
+
|
||||
+ if ((insn & 0xc0) == DW_CFA_advance_loc)
|
||||
+ fs->pc += (insn & 0x3f) * CODE_ALIGN;
|
||||
+ else if ((insn & 0xc0) == DW_CFA_offset)
|
||||
+ {
|
||||
+ reg = insn & 0x3f;
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ offset = (_Unwind_Sword) utmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = offset;
|
||||
+ }
|
||||
+ }
|
||||
+ else if ((insn & 0xc0) == DW_CFA_restore)
|
||||
+ {
|
||||
+ reg = insn & 0x3f;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ fs->regs.how[reg] = REG_UNSAVED;
|
||||
+ }
|
||||
+ else switch (insn)
|
||||
+ {
|
||||
+ case DW_CFA_set_loc:
|
||||
+ {
|
||||
+ _Unwind_Ptr pc;
|
||||
+
|
||||
+ insn_ptr = read_encoded_value (context, fs->fde_encoding,
|
||||
+ insn_ptr, &pc);
|
||||
+ fs->pc = (void *) pc;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_advance_loc1:
|
||||
+ fs->pc += read_1u (insn_ptr) * CODE_ALIGN;
|
||||
+ insn_ptr += 1;
|
||||
+ break;
|
||||
+ case DW_CFA_advance_loc2:
|
||||
+ fs->pc += read_2u (insn_ptr) * CODE_ALIGN;
|
||||
+ insn_ptr += 2;
|
||||
+ break;
|
||||
+ case DW_CFA_advance_loc4:
|
||||
+ fs->pc += read_4u (insn_ptr) * CODE_ALIGN;
|
||||
+ insn_ptr += 4;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_offset_extended:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ offset = (_Unwind_Sword) utmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = offset;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_restore_extended:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ /* FIXME, this is wrong; the CIE might have said that the
|
||||
+ register was saved somewhere. */
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ fs->regs.how[reg] = REG_UNSAVED;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_same_value:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ fs->regs.how[reg] = REG_UNSAVED;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_undefined:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ fs->regs.how[reg] = REG_UNDEFINED;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_nop:
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_register:
|
||||
+ {
|
||||
+ _uleb128_t reg2;
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®2);
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_REG;
|
||||
+ fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_remember_state:
|
||||
+ {
|
||||
+ struct frame_state_reg_info *new_rs;
|
||||
+ if (unused_rs)
|
||||
+ {
|
||||
+ new_rs = unused_rs;
|
||||
+ unused_rs = unused_rs->prev;
|
||||
+ }
|
||||
+ else
|
||||
+ new_rs = alloca (sizeof (struct frame_state_reg_info));
|
||||
+
|
||||
+ *new_rs = fs->regs;
|
||||
+ fs->regs.prev = new_rs;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_restore_state:
|
||||
+ {
|
||||
+ struct frame_state_reg_info *old_rs = fs->regs.prev;
|
||||
+ fs->regs = *old_rs;
|
||||
+ old_rs->prev = unused_rs;
|
||||
+ unused_rs = old_rs;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ fs->regs.cfa_offset = (_Unwind_Word)utmp;
|
||||
+ fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_register:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
+ fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_offset:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ fs->regs.cfa_offset = utmp;
|
||||
+ /* cfa_how deliberately not set. */
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_expression:
|
||||
+ fs->regs.cfa_exp = insn_ptr;
|
||||
+ fs->regs.cfa_how = CFA_EXP;
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ insn_ptr += utmp;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_expression:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_EXP;
|
||||
+ fs->regs.reg[reg].loc.exp = insn_ptr;
|
||||
+ }
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ insn_ptr += utmp;
|
||||
+ break;
|
||||
+
|
||||
+ /* Dwarf3. */
|
||||
+ case DW_CFA_offset_extended_sf:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
+ offset = stmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = offset;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_sf:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
+ fs->regs.cfa_offset = (_Unwind_Sword)stmp;
|
||||
+ fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
+ fs->regs.cfa_offset *= DATA_ALIGN;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_def_cfa_offset_sf:
|
||||
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
+ fs->regs.cfa_offset = (_Unwind_Sword)stmp;
|
||||
+ fs->regs.cfa_offset *= DATA_ALIGN;
|
||||
+ /* cfa_how deliberately not set. */
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_val_offset:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ offset = (_Unwind_Sword) utmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = offset;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_val_offset_sf:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
+ offset = stmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = offset;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_val_expression:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_VAL_EXP;
|
||||
+ fs->regs.reg[reg].loc.exp = insn_ptr;
|
||||
+ }
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ insn_ptr += utmp;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_GNU_window_save:
|
||||
+#if defined (__aarch64__) && !defined (__ILP32__)
|
||||
+ /* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
|
||||
+ return address signing status. */
|
||||
+ reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
+ gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
|
||||
+ fs->regs.reg[reg].loc.offset ^= 1;
|
||||
+#else
|
||||
+ /* ??? Hardcoded for SPARC register window configuration. */
|
||||
+ if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
|
||||
+ for (reg = 16; reg < 32; ++reg)
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
|
||||
+ }
|
||||
+#endif
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_GNU_args_size:
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ context->args_size = (_Unwind_Word)utmp;
|
||||
+ break;
|
||||
+
|
||||
+ case DW_CFA_GNU_negative_offset_extended:
|
||||
+ /* Obsoleted by DW_CFA_offset_extended_sf, but used by
|
||||
+ older PowerPC code. */
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
+ insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
+ offset = (_Unwind_Word) utmp * DATA_ALIGN;
|
||||
+ reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
+ if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
+ {
|
||||
+ fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
+ fs->regs.reg[reg].loc.offset = -offset;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ gcc_unreachable ();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#undef DATA_ALIGN
|
||||
+#undef CODE_ALIGN
|
||||
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
|
||||
index daebcb8bf7d215fe..701552634c6e87c5 100644
|
||||
--- a/libgcc/unwind-dw2.c
|
||||
+++ b/libgcc/unwind-dw2.c
|
||||
@@ -947,302 +947,43 @@ execute_stack_op (const unsigned char *op_ptr, const unsigned char *op_end,
|
||||
instruction sequence to decode, current register information and
|
||||
CIE info, and the PC range to evaluate. */
|
||||
|
||||
+static void __attribute__ ((__noinline__))
|
||||
+execute_cfa_program_generic (const unsigned char *insn_ptr,
|
||||
+ const unsigned char *insn_end,
|
||||
+ struct _Unwind_Context *context,
|
||||
+ _Unwind_FrameState *fs)
|
||||
+{
|
||||
+#define DATA_ALIGN fs->data_align
|
||||
+#define CODE_ALIGN fs->code_align
|
||||
+#include "unwind-dw2-execute_cfa.h"
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+execute_cfa_program_specialized (const unsigned char *insn_ptr,
|
||||
+ const unsigned char *insn_end,
|
||||
+ struct _Unwind_Context *context,
|
||||
+ _Unwind_FrameState *fs)
|
||||
+{
|
||||
+#define DATA_ALIGN __LIBGCC_DWARF_CIE_DATA_ALIGNMENT__
|
||||
+ /* GCC always uses 1 even on architectures with a fixed instruction
|
||||
+ width. */
|
||||
+#define CODE_ALIGN 1
|
||||
+#include "unwind-dw2-execute_cfa.h"
|
||||
+}
|
||||
+
|
||||
static void
|
||||
execute_cfa_program (const unsigned char *insn_ptr,
|
||||
const unsigned char *insn_end,
|
||||
struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
- struct frame_state_reg_info *unused_rs = NULL;
|
||||
-
|
||||
- /* Don't allow remember/restore between CIE and FDE programs. */
|
||||
- fs->regs.prev = NULL;
|
||||
-
|
||||
- /* The comparison with the return address uses < rather than <= because
|
||||
- we are only interested in the effects of code before the call; for a
|
||||
- noreturn function, the return address may point to unrelated code with
|
||||
- a different stack configuration that we are not interested in. We
|
||||
- assume that the call itself is unwind info-neutral; if not, or if
|
||||
- there are delay instructions that adjust the stack, these must be
|
||||
- reflected at the point immediately before the call insn.
|
||||
- In signal frames, return address is after last completed instruction,
|
||||
- so we add 1 to return address to make the comparison <=. */
|
||||
- while (insn_ptr < insn_end
|
||||
- && fs->pc < context->ra + _Unwind_IsSignalFrame (context))
|
||||
- {
|
||||
- unsigned char insn = *insn_ptr++;
|
||||
- _uleb128_t reg, utmp;
|
||||
- _sleb128_t offset, stmp;
|
||||
-
|
||||
- if ((insn & 0xc0) == DW_CFA_advance_loc)
|
||||
- fs->pc += (insn & 0x3f) * fs->code_align;
|
||||
- else if ((insn & 0xc0) == DW_CFA_offset)
|
||||
- {
|
||||
- reg = insn & 0x3f;
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- offset = (_Unwind_Sword) utmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = offset;
|
||||
- }
|
||||
- }
|
||||
- else if ((insn & 0xc0) == DW_CFA_restore)
|
||||
- {
|
||||
- reg = insn & 0x3f;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- fs->regs.how[reg] = REG_UNSAVED;
|
||||
- }
|
||||
- else switch (insn)
|
||||
- {
|
||||
- case DW_CFA_set_loc:
|
||||
- {
|
||||
- _Unwind_Ptr pc;
|
||||
-
|
||||
- insn_ptr = read_encoded_value (context, fs->fde_encoding,
|
||||
- insn_ptr, &pc);
|
||||
- fs->pc = (void *) pc;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_advance_loc1:
|
||||
- fs->pc += read_1u (insn_ptr) * fs->code_align;
|
||||
- insn_ptr += 1;
|
||||
- break;
|
||||
- case DW_CFA_advance_loc2:
|
||||
- fs->pc += read_2u (insn_ptr) * fs->code_align;
|
||||
- insn_ptr += 2;
|
||||
- break;
|
||||
- case DW_CFA_advance_loc4:
|
||||
- fs->pc += read_4u (insn_ptr) * fs->code_align;
|
||||
- insn_ptr += 4;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_offset_extended:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- offset = (_Unwind_Sword) utmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = offset;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_restore_extended:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- /* FIXME, this is wrong; the CIE might have said that the
|
||||
- register was saved somewhere. */
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- fs->regs.how[reg] = REG_UNSAVED;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_same_value:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- fs->regs.how[reg] = REG_UNSAVED;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_undefined:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- fs->regs.how[reg] = REG_UNDEFINED;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_nop:
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_register:
|
||||
- {
|
||||
- _uleb128_t reg2;
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®2);
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_REG;
|
||||
- fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2;
|
||||
- }
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_remember_state:
|
||||
- {
|
||||
- struct frame_state_reg_info *new_rs;
|
||||
- if (unused_rs)
|
||||
- {
|
||||
- new_rs = unused_rs;
|
||||
- unused_rs = unused_rs->prev;
|
||||
- }
|
||||
- else
|
||||
- new_rs = alloca (sizeof (struct frame_state_reg_info));
|
||||
-
|
||||
- *new_rs = fs->regs;
|
||||
- fs->regs.prev = new_rs;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_restore_state:
|
||||
- {
|
||||
- struct frame_state_reg_info *old_rs = fs->regs.prev;
|
||||
- fs->regs = *old_rs;
|
||||
- old_rs->prev = unused_rs;
|
||||
- unused_rs = old_rs;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- fs->regs.cfa_offset = (_Unwind_Word)utmp;
|
||||
- fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_register:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
- fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_offset:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- fs->regs.cfa_offset = utmp;
|
||||
- /* cfa_how deliberately not set. */
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_expression:
|
||||
- fs->regs.cfa_exp = insn_ptr;
|
||||
- fs->regs.cfa_how = CFA_EXP;
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- insn_ptr += utmp;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_expression:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_EXP;
|
||||
- fs->regs.reg[reg].loc.exp = insn_ptr;
|
||||
- }
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- insn_ptr += utmp;
|
||||
- break;
|
||||
-
|
||||
- /* Dwarf3. */
|
||||
- case DW_CFA_offset_extended_sf:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
- offset = stmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = offset;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_sf:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- fs->regs.cfa_reg = (_Unwind_Word)utmp;
|
||||
- insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
- fs->regs.cfa_offset = (_Unwind_Sword)stmp;
|
||||
- fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||
- fs->regs.cfa_offset *= fs->data_align;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_def_cfa_offset_sf:
|
||||
- insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
- fs->regs.cfa_offset = (_Unwind_Sword)stmp;
|
||||
- fs->regs.cfa_offset *= fs->data_align;
|
||||
- /* cfa_how deliberately not set. */
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_val_offset:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- offset = (_Unwind_Sword) utmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = offset;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_val_offset_sf:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_sleb128 (insn_ptr, &stmp);
|
||||
- offset = stmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_VAL_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = offset;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_val_expression:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_VAL_EXP;
|
||||
- fs->regs.reg[reg].loc.exp = insn_ptr;
|
||||
- }
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- insn_ptr += utmp;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_GNU_window_save:
|
||||
-#if defined (__aarch64__) && !defined (__ILP32__)
|
||||
- /* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
|
||||
- return address signing status. */
|
||||
- reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
- gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
|
||||
- fs->regs.reg[reg].loc.offset ^= 1;
|
||||
-#else
|
||||
- /* ??? Hardcoded for SPARC register window configuration. */
|
||||
- if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
|
||||
- for (reg = 16; reg < 32; ++reg)
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);
|
||||
- }
|
||||
-#endif
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_GNU_args_size:
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- context->args_size = (_Unwind_Word)utmp;
|
||||
- break;
|
||||
-
|
||||
- case DW_CFA_GNU_negative_offset_extended:
|
||||
- /* Obsoleted by DW_CFA_offset_extended_sf, but used by
|
||||
- older PowerPC code. */
|
||||
- insn_ptr = read_uleb128 (insn_ptr, ®);
|
||||
- insn_ptr = read_uleb128 (insn_ptr, &utmp);
|
||||
- offset = (_Unwind_Word) utmp * fs->data_align;
|
||||
- reg = DWARF_REG_TO_UNWIND_COLUMN (reg);
|
||||
- if (UNWIND_COLUMN_IN_RANGE (reg))
|
||||
- {
|
||||
- fs->regs.how[reg] = REG_SAVED_OFFSET;
|
||||
- fs->regs.reg[reg].loc.offset = -offset;
|
||||
- }
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- gcc_unreachable ();
|
||||
- }
|
||||
- }
|
||||
+ if (fs->data_align == __LIBGCC_DWARF_CIE_DATA_ALIGNMENT__
|
||||
+ && fs->code_align == 1)
|
||||
+ execute_cfa_program_specialized (insn_ptr, insn_end, context, fs);
|
||||
+ else
|
||||
+ execute_cfa_program_generic (insn_ptr, insn_end, context, fs);
|
||||
}
|
||||
+
|
||||
|
||||
/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for
|
||||
its caller and decode it into FS. This function also sets the
|
||||
146
SOURCES/gcc-RHEL-105072-18.patch
Normal file
146
SOURCES/gcc-RHEL-105072-18.patch
Normal file
@ -0,0 +1,146 @@
|
||||
commit c98cd1df22fbe0829149e346a1ba9bf1f0be8a40
|
||||
Author: Wilco Dijkstra <wilco.dijkstra@arm.com>
|
||||
Date: Tue Jan 3 15:57:46 2023 +0000
|
||||
|
||||
libgcc: Fix uninitialized RA signing on AArch64 [PR107678]
|
||||
|
||||
A recent change only initializes the regs.how[] during Dwarf unwinding
|
||||
which resulted in an uninitialized offset used in return address signing
|
||||
and random failures during unwinding. The fix is to encode the return
|
||||
address signing state in REG_UNSAVED and a new state REG_UNSAVED_ARCHEXT.
|
||||
|
||||
libgcc/
|
||||
PR target/107678
|
||||
* unwind-dw2.h (REG_UNSAVED_ARCHEXT): Add new enum.
|
||||
* unwind-dw2.c (uw_update_context_1): Add REG_UNSAVED_ARCHEXT case.
|
||||
* unwind-dw2-execute_cfa.h: Use REG_UNSAVED_ARCHEXT/REG_UNSAVED to
|
||||
encode the return address signing state.
|
||||
* config/aarch64/aarch64-unwind.h (aarch64_demangle_return_addr)
|
||||
Check current return address signing state.
|
||||
(aarch64_frob_update_contex): Remove.
|
||||
|
||||
diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h
|
||||
index 466e4235991485ea..2fddadc57564348f 100644
|
||||
--- a/libgcc/config/aarch64/aarch64-unwind.h
|
||||
+++ b/libgcc/config/aarch64/aarch64-unwind.h
|
||||
@@ -29,8 +29,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
|
||||
#define MD_DEMANGLE_RETURN_ADDR(context, fs, addr) \
|
||||
aarch64_demangle_return_addr (context, fs, addr)
|
||||
-#define MD_FROB_UPDATE_CONTEXT(context, fs) \
|
||||
- aarch64_frob_update_context (context, fs)
|
||||
|
||||
static inline int
|
||||
aarch64_cie_signed_with_b_key (struct _Unwind_Context *context)
|
||||
@@ -55,42 +53,28 @@ aarch64_cie_signed_with_b_key (struct _Unwind_Context *context)
|
||||
|
||||
static inline void *
|
||||
aarch64_demangle_return_addr (struct _Unwind_Context *context,
|
||||
- _Unwind_FrameState *fs ATTRIBUTE_UNUSED,
|
||||
+ _Unwind_FrameState *fs,
|
||||
_Unwind_Word addr_word)
|
||||
{
|
||||
void *addr = (void *)addr_word;
|
||||
- if (context->flags & RA_SIGNED_BIT)
|
||||
+ const int reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
+
|
||||
+ if (fs->regs.how[reg] == REG_UNSAVED)
|
||||
+ return addr;
|
||||
+
|
||||
+ /* Return-address signing state is toggled by DW_CFA_GNU_window_save (where
|
||||
+ REG_UNSAVED/REG_UNSAVED_ARCHEXT means RA signing is disabled/enabled),
|
||||
+ or set by a DW_CFA_expression. */
|
||||
+ if (fs->regs.how[reg] == REG_UNSAVED_ARCHEXT
|
||||
+ || (_Unwind_GetGR (context, reg) & 0x1) != 0)
|
||||
{
|
||||
_Unwind_Word salt = (_Unwind_Word) context->cfa;
|
||||
if (aarch64_cie_signed_with_b_key (context) != 0)
|
||||
return __builtin_aarch64_autib1716 (addr, salt);
|
||||
return __builtin_aarch64_autia1716 (addr, salt);
|
||||
}
|
||||
- else
|
||||
- return addr;
|
||||
-}
|
||||
-
|
||||
-/* Do AArch64 private initialization on CONTEXT based on frame info FS. Mark
|
||||
- CONTEXT as return address signed if bit 0 of DWARF_REGNUM_AARCH64_RA_STATE is
|
||||
- set. */
|
||||
-
|
||||
-static inline void
|
||||
-aarch64_frob_update_context (struct _Unwind_Context *context,
|
||||
- _Unwind_FrameState *fs)
|
||||
-{
|
||||
- const int reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
- int ra_signed;
|
||||
- if (fs->regs.how[reg] == REG_UNSAVED)
|
||||
- ra_signed = fs->regs.reg[reg].loc.offset & 0x1;
|
||||
- else
|
||||
- ra_signed = _Unwind_GetGR (context, reg) & 0x1;
|
||||
- if (ra_signed)
|
||||
- /* The flag is used for re-authenticating EH handler's address. */
|
||||
- context->flags |= RA_SIGNED_BIT;
|
||||
- else
|
||||
- context->flags &= ~RA_SIGNED_BIT;
|
||||
|
||||
- return;
|
||||
+ return addr;
|
||||
}
|
||||
|
||||
#endif /* defined AARCH64_UNWIND_H && defined __ILP32__ */
|
||||
diff --git a/libgcc/unwind-dw2-execute_cfa.h b/libgcc/unwind-dw2-execute_cfa.h
|
||||
index dd97b7866686a361..0166f85965d4a5ee 100644
|
||||
--- a/libgcc/unwind-dw2-execute_cfa.h
|
||||
+++ b/libgcc/unwind-dw2-execute_cfa.h
|
||||
@@ -278,10 +278,15 @@
|
||||
case DW_CFA_GNU_window_save:
|
||||
#if defined (__aarch64__) && !defined (__ILP32__)
|
||||
/* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
|
||||
- return address signing status. */
|
||||
+ return address signing status. REG_UNSAVED/REG_UNSAVED_ARCHEXT
|
||||
+ mean RA signing is disabled/enabled. */
|
||||
reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
- gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
|
||||
- fs->regs.reg[reg].loc.offset ^= 1;
|
||||
+ gcc_assert (fs->regs.how[reg] == REG_UNSAVED
|
||||
+ || fs->regs.how[reg] == REG_UNSAVED_ARCHEXT);
|
||||
+ if (fs->regs.how[reg] == REG_UNSAVED)
|
||||
+ fs->regs.how[reg] = REG_UNSAVED_ARCHEXT;
|
||||
+ else
|
||||
+ fs->regs.how[reg] = REG_UNSAVED;
|
||||
#else
|
||||
/* ??? Hardcoded for SPARC register window configuration. */
|
||||
if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
|
||||
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
|
||||
index 701552634c6e87c5..280ec2eb4df3d2a2 100644
|
||||
--- a/libgcc/unwind-dw2.c
|
||||
+++ b/libgcc/unwind-dw2.c
|
||||
@@ -137,9 +137,6 @@ struct _Unwind_Context
|
||||
#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1)
|
||||
/* Context which has version/args_size/by_value fields. */
|
||||
#define EXTENDED_CONTEXT_BIT ((~(_Unwind_Word) 0 >> 2) + 1)
|
||||
- /* Bit reserved on AArch64, return address has been signed with A or B
|
||||
- key. */
|
||||
-#define RA_SIGNED_BIT ((~(_Unwind_Word) 0 >> 3) + 1)
|
||||
_Unwind_Word flags;
|
||||
/* 0 for now, can be increased when further fields are added to
|
||||
struct _Unwind_Context. */
|
||||
@@ -1200,6 +1197,7 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
|
||||
{
|
||||
case REG_UNSAVED:
|
||||
case REG_UNDEFINED:
|
||||
+ case REG_UNSAVED_ARCHEXT:
|
||||
break;
|
||||
|
||||
case REG_SAVED_OFFSET:
|
||||
diff --git a/libgcc/unwind-dw2.h b/libgcc/unwind-dw2.h
|
||||
index 437c785efa4f297d..44f63e2eb31298d8 100644
|
||||
--- a/libgcc/unwind-dw2.h
|
||||
+++ b/libgcc/unwind-dw2.h
|
||||
@@ -29,6 +29,7 @@ enum {
|
||||
REG_SAVED_EXP,
|
||||
REG_SAVED_VAL_OFFSET,
|
||||
REG_SAVED_VAL_EXP,
|
||||
+ REG_UNSAVED_ARCHEXT, /* Target specific extension. */
|
||||
REG_UNDEFINED
|
||||
};
|
||||
|
||||
34
SOURCES/gcc-RHEL-105072-19.patch
Normal file
34
SOURCES/gcc-RHEL-105072-19.patch
Normal file
@ -0,0 +1,34 @@
|
||||
commit 9be9be828dc9020735bc7eacddd1ceae1aeedb1b
|
||||
Author: Sören Tempel <soeren+git@soeren-tempel.net>
|
||||
Date: Sun May 14 19:30:21 2023 +0200
|
||||
|
||||
fix assert in __deregister_frame_info_bases
|
||||
|
||||
The assertion in __deregister_frame_info_bases assumes that for every
|
||||
frame something was inserted into the lookup data structure by
|
||||
__register_frame_info_bases. Unfortunately, this does not necessarily
|
||||
hold true as the btree_insert call in __register_frame_info_bases will
|
||||
not insert anything for empty ranges. Therefore, we need to explicitly
|
||||
account for such empty ranges in the assertion as `ob` will be a null
|
||||
pointer for such ranges, hence causing the assertion to fail.
|
||||
|
||||
Signed-off-by: Sören Tempel <soeren@soeren-tempel.net>
|
||||
|
||||
libgcc/ChangeLog:
|
||||
* unwind-dw2-fde.c: Accept empty ranges when deregistering frames.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index efcf9490469ad1a0..fdf52396e8576b79 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -278,7 +278,9 @@ __deregister_frame_info_bases (const void *begin)
|
||||
__gthread_mutex_unlock (&object_mutex);
|
||||
#endif
|
||||
|
||||
- gcc_assert (in_shutdown || ob);
|
||||
+ // If we didn't find anything in the lookup data structures then they
|
||||
+ // were either already destroyed or we tried to remove an empty range.
|
||||
+ gcc_assert (in_shutdown || ((range[1] - range[0]) == 0 || ob));
|
||||
return (void *) ob;
|
||||
}
|
||||
|
||||
147
SOURCES/gcc-RHEL-105072-2.patch
Normal file
147
SOURCES/gcc-RHEL-105072-2.patch
Normal file
@ -0,0 +1,147 @@
|
||||
commit f58bf16f672cda3ac55f92f12e258c817ece6e3c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 22 13:30:23 2021 +0100
|
||||
|
||||
libgcc: Remove dbase member from struct unw_eh_callback_data if NULL
|
||||
|
||||
Only bfin, frv, i386 and nios2 need this member at present.
|
||||
|
||||
libgcc/ChangeLog
|
||||
|
||||
* unwind-dw2-fde-dip.c (NEED_DBASE_MEMBER): Define.
|
||||
(struct unw_eh_callback_data): Make dbase member conditional.
|
||||
(unw_eh_callback_data_dbase): New function.
|
||||
(base_from_cb_data): Simplify for the non-dbase case.
|
||||
(_Unwind_IteratePhdrCallback): Adjust.
|
||||
(_Unwind_Find_FDE): Likewise.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index 4a4d990f455e5c11..3f302826d2d49074 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -101,15 +101,35 @@ static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases
|
||||
#define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550)
|
||||
#endif
|
||||
|
||||
+#ifdef CRT_GET_RFIB_DATA
|
||||
+#define NEED_DBASE_MEMBER 1
|
||||
+#else
|
||||
+#define NEED_DBASE_MEMBER 0
|
||||
+#endif
|
||||
+
|
||||
struct unw_eh_callback_data
|
||||
{
|
||||
_Unwind_Ptr pc;
|
||||
+#if NEED_DBASE_MEMBER
|
||||
void *dbase;
|
||||
+#endif
|
||||
void *func;
|
||||
const fde *ret;
|
||||
int check_cache;
|
||||
};
|
||||
|
||||
+/* Returns DATA->dbase if available, else NULL. */
|
||||
+static inline _Unwind_Ptr
|
||||
+unw_eh_callback_data_dbase (const struct unw_eh_callback_data *data
|
||||
+ __attribute__ ((unused)))
|
||||
+{
|
||||
+#if NEED_DBASE_MEMBER
|
||||
+ return (_Unwind_Ptr) data->dbase;
|
||||
+#else
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
struct unw_eh_frame_hdr
|
||||
{
|
||||
unsigned char version;
|
||||
@@ -139,9 +159,11 @@ static struct frame_hdr_cache_element *frame_hdr_cache_head;
|
||||
/* Like base_of_encoded_value, but take the base from a struct
|
||||
unw_eh_callback_data instead of an _Unwind_Context. */
|
||||
|
||||
-static _Unwind_Ptr
|
||||
-base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
|
||||
+static inline _Unwind_Ptr
|
||||
+base_from_cb_data (unsigned char encoding __attribute__ ((unused)),
|
||||
+ _Unwind_Ptr dbase __attribute__ ((unused)))
|
||||
{
|
||||
+#if NEED_DBASE_MEMBER
|
||||
if (encoding == DW_EH_PE_omit)
|
||||
return 0;
|
||||
|
||||
@@ -155,10 +177,13 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
|
||||
case DW_EH_PE_textrel:
|
||||
return 0;
|
||||
case DW_EH_PE_datarel:
|
||||
- return (_Unwind_Ptr) data->dbase;
|
||||
+ return dbase;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
+#else /* !NEED_DBASE_MEMBER */
|
||||
+ return 0;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -358,9 +383,10 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
+ _Unwind_Ptr dbase = unw_eh_callback_data_dbase (data);
|
||||
p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
base_from_cb_data (hdr->eh_frame_ptr_enc,
|
||||
- data),
|
||||
+ dbase),
|
||||
(const unsigned char *) (hdr + 1),
|
||||
&eh_frame);
|
||||
|
||||
@@ -374,7 +400,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
|
||||
p = read_encoded_value_with_base (hdr->fde_count_enc,
|
||||
base_from_cb_data (hdr->fde_count_enc,
|
||||
- data),
|
||||
+ dbase),
|
||||
p, &fde_count);
|
||||
/* Shouldn't happen. */
|
||||
if (fde_count == 0)
|
||||
@@ -431,7 +457,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
removed, we could cache this (and thus use search_object). */
|
||||
ob.pc_begin = NULL;
|
||||
ob.tbase = NULL;
|
||||
- ob.dbase = data->dbase;
|
||||
+ ob.dbase = (void *) dbase;
|
||||
ob.u.single = (fde *) eh_frame;
|
||||
ob.s.i = 0;
|
||||
ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */
|
||||
@@ -442,7 +468,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
unsigned int encoding = get_fde_encoding (data->ret);
|
||||
|
||||
read_encoded_value_with_base (encoding,
|
||||
- base_from_cb_data (encoding, data),
|
||||
+ base_from_cb_data (encoding, dbase),
|
||||
data->ret->pc_begin, &func);
|
||||
data->func = (void *) func;
|
||||
}
|
||||
@@ -460,7 +486,9 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
return ret;
|
||||
|
||||
data.pc = (_Unwind_Ptr) pc;
|
||||
+#if NEED_DBASE_MEMBER
|
||||
data.dbase = NULL;
|
||||
+#endif
|
||||
data.func = NULL;
|
||||
data.ret = NULL;
|
||||
data.check_cache = 1;
|
||||
@@ -471,7 +499,11 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
if (data.ret)
|
||||
{
|
||||
bases->tbase = NULL;
|
||||
+#if NEED_DBASE_MEMBER
|
||||
bases->dbase = data.dbase;
|
||||
+#else
|
||||
+ bases->dbase = NULL;
|
||||
+#endif
|
||||
bases->func = data.func;
|
||||
}
|
||||
return data.ret;
|
||||
38
SOURCES/gcc-RHEL-105072-20.patch
Normal file
38
SOURCES/gcc-RHEL-105072-20.patch
Normal file
@ -0,0 +1,38 @@
|
||||
commit 30adfb85ff994c0faa0cc556ba46838b218263f5
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Mon May 15 14:59:22 2023 +0200
|
||||
|
||||
fix assert in non-atomic path
|
||||
|
||||
The non-atomic path does not have range information,
|
||||
we have to adjust the assert handle that case, too.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
* unwind-dw2-fde.c: Fix assert in non-atomic path.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index fdf52396e8576b79..9b0c229efa5427a9 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -240,6 +240,7 @@ __deregister_frame_info_bases (const void *begin)
|
||||
|
||||
// And remove
|
||||
ob = btree_remove (®istered_frames, range[0]);
|
||||
+ bool empty_table = (range[1] - range[0]) == 0;
|
||||
#else
|
||||
init_object_mutex_once ();
|
||||
__gthread_mutex_lock (&object_mutex);
|
||||
@@ -276,11 +277,12 @@ __deregister_frame_info_bases (const void *begin)
|
||||
|
||||
out:
|
||||
__gthread_mutex_unlock (&object_mutex);
|
||||
+ const int empty_table = 0; // The non-atomic path stores all tables.
|
||||
#endif
|
||||
|
||||
// If we didn't find anything in the lookup data structures then they
|
||||
// were either already destroyed or we tried to remove an empty range.
|
||||
- gcc_assert (in_shutdown || ((range[1] - range[0]) == 0 || ob));
|
||||
+ gcc_assert (in_shutdown || (empty_table || ob));
|
||||
return (void *) ob;
|
||||
}
|
||||
|
||||
31
SOURCES/gcc-RHEL-105072-21.patch
Normal file
31
SOURCES/gcc-RHEL-105072-21.patch
Normal file
@ -0,0 +1,31 @@
|
||||
commit 5cf60b6ba111f4169305c7832b063b000e9ec36a
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Tue May 2 16:21:09 2023 +0200
|
||||
|
||||
release the sorted FDE array when deregistering a frame [PR109685]
|
||||
|
||||
The atomic fastpath bypasses the code that releases the sort
|
||||
array which was lazily allocated during unwinding. We now
|
||||
check after deregistering if there is an array to free.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
PR libgcc/109685
|
||||
* unwind-dw2-fde.c: Free sort array in atomic fast path.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index 9b0c229efa5427a9..0fd2fc54aa651350 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -241,6 +241,12 @@ __deregister_frame_info_bases (const void *begin)
|
||||
// And remove
|
||||
ob = btree_remove (®istered_frames, range[0]);
|
||||
bool empty_table = (range[1] - range[0]) == 0;
|
||||
+
|
||||
+ // Deallocate the sort array if any.
|
||||
+ if (ob && ob->s.b.sorted)
|
||||
+ {
|
||||
+ free (ob->u.sort);
|
||||
+ }
|
||||
#else
|
||||
init_object_mutex_once ();
|
||||
__gthread_mutex_lock (&object_mutex);
|
||||
51
SOURCES/gcc-RHEL-105072-22.patch
Normal file
51
SOURCES/gcc-RHEL-105072-22.patch
Normal file
@ -0,0 +1,51 @@
|
||||
commit 38e88d41f50d844f1404172657ef7e8372014ef6
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Wed May 10 12:33:49 2023 +0200
|
||||
|
||||
fix radix sort on 32bit platforms [PR109670]
|
||||
|
||||
The radix sort uses two buffers, a1 for input and a2 for output.
|
||||
After every digit the role of the two buffers is swapped.
|
||||
When terminating the sort early the code made sure the output
|
||||
was in a2. However, when we run out of bits, as can happen on
|
||||
32bit platforms, the sorted result was in a1, as we had just
|
||||
swapped a1 and a2.
|
||||
This patch fixes the problem by unconditionally having a1 as
|
||||
output after every loop iteration.
|
||||
|
||||
This bug manifested itself only on 32bit platforms and even then
|
||||
only in some circumstances, as it needs frames where a swap
|
||||
is required due to differences in the top-most byte, which is
|
||||
affected by ASLR. The new logic was validated by exhaustive
|
||||
search over 32bit input values.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
PR libgcc/109670
|
||||
* unwind-dw2-fde.c: Fix radix sort buffer management.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index 0fd2fc54aa651350..41b8c2e9380bc45b 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -634,8 +634,6 @@ fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
|
||||
// Stop if we are already sorted.
|
||||
if (!violations)
|
||||
{
|
||||
- // The sorted data is in a1 now.
|
||||
- a2 = a1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -670,9 +668,9 @@ fde_radixsort (struct object *ob, fde_extractor_t fde_extractor,
|
||||
#undef FANOUT
|
||||
#undef FANOUTBITS
|
||||
|
||||
- // The data is in a2 now, move in place if needed.
|
||||
- if (a2 != v1->array)
|
||||
- memcpy (v1->array, a2, sizeof (const fde *) * n);
|
||||
+ // The data is in a1 now, move in place if needed.
|
||||
+ if (a1 != v1->array)
|
||||
+ memcpy (v1->array, a1, sizeof (const fde *) * n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
33
SOURCES/gcc-RHEL-105072-23.patch
Normal file
33
SOURCES/gcc-RHEL-105072-23.patch
Normal file
@ -0,0 +1,33 @@
|
||||
commit 49310a993308492348119f4033e4db0bda4fe46a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jun 6 11:01:07 2023 +0200
|
||||
|
||||
libgcc: Fix eh_frame fast path in find_fde_tail
|
||||
|
||||
The eh_frame value is only used by linear_search_fdes, not the binary
|
||||
search directly in find_fde_tail, so the bug is not immediately
|
||||
apparent with most programs.
|
||||
|
||||
Fixes commit e724b0480bfa5ec04f39be8c7290330b495c59de ("libgcc:
|
||||
Special-case BFD ld unwind table encodings in find_fde_tail").
|
||||
|
||||
libgcc/
|
||||
|
||||
PR libgcc/109712
|
||||
* unwind-dw2-fde-dip.c (find_fde_tail): Correct fast path for
|
||||
parsing eh_frame.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index d4821d7d19950f15..b46e95dc8f88ac5c 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -403,8 +403,8 @@ find_fde_tail (_Unwind_Ptr pc,
|
||||
BFD ld generates. */
|
||||
signed value __attribute__ ((mode (SI)));
|
||||
memcpy (&value, p, sizeof (value));
|
||||
+ eh_frame = p + value;
|
||||
p += sizeof (value);
|
||||
- dbase = value; /* No adjustment because pcrel has base 0. */
|
||||
}
|
||||
else
|
||||
p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
28
SOURCES/gcc-RHEL-105072-24.patch
Normal file
28
SOURCES/gcc-RHEL-105072-24.patch
Normal file
@ -0,0 +1,28 @@
|
||||
commit 104b09005229ef48a79a33511ea192bb3ec3c415
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jul 11 06:19:39 2023 +0200
|
||||
|
||||
libgcc: Fix -Wint-conversion warning in find_fde_tail
|
||||
|
||||
Fixes commit r14-1614-g49310a99330849 ("libgcc: Fix eh_frame fast path
|
||||
in find_fde_tail").
|
||||
|
||||
libgcc/
|
||||
|
||||
PR libgcc/110179
|
||||
* unwind-dw2-fde-dip.c (find_fde_tail): Add cast to avoid
|
||||
implicit conversion of pointer value to integer.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index b46e95dc8f88ac5c..e08154c1442d748f 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -403,7 +403,7 @@ find_fde_tail (_Unwind_Ptr pc,
|
||||
BFD ld generates. */
|
||||
signed value __attribute__ ((mode (SI)));
|
||||
memcpy (&value, p, sizeof (value));
|
||||
- eh_frame = p + value;
|
||||
+ eh_frame = (_Unwind_Ptr) (p + value);
|
||||
p += sizeof (value);
|
||||
}
|
||||
else
|
||||
97
SOURCES/gcc-RHEL-105072-25.patch
Normal file
97
SOURCES/gcc-RHEL-105072-25.patch
Normal file
@ -0,0 +1,97 @@
|
||||
commit c46bded78f3733ad1312d141ebf1ae541032a48b
|
||||
Author: Thomas Neumann <thomas.neumann@in.tum.de>
|
||||
Date: Fri Aug 11 09:20:27 2023 -0600
|
||||
|
||||
preserve base pointer for __deregister_frame [PR110956]
|
||||
|
||||
Original bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110956
|
||||
Rainer Orth successfully tested the patch on Solaris with a full bootstrap.
|
||||
|
||||
Some uncommon unwinding table encodings need to access the base pointer
|
||||
for address computations. We do not have that information in calls to
|
||||
__deregister_frame_info_bases, and previously simply used nullptr as
|
||||
base pointer. That is usually fine, but for some Solaris i386 shared
|
||||
libraries that results in wrong address computations.
|
||||
|
||||
To fix this problem we now associate the unwinding object with
|
||||
the table pointer itself, which is always known, in addition to
|
||||
the PC range. When deregistering a frame, we first locate the object
|
||||
using the table pointer, and then use the base pointer stored within
|
||||
the object to compute the PC range.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
PR libgcc/110956
|
||||
* unwind-dw2-fde.c: Associate object with address of unwinding
|
||||
table.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index 41b8c2e9380bc45b..5d6fb29acd440563 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -124,6 +124,9 @@ __register_frame_info_bases (const void *begin, struct object *ob,
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
+ // Register the object itself to know the base pointer on deregistration.
|
||||
+ btree_insert (®istered_frames, (uintptr_type) begin, 1, ob);
|
||||
+
|
||||
// Register the frame in the b-tree
|
||||
uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
@@ -175,6 +178,9 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
|
||||
ob->s.b.encoding = DW_EH_PE_omit;
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
+ // Register the object itself to know the base pointer on deregistration.
|
||||
+ btree_insert (®istered_frames, (uintptr_type) begin, 1, ob);
|
||||
+
|
||||
// Register the frame in the b-tree
|
||||
uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
@@ -225,22 +231,17 @@ __deregister_frame_info_bases (const void *begin)
|
||||
return ob;
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- // Find the corresponding PC range
|
||||
- struct object lookupob;
|
||||
- lookupob.tbase = 0;
|
||||
- lookupob.dbase = 0;
|
||||
- lookupob.u.single = begin;
|
||||
- lookupob.s.i = 0;
|
||||
- lookupob.s.b.encoding = DW_EH_PE_omit;
|
||||
-#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
||||
- lookupob.fde_end = NULL;
|
||||
-#endif
|
||||
- uintptr_type range[2];
|
||||
- get_pc_range (&lookupob, range);
|
||||
+ // Find the originally registered object to get the base pointer.
|
||||
+ ob = btree_remove (®istered_frames, (uintptr_type) begin);
|
||||
|
||||
- // And remove
|
||||
- ob = btree_remove (®istered_frames, range[0]);
|
||||
- bool empty_table = (range[1] - range[0]) == 0;
|
||||
+ // Remove the corresponding PC range.
|
||||
+ if (ob)
|
||||
+ {
|
||||
+ uintptr_type range[2];
|
||||
+ get_pc_range (ob, range);
|
||||
+ if (range[0] != range[1])
|
||||
+ btree_remove (®istered_frames, range[0]);
|
||||
+ }
|
||||
|
||||
// Deallocate the sort array if any.
|
||||
if (ob && ob->s.b.sorted)
|
||||
@@ -283,12 +284,11 @@ __deregister_frame_info_bases (const void *begin)
|
||||
|
||||
out:
|
||||
__gthread_mutex_unlock (&object_mutex);
|
||||
- const int empty_table = 0; // The non-atomic path stores all tables.
|
||||
#endif
|
||||
|
||||
// If we didn't find anything in the lookup data structures then they
|
||||
// were either already destroyed or we tried to remove an empty range.
|
||||
- gcc_assert (in_shutdown || (empty_table || ob));
|
||||
+ gcc_assert (in_shutdown || ob);
|
||||
return (void *) ob;
|
||||
}
|
||||
|
||||
112
SOURCES/gcc-RHEL-105072-26.patch
Normal file
112
SOURCES/gcc-RHEL-105072-26.patch
Normal file
@ -0,0 +1,112 @@
|
||||
commit a364148530c28645ce87adbc58a66c9f32a325ab
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Mon Mar 11 14:35:20 2024 +0100
|
||||
|
||||
handle unwind tables that are embedded within unwinding code [PR111731]
|
||||
|
||||
Original bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111731
|
||||
|
||||
The unwinding mechanism registers both the code range and the unwind
|
||||
table itself within a b-tree lookup structure. That data structure
|
||||
assumes that is consists of non-overlappping intervals. This
|
||||
becomes a problem if the unwinding table is embedded within the
|
||||
code itself, as now the intervals do overlap.
|
||||
|
||||
To fix this problem we now keep the unwind tables in a separate
|
||||
b-tree, which prevents the overlap.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
PR libgcc/111731
|
||||
* unwind-dw2-fde.c: Split unwind ranges if they contain the
|
||||
unwind table.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index 5d6fb29acd440563..421068b538abc66d 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -48,6 +48,7 @@ typedef __UINTPTR_TYPE__ uintptr_type;
|
||||
#include "unwind-dw2-btree.h"
|
||||
|
||||
static struct btree registered_frames;
|
||||
+static struct btree registered_objects;
|
||||
static bool in_shutdown;
|
||||
|
||||
static void
|
||||
@@ -58,6 +59,7 @@ release_registered_frames (void)
|
||||
/* Release the b-tree and all frames. Frame releases that happen later are
|
||||
* silently ignored */
|
||||
btree_destroy (®istered_frames);
|
||||
+ btree_destroy (®istered_objects);
|
||||
in_shutdown = true;
|
||||
}
|
||||
|
||||
@@ -103,6 +105,21 @@ static __gthread_mutex_t object_mutex;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#ifdef ATOMIC_FDE_FAST_PATH
|
||||
+// Register the pc range for a given object in the lookup structure.
|
||||
+static void
|
||||
+register_pc_range_for_object (uintptr_type begin, struct object *ob)
|
||||
+{
|
||||
+ // Register the object itself to know the base pointer on deregistration.
|
||||
+ btree_insert (®istered_objects, begin, 1, ob);
|
||||
+
|
||||
+ // Register the frame in the b-tree
|
||||
+ uintptr_type range[2];
|
||||
+ get_pc_range (ob, range);
|
||||
+ btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Called from crtbegin.o to register the unwind info for an object. */
|
||||
|
||||
void
|
||||
@@ -124,13 +141,7 @@ __register_frame_info_bases (const void *begin, struct object *ob,
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- // Register the object itself to know the base pointer on deregistration.
|
||||
- btree_insert (®istered_frames, (uintptr_type) begin, 1, ob);
|
||||
-
|
||||
- // Register the frame in the b-tree
|
||||
- uintptr_type range[2];
|
||||
- get_pc_range (ob, range);
|
||||
- btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
+ register_pc_range_for_object ((uintptr_type) begin, ob);
|
||||
#else
|
||||
init_object_mutex_once ();
|
||||
__gthread_mutex_lock (&object_mutex);
|
||||
@@ -178,13 +189,7 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
|
||||
ob->s.b.encoding = DW_EH_PE_omit;
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- // Register the object itself to know the base pointer on deregistration.
|
||||
- btree_insert (®istered_frames, (uintptr_type) begin, 1, ob);
|
||||
-
|
||||
- // Register the frame in the b-tree
|
||||
- uintptr_type range[2];
|
||||
- get_pc_range (ob, range);
|
||||
- btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
+ register_pc_range_for_object ((uintptr_type) begin, ob);
|
||||
#else
|
||||
init_object_mutex_once ();
|
||||
__gthread_mutex_lock (&object_mutex);
|
||||
@@ -232,7 +237,7 @@ __deregister_frame_info_bases (const void *begin)
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
// Find the originally registered object to get the base pointer.
|
||||
- ob = btree_remove (®istered_frames, (uintptr_type) begin);
|
||||
+ ob = btree_remove (®istered_objects, (uintptr_type) begin);
|
||||
|
||||
// Remove the corresponding PC range.
|
||||
if (ob)
|
||||
@@ -240,7 +245,7 @@ __deregister_frame_info_bases (const void *begin)
|
||||
uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
if (range[0] != range[1])
|
||||
- btree_remove (®istered_frames, range[0]);
|
||||
+ btree_remove (®istered_frames, range[0]);
|
||||
}
|
||||
|
||||
// Deallocate the sort array if any.
|
||||
299
SOURCES/gcc-RHEL-105072-27.patch
Normal file
299
SOURCES/gcc-RHEL-105072-27.patch
Normal file
@ -0,0 +1,299 @@
|
||||
commit 21109b37e8585a7a1b27650fcbf1749380016108
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon Mar 10 10:34:00 2025 +0100
|
||||
|
||||
libgcc: Fix up unwind-dw2-btree.h [PR119151]
|
||||
|
||||
The following testcase shows a bug in unwind-dw2-btree.h.
|
||||
In short, the header provides lock-free btree data structure (so no parent
|
||||
link on nodes, both insertion and deletion are done in top-down walks
|
||||
with some locking of just a few nodes at a time so that lookups can notice
|
||||
concurrent modifications and retry, non-leaf (inner) nodes contain keys
|
||||
which are initially the base address of the left-most leaf entry of the
|
||||
following child (or all ones if there is none) minus one, insertion ensures
|
||||
balancing of the tree to ensure [d/2, d] entries filled through aggressive
|
||||
splitting if it sees a full tree while walking, deletion performs various
|
||||
operations like merging neighbour trees, merging into parent or moving some
|
||||
nodes from neighbour to the current one).
|
||||
What differs from the textbook implementations is mostly that the leaf nodes
|
||||
don't include just address as a key, but address range, address + size
|
||||
(where we don't insert any ranges with zero size) and the lookups can be
|
||||
performed for any address in the [address, address + size) range. The keys
|
||||
on inner nodes are still just address-1, so the child covers all nodes
|
||||
where addr <= key unless it is covered already in children to the left.
|
||||
The user (static executables or JIT) should always ensure there is no
|
||||
overlap in between any of the ranges.
|
||||
|
||||
In the testcase a bunch of insertions are done, always followed by one
|
||||
removal, followed by one insertion of a range slightly different from the
|
||||
removed one. E.g. in the first case [&code[0x50], &code[0x59]] range
|
||||
is removed and then we insert [&code[0x4c], &code[0x53]] range instead.
|
||||
This is valid, it doesn't overlap anything. But the problem is that some
|
||||
non-leaf (inner) one used the &code[0x4f] key (after the 11 insertions
|
||||
completely correctly). On removal, nothing adjusts the keys on the parent
|
||||
nodes (it really can't in the top-down only walk, the keys could be many nodes
|
||||
above it and unlike insertion, removal only knows the start address, doesn't
|
||||
know the removed size and so will discover it only when reaching the leaf
|
||||
node which contains it; plus even if it knew the address and size, it still
|
||||
doesn't know what the second left-most leaf node will be (i.e. the one after
|
||||
removal)). And on insertion, if nodes aren't split at a level, nothing
|
||||
adjusts the inner keys either. If a range is inserted and is either fully
|
||||
bellow key (keys are - 1, so having address + size - 1 being equal to key is
|
||||
fine) or fully after key (i.e. address > key), it works just fine, but if
|
||||
the key is in a middle of the range like in this case, &code[0x4f] is in the
|
||||
middle of the [&code[0x4c], &code[0x53]] range, then insertion works fine
|
||||
(we only use size on the leaf nodes), and lookup of the addresses below
|
||||
the key work fine too (i.e. [&code[0x4c], &code[0x4f]] will succeed).
|
||||
The problem is with lookups after the key (i.e. [&code[0x50, &code[0x53]]),
|
||||
the lookup looks for them in different children of the btree and doesn't
|
||||
find an entry and returns NULL.
|
||||
|
||||
As users need to ensure non-overlapping entries at any time, the following
|
||||
patch fixes it by adjusting keys during insertion where we know not just
|
||||
the address but also size; if we find during the top-down walk a key
|
||||
which is in the middle of the range being inserted, we simply increase the
|
||||
key to be equal to address + size - 1 of the range being inserted.
|
||||
There can't be any existing leaf nodes overlapping the range in correct
|
||||
programs and the btree rebalancing done on deletion ensures we don't have
|
||||
any empty nodes which would also cause problems.
|
||||
|
||||
The patch adjusts the keys in two spots, once for the current node being
|
||||
walked (the last hunk in the header, with large comment trying to explain
|
||||
it) and once during inner node splitting in a parent node if we'd otherwise
|
||||
try to add that key in the middle of the range being inserted into the
|
||||
parent node (in that case it would be missed in the last hunk).
|
||||
The testcase covers both of those spots, so succeeds with GCC 12 (which
|
||||
didn't have btrees) and fails with vanilla GCC trunk and also fails if
|
||||
either the
|
||||
if (fence < base + size - 1)
|
||||
fence = iter->content.children[slot].separator = base + size - 1;
|
||||
or
|
||||
if (left_fence >= target && left_fence < target + size - 1)
|
||||
left_fence = target + size - 1;
|
||||
hunk is removed (of course, only with the current node sizes, i.e. up to
|
||||
15 children of inner nodes and up to 10 entries in leaf nodes).
|
||||
|
||||
2025-03-10 Jakub Jelinek <jakub@redhat.com>
|
||||
Michael Leuchtenburg <michael@slashhome.org>
|
||||
|
||||
PR libgcc/119151
|
||||
* unwind-dw2-btree.h (btree_split_inner): Add size argument. If
|
||||
left_fence is in the middle of [target,target + size - 1] range,
|
||||
increase it to target + size - 1.
|
||||
(btree_insert): Adjust btree_split_inner caller. If fence is smaller
|
||||
than base + size - 1, increase it and separator of the slot to
|
||||
base + size - 1.
|
||||
|
||||
* gcc.dg/pr119151.c: New test.
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr119151.c b/gcc/testsuite/gcc.dg/pr119151.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..6ef0f12ce9ae6c06
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/pr119151.c
|
||||
@@ -0,0 +1,151 @@
|
||||
+/* PR libgcc/119151 */
|
||||
+/* Should be run just on targets which don't have _Unwind_Find_FDE in libc.so. */
|
||||
+/* { dg-do run { target { { x86_64-*-linux* aarch64*-*-linux* powerpc64*-*-linux* riscv*-*-linux* } && lp64 } } } */
|
||||
+/* { dg-options "-O2" } */
|
||||
+
|
||||
+struct object
|
||||
+{
|
||||
+ void *pc_begin, *tbase, *dbase, *single;
|
||||
+ __SIZE_TYPE__ i;
|
||||
+ void *fde_end, *next;
|
||||
+};
|
||||
+struct dwarf_eh_bases
|
||||
+{
|
||||
+ void *tbase, *dbase, *func;
|
||||
+};
|
||||
+extern void __register_frame_info (const void *, struct object *);
|
||||
+extern void *__deregister_frame_info (const void *);
|
||||
+extern const void *_Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
|
||||
+#define DW_EH_PE_sdata8 0x0c
|
||||
+#define DW_EH_PE_pcrel 0x10
|
||||
+#define DW_CFA_def_cfa 0x0c
|
||||
+#define DW_CFA_offset 0x80
|
||||
+
|
||||
+struct __attribute__((aligned (8))) eh_frame_cie {
|
||||
+ unsigned len;
|
||||
+ unsigned tag;
|
||||
+ unsigned char version;
|
||||
+ unsigned char augmentation[3];
|
||||
+ unsigned char code_align_factor;
|
||||
+ unsigned char data_align_factor;
|
||||
+ unsigned char ra_column;
|
||||
+ unsigned char augmentation_size;
|
||||
+ unsigned char encoding;
|
||||
+ unsigned char def_cfa;
|
||||
+ unsigned char def_cfa_op1, def_cfa_op2;
|
||||
+ unsigned char offset;
|
||||
+ unsigned char offset_op;
|
||||
+};
|
||||
+struct __attribute__((aligned (8))) eh_frame_fde {
|
||||
+ unsigned len;
|
||||
+ unsigned cie_offset;
|
||||
+ unsigned long long begin, size;
|
||||
+ unsigned char augmentation;
|
||||
+};
|
||||
+struct eh_frame_cie_fde {
|
||||
+ struct eh_frame_cie cie;
|
||||
+ struct eh_frame_fde fde;
|
||||
+ unsigned int zero;
|
||||
+ struct object obj;
|
||||
+} eh_frame[256];
|
||||
+unsigned ehidx;
|
||||
+unsigned char code[0x800] __attribute__((aligned (8)));
|
||||
+
|
||||
+void *
|
||||
+register_range (void *addr, unsigned size)
|
||||
+{
|
||||
+ /* Fills in empty-ish CIE and FDE with pcrel sdata8 encoding so that
|
||||
+ we don't need to worry about lp64 large code models.
|
||||
+ We don't actually execute anything in code and only _Unwind_Find_FDE,
|
||||
+ don't actually try to unwind anything. */
|
||||
+ eh_frame[ehidx].cie.len
|
||||
+ = (unsigned) ((char *) &eh_frame[ehidx].fde
|
||||
+ - (char *) &eh_frame[ehidx].cie.tag);
|
||||
+ eh_frame[ehidx].cie.tag = 0;
|
||||
+ eh_frame[ehidx].cie.version = 3;
|
||||
+ __builtin_memcpy (eh_frame[ehidx].cie.augmentation, "zR", 3);
|
||||
+ eh_frame[ehidx].cie.code_align_factor = 1;
|
||||
+ eh_frame[ehidx].cie.data_align_factor = 0x78; /* sleb128 -8 */
|
||||
+ eh_frame[ehidx].cie.ra_column = 0x10;
|
||||
+ eh_frame[ehidx].cie.augmentation_size = 1;
|
||||
+ eh_frame[ehidx].cie.encoding = DW_EH_PE_pcrel | DW_EH_PE_sdata8;
|
||||
+ eh_frame[ehidx].cie.def_cfa = DW_CFA_def_cfa;
|
||||
+ eh_frame[ehidx].cie.def_cfa_op1 = 7;
|
||||
+ eh_frame[ehidx].cie.def_cfa_op2 = 8;
|
||||
+ eh_frame[ehidx].cie.offset = DW_CFA_offset + 0x10;
|
||||
+ eh_frame[ehidx].cie.offset_op = 1;
|
||||
+ eh_frame[ehidx].fde.len
|
||||
+ = (unsigned) ((char *) &eh_frame[ehidx].zero
|
||||
+ - (char *) &eh_frame[ehidx].fde.cie_offset);
|
||||
+ eh_frame[ehidx].fde.cie_offset
|
||||
+ = (unsigned) ((char *) &eh_frame[ehidx].fde.cie_offset
|
||||
+ - (char *) &eh_frame[ehidx].cie);
|
||||
+ eh_frame[ehidx].fde.begin
|
||||
+ = (__INTPTR_TYPE__) ((__UINTPTR_TYPE__) addr
|
||||
+ - (__UINTPTR_TYPE__) &eh_frame[ehidx].fde.begin);
|
||||
+ eh_frame[ehidx].fde.size = size;
|
||||
+ eh_frame[ehidx].fde.augmentation = 0;
|
||||
+ eh_frame[ehidx].zero = 0;
|
||||
+ __register_frame_info (&eh_frame[ehidx].cie, &eh_frame[ehidx].obj);
|
||||
+ ++ehidx;
|
||||
+ return &eh_frame[ehidx - 1].cie;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+unregister (void *eh_frame)
|
||||
+{
|
||||
+ __deregister_frame_info (eh_frame);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ for (int i = 0; i < 0x50; i += 0x10)
|
||||
+ register_range (&code[i], 10);
|
||||
+ void *p = register_range (&code[0x50], 10);
|
||||
+ for (int i = 0x60; i < 0xb0; i += 0x10)
|
||||
+ register_range (&code[i], 10);
|
||||
+ unregister (p);
|
||||
+ register_range (&code[0x4c], 8);
|
||||
+ struct dwarf_eh_bases bases;
|
||||
+ const void *q = _Unwind_Find_FDE (&code[0x4c], &bases);
|
||||
+ const void *r = _Unwind_Find_FDE (&code[0x51], &bases);
|
||||
+ if (!q || q != r)
|
||||
+ __builtin_abort ();
|
||||
+ for (int i = 0; i <= 0xa0; i += 0x10)
|
||||
+ if (i != 0x50)
|
||||
+ {
|
||||
+ q = _Unwind_Find_FDE (&code[i], &bases);
|
||||
+ r = _Unwind_Find_FDE (&code[i + 9], &bases);
|
||||
+ if (!q || q != r)
|
||||
+ __builtin_abort ();
|
||||
+ }
|
||||
+ for (int i = 0xb0; i < 0x240; i += 0x10)
|
||||
+ register_range (&code[i], 10);
|
||||
+ p = register_range (&code[0x240], 10);
|
||||
+ for (int i = 0x250; i < 0x470; i += 0x10)
|
||||
+ register_range (&code[i], 10);
|
||||
+ void *s = register_range (&code[0x470], 10);
|
||||
+ for (int i = 0x480; i < 0x700; i += 0x10)
|
||||
+ register_range (&code[i], 10);
|
||||
+ unregister (p);
|
||||
+ register_range (&code[0x23c], 16);
|
||||
+ q = _Unwind_Find_FDE (&code[0x23d], &bases);
|
||||
+ r = _Unwind_Find_FDE (&code[0x24b], &bases);
|
||||
+ if (!q || q != r)
|
||||
+ __builtin_abort ();
|
||||
+ unregister (s);
|
||||
+ register_range (&code[0x46c], 16);
|
||||
+ q = _Unwind_Find_FDE (&code[0x46d], &bases);
|
||||
+ r = _Unwind_Find_FDE (&code[0x47b], &bases);
|
||||
+ if (!q || q != r)
|
||||
+ __builtin_abort ();
|
||||
+ for (int i = 0; i < 0x700; i += 0x10)
|
||||
+ if (i != 0x50 && i != 0x240 && i != 0x470)
|
||||
+ {
|
||||
+ q = _Unwind_Find_FDE (&code[i], &bases);
|
||||
+ r = _Unwind_Find_FDE (&code[i + 9], &bases);
|
||||
+ if (!q || q != r)
|
||||
+ __builtin_abort ();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/libgcc/unwind-dw2-btree.h b/libgcc/unwind-dw2-btree.h
|
||||
index ace507d9ffbdffb7..e3f3a11a7b5443d6 100644
|
||||
--- a/libgcc/unwind-dw2-btree.h
|
||||
+++ b/libgcc/unwind-dw2-btree.h
|
||||
@@ -474,7 +474,8 @@ btree_handle_root_split (struct btree *t, struct btree_node **node,
|
||||
// Split an inner node.
|
||||
static void
|
||||
btree_split_inner (struct btree *t, struct btree_node **inner,
|
||||
- struct btree_node **parent, uintptr_type target)
|
||||
+ struct btree_node **parent, uintptr_type target,
|
||||
+ uintptr_type size)
|
||||
{
|
||||
// Check for the root.
|
||||
btree_handle_root_split (t, inner, parent);
|
||||
@@ -490,6 +491,9 @@ btree_split_inner (struct btree *t, struct btree_node **inner,
|
||||
= left_inner->content.children[split + index];
|
||||
left_inner->entry_count = split;
|
||||
uintptr_type left_fence = btree_node_get_fence_key (left_inner);
|
||||
+ if (left_fence >= target && left_fence < target + size - 1)
|
||||
+ // See the PR119151 comment in btree_insert.
|
||||
+ left_fence = target + size - 1;
|
||||
btree_node_update_separator_after_split (*parent, right_fence, left_fence,
|
||||
right_inner);
|
||||
if (target <= left_fence)
|
||||
@@ -753,13 +757,28 @@ btree_insert (struct btree *t, uintptr_type base, uintptr_type size,
|
||||
{
|
||||
// Use eager splits to avoid lock coupling up.
|
||||
if (iter->entry_count == max_fanout_inner)
|
||||
- btree_split_inner (t, &iter, &parent, base);
|
||||
+ btree_split_inner (t, &iter, &parent, base, size);
|
||||
|
||||
unsigned slot = btree_node_find_inner_slot (iter, base);
|
||||
if (parent)
|
||||
btree_node_unlock_exclusive (parent);
|
||||
parent = iter;
|
||||
fence = iter->content.children[slot].separator;
|
||||
+ if (fence < base + size - 1)
|
||||
+ // The separator was set to the base - 1 of the leftmost leaf child
|
||||
+ // at some point but such an entry could have been removed afterwards.
|
||||
+ // As both insertion and removal are just walking down the tree with
|
||||
+ // only a few current nodes locked at a time, updating the separator
|
||||
+ // on removal is not possible, especially because btree_remove does
|
||||
+ // not know the size until it reaches leaf node. We must ensure that
|
||||
+ // the separator is not in a middle of some entry though, as
|
||||
+ // btree_lookup can look up any address in the entry's range and if
|
||||
+ // the separator is in the middle, addresses below it or equal to it
|
||||
+ // would be found while addresses above it would result in failed
|
||||
+ // lookup. Update the separator now. Assumption that users
|
||||
+ // ensure no overlapping registered ranges, there should be no
|
||||
+ // current entry for any address in the range. See PR119151.
|
||||
+ fence = iter->content.children[slot].separator = base + size - 1;
|
||||
iter = iter->content.children[slot].child;
|
||||
btree_node_lock_exclusive (iter);
|
||||
}
|
||||
204
SOURCES/gcc-RHEL-105072-3.patch
Normal file
204
SOURCES/gcc-RHEL-105072-3.patch
Normal file
@ -0,0 +1,204 @@
|
||||
commit 9488d24206687be80443dafdb2cdfc4ff3aca28c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Nov 25 18:40:51 2021 +0100
|
||||
|
||||
libgcc: Split FDE search code from PT_GNU_EH_FRAME lookup
|
||||
|
||||
This allows switching to a different implementation for
|
||||
PT_GNU_EH_FRAME lookup in a subsequent commit.
|
||||
|
||||
This moves some of the PT_GNU_EH_FRAME parsing out of the glibc loader
|
||||
lock that is implied by dl_iterate_phdr. However, the FDE is already
|
||||
parsed outside the lock before this change, so this does not introduce
|
||||
additional crashes in case of a concurrent dlclose.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
* unwind-dw2-fde-dip.c (struct unw_eh_callback_data): Add hdr.
|
||||
Remove func, ret.
|
||||
(find_fde_tail): New function. Split from
|
||||
_Unwind_IteratePhdrCallback. Move the result initialization
|
||||
from _Unwind_Find_FDE.
|
||||
(_Unwind_Find_FDE): Updated to call find_fde_tail.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index 3f302826d2d49074..fbb0fbdebb92d484 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -113,8 +113,7 @@ struct unw_eh_callback_data
|
||||
#if NEED_DBASE_MEMBER
|
||||
void *dbase;
|
||||
#endif
|
||||
- void *func;
|
||||
- const fde *ret;
|
||||
+ const struct unw_eh_frame_hdr *hdr;
|
||||
int check_cache;
|
||||
};
|
||||
|
||||
@@ -197,10 +196,6 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
#else
|
||||
_Unwind_Ptr load_base;
|
||||
#endif
|
||||
- const unsigned char *p;
|
||||
- const struct unw_eh_frame_hdr *hdr;
|
||||
- _Unwind_Ptr eh_frame;
|
||||
- struct object ob;
|
||||
_Unwind_Ptr pc_low = 0, pc_high = 0;
|
||||
|
||||
struct ext_dl_phdr_info
|
||||
@@ -348,10 +343,8 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
return 0;
|
||||
|
||||
/* Read .eh_frame_hdr header. */
|
||||
- hdr = (const struct unw_eh_frame_hdr *)
|
||||
+ data->hdr = (const struct unw_eh_frame_hdr *)
|
||||
__RELOC_POINTER (p_eh_frame_hdr->p_vaddr, load_base);
|
||||
- if (hdr->version != 1)
|
||||
- return 1;
|
||||
|
||||
#ifdef CRT_GET_RFIB_DATA
|
||||
# if defined __i386__ || defined __nios2__
|
||||
@@ -383,12 +376,30 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
- _Unwind_Ptr dbase = unw_eh_callback_data_dbase (data);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* Find the FDE for the program counter PC, in a previously located
|
||||
+ PT_GNU_EH_FRAME data region. *BASES is updated if an FDE to return is
|
||||
+ found. */
|
||||
+
|
||||
+static const fde *
|
||||
+find_fde_tail (_Unwind_Ptr pc,
|
||||
+ const struct unw_eh_frame_hdr *hdr,
|
||||
+ _Unwind_Ptr dbase,
|
||||
+ struct dwarf_eh_bases *bases)
|
||||
+{
|
||||
+ const unsigned char *p = (const unsigned char *) (hdr + 1);
|
||||
+ _Unwind_Ptr eh_frame;
|
||||
+ struct object ob;
|
||||
+
|
||||
+ if (hdr->version != 1)
|
||||
+ return NULL;
|
||||
+
|
||||
p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
|
||||
base_from_cb_data (hdr->eh_frame_ptr_enc,
|
||||
dbase),
|
||||
- (const unsigned char *) (hdr + 1),
|
||||
- &eh_frame);
|
||||
+ p, &eh_frame);
|
||||
|
||||
/* We require here specific table encoding to speed things up.
|
||||
Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start
|
||||
@@ -404,7 +415,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
p, &fde_count);
|
||||
/* Shouldn't happen. */
|
||||
if (fde_count == 0)
|
||||
- return 1;
|
||||
+ return NULL;
|
||||
if ((((_Unwind_Ptr) p) & 3) == 0)
|
||||
{
|
||||
struct fde_table {
|
||||
@@ -419,9 +430,9 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
_Unwind_Ptr range;
|
||||
|
||||
mid = fde_count - 1;
|
||||
- if (data->pc < table[0].initial_loc + data_base)
|
||||
- return 1;
|
||||
- else if (data->pc < table[mid].initial_loc + data_base)
|
||||
+ if (pc < table[0].initial_loc + data_base)
|
||||
+ return NULL;
|
||||
+ else if (pc < table[mid].initial_loc + data_base)
|
||||
{
|
||||
lo = 0;
|
||||
hi = mid;
|
||||
@@ -429,9 +440,9 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
while (lo < hi)
|
||||
{
|
||||
mid = (lo + hi) / 2;
|
||||
- if (data->pc < table[mid].initial_loc + data_base)
|
||||
+ if (pc < table[mid].initial_loc + data_base)
|
||||
hi = mid;
|
||||
- else if (data->pc >= table[mid + 1].initial_loc + data_base)
|
||||
+ else if (pc >= table[mid + 1].initial_loc + data_base)
|
||||
lo = mid + 1;
|
||||
else
|
||||
break;
|
||||
@@ -445,10 +456,16 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
f_enc_size = size_of_encoded_value (f_enc);
|
||||
read_encoded_value_with_base (f_enc & 0x0f, 0,
|
||||
&f->pc_begin[f_enc_size], &range);
|
||||
- if (data->pc < table[mid].initial_loc + data_base + range)
|
||||
- data->ret = f;
|
||||
- data->func = (void *) (table[mid].initial_loc + data_base);
|
||||
- return 1;
|
||||
+ _Unwind_Ptr func = table[mid].initial_loc + data_base;
|
||||
+ if (pc < table[mid].initial_loc + data_base + range)
|
||||
+ {
|
||||
+ bases->tbase = NULL;
|
||||
+ bases->dbase = (void *) dbase;
|
||||
+ bases->func = (void *) func;
|
||||
+ return f;
|
||||
+ }
|
||||
+ else
|
||||
+ return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,18 +478,20 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
|
||||
ob.u.single = (fde *) eh_frame;
|
||||
ob.s.i = 0;
|
||||
ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */
|
||||
- data->ret = linear_search_fdes (&ob, (fde *) eh_frame, (void *) data->pc);
|
||||
- if (data->ret != NULL)
|
||||
+ const fde *entry = linear_search_fdes (&ob, (fde *) eh_frame, (void *) pc);
|
||||
+ if (entry != NULL)
|
||||
{
|
||||
_Unwind_Ptr func;
|
||||
- unsigned int encoding = get_fde_encoding (data->ret);
|
||||
+ unsigned int encoding = get_fde_encoding (entry);
|
||||
|
||||
read_encoded_value_with_base (encoding,
|
||||
base_from_cb_data (encoding, dbase),
|
||||
- data->ret->pc_begin, &func);
|
||||
- data->func = (void *) func;
|
||||
+ entry->pc_begin, &func);
|
||||
+ bases->tbase = NULL;
|
||||
+ bases->dbase = (void *) dbase;
|
||||
+ bases->func = (void *) func;
|
||||
}
|
||||
- return 1;
|
||||
+ return entry;
|
||||
}
|
||||
|
||||
const fde *
|
||||
@@ -489,24 +508,13 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
#if NEED_DBASE_MEMBER
|
||||
data.dbase = NULL;
|
||||
#endif
|
||||
- data.func = NULL;
|
||||
- data.ret = NULL;
|
||||
data.check_cache = 1;
|
||||
|
||||
- if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) < 0)
|
||||
+ if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) <= 0)
|
||||
return NULL;
|
||||
|
||||
- if (data.ret)
|
||||
- {
|
||||
- bases->tbase = NULL;
|
||||
-#if NEED_DBASE_MEMBER
|
||||
- bases->dbase = data.dbase;
|
||||
-#else
|
||||
- bases->dbase = NULL;
|
||||
-#endif
|
||||
- bases->func = data.func;
|
||||
- }
|
||||
- return data.ret;
|
||||
+ _Unwind_Ptr dbase = unw_eh_callback_data_dbase (&data);
|
||||
+ return find_fde_tail ((_Unwind_Ptr) pc, data.hdr, dbase, bases);
|
||||
}
|
||||
|
||||
#else
|
||||
40
SOURCES/gcc-RHEL-105072-4.patch
Normal file
40
SOURCES/gcc-RHEL-105072-4.patch
Normal file
@ -0,0 +1,40 @@
|
||||
commit 790854ea7670f11c14d431c102a49181d2915965
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jan 4 15:47:30 2022 +0100
|
||||
|
||||
libgcc: Use _dl_find_object in _Unwind_Find_FDE
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
* unwind-dw2-fde-dip.c (_Unwind_Find_FDE): Call _dl_find_object
|
||||
if available.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index fbb0fbdebb92d484..b837d8e490425652 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -504,6 +504,24 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
|
||||
+ /* Use DLFO_STRUCT_HAS_EH_DBASE as a proxy for the existence of a glibc-style
|
||||
+ _dl_find_object function. */
|
||||
+#ifdef DLFO_STRUCT_HAS_EH_DBASE
|
||||
+ {
|
||||
+ struct dl_find_object dlfo;
|
||||
+ if (_dl_find_object (pc, &dlfo) == 0)
|
||||
+ return find_fde_tail ((_Unwind_Ptr) pc, dlfo.dlfo_eh_frame,
|
||||
+# if DLFO_STRUCT_HAS_EH_DBASE
|
||||
+ (_Unwind_Ptr) dlfo.dlfo_eh_dbase,
|
||||
+# else
|
||||
+ NULL,
|
||||
+# endif
|
||||
+ bases);
|
||||
+ else
|
||||
+ return NULL;
|
||||
+ }
|
||||
+#endif /* DLFO_STRUCT_HAS_EH_DBASE */
|
||||
+
|
||||
data.pc = (_Unwind_Ptr) pc;
|
||||
#if NEED_DBASE_MEMBER
|
||||
data.dbase = NULL;
|
||||
27
SOURCES/gcc-RHEL-105072-5.patch
Normal file
27
SOURCES/gcc-RHEL-105072-5.patch
Normal file
@ -0,0 +1,27 @@
|
||||
commit ab2a2457780d224343ce05e7d8e2964c6a47fd83
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Jan 25 12:09:56 2022 +0100
|
||||
|
||||
libgcc: Fix _Unwind_Find_FDE for missing unwind data with glibc 2.35
|
||||
|
||||
_dl_find_object returns success even if no unwind information has been
|
||||
found, and dlfo_eh_frame is NULL.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
PR libgcc/104207
|
||||
* unwind-dw2-fde-dip.c (_Unwind_Find_FDE): Add NULL check.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index b837d8e490425652..1744c91958013ebb 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -509,7 +509,7 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
#ifdef DLFO_STRUCT_HAS_EH_DBASE
|
||||
{
|
||||
struct dl_find_object dlfo;
|
||||
- if (_dl_find_object (pc, &dlfo) == 0)
|
||||
+ if (_dl_find_object (pc, &dlfo) == 0 && dlfo.dlfo_eh_frame != NULL)
|
||||
return find_fde_tail ((_Unwind_Ptr) pc, dlfo.dlfo_eh_frame,
|
||||
# if DLFO_STRUCT_HAS_EH_DBASE
|
||||
(_Unwind_Ptr) dlfo.dlfo_eh_dbase,
|
||||
28
SOURCES/gcc-RHEL-105072-6.patch
Normal file
28
SOURCES/gcc-RHEL-105072-6.patch
Normal file
@ -0,0 +1,28 @@
|
||||
commit 157cc4e0117756503c7c63df97cf31de7570b088
|
||||
Author: Xi Ruoyao <xry111@mengyan1223.wang>
|
||||
Date: Fri Feb 25 01:45:57 2022 +0800
|
||||
|
||||
libgcc: fix a warning calling find_fde_tail
|
||||
|
||||
The third parameter of find_fde_tail is an _Unwind_Ptr (which is an
|
||||
integer type instead of a pointer), but we are passing NULL to it. This
|
||||
causes a -Wint-conversion warning.
|
||||
|
||||
libgcc/
|
||||
|
||||
* unwind-dw2-fde-dip.c (_Unwind_Find_FDE): Call find_fde_tail
|
||||
with 0 instead of NULL.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
|
||||
index 1744c91958013ebb..25f2e44c5823cf64 100644
|
||||
--- a/libgcc/unwind-dw2-fde-dip.c
|
||||
+++ b/libgcc/unwind-dw2-fde-dip.c
|
||||
@@ -514,7 +514,7 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
# if DLFO_STRUCT_HAS_EH_DBASE
|
||||
(_Unwind_Ptr) dlfo.dlfo_eh_dbase,
|
||||
# else
|
||||
- NULL,
|
||||
+ 0,
|
||||
# endif
|
||||
bases);
|
||||
else
|
||||
222
SOURCES/gcc-RHEL-105072-7.patch
Normal file
222
SOURCES/gcc-RHEL-105072-7.patch
Normal file
@ -0,0 +1,222 @@
|
||||
commit 0d344b557604e966dc7f91739881f03e1f221efd
|
||||
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
Date: Thu Feb 10 17:42:56 2022 +0000
|
||||
|
||||
aarch64: Fix pac-ret with unusual dwarf in libgcc unwinder [PR104689]
|
||||
|
||||
The RA_SIGN_STATE dwarf pseudo-register is normally only set using the
|
||||
DW_CFA_AARCH64_negate_ra_state (== DW_CFA_window_save) operation which
|
||||
toggles the return address signedness state (the default state is 0).
|
||||
(It may be set by remember/restore_state CFI too, those save/restore
|
||||
the state of all registers.)
|
||||
|
||||
However RA_SIGN_STATE can be set directly via DW_CFA_val_expression too.
|
||||
GCC does not generate such CFI but some other compilers reportedly do.
|
||||
|
||||
Note: the toggle operation must not be mixed with other dwarf register
|
||||
rule CFI within the same CIE and FDE.
|
||||
|
||||
In libgcc we assume REG_UNSAVED means the RA_STATE is set using toggle
|
||||
operations, otherwise we assume its value is set by other CFI.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
PR target/104689
|
||||
* config/aarch64/aarch64-unwind.h (aarch64_frob_update_context):
|
||||
Handle the !REG_UNSAVED case.
|
||||
* unwind-dw2.c (execute_cfa_program): Fail toggle if !REG_UNSAVED.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
PR target/104689
|
||||
* gcc.target/aarch64/pr104689.c: New test.
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/pr104689.c b/gcc/testsuite/gcc.target/aarch64/pr104689.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..3b7adbdfe7d6f969
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/pr104689.c
|
||||
@@ -0,0 +1,149 @@
|
||||
+/* PR target/104689. Unwind across pac-ret frames with unusual dwarf. */
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-require-effective-target lp64 } */
|
||||
+/* { dg-options "-fexceptions -O2" } */
|
||||
+
|
||||
+#include <unwind.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#define die() \
|
||||
+ do { \
|
||||
+ printf ("%s:%d: reached unexpectedly.\n", __FILE__, __LINE__); \
|
||||
+ fflush (stdout); \
|
||||
+ abort (); \
|
||||
+ } while (0)
|
||||
+
|
||||
+
|
||||
+/* Code to invoke unwinding with a logging callback. */
|
||||
+
|
||||
+static struct _Unwind_Exception exc;
|
||||
+
|
||||
+static _Unwind_Reason_Code
|
||||
+force_unwind_stop (int version, _Unwind_Action actions,
|
||||
+ _Unwind_Exception_Class exc_class,
|
||||
+ struct _Unwind_Exception *exc_obj,
|
||||
+ struct _Unwind_Context *context,
|
||||
+ void *stop_parameter)
|
||||
+{
|
||||
+ printf ("%s: CFA: %p PC: %p actions: %d\n",
|
||||
+ __func__,
|
||||
+ (void *)_Unwind_GetCFA (context),
|
||||
+ (void *)_Unwind_GetIP (context),
|
||||
+ (int)actions);
|
||||
+ if (actions & _UA_END_OF_STACK)
|
||||
+ die ();
|
||||
+ return _URC_NO_REASON;
|
||||
+}
|
||||
+
|
||||
+static void force_unwind (void)
|
||||
+{
|
||||
+#ifndef __USING_SJLJ_EXCEPTIONS__
|
||||
+ _Unwind_ForcedUnwind (&exc, force_unwind_stop, 0);
|
||||
+#else
|
||||
+ _Unwind_SjLj_ForcedUnwind (&exc, force_unwind_stop, 0);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Define functions with unusual pac-ret dwarf via top level asm. */
|
||||
+
|
||||
+#define STR(x) #x
|
||||
+#define DW_CFA_val_expression 0x16
|
||||
+#define RA_SIGN_STATE 34
|
||||
+#define DW_OP_lit0 0x30
|
||||
+#define DW_OP_lit1 0x31
|
||||
+
|
||||
+#define cfi_escape(a1, a2, a3, a4) \
|
||||
+ ".cfi_escape " STR(a1) ", " STR(a2) ", " STR(a3) ", " STR(a4)
|
||||
+
|
||||
+/* Bytes: 0x16 0x22 0x01 0x30 */
|
||||
+#define SET_RA_STATE_0 \
|
||||
+ cfi_escape (DW_CFA_val_expression, RA_SIGN_STATE, 1, DW_OP_lit0)
|
||||
+
|
||||
+/* Bytes: 0x16 0x22 0x01 0x31 */
|
||||
+#define SET_RA_STATE_1 \
|
||||
+ cfi_escape (DW_CFA_val_expression, RA_SIGN_STATE, 1, DW_OP_lit1)
|
||||
+
|
||||
+/* These function call their argument. */
|
||||
+void unusual_pac_ret (void *);
|
||||
+void unusual_no_pac_ret (void *);
|
||||
+
|
||||
+asm(""
|
||||
+".global unusual_pac_ret\n"
|
||||
+".type unusual_pac_ret, %function\n"
|
||||
+"unusual_pac_ret:\n"
|
||||
+" .cfi_startproc\n"
|
||||
+" " SET_RA_STATE_0 "\n"
|
||||
+" hint 25 // paciasp\n"
|
||||
+" " SET_RA_STATE_1 "\n"
|
||||
+" stp x29, x30, [sp, -16]!\n"
|
||||
+" .cfi_def_cfa_offset 16\n"
|
||||
+" .cfi_offset 29, -16\n"
|
||||
+" .cfi_offset 30, -8\n"
|
||||
+" mov x29, sp\n"
|
||||
+" blr x0\n"
|
||||
+" ldp x29, x30, [sp], 16\n"
|
||||
+" .cfi_restore 30\n"
|
||||
+" .cfi_restore 29\n"
|
||||
+" .cfi_def_cfa_offset 0\n"
|
||||
+" hint 29 // autiasp\n"
|
||||
+" " SET_RA_STATE_0 "\n"
|
||||
+" ret\n"
|
||||
+" .cfi_endproc\n");
|
||||
+
|
||||
+asm(""
|
||||
+".global unusual_no_pac_ret\n"
|
||||
+".type unusual_no_pac_ret, %function\n"
|
||||
+"unusual_no_pac_ret:\n"
|
||||
+" .cfi_startproc\n"
|
||||
+" " SET_RA_STATE_0 "\n"
|
||||
+" stp x29, x30, [sp, -16]!\n"
|
||||
+" .cfi_def_cfa_offset 16\n"
|
||||
+" .cfi_offset 29, -16\n"
|
||||
+" .cfi_offset 30, -8\n"
|
||||
+" mov x29, sp\n"
|
||||
+" blr x0\n"
|
||||
+" ldp x29, x30, [sp], 16\n"
|
||||
+" .cfi_restore 30\n"
|
||||
+" .cfi_restore 29\n"
|
||||
+" .cfi_def_cfa_offset 0\n"
|
||||
+" ret\n"
|
||||
+" .cfi_endproc\n");
|
||||
+
|
||||
+
|
||||
+/* Functions to create a call chain with mixed pac-ret dwarf. */
|
||||
+
|
||||
+__attribute__((target("branch-protection=pac-ret")))
|
||||
+static void f2_pac_ret (void)
|
||||
+{
|
||||
+ force_unwind ();
|
||||
+ die ();
|
||||
+}
|
||||
+
|
||||
+__attribute__((target("branch-protection=none")))
|
||||
+static void f1_no_pac_ret (void)
|
||||
+{
|
||||
+ unusual_pac_ret (f2_pac_ret);
|
||||
+ die ();
|
||||
+}
|
||||
+
|
||||
+__attribute__((noinline, target("branch-protection=pac-ret")))
|
||||
+static void f0_pac_ret (void)
|
||||
+{
|
||||
+ unusual_no_pac_ret (f1_no_pac_ret);
|
||||
+ die ();
|
||||
+}
|
||||
+
|
||||
+static void cleanup_handler (void *p)
|
||||
+{
|
||||
+ printf ("%s: Success.\n", __func__);
|
||||
+ exit (0);
|
||||
+}
|
||||
+
|
||||
+int main ()
|
||||
+{
|
||||
+ char dummy __attribute__((cleanup (cleanup_handler)));
|
||||
+ f0_pac_ret ();
|
||||
+ die ();
|
||||
+}
|
||||
diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h
|
||||
index b6faa9b495094d8e..3158af4c8c371fac 100644
|
||||
--- a/libgcc/config/aarch64/aarch64-unwind.h
|
||||
+++ b/libgcc/config/aarch64/aarch64-unwind.h
|
||||
@@ -78,7 +78,13 @@ static inline void
|
||||
aarch64_frob_update_context (struct _Unwind_Context *context,
|
||||
_Unwind_FrameState *fs)
|
||||
{
|
||||
- if (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 0x1)
|
||||
+ const int reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
+ int ra_signed;
|
||||
+ if (fs->regs.reg[reg].how == REG_UNSAVED)
|
||||
+ ra_signed = fs->regs.reg[reg].loc.offset & 0x1;
|
||||
+ else
|
||||
+ ra_signed = _Unwind_GetGR (context, reg) & 0x1;
|
||||
+ if (ra_signed)
|
||||
/* The flag is used for re-authenticating EH handler's address. */
|
||||
context->flags |= RA_SIGNED_BIT;
|
||||
else
|
||||
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
|
||||
index 41af7e23f47602ec..43d06531fce9bed1 100644
|
||||
--- a/libgcc/unwind-dw2.c
|
||||
+++ b/libgcc/unwind-dw2.c
|
||||
@@ -1204,7 +1204,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
|
||||
#if defined (__aarch64__) && !defined (__ILP32__)
|
||||
/* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle
|
||||
return address signing status. */
|
||||
- fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset ^= 1;
|
||||
+ reg = DWARF_REGNUM_AARCH64_RA_STATE;
|
||||
+ gcc_assert (fs->regs.reg[reg].how == REG_UNSAVED);
|
||||
+ fs->regs.reg[reg].loc.offset ^= 1;
|
||||
#else
|
||||
/* ??? Hardcoded for SPARC register window configuration. */
|
||||
if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)
|
||||
1354
SOURCES/gcc-RHEL-105072-8.patch
Normal file
1354
SOURCES/gcc-RHEL-105072-8.patch
Normal file
File diff suppressed because it is too large
Load Diff
377
SOURCES/gcc-RHEL-105072-9.patch
Normal file
377
SOURCES/gcc-RHEL-105072-9.patch
Normal file
@ -0,0 +1,377 @@
|
||||
commit d458f806afe07d1e06bdf275e94d05a716f41bf6
|
||||
Author: Thomas Neumann <tneumann@users.sourceforge.net>
|
||||
Date: Sun Sep 18 11:31:01 2022 +0200
|
||||
|
||||
Remove dependency on uintptr_t in libgcc
|
||||
|
||||
uintptr_t is no available for all targets, use __UINTPTR_TYPE__
|
||||
instead.
|
||||
|
||||
libgcc/ChangeLog:
|
||||
|
||||
* unwind-dw2-fde.c: Replace uintptr_t with typedef
|
||||
for __UINTPTR_TYPE__.
|
||||
* unwind-dw2-btree.h: Likewise.
|
||||
|
||||
diff --git a/libgcc/unwind-dw2-btree.h b/libgcc/unwind-dw2-btree.h
|
||||
index 8853f0eab486b847..ace507d9ffbdffb7 100644
|
||||
--- a/libgcc/unwind-dw2-btree.h
|
||||
+++ b/libgcc/unwind-dw2-btree.h
|
||||
@@ -39,7 +39,7 @@ struct version_lock
|
||||
// range. Even on 32 bit platforms that would require 1 billion
|
||||
// frame registrations within the time span of a few assembler
|
||||
// instructions.
|
||||
- uintptr_t version_lock;
|
||||
+ uintptr_type version_lock;
|
||||
};
|
||||
|
||||
#ifdef __GTHREAD_HAS_COND
|
||||
@@ -60,7 +60,7 @@ version_lock_initialize_locked_exclusive (struct version_lock *vl)
|
||||
static inline bool
|
||||
version_lock_try_lock_exclusive (struct version_lock *vl)
|
||||
{
|
||||
- uintptr_t state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
+ uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
if (state & 1)
|
||||
return false;
|
||||
return __atomic_compare_exchange_n (&(vl->version_lock), &state, state | 1,
|
||||
@@ -78,7 +78,7 @@ restart:
|
||||
|
||||
// We should virtually never get contention here, as frame
|
||||
// changes are rare.
|
||||
- uintptr_t state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
+ uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
if (!(state & 1))
|
||||
{
|
||||
if (__atomic_compare_exchange_n (&(vl->version_lock), &state, state | 1,
|
||||
@@ -134,8 +134,8 @@ static void
|
||||
version_lock_unlock_exclusive (struct version_lock *vl)
|
||||
{
|
||||
// increase version, reset exclusive lock bits
|
||||
- uintptr_t state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
- uintptr_t ns = (state + 4) & (~((uintptr_t) 3));
|
||||
+ uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
+ uintptr_type ns = (state + 4) & (~((uintptr_type) 3));
|
||||
state = __atomic_exchange_n (&(vl->version_lock), ns, __ATOMIC_SEQ_CST);
|
||||
|
||||
#ifdef __GTHREAD_HAS_COND
|
||||
@@ -152,9 +152,9 @@ version_lock_unlock_exclusive (struct version_lock *vl)
|
||||
// Acquire an optimistic "lock". Note that this does not lock at all, it
|
||||
// only allows for validation later.
|
||||
static inline bool
|
||||
-version_lock_lock_optimistic (const struct version_lock *vl, uintptr_t *lock)
|
||||
+version_lock_lock_optimistic (const struct version_lock *vl, uintptr_type *lock)
|
||||
{
|
||||
- uintptr_t state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
+ uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
*lock = state;
|
||||
|
||||
// Acquiring the lock fails when there is currently an exclusive lock.
|
||||
@@ -163,7 +163,7 @@ version_lock_lock_optimistic (const struct version_lock *vl, uintptr_t *lock)
|
||||
|
||||
// Validate a previously acquired "lock".
|
||||
static inline bool
|
||||
-version_lock_validate (const struct version_lock *vl, uintptr_t lock)
|
||||
+version_lock_validate (const struct version_lock *vl, uintptr_type lock)
|
||||
{
|
||||
// Prevent the reordering of non-atomic loads behind the atomic load.
|
||||
// Hans Boehm, Can Seqlocks Get Along with Programming Language Memory
|
||||
@@ -171,26 +171,26 @@ version_lock_validate (const struct version_lock *vl, uintptr_t lock)
|
||||
__atomic_thread_fence (__ATOMIC_ACQUIRE);
|
||||
|
||||
// Check that the node is still in the same state.
|
||||
- uintptr_t state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
+ uintptr_type state = __atomic_load_n (&(vl->version_lock), __ATOMIC_SEQ_CST);
|
||||
return (state == lock);
|
||||
}
|
||||
|
||||
// The largest possible separator value.
|
||||
-static const uintptr_t max_separator = ~((uintptr_t) (0));
|
||||
+static const uintptr_type max_separator = ~((uintptr_type) (0));
|
||||
|
||||
struct btree_node;
|
||||
|
||||
// Inner entry. The child tree contains all entries <= separator.
|
||||
struct inner_entry
|
||||
{
|
||||
- uintptr_t separator;
|
||||
+ uintptr_type separator;
|
||||
struct btree_node *child;
|
||||
};
|
||||
|
||||
// Leaf entry. Stores an object entry.
|
||||
struct leaf_entry
|
||||
{
|
||||
- uintptr_t base, size;
|
||||
+ uintptr_type base, size;
|
||||
struct object *ob;
|
||||
};
|
||||
|
||||
@@ -248,7 +248,7 @@ btree_node_needs_merge (const struct btree_node *n)
|
||||
}
|
||||
|
||||
// Get the fence key for inner nodes.
|
||||
-static inline uintptr_t
|
||||
+static inline uintptr_type
|
||||
btree_node_get_fence_key (const struct btree_node *n)
|
||||
{
|
||||
// For inner nodes we just return our right-most entry.
|
||||
@@ -257,7 +257,7 @@ btree_node_get_fence_key (const struct btree_node *n)
|
||||
|
||||
// Find the position for a slot in an inner node.
|
||||
static unsigned
|
||||
-btree_node_find_inner_slot (const struct btree_node *n, uintptr_t value)
|
||||
+btree_node_find_inner_slot (const struct btree_node *n, uintptr_type value)
|
||||
{
|
||||
for (unsigned index = 0, ec = n->entry_count; index != ec; ++index)
|
||||
if (n->content.children[index].separator >= value)
|
||||
@@ -267,7 +267,7 @@ btree_node_find_inner_slot (const struct btree_node *n, uintptr_t value)
|
||||
|
||||
// Find the position for a slot in a leaf node.
|
||||
static unsigned
|
||||
-btree_node_find_leaf_slot (const struct btree_node *n, uintptr_t value)
|
||||
+btree_node_find_leaf_slot (const struct btree_node *n, uintptr_type value)
|
||||
{
|
||||
for (unsigned index = 0, ec = n->entry_count; index != ec; ++index)
|
||||
if (n->content.entries[index].base + n->content.entries[index].size > value)
|
||||
@@ -299,14 +299,14 @@ btree_node_unlock_exclusive (struct btree_node *n)
|
||||
// Acquire an optimistic "lock". Note that this does not lock at all, it
|
||||
// only allows for validation later.
|
||||
static inline bool
|
||||
-btree_node_lock_optimistic (const struct btree_node *n, uintptr_t *lock)
|
||||
+btree_node_lock_optimistic (const struct btree_node *n, uintptr_type *lock)
|
||||
{
|
||||
return version_lock_lock_optimistic (&(n->version_lock), lock);
|
||||
}
|
||||
|
||||
// Validate a previously acquire lock.
|
||||
static inline bool
|
||||
-btree_node_validate (const struct btree_node *n, uintptr_t lock)
|
||||
+btree_node_validate (const struct btree_node *n, uintptr_type lock)
|
||||
{
|
||||
return version_lock_validate (&(n->version_lock), lock);
|
||||
}
|
||||
@@ -314,8 +314,8 @@ btree_node_validate (const struct btree_node *n, uintptr_t lock)
|
||||
// Insert a new separator after splitting.
|
||||
static void
|
||||
btree_node_update_separator_after_split (struct btree_node *n,
|
||||
- uintptr_t old_separator,
|
||||
- uintptr_t new_separator,
|
||||
+ uintptr_type old_separator,
|
||||
+ uintptr_type new_separator,
|
||||
struct btree_node *new_right)
|
||||
{
|
||||
unsigned slot = btree_node_find_inner_slot (n, old_separator);
|
||||
@@ -474,13 +474,13 @@ btree_handle_root_split (struct btree *t, struct btree_node **node,
|
||||
// Split an inner node.
|
||||
static void
|
||||
btree_split_inner (struct btree *t, struct btree_node **inner,
|
||||
- struct btree_node **parent, uintptr_t target)
|
||||
+ struct btree_node **parent, uintptr_type target)
|
||||
{
|
||||
// Check for the root.
|
||||
btree_handle_root_split (t, inner, parent);
|
||||
|
||||
// Create two inner node.
|
||||
- uintptr_t right_fence = btree_node_get_fence_key (*inner);
|
||||
+ uintptr_type right_fence = btree_node_get_fence_key (*inner);
|
||||
struct btree_node *left_inner = *inner;
|
||||
struct btree_node *right_inner = btree_allocate_node (t, true);
|
||||
unsigned split = left_inner->entry_count / 2;
|
||||
@@ -489,7 +489,7 @@ btree_split_inner (struct btree *t, struct btree_node **inner,
|
||||
right_inner->content.children[index]
|
||||
= left_inner->content.children[split + index];
|
||||
left_inner->entry_count = split;
|
||||
- uintptr_t left_fence = btree_node_get_fence_key (left_inner);
|
||||
+ uintptr_type left_fence = btree_node_get_fence_key (left_inner);
|
||||
btree_node_update_separator_after_split (*parent, right_fence, left_fence,
|
||||
right_inner);
|
||||
if (target <= left_fence)
|
||||
@@ -507,13 +507,14 @@ btree_split_inner (struct btree *t, struct btree_node **inner,
|
||||
// Split a leaf node.
|
||||
static void
|
||||
btree_split_leaf (struct btree *t, struct btree_node **leaf,
|
||||
- struct btree_node **parent, uintptr_t fence, uintptr_t target)
|
||||
+ struct btree_node **parent, uintptr_type fence,
|
||||
+ uintptr_type target)
|
||||
{
|
||||
// Check for the root.
|
||||
btree_handle_root_split (t, leaf, parent);
|
||||
|
||||
// Create two leaf nodes.
|
||||
- uintptr_t right_fence = fence;
|
||||
+ uintptr_type right_fence = fence;
|
||||
struct btree_node *left_leaf = *leaf;
|
||||
struct btree_node *right_leaf = btree_allocate_node (t, false);
|
||||
unsigned split = left_leaf->entry_count / 2;
|
||||
@@ -522,7 +523,7 @@ btree_split_leaf (struct btree *t, struct btree_node **leaf,
|
||||
right_leaf->content.entries[index]
|
||||
= left_leaf->content.entries[split + index];
|
||||
left_leaf->entry_count = split;
|
||||
- uintptr_t left_fence = right_leaf->content.entries[0].base - 1;
|
||||
+ uintptr_type left_fence = right_leaf->content.entries[0].base - 1;
|
||||
btree_node_update_separator_after_split (*parent, right_fence, left_fence,
|
||||
right_leaf);
|
||||
if (target <= left_fence)
|
||||
@@ -540,7 +541,7 @@ btree_split_leaf (struct btree *t, struct btree_node **leaf,
|
||||
// Merge (or balance) child nodes.
|
||||
static struct btree_node *
|
||||
btree_merge_node (struct btree *t, unsigned child_slot,
|
||||
- struct btree_node *parent, uintptr_t target)
|
||||
+ struct btree_node *parent, uintptr_type target)
|
||||
{
|
||||
// Choose the emptiest neighbor and lock both. The target child is already
|
||||
// locked.
|
||||
@@ -693,7 +694,7 @@ btree_merge_node (struct btree *t, unsigned child_slot,
|
||||
left_node->entry_count += to_shift;
|
||||
right_node->entry_count -= to_shift;
|
||||
}
|
||||
- uintptr_t left_fence;
|
||||
+ uintptr_type left_fence;
|
||||
if (btree_node_is_leaf (left_node))
|
||||
{
|
||||
left_fence = right_node->content.entries[0].base - 1;
|
||||
@@ -718,7 +719,7 @@ btree_merge_node (struct btree *t, unsigned child_slot,
|
||||
|
||||
// Insert an entry.
|
||||
static bool
|
||||
-btree_insert (struct btree *t, uintptr_t base, uintptr_t size,
|
||||
+btree_insert (struct btree *t, uintptr_type base, uintptr_type size,
|
||||
struct object *ob)
|
||||
{
|
||||
// Sanity check.
|
||||
@@ -747,7 +748,7 @@ btree_insert (struct btree *t, uintptr_t base, uintptr_t size,
|
||||
// But that is more difficult to implement and frame registration is
|
||||
// rare anyway, we use simple locking for now.
|
||||
|
||||
- uintptr_t fence = max_separator;
|
||||
+ uintptr_type fence = max_separator;
|
||||
while (btree_node_is_inner (iter))
|
||||
{
|
||||
// Use eager splits to avoid lock coupling up.
|
||||
@@ -790,7 +791,7 @@ btree_insert (struct btree *t, uintptr_t base, uintptr_t size,
|
||||
|
||||
// Remove an entry.
|
||||
static struct object *
|
||||
-btree_remove (struct btree *t, uintptr_t base)
|
||||
+btree_remove (struct btree *t, uintptr_type base)
|
||||
{
|
||||
// Access the root.
|
||||
version_lock_lock_exclusive (&(t->root_lock));
|
||||
@@ -838,7 +839,7 @@ btree_remove (struct btree *t, uintptr_t base)
|
||||
|
||||
// Find the corresponding entry for the given address.
|
||||
static struct object *
|
||||
-btree_lookup (const struct btree *t, uintptr_t target_addr)
|
||||
+btree_lookup (const struct btree *t, uintptr_type target_addr)
|
||||
{
|
||||
// Within this function many loads are relaxed atomic loads.
|
||||
// Use a macro to keep the code reasonable.
|
||||
@@ -867,7 +868,7 @@ btree_lookup (const struct btree *t, uintptr_t target_addr)
|
||||
|
||||
restart:
|
||||
struct btree_node *iter;
|
||||
- uintptr_t lock;
|
||||
+ uintptr_type lock;
|
||||
{
|
||||
// Accessing the root node requires defending against concurrent pointer
|
||||
// changes Thus we couple rootLock -> lock on root node -> validate rootLock
|
||||
@@ -878,7 +879,7 @@ restart:
|
||||
goto restart;
|
||||
if (!iter)
|
||||
return NULL;
|
||||
- uintptr_t child_lock;
|
||||
+ uintptr_type child_lock;
|
||||
if ((!btree_node_lock_optimistic (iter, &child_lock))
|
||||
|| (!version_lock_validate (&(t->root_lock), lock)))
|
||||
goto restart;
|
||||
@@ -910,7 +911,7 @@ restart:
|
||||
|
||||
// The node content can change at any point in time, thus we must
|
||||
// interleave parent and child checks.
|
||||
- uintptr_t child_lock;
|
||||
+ uintptr_type child_lock;
|
||||
if (!btree_node_lock_optimistic (child, &child_lock))
|
||||
goto restart;
|
||||
if (!btree_node_validate (iter, lock))
|
||||
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
|
||||
index a591faaa579b5883..f38efd3c09efc3e9 100644
|
||||
--- a/libgcc/unwind-dw2-fde.c
|
||||
+++ b/libgcc/unwind-dw2-fde.c
|
||||
@@ -42,6 +42,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+typedef __UINTPTR_TYPE__ uintptr_type;
|
||||
+
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
#include "unwind-dw2-btree.h"
|
||||
|
||||
@@ -58,7 +60,7 @@ release_registered_frames (void)
|
||||
}
|
||||
|
||||
static void
|
||||
-get_pc_range (const struct object *ob, uintptr_t *range);
|
||||
+get_pc_range (const struct object *ob, uintptr_type *range);
|
||||
static void
|
||||
init_object (struct object *ob);
|
||||
|
||||
@@ -124,7 +126,7 @@ __register_frame_info_bases (const void *begin, struct object *ob,
|
||||
init_object (ob);
|
||||
|
||||
// And register the frame
|
||||
- uintptr_t range[2];
|
||||
+ uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
#else
|
||||
@@ -178,7 +180,7 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
|
||||
init_object (ob);
|
||||
|
||||
// And register the frame
|
||||
- uintptr_t range[2];
|
||||
+ uintptr_type range[2];
|
||||
get_pc_range (ob, range);
|
||||
btree_insert (®istered_frames, range[0], range[1] - range[0], ob);
|
||||
#else
|
||||
@@ -237,7 +239,7 @@ __deregister_frame_info_bases (const void *begin)
|
||||
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
||||
lookupob.fde_end = NULL;
|
||||
#endif
|
||||
- uintptr_t range[2];
|
||||
+ uintptr_type range[2];
|
||||
get_pc_range (&lookupob, range);
|
||||
|
||||
// And remove
|
||||
@@ -677,7 +679,7 @@ end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
|
||||
|
||||
static size_t
|
||||
classify_object_over_fdes (struct object *ob, const fde *this_fde,
|
||||
- uintptr_t *range)
|
||||
+ uintptr_type *range)
|
||||
{
|
||||
const struct dwarf_cie *last_cie = 0;
|
||||
size_t count = 0;
|
||||
@@ -892,11 +894,11 @@ init_object (struct object* ob)
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
/* Get the PC range for lookup */
|
||||
static void
|
||||
-get_pc_range (const struct object *ob, uintptr_t *range)
|
||||
+get_pc_range (const struct object *ob, uintptr_type *range)
|
||||
{
|
||||
// It is safe to cast to non-const object* here as
|
||||
// classify_object_over_fdes does not modify ob in query mode.
|
||||
- struct object *ncob = (struct object *) (uintptr_t) ob;
|
||||
+ struct object *ncob = (struct object *) (uintptr_type) ob;
|
||||
range[0] = range[1] = 0;
|
||||
if (ob->s.b.sorted)
|
||||
{
|
||||
@@ -1131,7 +1133,7 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
|
||||
const fde *f = NULL;
|
||||
|
||||
#ifdef ATOMIC_FDE_FAST_PATH
|
||||
- ob = btree_lookup (®istered_frames, (uintptr_t) pc);
|
||||
+ ob = btree_lookup (®istered_frames, (uintptr_type) pc);
|
||||
if (!ob)
|
||||
return NULL;
|
||||
|
||||
@ -96,10 +96,10 @@ Date: Wed Oct 6 14:33:59 2021 -0400
|
||||
* c-c++-common/Wbidi-chars-17.c: New test.
|
||||
|
||||
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
|
||||
index f591b39be5a..cf922812198 100644
|
||||
index 8a4cd634f77..3976fc368db 100644
|
||||
--- a/gcc/c-family/c.opt
|
||||
+++ b/gcc/c-family/c.opt
|
||||
@@ -334,6 +334,30 @@ Wbad-function-cast
|
||||
@@ -374,6 +374,30 @@ Wbad-function-cast
|
||||
C ObjC Var(warn_bad_function_cast) Warning
|
||||
Warn about casting functions to incompatible types.
|
||||
|
||||
@ -131,22 +131,23 @@ index f591b39be5a..cf922812198 100644
|
||||
C ObjC C++ ObjC++ Var(warn_bool_compare) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
|
||||
Warn about boolean expression compared with an integer value different from true/false.
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 78ca7738df2..cc85c53aede 100644
|
||||
index 6070288856c..a22758d18ee 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -264,7 +264,8 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-Walloc-zero -Walloc-size-larger-than=@var{n}
|
||||
-Walloca -Walloca-larger-than=@var{n} @gol
|
||||
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
|
||||
--Wno-attributes -Wbool-compare -Wbool-operation @gol
|
||||
+-Wno-attributes -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} @gol
|
||||
@@ -325,7 +325,9 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-Warith-conversion @gol
|
||||
-Warray-bounds -Warray-bounds=@var{n} @gol
|
||||
-Wno-attributes -Wattribute-alias=@var{n} -Wno-attribute-alias @gol
|
||||
--Wno-attribute-warning -Wbool-compare -Wbool-operation @gol
|
||||
+-Wno-attribute-warning @gol
|
||||
+-Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]} @gol
|
||||
+-Wbool-compare -Wbool-operation @gol
|
||||
-Wno-builtin-declaration-mismatch @gol
|
||||
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
|
||||
-Wc++-compat -Wc++11-compat -Wc++14-compat @gol
|
||||
@@ -5606,6 +5607,23 @@ Warn about declarations using the @code{alias} and similar attributes whose
|
||||
target is incompatible with the type of the alias. @xref{Function Attributes,
|
||||
,Declaring Attributes of Functions}.
|
||||
-Wc11-c2x-compat @gol
|
||||
@@ -7557,6 +7559,23 @@ Attributes considered include @code{alloc_align}, @code{alloc_size},
|
||||
This is the default. You can disable these warnings with either
|
||||
@option{-Wno-attribute-alias} or @option{-Wattribute-alias=0}.
|
||||
|
||||
+@item -Wbidi-chars=@r{[}none@r{|}unpaired@r{|}any@r{]}
|
||||
+@opindex Wbidi-chars=
|
||||
@ -221,15 +222,19 @@ index 00000000000..3f851b69e65
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-11.c b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c
|
||||
new file mode 100644
|
||||
index 00000000000..44d044d82de
|
||||
index 00000000000..270ce2368a9
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-11.c
|
||||
@@ -0,0 +1,9 @@
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* PR preprocessor/103026 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-Wbidi-chars=unpaired" } */
|
||||
+/* Test that we warn when mixing UCN and UTF-8. */
|
||||
+
|
||||
+int LRE__PDF_\u202c;
|
||||
+/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */
|
||||
+int LRE_\u202a_PDF__;
|
||||
+/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */
|
||||
+const char *s1 = "LRE__PDF_\u202c";
|
||||
+/* { dg-warning "mismatch" "" { target *-*-* } .-1 } */
|
||||
+const char *s2 = "LRE_\u202a_PDF_";
|
||||
@ -493,10 +498,10 @@ index 00000000000..9dc7edb6e64
|
||||
+}
|
||||
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-4.c b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c
|
||||
new file mode 100644
|
||||
index 00000000000..49f856b9bfe
|
||||
index 00000000000..639e5c62e88
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-4.c
|
||||
@@ -0,0 +1,172 @@
|
||||
@@ -0,0 +1,188 @@
|
||||
+/* PR preprocessor/103026 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-Wbidi-chars=any -Wno-multichar -Wno-overflow" } */
|
||||
@ -640,6 +645,22 @@ index 00000000000..49f856b9bfe
|
||||
+/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */
|
||||
+}
|
||||
+
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+202A" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+202B" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+202D" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+202E" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+2066" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+2067" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-warning "U\\+2068" "" { target *-*-* } .-1 } */
|
||||
+int AX;
|
||||
+/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */
|
||||
+int A\u202cY;
|
||||
+/* { dg-warning "U\\+202C" "" { target *-*-* } .-1 } */
|
||||
+int A\u202CY2;
|
||||
@ -671,10 +692,10 @@ index 00000000000..49f856b9bfe
|
||||
+/* { dg-warning "U\\+2069" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-5.c b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c
|
||||
new file mode 100644
|
||||
index 00000000000..f5776806c79
|
||||
index 00000000000..68cb053144b
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-5.c
|
||||
@@ -0,0 +1,172 @@
|
||||
@@ -0,0 +1,188 @@
|
||||
+/* PR preprocessor/103026 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-Wbidi-chars=unpaired -Wno-multichar -Wno-overflow" } */
|
||||
@ -818,6 +839,22 @@ index 00000000000..f5776806c79
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+}
|
||||
+
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int abc;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int AX;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int A\u202cY;
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int A\u202CY2;
|
||||
@ -849,10 +886,10 @@ index 00000000000..f5776806c79
|
||||
+/* { dg-bogus "unpaired" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-6.c b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c
|
||||
new file mode 100644
|
||||
index 00000000000..a65d6faf60e
|
||||
index 00000000000..0ce6fff2dee
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/c-c++-common/Wbidi-chars-6.c
|
||||
@@ -0,0 +1,130 @@
|
||||
@@ -0,0 +1,155 @@
|
||||
+/* PR preprocessor/103026 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-Wbidi-chars=unpaired" } */
|
||||
@ -963,24 +1000,49 @@ index 00000000000..a65d6faf60e
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+}
|
||||
+
|
||||
+int aLREbPDI;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int A\u202aB\u2069C;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aRLEbPDI;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a\u202bB\u2069c;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aLRObPDI;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a\u202db\u2069c2;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aRLObPDI;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a\u202eb\u2069;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aLRIbPDF;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a\u2066b\u202c;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aRLIbPDFc
|
||||
+;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-2 } */
|
||||
+int a\u2067b\u202c;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aFSIbPDF;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a\u2068b\u202c;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aFSIbPD\u202C;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aFSI\u2068bPDF_;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int aLREbPDFb;
|
||||
+int A\u202aB\u202c;
|
||||
+int a_LRE_LRE_b_PDF_PDF;
|
||||
+int A\u202aA\u202aB\u202cB\u202c;
|
||||
+int aPDFbLREadPDF;
|
||||
+int a_\u202C_\u202a_\u202c;
|
||||
+int a_LRE_b_PDF_c_LRE_PDF;
|
||||
+int a_\u202a_\u202c_\u202a_\u202c_;
|
||||
+int a_LRE_b_PDF_c_LRE;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
+int a_\u202a_\u202c_\u202a_;
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/c-c++-common/Wbidi-chars-7.c b/gcc/testsuite/c-c++-common/Wbidi-chars-7.c
|
||||
@ -1053,11 +1115,11 @@ index 00000000000..e2af1b1ca97
|
||||
+int lre_\u202a; const char *s4 = "PDF\u202c";
|
||||
+/* { dg-warning "unpaired" "" { target *-*-* } .-1 } */
|
||||
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
|
||||
index 3ad52d5e01e..e0dcb7f0529 100644
|
||||
index 176f8c5bbce..112b9c24751 100644
|
||||
--- a/libcpp/include/cpplib.h
|
||||
+++ b/libcpp/include/cpplib.h
|
||||
@@ -305,6 +305,17 @@ enum cpp_normalize_level {
|
||||
normalized_none
|
||||
@@ -319,6 +319,17 @@ enum cpp_main_search
|
||||
CMS_system, /* Search the system INCLUDE path. */
|
||||
};
|
||||
|
||||
+/* The possible bidirectional control characters checking levels, from least
|
||||
@ -1074,7 +1136,7 @@ index 3ad52d5e01e..e0dcb7f0529 100644
|
||||
/* This structure is nested inside struct cpp_reader, and
|
||||
carries all the options visible to the command line. */
|
||||
struct cpp_options
|
||||
@@ -506,6 +517,10 @@ struct cpp_options
|
||||
@@ -539,6 +550,10 @@ struct cpp_options
|
||||
/* True if warn about differences between C++98 and C++11. */
|
||||
bool cpp_warn_cxx11_compat;
|
||||
|
||||
@ -1085,21 +1147,21 @@ index 3ad52d5e01e..e0dcb7f0529 100644
|
||||
/* Dependency generation. */
|
||||
struct
|
||||
{
|
||||
@@ -1063,7 +1078,8 @@ enum {
|
||||
CPP_W_PEDANTIC,
|
||||
@@ -643,7 +658,8 @@ enum cpp_warning_reason {
|
||||
CPP_W_C90_C99_COMPAT,
|
||||
CPP_W_C11_C2X_COMPAT,
|
||||
CPP_W_CXX11_COMPAT,
|
||||
- CPP_W_EXPANSION_TO_DEFINED
|
||||
+ CPP_W_EXPANSION_TO_DEFINED,
|
||||
+ CPP_W_BIDIRECTIONAL
|
||||
};
|
||||
|
||||
/* Output a diagnostic of some kind. */
|
||||
/* Callback for header lookup for HEADER, which is the name of a
|
||||
diff --git a/libcpp/init.c b/libcpp/init.c
|
||||
index ca3fbaa5c05..5c15da82ff8 100644
|
||||
index 5a424e23553..f9a8f5f088f 100644
|
||||
--- a/libcpp/init.c
|
||||
+++ b/libcpp/init.c
|
||||
@@ -208,6 +208,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
|
||||
@@ -223,6 +223,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
|
||||
= ENABLE_CANONICAL_SYSTEM_HEADERS;
|
||||
CPP_OPTION (pfile, ext_numeric_literals) = 1;
|
||||
CPP_OPTION (pfile, warn_date_time) = 0;
|
||||
@ -1108,13 +1170,13 @@ index ca3fbaa5c05..5c15da82ff8 100644
|
||||
/* Default CPP arithmetic to something sensible for the host for the
|
||||
benefit of dumb users like fix-header. */
|
||||
diff --git a/libcpp/internal.h b/libcpp/internal.h
|
||||
index 4f74f995cec..53b4c0f4af7 100644
|
||||
index 8577cab6c83..0ce0246c5a2 100644
|
||||
--- a/libcpp/internal.h
|
||||
+++ b/libcpp/internal.h
|
||||
@@ -576,6 +576,13 @@ struct cpp_reader
|
||||
/* If non-null, the lexer will use this location for the next token
|
||||
instead of getting a location from the linemap. */
|
||||
source_location *forced_token_location_p;
|
||||
@@ -597,6 +597,13 @@ struct cpp_reader
|
||||
/* Location identifying the main source file -- intended to be line
|
||||
zero of said file. */
|
||||
location_t main_loc;
|
||||
+
|
||||
+ /* Returns true iff we should warn about UTF-8 bidirectional control
|
||||
+ characters. */
|
||||
@ -1126,7 +1188,7 @@ index 4f74f995cec..53b4c0f4af7 100644
|
||||
|
||||
/* Character classes. Based on the more primitive macros in safe-ctype.h.
|
||||
diff --git a/libcpp/lex.c b/libcpp/lex.c
|
||||
index a408f912c5c..ea7f75e842e 100644
|
||||
index fa2253d41c3..6a4fbce6030 100644
|
||||
--- a/libcpp/lex.c
|
||||
+++ b/libcpp/lex.c
|
||||
@@ -1164,6 +1164,324 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
|
||||
@ -1134,12 +1196,12 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
}
|
||||
|
||||
+namespace bidi {
|
||||
+ enum kind {
|
||||
+ enum class kind {
|
||||
+ NONE, LRE, RLE, LRO, RLO, LRI, RLI, FSI, PDF, PDI, LTR, RTL
|
||||
+ };
|
||||
+
|
||||
+ /* All the UTF-8 encodings of bidi characters start with E2. */
|
||||
+ const uchar utf8_start = 0xe2;
|
||||
+ constexpr uchar utf8_start = 0xe2;
|
||||
+
|
||||
+ /* A vector holding currently open bidi contexts. We use a char for
|
||||
+ each context, its LSB is 1 if it represents a PDF context, 0 if it
|
||||
@ -1165,7 +1227,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ /* Return the context of the Ith element. */
|
||||
+ kind ctx_at (unsigned int i)
|
||||
+ {
|
||||
+ return (vec[i] & 1) ? PDF : PDI;
|
||||
+ return (vec[i] & 1) ? kind::PDF : kind::PDI;
|
||||
+ }
|
||||
+
|
||||
+ /* Return which context is currently opened. */
|
||||
@ -1173,7 +1235,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ {
|
||||
+ unsigned int len = vec.count ();
|
||||
+ if (len == 0)
|
||||
+ return NONE;
|
||||
+ return kind::NONE;
|
||||
+ return ctx_at (len - 1);
|
||||
+ }
|
||||
+
|
||||
@ -1191,40 +1253,40 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ {
|
||||
+ switch (k)
|
||||
+ {
|
||||
+ case LRE:
|
||||
+ case RLE:
|
||||
+ case LRO:
|
||||
+ case RLO:
|
||||
+ case kind::LRE:
|
||||
+ case kind::RLE:
|
||||
+ case kind::LRO:
|
||||
+ case kind::RLO:
|
||||
+ vec.push (ucn_p ? 3u : 1u);
|
||||
+ break;
|
||||
+ case LRI:
|
||||
+ case RLI:
|
||||
+ case FSI:
|
||||
+ case kind::LRI:
|
||||
+ case kind::RLI:
|
||||
+ case kind::FSI:
|
||||
+ vec.push (ucn_p ? 2u : 0u);
|
||||
+ break;
|
||||
+ /* PDF terminates the scope of the last LRE, RLE, LRO, or RLO
|
||||
+ whose scope has not yet been terminated. */
|
||||
+ case PDF:
|
||||
+ if (current_ctx () == PDF)
|
||||
+ case kind::PDF:
|
||||
+ if (current_ctx () == kind::PDF)
|
||||
+ pop ();
|
||||
+ break;
|
||||
+ /* PDI terminates the scope of the last LRI, RLI, or FSI whose
|
||||
+ scope has not yet been terminated, as well as the scopes of
|
||||
+ any subsequent LREs, RLEs, LROs, or RLOs whose scopes have not
|
||||
+ yet been terminated. */
|
||||
+ case PDI:
|
||||
+ case kind::PDI:
|
||||
+ for (int i = vec.count () - 1; i >= 0; --i)
|
||||
+ if (ctx_at (i) == PDI)
|
||||
+ if (ctx_at (i) == kind::PDI)
|
||||
+ {
|
||||
+ vec.truncate (i);
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ case LTR:
|
||||
+ case RTL:
|
||||
+ case kind::LTR:
|
||||
+ case kind::RTL:
|
||||
+ /* These aren't popped by a PDF/PDI. */
|
||||
+ break;
|
||||
+ [[likely]] case NONE:
|
||||
+ [[likely]] case kind::NONE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ abort ();
|
||||
@ -1236,27 +1298,27 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ {
|
||||
+ switch (k)
|
||||
+ {
|
||||
+ case LRE:
|
||||
+ case kind::LRE:
|
||||
+ return "U+202A (LEFT-TO-RIGHT EMBEDDING)";
|
||||
+ case RLE:
|
||||
+ case kind::RLE:
|
||||
+ return "U+202B (RIGHT-TO-LEFT EMBEDDING)";
|
||||
+ case LRO:
|
||||
+ case kind::LRO:
|
||||
+ return "U+202D (LEFT-TO-RIGHT OVERRIDE)";
|
||||
+ case RLO:
|
||||
+ case kind::RLO:
|
||||
+ return "U+202E (RIGHT-TO-LEFT OVERRIDE)";
|
||||
+ case LRI:
|
||||
+ case kind::LRI:
|
||||
+ return "U+2066 (LEFT-TO-RIGHT ISOLATE)";
|
||||
+ case RLI:
|
||||
+ case kind::RLI:
|
||||
+ return "U+2067 (RIGHT-TO-LEFT ISOLATE)";
|
||||
+ case FSI:
|
||||
+ case kind::FSI:
|
||||
+ return "U+2068 (FIRST STRONG ISOLATE)";
|
||||
+ case PDF:
|
||||
+ case kind::PDF:
|
||||
+ return "U+202C (POP DIRECTIONAL FORMATTING)";
|
||||
+ case PDI:
|
||||
+ case kind::PDI:
|
||||
+ return "U+2069 (POP DIRECTIONAL ISOLATE)";
|
||||
+ case LTR:
|
||||
+ case kind::LTR:
|
||||
+ return "U+200E (LEFT-TO-RIGHT MARK)";
|
||||
+ case RTL:
|
||||
+ case kind::RTL:
|
||||
+ return "U+200F (RIGHT-TO-LEFT MARK)";
|
||||
+ default:
|
||||
+ abort ();
|
||||
@ -1275,19 +1337,19 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ switch (p[2])
|
||||
+ {
|
||||
+ case 0xaa:
|
||||
+ return bidi::LRE;
|
||||
+ return bidi::kind::LRE;
|
||||
+ case 0xab:
|
||||
+ return bidi::RLE;
|
||||
+ return bidi::kind::RLE;
|
||||
+ case 0xac:
|
||||
+ return bidi::PDF;
|
||||
+ return bidi::kind::PDF;
|
||||
+ case 0xad:
|
||||
+ return bidi::LRO;
|
||||
+ return bidi::kind::LRO;
|
||||
+ case 0xae:
|
||||
+ return bidi::RLO;
|
||||
+ return bidi::kind::RLO;
|
||||
+ case 0x8e:
|
||||
+ return bidi::LTR;
|
||||
+ return bidi::kind::LTR;
|
||||
+ case 0x8f:
|
||||
+ return bidi::RTL;
|
||||
+ return bidi::kind::RTL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
@ -1295,18 +1357,18 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ switch (p[2])
|
||||
+ {
|
||||
+ case 0xa6:
|
||||
+ return bidi::LRI;
|
||||
+ return bidi::kind::LRI;
|
||||
+ case 0xa7:
|
||||
+ return bidi::RLI;
|
||||
+ return bidi::kind::RLI;
|
||||
+ case 0xa8:
|
||||
+ return bidi::FSI;
|
||||
+ return bidi::kind::FSI;
|
||||
+ case 0xa9:
|
||||
+ return bidi::PDI;
|
||||
+ return bidi::kind::PDI;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return bidi::NONE;
|
||||
+ return bidi::kind::NONE;
|
||||
+}
|
||||
+
|
||||
+/* Parse a UCN where P points just past \u or \U and return its bidi code. */
|
||||
@ -1322,32 +1384,32 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ if (is_U)
|
||||
+ {
|
||||
+ if (p[0] != '0' || p[1] != '0' || p[2] != '0' || p[3] != '0')
|
||||
+ return bidi::NONE;
|
||||
+ return bidi::kind::NONE;
|
||||
+ /* Skip 4B so we can treat \u and \U the same below. */
|
||||
+ p += 4;
|
||||
+ }
|
||||
+
|
||||
+ /* All code points we are looking for start with 20xx. */
|
||||
+ if (p[0] != '2' || p[1] != '0')
|
||||
+ return bidi::NONE;
|
||||
+ return bidi::kind::NONE;
|
||||
+ else if (p[2] == '2')
|
||||
+ switch (p[3])
|
||||
+ {
|
||||
+ case 'a':
|
||||
+ case 'A':
|
||||
+ return bidi::LRE;
|
||||
+ return bidi::kind::LRE;
|
||||
+ case 'b':
|
||||
+ case 'B':
|
||||
+ return bidi::RLE;
|
||||
+ return bidi::kind::RLE;
|
||||
+ case 'c':
|
||||
+ case 'C':
|
||||
+ return bidi::PDF;
|
||||
+ return bidi::kind::PDF;
|
||||
+ case 'd':
|
||||
+ case 'D':
|
||||
+ return bidi::LRO;
|
||||
+ return bidi::kind::LRO;
|
||||
+ case 'e':
|
||||
+ case 'E':
|
||||
+ return bidi::RLO;
|
||||
+ return bidi::kind::RLO;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
@ -1355,13 +1417,13 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ switch (p[3])
|
||||
+ {
|
||||
+ case '6':
|
||||
+ return bidi::LRI;
|
||||
+ return bidi::kind::LRI;
|
||||
+ case '7':
|
||||
+ return bidi::RLI;
|
||||
+ return bidi::kind::RLI;
|
||||
+ case '8':
|
||||
+ return bidi::FSI;
|
||||
+ return bidi::kind::FSI;
|
||||
+ case '9':
|
||||
+ return bidi::PDI;
|
||||
+ return bidi::kind::PDI;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
@ -1370,15 +1432,15 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ {
|
||||
+ case 'e':
|
||||
+ case 'E':
|
||||
+ return bidi::LTR;
|
||||
+ return bidi::kind::LTR;
|
||||
+ case 'f':
|
||||
+ case 'F':
|
||||
+ return bidi::RTL;
|
||||
+ return bidi::kind::RTL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return bidi::NONE;
|
||||
+ return bidi::kind::NONE;
|
||||
+}
|
||||
+
|
||||
+/* We're closing a bidi context, that is, we've encountered a newline,
|
||||
@ -1393,7 +1455,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ if (CPP_OPTION (pfile, cpp_warn_bidirectional) == bidirectional_unpaired
|
||||
+ && bidi::vec.count () > 0)
|
||||
+ {
|
||||
+ const source_location loc
|
||||
+ const location_t loc
|
||||
+ = linemap_position_for_column (pfile->line_table,
|
||||
+ CPP_BUF_COLUMN (pfile->buffer, p));
|
||||
+ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0,
|
||||
@ -1413,14 +1475,14 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+maybe_warn_bidi_on_char (cpp_reader *pfile, const uchar *p, bidi::kind kind,
|
||||
+ bool ucn_p)
|
||||
+{
|
||||
+ if (__builtin_expect (kind == bidi::NONE, 1))
|
||||
+ if (__builtin_expect (kind == bidi::kind::NONE, 1))
|
||||
+ return;
|
||||
+
|
||||
+ const unsigned char warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional);
|
||||
+ const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional);
|
||||
+
|
||||
+ if (warn_bidi != bidirectional_none)
|
||||
+ {
|
||||
+ const source_location loc
|
||||
+ const location_t loc
|
||||
+ = linemap_position_for_column (pfile->line_table,
|
||||
+ CPP_BUF_COLUMN (pfile->buffer, p));
|
||||
+ /* It seems excessive to warn about a PDI/PDF that is closing
|
||||
@ -1437,7 +1499,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
+ }
|
||||
+ else if (warn_bidi == bidirectional_any)
|
||||
+ {
|
||||
+ if (kind == bidi::PDF || kind == bidi::PDI)
|
||||
+ if (kind == bidi::kind::PDF || kind == bidi::kind::PDI)
|
||||
+ cpp_warning_with_line (pfile, CPP_W_BIDIRECTIONAL, loc, 0,
|
||||
+ "\"%s\" is closing an unopened context",
|
||||
+ bidi::to_str (kind));
|
||||
@ -1501,7 +1563,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
@@ -1233,9 +1565,31 @@ skip_line_comment (cpp_reader *pfile)
|
||||
{
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
source_location orig_line = pfile->line_table->highest_line;
|
||||
location_t orig_line = pfile->line_table->highest_line;
|
||||
+ const bool warn_bidi_p = pfile->warn_bidi_p ();
|
||||
|
||||
- while (*buffer->cur != '\n')
|
||||
@ -1532,9 +1594,9 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
|
||||
_cpp_process_line_notes (pfile, true);
|
||||
return orig_line != pfile->line_table->highest_line;
|
||||
@@ -1315,11 +1669,13 @@ warn_about_normalization (cpp_reader *pfile,
|
||||
@@ -1346,11 +1700,13 @@ static const cppchar_t utf8_signifier = 0xC0;
|
||||
|
||||
/* Returns TRUE if the sequence starting at buffer->cur is invalid in
|
||||
/* Returns TRUE if the sequence starting at buffer->cur is valid in
|
||||
an identifier. FIRST is TRUE if this starts an identifier. */
|
||||
+
|
||||
static bool
|
||||
@ -1546,20 +1608,35 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
|
||||
if (*buffer->cur == '$')
|
||||
{
|
||||
@@ -1343,6 +1699,12 @@ forms_identifier_p (cpp_reader *pfile, int first,
|
||||
{
|
||||
@@ -1373,6 +1729,13 @@ forms_identifier_p (cpp_reader *pfile, int first,
|
||||
cppchar_t s;
|
||||
buffer->cur += 2;
|
||||
+ if (warn_bidi_p)
|
||||
+ {
|
||||
+ bidi::kind kind = get_bidi_ucn (buffer->cur,
|
||||
+ buffer->cur[-1] == 'U');
|
||||
+ maybe_warn_bidi_on_char (pfile, buffer->cur, kind, /*ucn_p=*/true);
|
||||
+ }
|
||||
if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first,
|
||||
state, &s, NULL, NULL))
|
||||
return true;
|
||||
@@ -1450,6 +1812,7 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
|
||||
if (*buffer->cur >= utf8_signifier)
|
||||
{
|
||||
+ if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)
|
||||
+ && warn_bidi_p)
|
||||
+ {
|
||||
+ bidi::kind kind = get_bidi_utf8 (buffer->cur);
|
||||
+ maybe_warn_bidi_on_char (pfile, buffer->cur, kind,
|
||||
+ /*ucn_p=*/false);
|
||||
+ }
|
||||
if (_cpp_valid_utf8 (pfile, &buffer->cur, buffer->rlimit, 1 + !first,
|
||||
state, &s))
|
||||
return true;
|
||||
@@ -1381,6 +1744,13 @@ forms_identifier_p (cpp_reader *pfile, int first,
|
||||
&& (buffer->cur[1] == 'u' || buffer->cur[1] == 'U'))
|
||||
{
|
||||
buffer->cur += 2;
|
||||
+ if (warn_bidi_p)
|
||||
+ {
|
||||
+ bidi::kind kind = get_bidi_ucn (buffer->cur,
|
||||
+ buffer->cur[-1] == 'U');
|
||||
+ maybe_warn_bidi_on_char (pfile, buffer->cur, kind,
|
||||
+ /*ucn_p=*/true);
|
||||
+ }
|
||||
if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first,
|
||||
state, &s, NULL, NULL))
|
||||
return true;
|
||||
@@ -1489,6 +1859,7 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
|
||||
const uchar *cur;
|
||||
unsigned int len;
|
||||
unsigned int hash = HT_HASHSTEP (0, *base);
|
||||
@ -1567,7 +1644,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
|
||||
cur = pfile->buffer->cur;
|
||||
if (! starts_ucn)
|
||||
@@ -1472,6 +1835,8 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
|
||||
@@ -1512,6 +1883,8 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
|
||||
pfile->buffer->cur++;
|
||||
}
|
||||
} while (forms_identifier_p (pfile, false, nst));
|
||||
@ -1576,31 +1653,31 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
result = _cpp_interpret_identifier (pfile, base,
|
||||
pfile->buffer->cur - base);
|
||||
*spelling = cpp_lookup (pfile, base, pfile->buffer->cur - base);
|
||||
@@ -1673,6 +2038,7 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
|
||||
_cpp_buff *first_buff = NULL, *last_buff = NULL;
|
||||
size_t raw_prefix_start;
|
||||
_cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note];
|
||||
@@ -1758,6 +2131,7 @@ static void
|
||||
lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
{
|
||||
const uchar *pos = base;
|
||||
+ const bool warn_bidi_p = pfile->warn_bidi_p ();
|
||||
|
||||
type = (*base == 'L' ? CPP_WSTRING :
|
||||
*base == 'U' ? CPP_STRING32 :
|
||||
@@ -1909,8 +2275,15 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
|
||||
cur = base = pfile->buffer->cur;
|
||||
/* 'tis a pity this information isn't passed down from the lexer's
|
||||
initial categorization of the token. */
|
||||
@@ -1994,8 +2368,15 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
pos = base = pfile->buffer->cur;
|
||||
note = &pfile->buffer->notes[pfile->buffer->cur_note];
|
||||
}
|
||||
+ else if (__builtin_expect ((unsigned char) c == bidi::utf8_start, 0)
|
||||
+ && warn_bidi_p)
|
||||
+ maybe_warn_bidi_on_char (pfile, cur - 1, get_bidi_utf8 (cur - 1),
|
||||
+ maybe_warn_bidi_on_char (pfile, pos - 1, get_bidi_utf8 (pos - 1),
|
||||
+ /*ucn_p=*/false);
|
||||
}
|
||||
|
||||
+ if (warn_bidi_p)
|
||||
+ maybe_warn_bidi_on_close (pfile, cur);
|
||||
+ maybe_warn_bidi_on_close (pfile, pos);
|
||||
+
|
||||
if (CPP_OPTION (pfile, user_literals))
|
||||
{
|
||||
/* If a string format macro, say from inttypes.h, is placed touching
|
||||
@@ -2005,15 +2378,27 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
@@ -2090,15 +2471,27 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
else
|
||||
terminator = '>', type = CPP_HEADER_NAME;
|
||||
|
||||
@ -1630,7 +1707,7 @@ index a408f912c5c..ea7f75e842e 100644
|
||||
else if (c == '\n')
|
||||
{
|
||||
cur--;
|
||||
@@ -2030,6 +2415,11 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
@@ -2115,6 +2508,11 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
|
||||
}
|
||||
else if (c == '\0')
|
||||
saw_NUL = true;
|
||||
79
SOURCES/gcc11-Wmismatched-dealloc-doc.patch
Normal file
79
SOURCES/gcc11-Wmismatched-dealloc-doc.patch
Normal file
@ -0,0 +1,79 @@
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 3419483c532..a2a6b1c98be 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -255,7 +255,7 @@ in the following sections.
|
||||
-Wno-inherited-variadic-ctor -Wno-init-list-lifetime @gol
|
||||
-Winvalid-imported-macros @gol
|
||||
-Wno-invalid-offsetof -Wno-literal-suffix @gol
|
||||
--Wno-mismatched-new-delete -Wmismatched-tags @gol
|
||||
+-Wmismatched-new-delete -Wmismatched-tags @gol
|
||||
-Wmultiple-inheritance -Wnamespaces -Wnarrowing @gol
|
||||
-Wnoexcept -Wnoexcept-type -Wnon-virtual-dtor @gol
|
||||
-Wpessimizing-move -Wno-placement-new -Wplacement-new=@var{n} @gol
|
||||
@@ -3966,7 +3966,7 @@ The warning is inactive inside a system header file, such as the STL, so
|
||||
one can still use the STL. One may also instantiate or specialize
|
||||
templates.
|
||||
|
||||
-@item -Wno-mismatched-new-delete @r{(C++ and Objective-C++ only)}
|
||||
+@item -Wmismatched-new-delete @r{(C++ and Objective-C++ only)}
|
||||
@opindex Wmismatched-new-delete
|
||||
@opindex Wno-mismatched-new-delete
|
||||
Warn for mismatches between calls to @code{operator new} or @code{operator
|
||||
@@ -3998,7 +3998,7 @@ The related option @option{-Wmismatched-dealloc} diagnoses mismatches
|
||||
involving allocation and deallocation functions other than @code{operator
|
||||
new} and @code{operator delete}.
|
||||
|
||||
-@option{-Wmismatched-new-delete} is enabled by default.
|
||||
+@option{-Wmismatched-new-delete} is included in @option{-Wall}.
|
||||
|
||||
@item -Wmismatched-tags @r{(C++ and Objective-C++ only)}
|
||||
@opindex Wmismatched-tags
|
||||
@@ -5543,6 +5543,8 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
|
||||
-Wmemset-elt-size @gol
|
||||
-Wmemset-transposed-args @gol
|
||||
-Wmisleading-indentation @r{(only for C/C++)} @gol
|
||||
+-Wmismatched-dealloc @gol
|
||||
+-Wmismatched-new-delete @r{(only for C/C++)} @gol
|
||||
-Wmissing-attributes @gol
|
||||
-Wmissing-braces @r{(only for C/ObjC)} @gol
|
||||
-Wmultistatement-macros @gol
|
||||
@@ -6428,7 +6430,7 @@ Ignoring the warning can result in poorly optimized code.
|
||||
disable the warning, but this is not recommended and should be done only
|
||||
when non-existent profile data is justified.
|
||||
|
||||
-@item -Wno-mismatched-dealloc
|
||||
+@item -Wmismatched-dealloc
|
||||
@opindex Wmismatched-dealloc
|
||||
@opindex Wno-mismatched-dealloc
|
||||
|
||||
@@ -6461,7 +6463,7 @@ void f (void)
|
||||
In C++, the related option @option{-Wmismatched-new-delete} diagnoses
|
||||
mismatches involving either @code{operator new} or @code{operator delete}.
|
||||
|
||||
-Option @option{-Wmismatched-dealloc} is enabled by default.
|
||||
+Option @option{-Wmismatched-dealloc} is included in @option{-Wall}.
|
||||
|
||||
@item -Wmultistatement-macros
|
||||
@opindex Wmultistatement-macros
|
||||
@@ -7951,9 +7953,9 @@ Warnings controlled by the option can be disabled either by specifying
|
||||
Disable @option{-Wframe-larger-than=} warnings. The option is equivalent
|
||||
to @option{-Wframe-larger-than=}@samp{SIZE_MAX} or larger.
|
||||
|
||||
-@item -Wno-free-nonheap-object
|
||||
-@opindex Wno-free-nonheap-object
|
||||
+@item -Wfree-nonheap-object
|
||||
@opindex Wfree-nonheap-object
|
||||
+@opindex Wno-free-nonheap-object
|
||||
Warn when attempting to deallocate an object that was either not allocated
|
||||
on the heap, or by using a pointer that was not returned from a prior call
|
||||
to the corresponding allocation function. For example, because the call
|
||||
@@ -7970,7 +7972,7 @@ void f (char *p)
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
-@option{-Wfree-nonheap-object} is enabled by default.
|
||||
+@option{-Wfree-nonheap-object} is included in @option{-Wall}.
|
||||
|
||||
@item -Wstack-usage=@var{byte-size}
|
||||
@opindex Wstack-usage
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
--- gcc/configure.ac.jj 2017-02-13 12:20:53.000000000 +0100
|
||||
+++ gcc/configure.ac 2017-02-25 12:42:32.859175403 +0100
|
||||
@@ -481,7 +481,7 @@ AC_ARG_ENABLE(build-format-warnings,
|
||||
@@ -480,7 +480,7 @@ AC_ARG_ENABLE(build-format-warnings,
|
||||
AS_HELP_STRING([--disable-build-format-warnings],[don't use -Wformat while building GCC]),
|
||||
[],[enable_build_format_warnings=yes])
|
||||
AS_IF([test $enable_build_format_warnings = no],
|
||||
@ -13,7 +13,7 @@
|
||||
+ [wf_opt="-Wno-format -Wno-format-security"],[wf_opt=])
|
||||
ACX_PROG_CXX_WARNING_OPTS(
|
||||
m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings ],
|
||||
[-Wcast-qual $wf_opt])), [loose_warn])
|
||||
[-Wcast-qual -Wno-error=format-diag $wf_opt])),
|
||||
--- gcc/configure.jj 2017-02-13 12:20:52.000000000 +0100
|
||||
+++ gcc/configure 2017-02-25 12:42:50.041946391 +0100
|
||||
@@ -6647,7 +6647,7 @@ else
|
||||
297
SOURCES/gcc11-bind-now.patch
Normal file
297
SOURCES/gcc11-bind-now.patch
Normal file
@ -0,0 +1,297 @@
|
||||
From 36362544fb039599c0eb58d839e90ffb5410ad27 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Polacek <polacek@redhat.com>
|
||||
Date: Wed, 9 Feb 2022 15:18:43 -0500
|
||||
Subject: [PATCH] configure: Implement --enable-host-bind-now
|
||||
|
||||
As promised in the --enable-host-pie patch, this patch adds another
|
||||
configure option, --enable-host-bind-now, which adds -z now when linking
|
||||
the compiler executables in order to extend hardening. BIND_NOW with RELRO
|
||||
allows the GOT to be marked RO; this prevents GOT modification attacks.
|
||||
|
||||
This option does not affect linking of target libraries; you can use
|
||||
LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now to enable RELRO/BIND_NOW.
|
||||
|
||||
Bootstrapped/regtested on x86_64-pc-linux-gnu (with the option enabled vs
|
||||
not enabled). I suppose this is GCC 13 material, but maybe I'll get some
|
||||
comments anyway.
|
||||
|
||||
c++tools/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-bind-now): New check.
|
||||
* configure: Regenerate.
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-bind-now): New check. Add
|
||||
-Wl,-z,now to LD_PICFLAG if --enable-host-bind-now.
|
||||
* configure: Regenerate.
|
||||
* doc/install.texi: Document --enable-host-bind-now.
|
||||
|
||||
lto-plugin/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-bind-now): New check. Link with
|
||||
-z,now.
|
||||
* configure: Regenerate.
|
||||
---
|
||||
c++tools/configure | 11 +++++++++++
|
||||
c++tools/configure.ac | 7 +++++++
|
||||
gcc/configure | 20 ++++++++++++++++++--
|
||||
gcc/configure.ac | 13 ++++++++++++-
|
||||
gcc/doc/install.texi | 6 ++++++
|
||||
lto-plugin/configure | 20 ++++++++++++++++++--
|
||||
lto-plugin/configure.ac | 11 +++++++++++
|
||||
7 files changed, 83 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/c++tools/configure b/c++tools/configure
|
||||
index c1aceb8404a..25432b5040d 100755
|
||||
--- a/c++tools/configure
|
||||
+++ b/c++tools/configure
|
||||
@@ -631,6 +631,7 @@ ac_ct_CC
|
||||
GREP
|
||||
CXXCPP
|
||||
LD_PICFLAG
|
||||
+enable_host_bind_now
|
||||
PICFLAG
|
||||
MAINTAINER
|
||||
CXX_AUX_TOOLS
|
||||
@@ -704,6 +705,7 @@ enable_c___tools
|
||||
enable_checking
|
||||
enable_default_pie
|
||||
enable_host_pie
|
||||
+enable_host_bind_now
|
||||
with_gcc_major_version_only
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@@ -1336,6 +1338,7 @@ Optional Features:
|
||||
yes,no,all,none,release.
|
||||
--enable-default-pie enable Position Independent Executable as default
|
||||
--enable-host-pie build host code as PIE
|
||||
+ --enable-host-bind-now link host code as BIND_NOW
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@@ -3009,6 +3012,14 @@ fi
|
||||
|
||||
|
||||
|
||||
+# Enable --enable-host-bind-now
|
||||
+# Check whether --enable-host-bind-now was given.
|
||||
+if test "${enable_host_bind_now+set}" = set; then :
|
||||
+ enableval=$enable_host_bind_now; LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
|
||||
# Check if O_CLOEXEC is defined by fcntl
|
||||
|
||||
diff --git a/c++tools/configure.ac b/c++tools/configure.ac
|
||||
index 1e42689f2eb..d3f23f66f00 100644
|
||||
--- a/c++tools/configure.ac
|
||||
+++ b/c++tools/configure.ac
|
||||
@@ -110,6 +110,13 @@ AC_ARG_ENABLE(host-pie,
|
||||
[build host code as PIE])],
|
||||
[PICFLAG=-fPIE; LD_PICFLAG=-pie], [])
|
||||
AC_SUBST(PICFLAG)
|
||||
+
|
||||
+# Enable --enable-host-bind-now
|
||||
+AC_ARG_ENABLE(host-bind-now,
|
||||
+[AS_HELP_STRING([--enable-host-bind-now],
|
||||
+ [link host code as BIND_NOW])],
|
||||
+[LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"], [])
|
||||
+AC_SUBST(enable_host_bind_now)
|
||||
AC_SUBST(LD_PICFLAG)
|
||||
|
||||
# Check if O_CLOEXEC is defined by fcntl
|
||||
diff --git a/gcc/configure b/gcc/configure
|
||||
index 2ded5d4c50b..5671dc7dcf4 100755
|
||||
--- a/gcc/configure
|
||||
+++ b/gcc/configure
|
||||
@@ -635,6 +635,7 @@ CET_HOST_FLAGS
|
||||
LD_PICFLAG
|
||||
PICFLAG
|
||||
enable_default_pie
|
||||
+enable_host_bind_now
|
||||
enable_host_pie
|
||||
enable_host_shared
|
||||
enable_plugin
|
||||
@@ -1023,6 +1024,7 @@ enable_version_specific_runtime_libs
|
||||
enable_plugin
|
||||
enable_host_shared
|
||||
enable_host_pie
|
||||
+enable_host_bind_now
|
||||
enable_libquadmath_support
|
||||
with_linker_hash_style
|
||||
with_diagnostics_color
|
||||
@@ -1786,6 +1788,7 @@ Optional Features:
|
||||
--enable-plugin enable plugin support
|
||||
--enable-host-shared build host code as shared libraries
|
||||
--enable-host-pie build host code as PIE
|
||||
+ --enable-host-bind-now link host code as BIND_NOW
|
||||
--disable-libquadmath-support
|
||||
disable libquadmath support for Fortran
|
||||
--enable-default-pie enable Position Independent Executable as default
|
||||
@@ -32109,6 +32112,14 @@ fi
|
||||
|
||||
|
||||
|
||||
+# Enable --enable-host-bind-now
|
||||
+# Check whether --enable-host-bind-now was given.
|
||||
+if test "${enable_host_bind_now+set}" = set; then :
|
||||
+ enableval=$enable_host_bind_now;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
# Check whether --enable-libquadmath-support was given.
|
||||
if test "${enable_libquadmath_support+set}" = set; then :
|
||||
enableval=$enable_libquadmath_support; ENABLE_LIBQUADMATH_SUPPORT=$enableval
|
||||
@@ -32295,6 +32306,8 @@ else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
+
|
||||
+
|
||||
if test x$enable_host_pie = xyes; then
|
||||
LD_PICFLAG=-pie
|
||||
elif test x$gcc_cv_no_pie = xyes; then
|
||||
@@ -32303,6 +32316,9 @@ else
|
||||
LD_PICFLAG=
|
||||
fi
|
||||
|
||||
+if test x$enable_host_bind_now = xyes; then
|
||||
+ LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||
+fi
|
||||
|
||||
|
||||
|
||||
diff --git a/gcc/configure.ac b/gcc/configure.ac
|
||||
index dca995aeec7..6017bcbc8c6 100644
|
||||
--- a/gcc/configure.ac
|
||||
+++ b/gcc/configure.ac
|
||||
@@ -7497,6 +7497,12 @@ AC_ARG_ENABLE(host-pie,
|
||||
[build host code as PIE])])
|
||||
AC_SUBST(enable_host_pie)
|
||||
|
||||
+# Enable --enable-host-bind-now
|
||||
+AC_ARG_ENABLE(host-bind-now,
|
||||
+[AS_HELP_STRING([--enable-host-bind-now],
|
||||
+ [link host code as BIND_NOW])])
|
||||
+AC_SUBST(enable_host_bind_now)
|
||||
+
|
||||
AC_ARG_ENABLE(libquadmath-support,
|
||||
[AS_HELP_STRING([--disable-libquadmath-support],
|
||||
[disable libquadmath support for Fortran])],
|
||||
@@ -7638,6 +7644,8 @@ else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
+AC_SUBST([PICFLAG])
|
||||
+
|
||||
if test x$enable_host_pie = xyes; then
|
||||
LD_PICFLAG=-pie
|
||||
elif test x$gcc_cv_no_pie = xyes; then
|
||||
@@ -7646,7 +7654,10 @@ else
|
||||
LD_PICFLAG=
|
||||
fi
|
||||
|
||||
-AC_SUBST([PICFLAG])
|
||||
+if test x$enable_host_bind_now = xyes; then
|
||||
+ LD_PICFLAG="$LD_PICFLAG -Wl,-z,now"
|
||||
+fi
|
||||
+
|
||||
AC_SUBST([LD_PICFLAG])
|
||||
|
||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
|
||||
index 9747f832a75..b59af198d3e 100644
|
||||
--- a/gcc/doc/install.texi
|
||||
+++ b/gcc/doc/install.texi
|
||||
@@ -1041,6 +1041,12 @@ protection against Return Oriented Programming (ROP) attacks.
|
||||
in which case @option{-fPIC} is used when compiling, and @option{-pie} when
|
||||
linking.
|
||||
|
||||
+@item --enable-host-bind-now
|
||||
+Specify that the @emph{host} executables should be linked with the option
|
||||
+@option{-Wl,-z,now}, which means that the dynamic linker will resolve all
|
||||
+symbols when the executables are started, and that in turn allows RELRO to
|
||||
+mark the GOT read-only, resulting in better security.
|
||||
+
|
||||
@item @anchor{with-gnu-as}--with-gnu-as
|
||||
Specify that the compiler should assume that the
|
||||
assembler it finds is the GNU assembler. However, this does not modify
|
||||
diff --git a/lto-plugin/configure b/lto-plugin/configure
|
||||
index baa84adbb6c..669ccaede52 100755
|
||||
--- a/lto-plugin/configure
|
||||
+++ b/lto-plugin/configure
|
||||
@@ -656,6 +656,7 @@ accel_dir_suffix
|
||||
gcc_build_dir
|
||||
CET_HOST_FLAGS
|
||||
ac_lto_plugin_ldflags
|
||||
+enable_host_bind_now
|
||||
ac_lto_plugin_warn_cflags
|
||||
EGREP
|
||||
GREP
|
||||
@@ -771,6 +772,7 @@ enable_maintainer_mode
|
||||
with_libiberty
|
||||
enable_dependency_tracking
|
||||
enable_largefile
|
||||
+enable_host_bind_now
|
||||
enable_cet
|
||||
with_gcc_major_version_only
|
||||
enable_shared
|
||||
@@ -1418,6 +1420,7 @@ Optional Features:
|
||||
--disable-dependency-tracking
|
||||
speeds up one-time build
|
||||
--disable-largefile omit support for large files
|
||||
+ --enable-host-bind-now link host code as BIND_NOW
|
||||
--enable-cet enable Intel CET in host libraries [default=auto]
|
||||
--enable-shared[=PKGS] build shared libraries [default=yes]
|
||||
--enable-static[=PKGS] build static libraries [default=yes]
|
||||
@@ -5662,6 +5665,19 @@ if test "x$have_static_libgcc" = xyes; then
|
||||
ac_lto_plugin_ldflags="-Wc,-static-libgcc"
|
||||
fi
|
||||
|
||||
+# Enable --enable-host-bind-now
|
||||
+# Check whether --enable-host-bind-now was given.
|
||||
+if test "${enable_host_bind_now+set}" = set; then :
|
||||
+ enableval=$enable_host_bind_now;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+if test x$enable_host_bind_now = xyes; then
|
||||
+ ac_lto_plugin_ldflags="$ac_lto_plugin_ldflags -Wl,-z,now"
|
||||
+fi
|
||||
+
|
||||
+
|
||||
|
||||
# Check whether --enable-cet was given.
|
||||
if test "${enable_cet+set}" = set; then :
|
||||
diff --git a/lto-plugin/configure.ac b/lto-plugin/configure.ac
|
||||
index 7e6f729e9dc..5d5fea8fe70 100644
|
||||
--- a/lto-plugin/configure.ac
|
||||
+++ b/lto-plugin/configure.ac
|
||||
@@ -25,6 +25,17 @@ LDFLAGS="$saved_LDFLAGS"
|
||||
if test "x$have_static_libgcc" = xyes; then
|
||||
ac_lto_plugin_ldflags="-Wc,-static-libgcc"
|
||||
fi
|
||||
+
|
||||
+# Enable --enable-host-bind-now
|
||||
+AC_ARG_ENABLE(host-bind-now,
|
||||
+[AS_HELP_STRING([--enable-host-bind-now],
|
||||
+ [link host code as BIND_NOW])])
|
||||
+AC_SUBST(enable_host_bind_now)
|
||||
+
|
||||
+if test x$enable_host_bind_now = xyes; then
|
||||
+ ac_lto_plugin_ldflags="$ac_lto_plugin_ldflags -Wl,-z,now"
|
||||
+fi
|
||||
+
|
||||
AC_SUBST(ac_lto_plugin_ldflags)
|
||||
|
||||
GCC_CET_HOST_FLAGS(CET_HOST_FLAGS)
|
||||
|
||||
base-commit: bf799d3409cb9a189114a6c9ff5b7cd123915764
|
||||
--
|
||||
2.34.1
|
||||
|
||||
20
SOURCES/gcc11-d-shared-libphobos.patch
Normal file
20
SOURCES/gcc11-d-shared-libphobos.patch
Normal file
@ -0,0 +1,20 @@
|
||||
2019-01-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* d-spec.cc (lang_specific_driver): Make -shared-libphobos
|
||||
the default rather than -static-libphobos.
|
||||
|
||||
--- gcc/d/d-spec.cc.jj 2019-01-01 12:37:49.502444257 +0100
|
||||
+++ gcc/d/d-spec.cc 2019-01-17 17:09:45.364949246 +0100
|
||||
@@ -408,9 +408,9 @@ lang_specific_driver (cl_decoded_option
|
||||
/* Add `-lgphobos' if we haven't already done so. */
|
||||
if (phobos_library != PHOBOS_NOLINK)
|
||||
{
|
||||
- /* Default to static linking. */
|
||||
- if (phobos_library != PHOBOS_DYNAMIC)
|
||||
- phobos_library = PHOBOS_STATIC;
|
||||
+ /* Default to shared linking. */
|
||||
+ if (phobos_library != PHOBOS_STATIC)
|
||||
+ phobos_library = PHOBOS_DYNAMIC;
|
||||
|
||||
#ifdef HAVE_LD_STATIC_DYNAMIC
|
||||
if (phobos_library == PHOBOS_STATIC && !static_link)
|
||||
32
SOURCES/gcc11-dejagnu-multiline.patch
Normal file
32
SOURCES/gcc11-dejagnu-multiline.patch
Normal file
@ -0,0 +1,32 @@
|
||||
commit 14c7757e9b751781360737f53b71f851fc356d3d
|
||||
Author: Jeff Law <jeffreyalaw@gmail.com>
|
||||
Date: Fri Oct 29 11:30:15 2021 -0400
|
||||
|
||||
Avoid overly-greedy match in dejagnu regexp.
|
||||
|
||||
Occasionally I've been seeing failures with the multi-line diagnostics. It's never been clear what's causing the spurious failures, though I have long suspected a greedy regexp match.
|
||||
|
||||
It happened again yesterday with a local change that in no way should affect diagnostics, so I finally went searching and found that sure enough the multi-line diagnostics had a ".*" in their regexp. According to the comments, the .* is primarily to catch any dg directives that may appear -- ie it should eat to EOL, but not multiple lines. But a .* can indeed match a newline and cause it to eat multiple lines.
|
||||
|
||||
The fix is simple. [^\r\n]* will eat to EOL, but not further.
|
||||
|
||||
Regression tested on x86_64 and on our internal target.
|
||||
|
||||
gcc/testsuite
|
||||
|
||||
* lib/multiline.exp (_build_multiline_regex): Use a better
|
||||
regexp than .* to match up to EOL.
|
||||
|
||||
diff --git a/gcc/testsuite/lib/multiline.exp b/gcc/testsuite/lib/multiline.exp
|
||||
index 0e151b6d222..86387f8209b 100644
|
||||
--- a/gcc/testsuite/lib/multiline.exp
|
||||
+++ b/gcc/testsuite/lib/multiline.exp
|
||||
@@ -331,7 +331,7 @@ proc _build_multiline_regex { multiline index } {
|
||||
# Support arbitrary followup text on each non-empty line,
|
||||
# to deal with comments containing containing DejaGnu
|
||||
# directives.
|
||||
- append rexp ".*"
|
||||
+ append rexp "\[^\\n\\r\]*"
|
||||
}
|
||||
}
|
||||
append rexp "\n"
|
||||
69
SOURCES/gcc11-detect-sapphirerapids.patch
Normal file
69
SOURCES/gcc11-detect-sapphirerapids.patch
Normal file
@ -0,0 +1,69 @@
|
||||
commit 63dd214dce603f4f99e2cb272255b6c2b4308c3d
|
||||
Author: Cui,Lili <lili.cui@intel.com>
|
||||
Date: Mon Nov 7 11:25:41 2022 +0800
|
||||
|
||||
Remove AVX512_VP2INTERSECT from PTA_SAPPHIRERAPIDS
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* config/i386/driver-i386.cc (host_detect_local_cpu):
|
||||
Move sapphirerapids out of AVX512_VP2INTERSECT.
|
||||
* config/i386/i386.h: Remove AVX512_VP2INTERSECT from PTA_SAPPHIRERAPIDS
|
||||
* doc/invoke.texi: Remove AVX512_VP2INTERSECT from SAPPHIRERAPIDS
|
||||
|
||||
(cherry picked from commit d644dfe36d9733c767af62d37250253ced6efd8c)
|
||||
|
||||
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
|
||||
index f844a168ddb..90f84aba4ee 100644
|
||||
--- a/gcc/config/i386/driver-i386.c
|
||||
+++ b/gcc/config/i386/driver-i386.c
|
||||
@@ -574,15 +574,12 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
/* This is unknown family 0x6 CPU. */
|
||||
if (has_feature (FEATURE_AVX))
|
||||
{
|
||||
+ /* Assume Tiger Lake */
|
||||
if (has_feature (FEATURE_AVX512VP2INTERSECT))
|
||||
- {
|
||||
- if (has_feature (FEATURE_TSXLDTRK))
|
||||
- /* Assume Sapphire Rapids. */
|
||||
- cpu = "sapphirerapids";
|
||||
- else
|
||||
- /* Assume Tiger Lake */
|
||||
- cpu = "tigerlake";
|
||||
- }
|
||||
+ cpu = "tigerlake";
|
||||
+ /* Assume Sapphire Rapids. */
|
||||
+ else if (has_feature (FEATURE_TSXLDTRK))
|
||||
+ cpu = "sapphirerapids";
|
||||
/* Assume Cooper Lake */
|
||||
else if (has_feature (FEATURE_AVX512BF16))
|
||||
cpu = "cooperlake";
|
||||
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
|
||||
index ac0e5da623c..e03279bcf39 100644
|
||||
--- a/gcc/config/i386/i386.h
|
||||
+++ b/gcc/config/i386/i386.h
|
||||
@@ -2562,7 +2562,7 @@ constexpr wide_int_bitmask PTA_ICELAKE_SERVER = PTA_ICELAKE_CLIENT
|
||||
constexpr wide_int_bitmask PTA_TIGERLAKE = PTA_ICELAKE_CLIENT | PTA_MOVDIRI
|
||||
| PTA_MOVDIR64B | PTA_CLWB | PTA_AVX512VP2INTERSECT | PTA_KL | PTA_WIDEKL;
|
||||
constexpr wide_int_bitmask PTA_SAPPHIRERAPIDS = PTA_ICELAKE_SERVER | PTA_MOVDIRI
|
||||
- | PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_ENQCMD | PTA_CLDEMOTE
|
||||
+ | PTA_MOVDIR64B | PTA_ENQCMD | PTA_CLDEMOTE
|
||||
| PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE | PTA_TSXLDTRK | PTA_AMX_TILE
|
||||
| PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR | PTA_AVXVNNI | PTA_AVX512BF16;
|
||||
constexpr wide_int_bitmask PTA_KNL = PTA_BROADWELL | PTA_AVX512PF
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 3419483c532..6b3afb827a5 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -30236,9 +30236,9 @@ Intel sapphirerapids CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3,
|
||||
SSSE3, SSE4.1, SSE4.2, POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE,
|
||||
RDRND, F16C, AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW,
|
||||
AES, CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ,
|
||||
-AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2
|
||||
+AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES, AVX512VBMI2,
|
||||
VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG, WBNOINVD, CLWB,
|
||||
-MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG,
|
||||
+MOVDIRI, MOVDIR64B, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG,
|
||||
SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI and
|
||||
AVX512BF16 instruction set support.
|
||||
|
||||
83
SOURCES/gcc11-dg-ice-fixes.patch
Normal file
83
SOURCES/gcc11-dg-ice-fixes.patch
Normal file
@ -0,0 +1,83 @@
|
||||
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c
|
||||
index 8c3884bdc00..141f089d4f8 100644
|
||||
--- a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c
|
||||
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Test OpenACC 'kernels' construct decomposition. */
|
||||
|
||||
/* { dg-additional-options "-fopt-info-omp-all" } */
|
||||
-/* { dg-additional-options "-fchecking --param=openacc-kernels=decompose" } */
|
||||
+/* { dg-additional-options "-fno-report-bug -fchecking --param=openacc-kernels=decompose" } */
|
||||
/* { dg-ice "TODO" }
|
||||
{ dg-prune-output "during GIMPLE pass: omplower" } */
|
||||
|
||||
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c
|
||||
index 8bf60a9a509..a07e0a42116 100644
|
||||
--- a/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c
|
||||
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-2.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Test OpenACC 'kernels' construct decomposition. */
|
||||
|
||||
-/* { dg-additional-options "-fchecking --param=openacc-kernels=decompose" } */
|
||||
+/* { dg-additional-options "-fno-report-bug -fchecking --param=openacc-kernels=decompose" } */
|
||||
/* { dg-ice "TODO" }
|
||||
{ dg-prune-output "during GIMPLE pass: omplower" } */
|
||||
|
||||
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
|
||||
index eae0d8c377b..ed37f95e865 100644
|
||||
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
|
||||
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52830.C
|
||||
@@ -1,6 +1,6 @@
|
||||
// PR c++/52830
|
||||
// { dg-do compile { target c++11 } }
|
||||
-// { dg-additional-options "-fchecking" }
|
||||
+// { dg-additional-options "-fchecking -fno-report-bug" }
|
||||
// { dg-ice "comptypes" }
|
||||
|
||||
template<bool b> struct eif { typedef void type; };
|
||||
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-88982.C b/gcc/testsuite/g++.dg/cpp0x/vt-88982.C
|
||||
index 7a868233d73..45307a63483 100644
|
||||
--- a/gcc/testsuite/g++.dg/cpp0x/vt-88982.C
|
||||
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-88982.C
|
||||
@@ -1,6 +1,6 @@
|
||||
// PR c++/88982
|
||||
// { dg-do compile { target c++11 } }
|
||||
-// { dg-additional-options "-fchecking" }
|
||||
+// { dg-additional-options "-fchecking -fno-report-bug" }
|
||||
// { dg-ice "tsubst_pack_expansion" }
|
||||
|
||||
template<typename...Ts> struct A {
|
||||
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn61.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn61.C
|
||||
index bed5ea0cfc0..cb235bf891a 100644
|
||||
--- a/gcc/testsuite/g++.dg/cpp1y/auto-fn61.C
|
||||
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn61.C
|
||||
@@ -1,6 +1,6 @@
|
||||
// PR c++/88003
|
||||
// { dg-do compile { target c++14 } }
|
||||
-// { dg-additional-options "-fchecking" }
|
||||
+// { dg-additional-options "-fchecking -fno-report-bug" }
|
||||
// { dg-ice "poplevel_class" }
|
||||
|
||||
auto test() {
|
||||
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C
|
||||
index 0cdb400d21c..8f17cca31dd 100644
|
||||
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C
|
||||
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda26.C
|
||||
@@ -1,6 +1,6 @@
|
||||
// PR c++/87765
|
||||
// { dg-do compile { target c++17 } }
|
||||
-// { dg-additional-options "-fchecking" }
|
||||
+// { dg-additional-options "-fchecking -fno-report-bug" }
|
||||
// { dg-ice "cxx_eval_constant_expression" }
|
||||
|
||||
template <int N>
|
||||
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c
|
||||
index 0777b612b63..53abbe2db83 100644
|
||||
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c
|
||||
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla-kernels-decompose-ice-1.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* { dg-additional-options "--param=openacc-kernels=decompose" } */
|
||||
+/* { dg-additional-options "--param=openacc-kernels=decompose -fno-report-bug" } */
|
||||
/* Hopefully, this is the same issue as '../../../gcc/testsuite/c-c++-common/goacc/kernels-decompose-ice-1.c'.
|
||||
{ dg-ice "TODO" }
|
||||
TODO { dg-prune-output "during GIMPLE pass: omplower" }
|
||||
@ -1,21 +1,22 @@
|
||||
2017-01-20 Jakub Jelinek <jakub@redhat.com>
|
||||
2019-01-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.c (offload_targets_default): New variable.
|
||||
(process_command): Set it if -foffload is defaulted.
|
||||
(driver::maybe_putenv_OFFLOAD_TARGETS): Add OFFLOAD_TARGET_DEFAULT=1
|
||||
into environment if -foffload has been defaulted.
|
||||
* lto-wrapper.c (OFFLOAD_TARGET_DEFAULT_ENV): Define.
|
||||
(compile_images_for_offload_targets): If OFFLOAD_TARGET_DEFAULT
|
||||
(compile_offload_image): If OFFLOAD_TARGET_DEFAULT
|
||||
is in the environment, don't fail if corresponding mkoffload
|
||||
can't be found. Free and clear offload_names if no valid offload
|
||||
is found.
|
||||
can't be found.
|
||||
(compile_images_for_offload_targets): Likewise. Free and clear
|
||||
offload_names if no valid offload is found.
|
||||
libgomp/
|
||||
* target.c (gomp_load_plugin_for_device): If a plugin can't be
|
||||
dlopened, assume it has no devices silently.
|
||||
|
||||
--- gcc/gcc.c.jj 2017-01-17 10:28:40.000000000 +0100
|
||||
+++ gcc/gcc.c 2017-01-20 16:26:29.649962902 +0100
|
||||
@@ -290,6 +290,10 @@ static const char *spec_host_machine = D
|
||||
@@ -319,6 +319,10 @@ static const char *spec_host_machine = D
|
||||
|
||||
static char *offload_targets = NULL;
|
||||
|
||||
@ -26,7 +27,7 @@ libgomp/
|
||||
/* Nonzero if cross-compiling.
|
||||
When -b is used, the value comes from the `specs' file. */
|
||||
|
||||
@@ -4457,7 +4461,10 @@ process_command (unsigned int decoded_op
|
||||
@@ -4828,7 +4832,10 @@ process_command (unsigned int decoded_op
|
||||
/* If the user didn't specify any, default to all configured offload
|
||||
targets. */
|
||||
if (ENABLE_OFFLOADING && offload_targets == NULL)
|
||||
@ -36,14 +37,14 @@ libgomp/
|
||||
+ offload_targets_default = true;
|
||||
+ }
|
||||
|
||||
if (output_file
|
||||
&& strcmp (output_file, "-") != 0
|
||||
@@ -7693,6 +7700,8 @@ driver::maybe_putenv_OFFLOAD_TARGETS ()
|
||||
/* Handle -gtoggle as it would later in toplev.c:process_options to
|
||||
make the debug-level-gt spec function work as expected. */
|
||||
@@ -8494,6 +8501,8 @@ driver::maybe_putenv_OFFLOAD_TARGETS ()
|
||||
obstack_grow (&collect_obstack, offload_targets,
|
||||
strlen (offload_targets) + 1);
|
||||
xputenv (XOBFINISH (&collect_obstack, char *));
|
||||
+ if (offload_targets_default)
|
||||
+ xputenv ("OFFLOAD_TARGET_DEFAULT=1");
|
||||
+ xputenv ("OFFLOAD_TARGET_DEFAULT=1");
|
||||
}
|
||||
|
||||
free (offload_targets);
|
||||
@ -55,55 +56,53 @@ libgomp/
|
||||
#define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES"
|
||||
+#define OFFLOAD_TARGET_DEFAULT_ENV "OFFLOAD_TARGET_DEFAULT"
|
||||
|
||||
enum lto_mode_d {
|
||||
LTO_MODE_NONE, /* Not doing LTO. */
|
||||
@@ -790,8 +791,10 @@ compile_images_for_offload_targets (unsi
|
||||
/* By default there is no special suffix for target executables. */
|
||||
#ifdef TARGET_EXECUTABLE_SUFFIX
|
||||
@@ -906,6 +907,12 @@ compile_offload_image (const char *targe
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (!compiler && getenv (OFFLOAD_TARGET_DEFAULT_ENV))
|
||||
+ {
|
||||
+ free_array_of_ptrs ((void **) paths, n_paths);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (!compiler)
|
||||
fatal_error (input_location,
|
||||
"could not find %s in %s (consider using %<-B%>)",
|
||||
@@ -975,6 +982,7 @@ compile_images_for_offload_targets (unsi
|
||||
if (!target_names)
|
||||
return;
|
||||
unsigned num_targets = parse_env_var (target_names, &names, NULL);
|
||||
+ const char *target_names_default = getenv (OFFLOAD_TARGET_DEFAULT_ENV);
|
||||
+ int next_name_entry = 0;
|
||||
|
||||
int next_name_entry = 0;
|
||||
+ bool hsa_seen = false;
|
||||
const char *compiler_path = getenv ("COMPILER_PATH");
|
||||
if (!compiler_path)
|
||||
goto out;
|
||||
@@ -804,18 +807,32 @@ compile_images_for_offload_targets (unsi
|
||||
/* HSA does not use LTO-like streaming and a different compiler, skip
|
||||
it. */
|
||||
if (strcmp (names[i], "hsa") == 0)
|
||||
- continue;
|
||||
+ {
|
||||
+ hsa_seen = true;
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
offload_names[next_name_entry]
|
||||
@@ -985,13 +993,19 @@ compile_images_for_offload_targets (unsi
|
||||
offload_names = XCNEWVEC (char *, num_targets + 1);
|
||||
for (unsigned i = 0; i < num_targets; i++)
|
||||
{
|
||||
- offload_names[i]
|
||||
+ offload_names[next_name_entry]
|
||||
= compile_offload_image (names[i], compiler_path, in_argc, in_argv,
|
||||
compiler_opts, compiler_opt_count,
|
||||
linker_opts, linker_opt_count);
|
||||
if (!offload_names[next_name_entry])
|
||||
- if (!offload_names[i])
|
||||
- fatal_error (input_location,
|
||||
- "problem with building target image for %s\n", names[i]);
|
||||
+ {
|
||||
+ if (target_names_default != NULL)
|
||||
+ continue;
|
||||
+ fatal_error (input_location,
|
||||
+ "problem with building target image for %s\n",
|
||||
+ names[i]);
|
||||
+ }
|
||||
next_name_entry++;
|
||||
}
|
||||
|
||||
+ if (next_name_entry == 0 && !hsa_seen)
|
||||
- "problem with building target image for %s", names[i]);
|
||||
+ if (!offload_names[next_name_entry])
|
||||
+ continue;
|
||||
+ next_name_entry++;
|
||||
+ }
|
||||
+
|
||||
+ if (next_name_entry == 0)
|
||||
+ {
|
||||
+ free (offload_names);
|
||||
+ offload_names = NULL;
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
out:
|
||||
free_array_of_ptrs ((void **) names, num_targets);
|
||||
}
|
||||
--- libgomp/target.c.jj 2017-01-01 12:45:52.000000000 +0100
|
||||
+++ libgomp/target.c 2017-01-20 20:12:13.756710875 +0100
|
||||
@@ -2356,7 +2356,7 @@ gomp_load_plugin_for_device (struct gomp
|
||||
181
SOURCES/gcc11-fortran-fdec-add-missing-indexes.patch
Normal file
181
SOURCES/gcc11-fortran-fdec-add-missing-indexes.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From 7001d522d0273658d9e1fb12ca104d56bfcae34d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 15:06:08 +0000
|
||||
Subject: [PATCH 10/10] Fill in missing array dimensions using the lower bound
|
||||
|
||||
Use -fdec-add-missing-indexes to enable feature. Also enabled by fdec.
|
||||
---
|
||||
gcc/fortran/lang.opt | 8 ++++++++
|
||||
gcc/fortran/options.c | 1 +
|
||||
gcc/fortran/resolve.c | 24 ++++++++++++++++++++++++
|
||||
gcc/testsuite/gfortran.dg/array_6.f90 | 23 +++++++++++++++++++++++
|
||||
gcc/testsuite/gfortran.dg/array_7.f90 | 23 +++++++++++++++++++++++
|
||||
gcc/testsuite/gfortran.dg/array_8.f90 | 23 +++++++++++++++++++++++
|
||||
6 files changed, 102 insertions(+)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/array_6.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/array_7.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/array_8.f90
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 019c798cf09..f27de88ea3f 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -281,6 +281,10 @@ Wmissing-include-dirs
|
||||
Fortran
|
||||
; Documented in C/C++
|
||||
|
||||
+Wmissing-index
|
||||
+Fortran Var(warn_missing_index) Warning LangEnabledBy(Fortran,Wall)
|
||||
+Warn that the lower bound of a missing index will be used.
|
||||
+
|
||||
Wuse-without-only
|
||||
Fortran Var(warn_use_without_only) Warning
|
||||
Warn about USE statements that have no ONLY qualifier.
|
||||
@@ -460,6 +464,10 @@ fdec
|
||||
Fortran Var(flag_dec)
|
||||
Enable all DEC language extensions.
|
||||
|
||||
+fdec-add-missing-indexes
|
||||
+Fortran Var(flag_dec_add_missing_indexes)
|
||||
+Enable the addition of missing indexes using their lower bounds.
|
||||
+
|
||||
fdec-blank-format-item
|
||||
Fortran Var(flag_dec_blank_format_item)
|
||||
Enable the use of blank format items in format strings.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index 050f56fdc25..c3b2822685d 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -84,6 +84,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_non_logical_if, value, value);
|
||||
SET_BITFLAG (flag_dec_promotion, value, value);
|
||||
SET_BITFLAG (flag_dec_sequence, value, value);
|
||||
+ SET_BITFLAG (flag_dec_add_missing_indexes, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
|
||||
index fe7d0cc5944..0efeedab46e 100644
|
||||
--- a/gcc/fortran/resolve.c
|
||||
+++ b/gcc/fortran/resolve.c
|
||||
@@ -4806,6 +4806,30 @@ compare_spec_to_ref (gfc_array_ref *ar)
|
||||
if (ar->type == AR_FULL)
|
||||
return true;
|
||||
|
||||
+ if (flag_dec_add_missing_indexes && as->rank > ar->dimen)
|
||||
+ {
|
||||
+ /* Add in the missing dimensions, assuming they are the lower bound
|
||||
+ of that dimension if not specified. */
|
||||
+ int j;
|
||||
+ if (warn_missing_index)
|
||||
+ {
|
||||
+ gfc_warning (OPT_Wmissing_index, "Using the lower bound for "
|
||||
+ "unspecified dimensions in array reference at %L",
|
||||
+ &ar->where);
|
||||
+ }
|
||||
+ /* Other parts of the code iterate ar->start and ar->end from 0 to
|
||||
+ ar->dimen, so it is safe to assume slots from ar->dimen upwards
|
||||
+ are unused (i.e. there are no gaps; the specified indexes are
|
||||
+ contiguous and start at zero. */
|
||||
+ for(j = ar->dimen; j <= as->rank; j++)
|
||||
+ {
|
||||
+ ar->start[j] = gfc_copy_expr (as->lower[j]);
|
||||
+ ar->end[j] = gfc_copy_expr (as->lower[j]);
|
||||
+ ar->dimen_type[j] = DIMEN_ELEMENT;
|
||||
+ }
|
||||
+ ar->dimen = as->rank;
|
||||
+ }
|
||||
+
|
||||
if (as->rank != ar->dimen)
|
||||
{
|
||||
gfc_error ("Rank mismatch in array reference at %L (%d/%d)",
|
||||
diff --git a/gcc/testsuite/gfortran.dg/array_6.f90 b/gcc/testsuite/gfortran.dg/array_6.f90
|
||||
new file mode 100644
|
||||
index 00000000000..5c26e18ab3e
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/array_6.f90
|
||||
@@ -0,0 +1,23 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec -Wmissing-index" }!
|
||||
+! Checks that under-specified arrays (referencing arrays with fewer
|
||||
+! dimensions than the array spec) generates a warning.
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
|
||||
+!
|
||||
+
|
||||
+program under_specified_array
|
||||
+ integer chessboard(8,8)
|
||||
+ integer chessboard3d(8,8,3:5)
|
||||
+ chessboard(3,1) = 5
|
||||
+ chessboard(3,2) = 55
|
||||
+ chessboard3d(4,1,3) = 6
|
||||
+ chessboard3d(4,1,4) = 66
|
||||
+ chessboard3d(4,4,3) = 7
|
||||
+ chessboard3d(4,4,4) = 77
|
||||
+
|
||||
+ if (chessboard(3).ne.5) stop 1 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+ if (chessboard3d(4).ne.6) stop 2 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+end program
|
||||
diff --git a/gcc/testsuite/gfortran.dg/array_7.f90 b/gcc/testsuite/gfortran.dg/array_7.f90
|
||||
new file mode 100644
|
||||
index 00000000000..5588a5bd02d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/array_7.f90
|
||||
@@ -0,0 +1,23 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-add-missing-indexes -Wmissing-index" }!
|
||||
+! Checks that under-specified arrays (referencing arrays with fewer
|
||||
+! dimensions than the array spec) generates a warning.
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
|
||||
+!
|
||||
+
|
||||
+program under_specified_array
|
||||
+ integer chessboard(8,8)
|
||||
+ integer chessboard3d(8,8,3:5)
|
||||
+ chessboard(3,1) = 5
|
||||
+ chessboard(3,2) = 55
|
||||
+ chessboard3d(4,1,3) = 6
|
||||
+ chessboard3d(4,1,4) = 66
|
||||
+ chessboard3d(4,4,3) = 7
|
||||
+ chessboard3d(4,4,4) = 77
|
||||
+
|
||||
+ if (chessboard(3).ne.5) stop 1 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+ if (chessboard3d(4).ne.6) stop 2 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
|
||||
+end program
|
||||
diff --git a/gcc/testsuite/gfortran.dg/array_8.f90 b/gcc/testsuite/gfortran.dg/array_8.f90
|
||||
new file mode 100644
|
||||
index 00000000000..f0d2ef5e37d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/array_8.f90
|
||||
@@ -0,0 +1,23 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-add-missing-indexes" }!
|
||||
+! Checks that under-specified arrays (referencing arrays with fewer
|
||||
+! dimensions than the array spec) generates a warning.
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
|
||||
+!
|
||||
+
|
||||
+program under_specified_array
|
||||
+ integer chessboard(8,8)
|
||||
+ integer chessboard3d(8,8,3:5)
|
||||
+ chessboard(3,1) = 5
|
||||
+ chessboard(3,2) = 55
|
||||
+ chessboard3d(4,1,3) = 6
|
||||
+ chessboard3d(4,1,4) = 66
|
||||
+ chessboard3d(4,4,3) = 7
|
||||
+ chessboard3d(4,4,4) = 77
|
||||
+
|
||||
+ if (chessboard(3).ne.5) stop 1 ! { dg-error "Rank mismatch" }
|
||||
+ if (chessboard3d(4).ne.6) stop 2 ! { dg-error "Rank mismatch" }
|
||||
+ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-error "Rank mismatch" }
|
||||
+end program
|
||||
--
|
||||
2.27.0
|
||||
|
||||
215
SOURCES/gcc11-fortran-fdec-duplicates.patch
Normal file
215
SOURCES/gcc11-fortran-fdec-duplicates.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From 23b1fcb104c666429451ffaf936f8da5fcd3d43a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 12:29:47 +0000
|
||||
Subject: [PATCH 01/10] Allow duplicate declarations.
|
||||
|
||||
Enabled by -fdec-duplicates and -fdec.
|
||||
|
||||
Some fixes by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
Addition of -fdec-duplicates by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++++
|
||||
gcc/fortran/options.c | 1 +
|
||||
gcc/fortran/symbol.c | 21 +++++++++++++++++--
|
||||
.../gfortran.dg/duplicate_type_4.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_5.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_6.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_7.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_8.f90 | 12 +++++++++++
|
||||
.../gfortran.dg/duplicate_type_9.f90 | 12 +++++++++++
|
||||
9 files changed, 100 insertions(+), 2 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 2b1977c523b..52bd522051e 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -469,6 +469,10 @@ Fortran Var(flag_dec_char_conversions)
|
||||
Enable the use of character literals in assignments and data statements
|
||||
for non-character variables.
|
||||
|
||||
+fdec-duplicates
|
||||
+Fortran Var(flag_dec_duplicates)
|
||||
+Allow varibles to be duplicated in the type specification matches.
|
||||
+
|
||||
fdec-include
|
||||
Fortran Var(flag_dec_include)
|
||||
Enable legacy parsing of INCLUDE as statement.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index 3a0b98bf1ec..f19ba87f8a0 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -77,6 +77,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_format_defaults, value, value);
|
||||
SET_BITFLAG (flag_dec_blank_format_item, value, value);
|
||||
SET_BITFLAG (flag_dec_char_conversions, value, value);
|
||||
+ SET_BITFLAG (flag_dec_duplicates, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
|
||||
index 3b988d1be22..9843175cc2a 100644
|
||||
--- a/gcc/fortran/symbol.c
|
||||
+++ b/gcc/fortran/symbol.c
|
||||
@@ -1995,6 +1995,8 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
if (sym->attr.result && type == BT_UNKNOWN && sym->ns->proc_name)
|
||||
type = sym->ns->proc_name->ts.type;
|
||||
|
||||
+ flavor = sym->attr.flavor;
|
||||
+
|
||||
if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type)
|
||||
&& !(gfc_state_stack->previous && gfc_state_stack->previous->previous
|
||||
&& gfc_state_stack->previous->previous->state == COMP_SUBMODULE)
|
||||
@@ -2007,6 +2009,23 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
else if (sym->attr.function && sym->attr.result)
|
||||
gfc_error ("Symbol %qs at %L already has basic type of %s",
|
||||
sym->ns->proc_name->name, where, gfc_basic_typename (type));
|
||||
+ else if (flag_dec_duplicates)
|
||||
+ {
|
||||
+ /* Ignore temporaries and class/procedure names */
|
||||
+ if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS
|
||||
+ || sym->ts.type == BT_PROCEDURE)
|
||||
+ return false;
|
||||
+
|
||||
+ if (gfc_compare_types (&sym->ts, ts)
|
||||
+ && (flavor == FL_UNKNOWN || flavor == FL_VARIABLE
|
||||
+ || flavor == FL_PROCEDURE))
|
||||
+ {
|
||||
+ return gfc_notify_std (GFC_STD_LEGACY,
|
||||
+ "Symbol '%qs' at %L already has "
|
||||
+ "basic type of %s", sym->name, where,
|
||||
+ gfc_basic_typename (type));
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
gfc_error ("Symbol %qs at %L already has basic type of %s", sym->name,
|
||||
where, gfc_basic_typename (type));
|
||||
@@ -2020,8 +2039,6 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
return false;
|
||||
}
|
||||
|
||||
- flavor = sym->attr.flavor;
|
||||
-
|
||||
if (flavor == FL_PROGRAM || flavor == FL_BLOCK_DATA || flavor == FL_MODULE
|
||||
|| flavor == FL_LABEL
|
||||
|| (flavor == FL_PROCEDURE && sym->attr.subroutine)
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_4.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
new file mode 100644
|
||||
index 00000000000..cdd29ea8846
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=f95" }
|
||||
+
|
||||
+! PR fortran/30239
|
||||
+! Check for errors when a symbol gets declared a type twice, even if it
|
||||
+! is the same.
|
||||
+
|
||||
+INTEGER FUNCTION foo ()
|
||||
+ IMPLICIT NONE
|
||||
+ INTEGER :: x
|
||||
+ INTEGER :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+END FUNCTION foo
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_5.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
new file mode 100644
|
||||
index 00000000000..00f931809aa
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_6.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
new file mode 100644
|
||||
index 00000000000..f0df27e323c
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-std=legacy -fdec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_7.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
new file mode 100644
|
||||
index 00000000000..f32472ff586
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x! { dg-warning "Legacy Extension" }
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_8.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
new file mode 100644
|
||||
index 00000000000..23c94add179
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
@@ -0,0 +1,12 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+integer function foo ()
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+end function foo
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_9.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
new file mode 100644
|
||||
index 00000000000..d5edee4d8ee
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
@@ -0,0 +1,12 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec-duplicates -fno-dec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+integer function foo ()
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+end function foo
|
||||
--
|
||||
2.27.0
|
||||
|
||||
78
SOURCES/gcc11-fortran-fdec-ichar.patch
Normal file
78
SOURCES/gcc11-fortran-fdec-ichar.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From f883ac209b0feea860354cb4ef7ff06dc8063fab Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 12:53:35 +0000
|
||||
Subject: [PATCH 03/10] Allow more than one character as argument to ICHAR
|
||||
|
||||
Use -fdec to enable.
|
||||
---
|
||||
gcc/fortran/check.c | 2 +-
|
||||
gcc/fortran/simplify.c | 4 ++--
|
||||
.../gfortran.dg/dec_ichar_with_string_1.f | 21 +++++++++++++++++++
|
||||
3 files changed, 24 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
|
||||
|
||||
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
|
||||
index 82db8e4e1b2..623c1cc470e 100644
|
||||
--- a/gcc/fortran/check.c
|
||||
+++ b/gcc/fortran/check.c
|
||||
@@ -3157,7 +3157,7 @@ gfc_check_ichar_iachar (gfc_expr *c, gfc_expr *kind)
|
||||
else
|
||||
return true;
|
||||
|
||||
- if (i != 1)
|
||||
+ if (i != 1 && !flag_dec)
|
||||
{
|
||||
gfc_error ("Argument of %s at %L must be of length one",
|
||||
gfc_current_intrinsic, &c->where);
|
||||
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
|
||||
index 23317a2e2d9..9900572424f 100644
|
||||
--- a/gcc/fortran/simplify.c
|
||||
+++ b/gcc/fortran/simplify.c
|
||||
@@ -3261,7 +3261,7 @@ gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
|
||||
if (e->expr_type != EXPR_CONSTANT)
|
||||
return NULL;
|
||||
|
||||
- if (e->value.character.length != 1)
|
||||
+ if (e->value.character.length != 1 && !flag_dec)
|
||||
{
|
||||
gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
|
||||
return &gfc_bad_expr;
|
||||
@@ -3459,7 +3459,7 @@ gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
|
||||
if (e->expr_type != EXPR_CONSTANT)
|
||||
return NULL;
|
||||
|
||||
- if (e->value.character.length != 1)
|
||||
+ if (e->value.character.length != 1 && !flag_dec)
|
||||
{
|
||||
gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
|
||||
return &gfc_bad_expr;
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f b/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..85efccecc0f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
|
||||
@@ -0,0 +1,21 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test ICHAR and IACHAR with more than one character as argument
|
||||
+!
|
||||
+! Test case contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM ichar_more_than_one_character
|
||||
+ CHARACTER*4 st/'Test'/
|
||||
+ INTEGER i
|
||||
+
|
||||
+ i = ICHAR(st)
|
||||
+ if (i.NE.84) STOP 1
|
||||
+ i = IACHAR(st)
|
||||
+ if (i.NE.84) STOP 2
|
||||
+ i = ICHAR('Test')
|
||||
+ if (i.NE.84) STOP 3
|
||||
+ i = IACHAR('Test')
|
||||
+ if (i.NE.84) STOP 4
|
||||
+ END
|
||||
--
|
||||
2.27.0
|
||||
|
||||
158
SOURCES/gcc11-fortran-fdec-non-integer-index.patch
Normal file
158
SOURCES/gcc11-fortran-fdec-non-integer-index.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 67aef262311d6a746786ee0f59748ccaa7e1e711 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 13:09:54 +0000
|
||||
Subject: [PATCH 04/10] Allow non-integer substring indexes
|
||||
|
||||
Use -fdec-non-integer-index compiler flag to enable. Also enabled by -fdec.
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++++
|
||||
gcc/fortran/options.c | 1 +
|
||||
gcc/fortran/resolve.c | 20 +++++++++++++++++++
|
||||
.../dec_not_integer_substring_indexes_1.f | 18 +++++++++++++++++
|
||||
.../dec_not_integer_substring_indexes_2.f | 18 +++++++++++++++++
|
||||
.../dec_not_integer_substring_indexes_3.f | 18 +++++++++++++++++
|
||||
6 files changed, 79 insertions(+)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index c4da248f07c..d527c106bd6 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -489,6 +489,10 @@ fdec-math
|
||||
Fortran Var(flag_dec_math)
|
||||
Enable legacy math intrinsics for compatibility.
|
||||
|
||||
+fdec-non-integer-index
|
||||
+Fortran Var(flag_dec_non_integer_index)
|
||||
+Enable support for non-integer substring indexes.
|
||||
+
|
||||
fdec-structure
|
||||
Fortran Var(flag_dec_structure)
|
||||
Enable support for DEC STRUCTURE/RECORD.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index f19ba87f8a0..9a042f64881 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -78,6 +78,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_blank_format_item, value, value);
|
||||
SET_BITFLAG (flag_dec_char_conversions, value, value);
|
||||
SET_BITFLAG (flag_dec_duplicates, value, value);
|
||||
+ SET_BITFLAG (flag_dec_non_integer_index, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
|
||||
index 4b90cb59902..bc0df0fdb99 100644
|
||||
--- a/gcc/fortran/resolve.c
|
||||
+++ b/gcc/fortran/resolve.c
|
||||
@@ -5131,6 +5131,16 @@ gfc_resolve_substring (gfc_ref *ref, bool *equal_length)
|
||||
if (!gfc_resolve_expr (ref->u.ss.start))
|
||||
return false;
|
||||
|
||||
+ /* In legacy mode, allow non-integer string indexes by converting */
|
||||
+ if (flag_dec_non_integer_index && ref->u.ss.start->ts.type != BT_INTEGER
|
||||
+ && gfc_numeric_ts (&ref->u.ss.start->ts))
|
||||
+ {
|
||||
+ gfc_typespec t;
|
||||
+ t.type = BT_INTEGER;
|
||||
+ t.kind = ref->u.ss.start->ts.kind;
|
||||
+ gfc_convert_type_warn (ref->u.ss.start, &t, 2, 1);
|
||||
+ }
|
||||
+
|
||||
if (ref->u.ss.start->ts.type != BT_INTEGER)
|
||||
{
|
||||
gfc_error ("Substring start index at %L must be of type INTEGER",
|
||||
@@ -5160,6 +5170,16 @@ gfc_resolve_substring (gfc_ref *ref, bool *equal_length)
|
||||
if (!gfc_resolve_expr (ref->u.ss.end))
|
||||
return false;
|
||||
|
||||
+ /* Non-integer string index endings, as for start */
|
||||
+ if (flag_dec_non_integer_index && ref->u.ss.end->ts.type != BT_INTEGER
|
||||
+ && gfc_numeric_ts (&ref->u.ss.end->ts))
|
||||
+ {
|
||||
+ gfc_typespec t;
|
||||
+ t.type = BT_INTEGER;
|
||||
+ t.kind = ref->u.ss.end->ts.kind;
|
||||
+ gfc_convert_type_warn (ref->u.ss.end, &t, 2, 1);
|
||||
+ }
|
||||
+
|
||||
if (ref->u.ss.end->ts.type != BT_INTEGER)
|
||||
{
|
||||
gfc_error ("Substring end index at %L must be of type INTEGER",
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..0be28abaa4b
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
|
||||
@@ -0,0 +1,18 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test not integer substring indexes
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM not_integer_substring_indexes
|
||||
+ CHARACTER*5 st/'Tests'/
|
||||
+ REAL ir/1.0/
|
||||
+ REAL ir2/4.0/
|
||||
+
|
||||
+ if (st(ir:4).ne.'Test') stop 1
|
||||
+ if (st(1:ir2).ne.'Test') stop 2
|
||||
+ if (st(1.0:4).ne.'Test') stop 3
|
||||
+ if (st(1:4.0).ne.'Test') stop 4
|
||||
+ if (st(2.5:4).ne.'est') stop 5
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..3cf05296d0c
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
|
||||
@@ -0,0 +1,18 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-non-integer-index" }
|
||||
+!
|
||||
+! Test not integer substring indexes
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM not_integer_substring_indexes
|
||||
+ CHARACTER*5 st/'Tests'/
|
||||
+ REAL ir/1.0/
|
||||
+ REAL ir2/4.0/
|
||||
+
|
||||
+ if (st(ir:4).ne.'Test') stop 1
|
||||
+ if (st(1:ir2).ne.'Test') stop 2
|
||||
+ if (st(1.0:4).ne.'Test') stop 3
|
||||
+ if (st(1:4.0).ne.'Test') stop 4
|
||||
+ if (st(2.5:4).ne.'est') stop 5
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..703de995897
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
|
||||
@@ -0,0 +1,18 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-non-integer-index" }
|
||||
+!
|
||||
+! Test not integer substring indexes
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM not_integer_substring_indexes
|
||||
+ CHARACTER*5 st/'Tests'/
|
||||
+ REAL ir/1.0/
|
||||
+ REAL ir2/4.0/
|
||||
+
|
||||
+ if (st(ir:4).ne.'Test') stop 1 ! { dg-error "Substring start index" }
|
||||
+ if (st(1:ir2).ne.'Test') stop 2 ! { dg-error "Substring end index" }
|
||||
+ if (st(1.0:4).ne.'Test') stop 3 ! { dg-error "Substring start index" }
|
||||
+ if (st(1:4.0).ne.'Test') stop 4 ! { dg-error "Substring end index" }
|
||||
+ if (st(2.5:4).ne.'est') stop 5 ! { dg-error "Substring start index" }
|
||||
+ END
|
||||
--
|
||||
2.27.0
|
||||
|
||||
378
SOURCES/gcc11-fortran-fdec-non-logical-if.patch
Normal file
378
SOURCES/gcc11-fortran-fdec-non-logical-if.patch
Normal file
@ -0,0 +1,378 @@
|
||||
From cc87ddb841017bb0976b05091733609ee17d7f05 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 13:15:17 +0000
|
||||
Subject: [PATCH 07/10] Allow non-logical expressions in IF statements
|
||||
|
||||
Use -fdec-non-logical-if to enable feature. Also enabled using -fdec.
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++
|
||||
gcc/fortran/options.c | 1 +
|
||||
gcc/fortran/resolve.c | 60 ++++++++++++++++---
|
||||
...gical_expressions_if_statements_blocks_1.f | 25 ++++++++
|
||||
...gical_expressions_if_statements_blocks_2.f | 25 ++++++++
|
||||
...gical_expressions_if_statements_blocks_3.f | 25 ++++++++
|
||||
...gical_expressions_if_statements_blocks_4.f | 45 ++++++++++++++
|
||||
...gical_expressions_if_statements_blocks_5.f | 45 ++++++++++++++
|
||||
...gical_expressions_if_statements_blocks_6.f | 45 ++++++++++++++
|
||||
9 files changed, 266 insertions(+), 9 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 4a269ebb22d..d886c2f33ed 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -497,6 +497,10 @@ fdec-override-kind
|
||||
Fortran Var(flag_dec_override_kind)
|
||||
Enable support for per variable kind specification.
|
||||
|
||||
+fdec-non-logical-if
|
||||
+Fortran Var(flag_dec_non_logical_if)
|
||||
+Enable support for non-logical expressions in if statements.
|
||||
+
|
||||
fdec-old-init
|
||||
Fortran Var(flag_dec_old_init)
|
||||
Enable support for old style initializers in derived types.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index edbab483b36..a946c86790a 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -81,6 +81,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_non_integer_index, value, value);
|
||||
SET_BITFLAG (flag_dec_old_init, value, value);
|
||||
SET_BITFLAG (flag_dec_override_kind, value, value);
|
||||
+ SET_BITFLAG (flag_dec_non_logical_if, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
|
||||
index bc0df0fdb99..07dd039f3bf 100644
|
||||
--- a/gcc/fortran/resolve.c
|
||||
+++ b/gcc/fortran/resolve.c
|
||||
@@ -10789,10 +10789,31 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
|
||||
switch (b->op)
|
||||
{
|
||||
case EXEC_IF:
|
||||
- if (t && b->expr1 != NULL
|
||||
- && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
|
||||
- gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
|
||||
- &b->expr1->where);
|
||||
+ if (t && b->expr1 != NULL)
|
||||
+ {
|
||||
+ if (flag_dec_non_logical_if && b->expr1->ts.type != BT_LOGICAL)
|
||||
+ {
|
||||
+ gfc_expr* cast;
|
||||
+ cast = gfc_ne (b->expr1,
|
||||
+ gfc_get_int_expr (1, &gfc_current_locus, 0),
|
||||
+ INTRINSIC_NE);
|
||||
+ if (cast == NULL)
|
||||
+ gfc_internal_error ("gfc_resolve_blocks(): Failed to cast "
|
||||
+ "to LOGICAL in IF");
|
||||
+ b->expr1 = cast;
|
||||
+ if (warn_conversion_extra)
|
||||
+ {
|
||||
+ gfc_warning (OPT_Wconversion_extra, "Non-LOGICAL type in"
|
||||
+ " IF statement condition %L will be true if"
|
||||
+ " it evaluates to nonzero",
|
||||
+ &b->expr1->where);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
|
||||
+ gfc_error ("IF clause at %L requires a scalar LOGICAL "
|
||||
+ "expression", &b->expr1->where);
|
||||
+ }
|
||||
break;
|
||||
|
||||
case EXEC_WHERE:
|
||||
@@ -12093,11 +12114,32 @@ start:
|
||||
break;
|
||||
|
||||
case EXEC_IF:
|
||||
- if (t && code->expr1 != NULL
|
||||
- && (code->expr1->ts.type != BT_LOGICAL
|
||||
- || code->expr1->rank != 0))
|
||||
- gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
|
||||
- &code->expr1->where);
|
||||
+ if (t && code->expr1 != NULL)
|
||||
+ {
|
||||
+ if (flag_dec_non_logical_if
|
||||
+ && code->expr1->ts.type != BT_LOGICAL)
|
||||
+ {
|
||||
+ gfc_expr* cast;
|
||||
+ cast = gfc_ne (code->expr1,
|
||||
+ gfc_get_int_expr (1, &gfc_current_locus, 0),
|
||||
+ INTRINSIC_NE);
|
||||
+ if (cast == NULL)
|
||||
+ gfc_internal_error ("gfc_resolve_code(): Failed to cast "
|
||||
+ "to LOGICAL in IF");
|
||||
+ code->expr1 = cast;
|
||||
+ if (warn_conversion_extra)
|
||||
+ {
|
||||
+ gfc_warning (OPT_Wconversion_extra, "Non-LOGICAL type in"
|
||||
+ " IF statement condition %L will be true if"
|
||||
+ " it evaluates to nonzero",
|
||||
+ &code->expr1->where);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (code->expr1->ts.type != BT_LOGICAL || code->expr1->rank != 0)
|
||||
+ gfc_error ("IF clause at %L requires a scalar LOGICAL "
|
||||
+ "expression", &code->expr1->where);
|
||||
+ }
|
||||
break;
|
||||
|
||||
case EXEC_CALL:
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..0101db893ca
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
|
||||
@@ -0,0 +1,25 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec -Wconversion-extra" }
|
||||
+!
|
||||
+! Allow logical expressions in if statements and blocks
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM logical_exp_if_st_bl
|
||||
+ INTEGER ipos/1/
|
||||
+ INTEGER ineg/0/
|
||||
+
|
||||
+ ! Test non logical variables
|
||||
+ if (ineg) STOP 1 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ if (0) STOP 2 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+
|
||||
+ ! Test non logical expressions in if statements
|
||||
+ if (MOD(ipos, 1)) STOP 3 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+
|
||||
+ ! Test non logical expressions in if blocks
|
||||
+ if (MOD(2 * ipos, 2)) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ STOP 4
|
||||
+ endif
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..876f4e09508
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
|
||||
@@ -0,0 +1,25 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-non-logical-if -Wconversion-extra" }
|
||||
+!
|
||||
+! Allow logical expressions in if statements and blocks
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM logical_exp_if_st_bl
|
||||
+ INTEGER ipos/1/
|
||||
+ INTEGER ineg/0/
|
||||
+
|
||||
+ ! Test non logical variables
|
||||
+ if (ineg) STOP 1 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ if (0) STOP 2 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+
|
||||
+ ! Test non logical expressions in if statements
|
||||
+ if (MOD(ipos, 1)) STOP 3 ! { dg-warning "if it evaluates to nonzero" }
|
||||
+
|
||||
+ ! Test non logical expressions in if blocks
|
||||
+ if (MOD(2 * ipos, 2)) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ STOP 4
|
||||
+ endif
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..35cb4c51b8d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
|
||||
@@ -0,0 +1,25 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-non-logical-if" }
|
||||
+!
|
||||
+! Allow logical expressions in if statements and blocks
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM logical_exp_if_st_bl
|
||||
+ INTEGER ipos/1/
|
||||
+ INTEGER ineg/0/
|
||||
+
|
||||
+ ! Test non logical variables
|
||||
+ if (ineg) STOP 1 ! { dg-error "IF clause at" }
|
||||
+ if (0) STOP 2 ! { dg-error "IF clause at" }
|
||||
+
|
||||
+ ! Test non logical expressions in if statements
|
||||
+ if (MOD(ipos, 1)) STOP 3 ! { dg-error "IF clause at" }
|
||||
+
|
||||
+ ! Test non logical expressions in if blocks
|
||||
+ if (MOD(2 * ipos, 2)) then ! { dg-error "IF clause at" }
|
||||
+ STOP 4
|
||||
+ endif
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
|
||||
new file mode 100644
|
||||
index 00000000000..7b60b60827f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
|
||||
@@ -0,0 +1,45 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec -Wconversion-extra" }
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ function othersub1()
|
||||
+ integer*4 othersub1
|
||||
+ othersub1 = 9
|
||||
+ end
|
||||
+
|
||||
+ function othersub2()
|
||||
+ integer*4 othersub2
|
||||
+ othersub2 = 0
|
||||
+ end
|
||||
+
|
||||
+ program MAIN
|
||||
+ integer*4 othersub1
|
||||
+ integer*4 othersub2
|
||||
+ integer a /1/
|
||||
+ integer b /2/
|
||||
+
|
||||
+ if (othersub1()) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 1
|
||||
+ end if
|
||||
+ if (othersub2()) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ stop 2
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ if (a-b) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 3
|
||||
+ end if
|
||||
+ if (b-(a+1)) then ! { dg-warning "if it evaluates to nonzero" }
|
||||
+ stop 3
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ end
|
||||
+
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
|
||||
new file mode 100644
|
||||
index 00000000000..80336f48ca1
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
|
||||
@@ -0,0 +1,45 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-non-logical-if -Wconversion-extra" }
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ function othersub1()
|
||||
+ integer*4 othersub1
|
||||
+ othersub1 = 9
|
||||
+ end
|
||||
+
|
||||
+ function othersub2()
|
||||
+ integer*4 othersub2
|
||||
+ othersub2 = 0
|
||||
+ end
|
||||
+
|
||||
+ program MAIN
|
||||
+ integer*4 othersub1
|
||||
+ integer*4 othersub2
|
||||
+ integer a /1/
|
||||
+ integer b /2/
|
||||
+
|
||||
+ if (othersub1()) then ! { dg-warning "Non-LOGICAL type in IF statement" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 1
|
||||
+ end if
|
||||
+ if (othersub2()) then ! { dg-warning "Non-LOGICAL type in IF statement" }
|
||||
+ stop 2
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ if (a-b) then ! { dg-warning "Non-LOGICAL type in IF statement" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 3
|
||||
+ end if
|
||||
+ if (b-(a+1)) then ! { dg-warning "Non-LOGICAL type in IF statement" }
|
||||
+ stop 3
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ end
|
||||
+
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
|
||||
new file mode 100644
|
||||
index 00000000000..e1125ca717a
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
|
||||
@@ -0,0 +1,45 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-non-logical-if" }
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
|
||||
+! and Jeff Law <law@redhat.com>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ function othersub1()
|
||||
+ integer*4 othersub1
|
||||
+ othersub1 = 9
|
||||
+ end
|
||||
+
|
||||
+ function othersub2()
|
||||
+ integer*4 othersub2
|
||||
+ othersub2 = 0
|
||||
+ end
|
||||
+
|
||||
+ program MAIN
|
||||
+ integer*4 othersub1
|
||||
+ integer*4 othersub2
|
||||
+ integer a /1/
|
||||
+ integer b /2/
|
||||
+
|
||||
+ if (othersub1()) then ! { dg-error "IF clause at" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 1
|
||||
+ end if
|
||||
+ if (othersub2()) then ! { dg-error "IF clause at" }
|
||||
+ stop 2
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ if (a-b) then ! { dg-error "IF clause at" }
|
||||
+ write(*,*) "OK"
|
||||
+ else
|
||||
+ stop 3
|
||||
+ end if
|
||||
+ if (b-(a+1)) then ! { dg-error "IF clause at" }
|
||||
+ stop 3
|
||||
+ else
|
||||
+ write(*,*) "OK"
|
||||
+ end if
|
||||
+ end
|
||||
+
|
||||
--
|
||||
2.27.0
|
||||
|
||||
185
SOURCES/gcc11-fortran-fdec-old-init.patch
Normal file
185
SOURCES/gcc11-fortran-fdec-old-init.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From 8bcc0f85ed1718c0dd9033ad4a34df181aabaffe Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 13:11:06 +0000
|
||||
Subject: [PATCH 05/10] Allow old-style initializers in derived types
|
||||
|
||||
This allows simple declarations in derived types and structures, such as:
|
||||
LOGICAL*1 NIL /0/
|
||||
Only single value expressions are allowed at the moment.
|
||||
|
||||
Use -fdec-old-init to enable. Also enabled by -fdec.
|
||||
---
|
||||
gcc/fortran/decl.c | 27 +++++++++++++++----
|
||||
gcc/fortran/lang.opt | 4 +++
|
||||
gcc/fortran/options.c | 1 +
|
||||
...ec_derived_types_initialised_old_style_1.f | 25 +++++++++++++++++
|
||||
...ec_derived_types_initialised_old_style_2.f | 25 +++++++++++++++++
|
||||
...ec_derived_types_initialised_old_style_3.f | 26 ++++++++++++++++++
|
||||
6 files changed, 103 insertions(+), 5 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
|
||||
|
||||
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
|
||||
index 723915822f3..5c8c1b7981b 100644
|
||||
--- a/gcc/fortran/decl.c
|
||||
+++ b/gcc/fortran/decl.c
|
||||
@@ -2827,12 +2827,29 @@ variable_decl (int elem)
|
||||
but not components of derived types. */
|
||||
else if (gfc_current_state () == COMP_DERIVED)
|
||||
{
|
||||
- gfc_error ("Invalid old style initialization for derived type "
|
||||
- "component at %C");
|
||||
- m = MATCH_ERROR;
|
||||
- goto cleanup;
|
||||
+ if (flag_dec_old_init)
|
||||
+ {
|
||||
+ /* Attempt to match an old-style initializer which is a simple
|
||||
+ integer or character expression; this will not work with
|
||||
+ multiple values. */
|
||||
+ m = gfc_match_init_expr (&initializer);
|
||||
+ if (m == MATCH_ERROR)
|
||||
+ goto cleanup;
|
||||
+ else if (m == MATCH_YES)
|
||||
+ {
|
||||
+ m = gfc_match ("/");
|
||||
+ if (m != MATCH_YES)
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ gfc_error ("Invalid old style initialization for derived type "
|
||||
+ "component at %C");
|
||||
+ m = MATCH_ERROR;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
/* For structure components, read the initializer as a special
|
||||
expression and let the rest of this function apply the initializer
|
||||
as usual. */
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index d527c106bd6..25cc948699b 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -493,6 +493,10 @@ fdec-non-integer-index
|
||||
Fortran Var(flag_dec_non_integer_index)
|
||||
Enable support for non-integer substring indexes.
|
||||
|
||||
+fdec-old-init
|
||||
+Fortran Var(flag_dec_old_init)
|
||||
+Enable support for old style initializers in derived types.
|
||||
+
|
||||
fdec-structure
|
||||
Fortran Var(flag_dec_structure)
|
||||
Enable support for DEC STRUCTURE/RECORD.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index 9a042f64881..d6bd36c3a8a 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -79,6 +79,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_char_conversions, value, value);
|
||||
SET_BITFLAG (flag_dec_duplicates, value, value);
|
||||
SET_BITFLAG (flag_dec_non_integer_index, value, value);
|
||||
+ SET_BITFLAG (flag_dec_old_init, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..eac4f9bfcf1
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
|
||||
@@ -0,0 +1,25 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test old style initializers in derived types
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM spec_in_var
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID /8/
|
||||
+ INTEGER*4 TYPE /5/
|
||||
+ INTEGER*8 DEFVAL /0/
|
||||
+ CHARACTER*(5) NAME /'tests'/
|
||||
+ LOGICAL*1 NIL /0/
|
||||
+ END TYPE STRUCT1
|
||||
+
|
||||
+ TYPE (STRUCT1) SINST
|
||||
+
|
||||
+ IF(SINST%ID.NE.8) STOP 1
|
||||
+ IF(SINST%TYPE.NE.5) STOP 2
|
||||
+ IF(SINST%DEFVAL.NE.0) STOP 3
|
||||
+ IF(SINST%NAME.NE.'tests') STOP 4
|
||||
+ IF(SINST%NIL) STOP 5
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..d904c8b2974
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
|
||||
@@ -0,0 +1,25 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-std=legacy -fdec-old-init" }
|
||||
+!
|
||||
+! Test old style initializers in derived types
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM spec_in_var
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID /8/
|
||||
+ INTEGER*4 TYPE /5/
|
||||
+ INTEGER*8 DEFVAL /0/
|
||||
+ CHARACTER*(5) NAME /'tests'/
|
||||
+ LOGICAL*1 NIL /0/
|
||||
+ END TYPE STRUCT1
|
||||
+
|
||||
+ TYPE (STRUCT1) SINST
|
||||
+
|
||||
+ IF(SINST%ID.NE.8) STOP 1
|
||||
+ IF(SINST%TYPE.NE.5) STOP 2
|
||||
+ IF(SINST%DEFVAL.NE.0) STOP 3
|
||||
+ IF(SINST%NAME.NE.'tests') STOP 4
|
||||
+ IF(SINST%NIL) STOP 5
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..58c2b4b66cf
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
|
||||
@@ -0,0 +1,26 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=legacy -fdec -fno-dec-old-init" }
|
||||
+!
|
||||
+! Test old style initializers in derived types
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+ PROGRAM spec_in_var
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID /8/ ! { dg-error "Invalid old style initialization" }
|
||||
+ INTEGER*4 TYPE /5/ ! { dg-error "Invalid old style initialization" }
|
||||
+ INTEGER*8 DEFVAL /0/ ! { dg-error "Invalid old style initialization" }
|
||||
+ CHARACTER*(5) NAME /'tests'/ ! { dg-error "Invalid old style initialization" }
|
||||
+ LOGICAL*1 NIL /0/ ! { dg-error "Invalid old style initialization" }
|
||||
+ END TYPE STRUCT1
|
||||
+
|
||||
+ TYPE (STRUCT1) SINST
|
||||
+
|
||||
+ IF(SINST%ID.NE.8) STOP 1 ! { dg-error "'id' at \\(1\\) is not a member" }
|
||||
+ IF(SINST%TYPE.NE.5) STOP 2 ! { dg-error "'type' at \\(1\\) is not a member" }
|
||||
+ IF(SINST%DEFVAL.NE.0) STOP 3 ! { dg-error "'defval' at \\(1\\) is not a member" }
|
||||
+ IF(SINST%NAME.NE.'tests') STOP 4 ! { dg-error "'name' at \\(1\\) is not a member" }
|
||||
+ IF(SINST%NIL) STOP 5 ! { dg-error "'nil' at \\(1\\) is not a member" }
|
||||
+ END
|
||||
--
|
||||
2.27.0
|
||||
|
||||
588
SOURCES/gcc11-fortran-fdec-override-kind.patch
Normal file
588
SOURCES/gcc11-fortran-fdec-override-kind.patch
Normal file
@ -0,0 +1,588 @@
|
||||
From 786869fd62813e80da9b6545a295d53c36275c19 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 13:12:14 +0000
|
||||
Subject: [PATCH 06/10] Allow string length and kind to be specified on a per
|
||||
variable basis.
|
||||
|
||||
This allows kind/length to be mixed with array specification in
|
||||
declarations.
|
||||
|
||||
e.g.
|
||||
|
||||
INTEGER*4 x*2, y*8
|
||||
CHARACTER names*20(10)
|
||||
REAL v(100)*8, vv*4(50)
|
||||
|
||||
The per-variable size overrides the kind or length specified for the type.
|
||||
|
||||
Use -fdec-override-kind to enable. Also enabled by -fdec.
|
||||
|
||||
Note: this feature is a merger of two previously separate features.
|
||||
|
||||
Now accepts named constants as kind parameters:
|
||||
|
||||
INTEGER A
|
||||
PARAMETER (A=2)
|
||||
INTEGER B*(A)
|
||||
|
||||
Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
|
||||
Now rejects invalid kind parameters and prints error messages:
|
||||
|
||||
INTEGER X*3
|
||||
|
||||
caused an internal compiler error.
|
||||
|
||||
Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
---
|
||||
gcc/fortran/decl.c | 156 ++++++++++++++----
|
||||
gcc/fortran/lang.opt | 4 +
|
||||
gcc/fortran/options.c | 1 +
|
||||
.../dec_mixed_char_array_declaration_1.f | 13 ++
|
||||
.../dec_mixed_char_array_declaration_2.f | 13 ++
|
||||
.../dec_mixed_char_array_declaration_3.f | 13 ++
|
||||
.../gfortran.dg/dec_spec_in_variable_1.f | 31 ++++
|
||||
.../gfortran.dg/dec_spec_in_variable_2.f | 31 ++++
|
||||
.../gfortran.dg/dec_spec_in_variable_3.f | 31 ++++
|
||||
.../gfortran.dg/dec_spec_in_variable_4.f | 14 ++
|
||||
.../gfortran.dg/dec_spec_in_variable_5.f | 19 +++
|
||||
.../gfortran.dg/dec_spec_in_variable_6.f | 19 +++
|
||||
.../gfortran.dg/dec_spec_in_variable_7.f | 15 ++
|
||||
.../gfortran.dg/dec_spec_in_variable_8.f | 14 ++
|
||||
14 files changed, 340 insertions(+), 34 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
|
||||
|
||||
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
|
||||
index 5c8c1b7981b..f7dc9d8263d 100644
|
||||
--- a/gcc/fortran/decl.c
|
||||
+++ b/gcc/fortran/decl.c
|
||||
@@ -1213,6 +1213,54 @@ syntax:
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
|
||||
+/* This matches the nonstandard kind given after a variable name, like:
|
||||
+ INTEGER x*2, y*4
|
||||
+ The per-variable kind will override any kind given in the type
|
||||
+ declaration.
|
||||
+*/
|
||||
+
|
||||
+static match
|
||||
+match_per_symbol_kind (int *length)
|
||||
+{
|
||||
+ match m;
|
||||
+ gfc_expr *expr = NULL;
|
||||
+
|
||||
+ m = gfc_match_char ('*');
|
||||
+ if (m != MATCH_YES)
|
||||
+ return m;
|
||||
+
|
||||
+ m = gfc_match_small_literal_int (length, NULL);
|
||||
+ if (m == MATCH_YES || m == MATCH_ERROR)
|
||||
+ return m;
|
||||
+
|
||||
+ if (gfc_match_char ('(') == MATCH_NO)
|
||||
+ return MATCH_ERROR;
|
||||
+
|
||||
+ m = gfc_match_expr (&expr);
|
||||
+ if (m == MATCH_YES)
|
||||
+ {
|
||||
+ m = MATCH_ERROR; // Assume error
|
||||
+ if (gfc_expr_check_typed (expr, gfc_current_ns, false))
|
||||
+ {
|
||||
+ if ((expr->expr_type == EXPR_CONSTANT)
|
||||
+ && (expr->ts.type == BT_INTEGER))
|
||||
+ {
|
||||
+ *length = mpz_get_si(expr->value.integer);
|
||||
+ m = MATCH_YES;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (m == MATCH_YES)
|
||||
+ {
|
||||
+ if (gfc_match_char (')') == MATCH_NO)
|
||||
+ m = MATCH_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (expr != NULL)
|
||||
+ gfc_free_expr (expr);
|
||||
+ return m;
|
||||
+}
|
||||
|
||||
/* Special subroutine for finding a symbol. Check if the name is found
|
||||
in the current name space. If not, and we're compiling a function or
|
||||
@@ -2443,6 +2491,35 @@ check_function_name (char *name)
|
||||
}
|
||||
|
||||
|
||||
+static match
|
||||
+match_character_length_clause (gfc_charlen **cl, bool *cl_deferred, int elem)
|
||||
+{
|
||||
+ gfc_expr* char_len;
|
||||
+ char_len = NULL;
|
||||
+
|
||||
+ match m = match_char_length (&char_len, cl_deferred, false);
|
||||
+ if (m == MATCH_YES)
|
||||
+ {
|
||||
+ *cl = gfc_new_charlen (gfc_current_ns, NULL);
|
||||
+ (*cl)->length = char_len;
|
||||
+ }
|
||||
+ else if (m == MATCH_NO)
|
||||
+ {
|
||||
+ if (elem > 1
|
||||
+ && (current_ts.u.cl->length == NULL
|
||||
+ || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
|
||||
+ {
|
||||
+ *cl = gfc_new_charlen (gfc_current_ns, NULL);
|
||||
+ (*cl)->length = gfc_copy_expr (current_ts.u.cl->length);
|
||||
+ }
|
||||
+ else
|
||||
+ *cl = current_ts.u.cl;
|
||||
+
|
||||
+ *cl_deferred = current_ts.deferred;
|
||||
+ }
|
||||
+ return m;
|
||||
+}
|
||||
+
|
||||
/* Match a variable name with an optional initializer. When this
|
||||
subroutine is called, a variable is expected to be parsed next.
|
||||
Depending on what is happening at the moment, updates either the
|
||||
@@ -2453,7 +2530,7 @@ variable_decl (int elem)
|
||||
{
|
||||
char name[GFC_MAX_SYMBOL_LEN + 1];
|
||||
static unsigned int fill_id = 0;
|
||||
- gfc_expr *initializer, *char_len;
|
||||
+ gfc_expr *initializer;
|
||||
gfc_array_spec *as;
|
||||
gfc_array_spec *cp_as; /* Extra copy for Cray Pointees. */
|
||||
gfc_charlen *cl;
|
||||
@@ -2462,11 +2539,15 @@ variable_decl (int elem)
|
||||
match m;
|
||||
bool t;
|
||||
gfc_symbol *sym;
|
||||
+ match cl_match;
|
||||
+ match kind_match;
|
||||
+ int overridden_kind;
|
||||
char c;
|
||||
|
||||
initializer = NULL;
|
||||
as = NULL;
|
||||
cp_as = NULL;
|
||||
+ kind_match = MATCH_NO;
|
||||
|
||||
/* When we get here, we've just matched a list of attributes and
|
||||
maybe a type and a double colon. The next thing we expect to see
|
||||
@@ -2519,6 +2600,28 @@ variable_decl (int elem)
|
||||
|
||||
var_locus = gfc_current_locus;
|
||||
|
||||
+
|
||||
+ cl = NULL;
|
||||
+ cl_deferred = false;
|
||||
+ cl_match = MATCH_NO;
|
||||
+
|
||||
+ /* Check for a character length clause before an array clause */
|
||||
+ if (flag_dec_override_kind)
|
||||
+ {
|
||||
+ if (current_ts.type == BT_CHARACTER)
|
||||
+ {
|
||||
+ cl_match = match_character_length_clause (&cl, &cl_deferred, elem);
|
||||
+ if (cl_match == MATCH_ERROR)
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ kind_match = match_per_symbol_kind (&overridden_kind);
|
||||
+ if (kind_match == MATCH_ERROR)
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Now we could see the optional array spec. or character length. */
|
||||
m = gfc_match_array_spec (&as, true, true);
|
||||
if (m == MATCH_ERROR)
|
||||
@@ -2667,40 +2770,12 @@ variable_decl (int elem)
|
||||
}
|
||||
}
|
||||
|
||||
- char_len = NULL;
|
||||
- cl = NULL;
|
||||
- cl_deferred = false;
|
||||
-
|
||||
- if (current_ts.type == BT_CHARACTER)
|
||||
+ /* Second chance for a character length clause */
|
||||
+ if (cl_match == MATCH_NO && current_ts.type == BT_CHARACTER)
|
||||
{
|
||||
- switch (match_char_length (&char_len, &cl_deferred, false))
|
||||
- {
|
||||
- case MATCH_YES:
|
||||
- cl = gfc_new_charlen (gfc_current_ns, NULL);
|
||||
-
|
||||
- cl->length = char_len;
|
||||
- break;
|
||||
-
|
||||
- /* Non-constant lengths need to be copied after the first
|
||||
- element. Also copy assumed lengths. */
|
||||
- case MATCH_NO:
|
||||
- if (elem > 1
|
||||
- && (current_ts.u.cl->length == NULL
|
||||
- || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
|
||||
- {
|
||||
- cl = gfc_new_charlen (gfc_current_ns, NULL);
|
||||
- cl->length = gfc_copy_expr (current_ts.u.cl->length);
|
||||
- }
|
||||
- else
|
||||
- cl = current_ts.u.cl;
|
||||
-
|
||||
- cl_deferred = current_ts.deferred;
|
||||
-
|
||||
- break;
|
||||
-
|
||||
- case MATCH_ERROR:
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ m = match_character_length_clause (&cl, &cl_deferred, elem);
|
||||
+ if (m == MATCH_ERROR)
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* The dummy arguments and result of the abreviated form of MODULE
|
||||
@@ -2802,6 +2877,19 @@ variable_decl (int elem)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ if (kind_match == MATCH_YES)
|
||||
+ {
|
||||
+ gfc_find_symbol (name, gfc_current_ns, 1, &sym);
|
||||
+ /* sym *must* be found at this point */
|
||||
+ sym->ts.kind = overridden_kind;
|
||||
+ if (gfc_validate_kind (sym->ts.type, sym->ts.kind, true) < 0)
|
||||
+ {
|
||||
+ gfc_error ("Kind %d not supported for type %s at %C",
|
||||
+ sym->ts.kind, gfc_basic_typename (sym->ts.type));
|
||||
+ return MATCH_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!check_function_name (name))
|
||||
{
|
||||
m = MATCH_ERROR;
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 25cc948699b..4a269ebb22d 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -493,6 +493,10 @@ fdec-non-integer-index
|
||||
Fortran Var(flag_dec_non_integer_index)
|
||||
Enable support for non-integer substring indexes.
|
||||
|
||||
+fdec-override-kind
|
||||
+Fortran Var(flag_dec_override_kind)
|
||||
+Enable support for per variable kind specification.
|
||||
+
|
||||
fdec-old-init
|
||||
Fortran Var(flag_dec_old_init)
|
||||
Enable support for old style initializers in derived types.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index d6bd36c3a8a..edbab483b36 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -80,6 +80,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_duplicates, value, value);
|
||||
SET_BITFLAG (flag_dec_non_integer_index, value, value);
|
||||
SET_BITFLAG (flag_dec_old_init, value, value);
|
||||
+ SET_BITFLAG (flag_dec_override_kind, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..706ea4112a4
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test character declaration with mixed string length and array specification
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM character_declaration
|
||||
+ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/
|
||||
+ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
|
||||
+ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..26d2acf01de
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-override-kind" }
|
||||
+!
|
||||
+! Test character declaration with mixed string length and array specification
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM character_declaration
|
||||
+ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/
|
||||
+ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
|
||||
+ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..76e4f0bdb93
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec-override-kind -fno-dec-override-kind" }
|
||||
+!
|
||||
+! Test character declaration with mixed string length and array specification
|
||||
+!
|
||||
+! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM character_declaration
|
||||
+ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/ ! { dg-error "Syntax error" }
|
||||
+ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
|
||||
+ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1 ! { dg-error " Operands of comparison operator" }
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..edd0f5874b7
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
|
||||
@@ -0,0 +1,31 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer*8 ai*1, bi*4, ci
|
||||
+ real*4 ar*4, br*8, cr
|
||||
+
|
||||
+ ai = 1
|
||||
+ ar = 1.0
|
||||
+ bi = 2
|
||||
+ br = 2.0
|
||||
+ ci = 3
|
||||
+ cr = 3.0
|
||||
+
|
||||
+ if (ai .ne. 1) stop 1
|
||||
+ if (abs(ar - 1.0) > 1.0D-6) stop 2
|
||||
+ if (bi .ne. 2) stop 3
|
||||
+ if (abs(br - 2.0) > 1.0D-6) stop 4
|
||||
+ if (ci .ne. 3) stop 5
|
||||
+ if (abs(cr - 3.0) > 1.0D-6) stop 6
|
||||
+ if (kind(ai) .ne. 1) stop 7
|
||||
+ if (kind(ar) .ne. 4) stop 8
|
||||
+ if (kind(bi) .ne. 4) stop 9
|
||||
+ if (kind(br) .ne. 8) stop 10
|
||||
+ if (kind(ci) .ne. 8) stop 11
|
||||
+ if (kind(cr) .ne. 4) stop 12
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..bfaba584dbb
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
|
||||
@@ -0,0 +1,31 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-override-kind" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer*8 ai*1, bi*4, ci
|
||||
+ real*4 ar*4, br*8, cr
|
||||
+
|
||||
+ ai = 1
|
||||
+ ar = 1.0
|
||||
+ bi = 2
|
||||
+ br = 2.0
|
||||
+ ci = 3
|
||||
+ cr = 3.0
|
||||
+
|
||||
+ if (ai .ne. 1) stop 1
|
||||
+ if (abs(ar - 1.0) > 1.0D-6) stop 2
|
||||
+ if (bi .ne. 2) stop 3
|
||||
+ if (abs(br - 2.0) > 1.0D-6) stop 4
|
||||
+ if (ci .ne. 3) stop 5
|
||||
+ if (abs(cr - 3.0) > 1.0D-6) stop 6
|
||||
+ if (kind(ai) .ne. 1) stop 7
|
||||
+ if (kind(ar) .ne. 4) stop 8
|
||||
+ if (kind(bi) .ne. 4) stop 9
|
||||
+ if (kind(br) .ne. 8) stop 10
|
||||
+ if (kind(ci) .ne. 8) stop 11
|
||||
+ if (kind(cr) .ne. 4) stop 12
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..5ff434e7466
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
|
||||
@@ -0,0 +1,31 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-override-kind" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer*8 ai*1, bi*4, ci ! { dg-error "Syntax error" }
|
||||
+ real*4 ar*4, br*8, cr ! { dg-error "Syntax error" }
|
||||
+
|
||||
+ ai = 1
|
||||
+ ar = 1.0
|
||||
+ bi = 2
|
||||
+ br = 2.0
|
||||
+ ci = 3
|
||||
+ cr = 3.0
|
||||
+
|
||||
+ if (ai .ne. 1) stop 1
|
||||
+ if (abs(ar - 1.0) > 1.0D-6) stop 2
|
||||
+ if (bi .ne. 2) stop 3
|
||||
+ if (abs(br - 2.0) > 1.0D-6) stop 4
|
||||
+ if (ci .ne. 3) stop 5
|
||||
+ if (abs(cr - 3.0) > 1.0D-6) stop 6
|
||||
+ if (kind(ai) .ne. 1) stop 7
|
||||
+ if (kind(ar) .ne. 4) stop 8
|
||||
+ if (kind(bi) .ne. 4) stop 9
|
||||
+ if (kind(br) .ne. 8) stop 10
|
||||
+ if (kind(ci) .ne. 8) stop 11
|
||||
+ if (kind(cr) .ne. 4) stop 12
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
|
||||
new file mode 100644
|
||||
index 00000000000..c01980e8b9d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
|
||||
@@ -0,0 +1,14 @@
|
||||
+! { dg-do compile }
|
||||
+!
|
||||
+! Test kind specification in variable not in type. The per variable
|
||||
+! kind specification is not enabled so these should fail
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer a
|
||||
+ parameter(a=2)
|
||||
+ integer b*(a) ! { dg-error "Syntax error" }
|
||||
+ real c*(8) ! { dg-error "Syntax error" }
|
||||
+ logical d*1_1 ! { dg-error "Syntax error" }
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
|
||||
new file mode 100644
|
||||
index 00000000000..e2f39da3f4f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
|
||||
@@ -0,0 +1,19 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-override-kind" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer a
|
||||
+ parameter(a=2)
|
||||
+ integer b*(a)
|
||||
+ real c*(8)
|
||||
+ logical d*(1_1)
|
||||
+ character e*(a)
|
||||
+ if (kind(b).ne.2) stop 1
|
||||
+ if (kind(c).ne.8) stop 2
|
||||
+ if (kind(d).ne.1) stop 3
|
||||
+ if (len(e).ne.2) stop 4
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
|
||||
new file mode 100644
|
||||
index 00000000000..569747874e3
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
|
||||
@@ -0,0 +1,19 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer a
|
||||
+ parameter(a=2)
|
||||
+ integer b*(a)
|
||||
+ real c*(8)
|
||||
+ logical d*(1_1)
|
||||
+ character e*(a)
|
||||
+ if (kind(b).ne.2) stop 1
|
||||
+ if (kind(c).ne.8) stop 2
|
||||
+ if (kind(d).ne.1) stop 3
|
||||
+ if (len(e).ne.2) stop 4
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
|
||||
new file mode 100644
|
||||
index 00000000000..b975bfd15c5
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
|
||||
@@ -0,0 +1,15 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-override-kind" }
|
||||
+!
|
||||
+! Test kind specification in variable not in type as the per variable
|
||||
+! kind specification is not enables these should fail
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer a
|
||||
+ parameter(a=2)
|
||||
+ integer b*(a) ! { dg-error "Syntax error" }
|
||||
+ real c*(8) ! { dg-error "Syntax error" }
|
||||
+ logical d*1_1 ! { dg-error "Syntax error" }
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
|
||||
new file mode 100644
|
||||
index 00000000000..85732e0bd85
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
|
||||
@@ -0,0 +1,14 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Check that invalid kind values are rejected.
|
||||
+!
|
||||
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ program spec_in_var
|
||||
+ integer a
|
||||
+ parameter(a=3)
|
||||
+ integer b*(a) ! { dg-error "Kind 3 not supported" }
|
||||
+ real c*(78) ! { dg-error "Kind 78 not supported" }
|
||||
+ logical d*(*) ! { dg-error "Invalid character" }
|
||||
+ end
|
||||
--
|
||||
2.27.0
|
||||
|
||||
2093
SOURCES/gcc11-fortran-fdec-promotion.patch
Normal file
2093
SOURCES/gcc11-fortran-fdec-promotion.patch
Normal file
File diff suppressed because it is too large
Load Diff
262
SOURCES/gcc11-fortran-fdec-sequence.patch
Normal file
262
SOURCES/gcc11-fortran-fdec-sequence.patch
Normal file
@ -0,0 +1,262 @@
|
||||
From bb76446db10c21860a4e19569ce3e350d8a2b59f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 15:00:44 +0000
|
||||
Subject: [PATCH 09/10] Add the SEQUENCE attribute by default if it's not
|
||||
present.
|
||||
|
||||
Use -fdec-sequence to enable this feature. Also enabled by -fdec.
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++
|
||||
gcc/fortran/options.c | 1 +
|
||||
gcc/fortran/resolve.c | 13 ++++-
|
||||
...dd_SEQUENCE_to_COMMON_block_by_default_1.f | 57 +++++++++++++++++++
|
||||
...dd_SEQUENCE_to_COMMON_block_by_default_2.f | 57 +++++++++++++++++++
|
||||
...dd_SEQUENCE_to_COMMON_block_by_default_3.f | 57 +++++++++++++++++++
|
||||
6 files changed, 186 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 4ca2f93f2df..019c798cf09 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -509,6 +509,10 @@ fdec-promotion
|
||||
Fortran Var(flag_dec_promotion)
|
||||
Add support for type promotion in intrinsic arguments.
|
||||
|
||||
+fdec-sequence
|
||||
+Fortran Var(flag_dec_sequence)
|
||||
+Add the SEQUENCE attribute by default if it's not present.
|
||||
+
|
||||
fdec-structure
|
||||
Fortran Var(flag_dec_structure)
|
||||
Enable support for DEC STRUCTURE/RECORD.
|
||||
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
|
||||
index 15079c7e95a..050f56fdc25 100644
|
||||
--- a/gcc/fortran/options.c
|
||||
+++ b/gcc/fortran/options.c
|
||||
@@ -83,6 +83,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_override_kind, value, value);
|
||||
SET_BITFLAG (flag_dec_non_logical_if, value, value);
|
||||
SET_BITFLAG (flag_dec_promotion, value, value);
|
||||
+ SET_BITFLAG (flag_dec_sequence, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
|
||||
index 07dd039f3bf..fe7d0cc5944 100644
|
||||
--- a/gcc/fortran/resolve.c
|
||||
+++ b/gcc/fortran/resolve.c
|
||||
@@ -978,9 +978,16 @@ resolve_common_vars (gfc_common_head *common_block, bool named_common)
|
||||
|
||||
if (!(csym->ts.u.derived->attr.sequence
|
||||
|| csym->ts.u.derived->attr.is_bind_c))
|
||||
- gfc_error_now ("Derived type variable %qs in COMMON at %L "
|
||||
- "has neither the SEQUENCE nor the BIND(C) "
|
||||
- "attribute", csym->name, &csym->declared_at);
|
||||
+ {
|
||||
+ if (flag_dec_sequence)
|
||||
+ /* Assume sequence. */
|
||||
+ csym->ts.u.derived->attr.sequence = 1;
|
||||
+ else
|
||||
+ gfc_error_now ("Derived type variable '%s' in COMMON at %L "
|
||||
+ "has neither the SEQUENCE nor the BIND(C) "
|
||||
+ "attribute", csym->name, &csym->declared_at);
|
||||
+ }
|
||||
+
|
||||
if (csym->ts.u.derived->attr.alloc_comp)
|
||||
gfc_error_now ("Derived type variable %qs in COMMON at %L "
|
||||
"has an ultimate component that is "
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..fe7b39625eb
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
|
||||
@@ -0,0 +1,57 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test add default SEQUENCE attribute derived types appearing in
|
||||
+! COMMON blocks and EQUIVALENCE statements.
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ MODULE SEQ
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID
|
||||
+ INTEGER*4 TYPE
|
||||
+ INTEGER*8 DEFVAL
|
||||
+ CHARACTER*(4) NAME
|
||||
+ LOGICAL*1 NIL
|
||||
+ END TYPE STRUCT1
|
||||
+ END MODULE
|
||||
+
|
||||
+ SUBROUTINE A
|
||||
+ USE SEQ
|
||||
+ TYPE (STRUCT1) S
|
||||
+ COMMON /BLOCK1/ S
|
||||
+ IF (S%ID.NE.5) STOP 1
|
||||
+ IF (S%TYPE.NE.1000) STOP 2
|
||||
+ IF (S%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S%NAME.NE."JANE") STOP 4
|
||||
+ IF (S%NIL.NEQV..FALSE.) STOP 5
|
||||
+ END SUBROUTINE
|
||||
+
|
||||
+ PROGRAM sequence_att_common
|
||||
+ USE SEQ
|
||||
+ IMPLICIT NONE
|
||||
+ TYPE (STRUCT1) S1
|
||||
+ TYPE (STRUCT1) S2
|
||||
+ TYPE (STRUCT1) S3
|
||||
+
|
||||
+ EQUIVALENCE (S1,S2)
|
||||
+ COMMON /BLOCK1/ S3
|
||||
+
|
||||
+ S1%ID = 5
|
||||
+ S1%TYPE = 1000
|
||||
+ S1%DEFVAL = -99
|
||||
+ S1%NAME = "JANE"
|
||||
+ S1%NIL = .FALSE.
|
||||
+
|
||||
+ IF (S2%ID.NE.5) STOP 1
|
||||
+ IF (S2%TYPE.NE.1000) STOP 2
|
||||
+ IF (S2%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S2%NAME.NE."JANE") STOP 4
|
||||
+ IF (S2%NIL.NEQV..FALSE.) STOP 5
|
||||
+
|
||||
+ S3 = S1
|
||||
+
|
||||
+ CALL A
|
||||
+
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..83512f0f3a2
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
|
||||
@@ -0,0 +1,57 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-sequence" }
|
||||
+!
|
||||
+! Test add default SEQUENCE attribute derived types appearing in
|
||||
+! COMMON blocks and EQUIVALENCE statements.
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ MODULE SEQ
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID
|
||||
+ INTEGER*4 TYPE
|
||||
+ INTEGER*8 DEFVAL
|
||||
+ CHARACTER*(4) NAME
|
||||
+ LOGICAL*1 NIL
|
||||
+ END TYPE STRUCT1
|
||||
+ END MODULE
|
||||
+
|
||||
+ SUBROUTINE A
|
||||
+ USE SEQ
|
||||
+ TYPE (STRUCT1) S
|
||||
+ COMMON /BLOCK1/ S
|
||||
+ IF (S%ID.NE.5) STOP 1
|
||||
+ IF (S%TYPE.NE.1000) STOP 2
|
||||
+ IF (S%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S%NAME.NE."JANE") STOP 4
|
||||
+ IF (S%NIL.NEQV..FALSE.) STOP 5
|
||||
+ END SUBROUTINE
|
||||
+
|
||||
+ PROGRAM sequence_att_common
|
||||
+ USE SEQ
|
||||
+ IMPLICIT NONE
|
||||
+ TYPE (STRUCT1) S1
|
||||
+ TYPE (STRUCT1) S2
|
||||
+ TYPE (STRUCT1) S3
|
||||
+
|
||||
+ EQUIVALENCE (S1,S2)
|
||||
+ COMMON /BLOCK1/ S3
|
||||
+
|
||||
+ S1%ID = 5
|
||||
+ S1%TYPE = 1000
|
||||
+ S1%DEFVAL = -99
|
||||
+ S1%NAME = "JANE"
|
||||
+ S1%NIL = .FALSE.
|
||||
+
|
||||
+ IF (S2%ID.NE.5) STOP 1
|
||||
+ IF (S2%TYPE.NE.1000) STOP 2
|
||||
+ IF (S2%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S2%NAME.NE."JANE") STOP 4
|
||||
+ IF (S2%NIL.NEQV..FALSE.) STOP 5
|
||||
+
|
||||
+ S3 = S1
|
||||
+
|
||||
+ CALL A
|
||||
+
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..26cd59f9090
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
|
||||
@@ -0,0 +1,57 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-sequence" }
|
||||
+!
|
||||
+! Test add default SEQUENCE attribute derived types appearing in
|
||||
+! COMMON blocks and EQUIVALENCE statements.
|
||||
+!
|
||||
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
|
||||
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ MODULE SEQ
|
||||
+ TYPE STRUCT1
|
||||
+ INTEGER*4 ID
|
||||
+ INTEGER*4 TYPE
|
||||
+ INTEGER*8 DEFVAL
|
||||
+ CHARACTER*(4) NAME
|
||||
+ LOGICAL*1 NIL
|
||||
+ END TYPE STRUCT1
|
||||
+ END MODULE
|
||||
+
|
||||
+ SUBROUTINE A
|
||||
+ USE SEQ
|
||||
+ TYPE (STRUCT1) S ! { dg-error "Derived type variable" }
|
||||
+ COMMON /BLOCK1/ S
|
||||
+ IF (S%ID.NE.5) STOP 1
|
||||
+ IF (S%TYPE.NE.1000) STOP 2
|
||||
+ IF (S%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S%NAME.NE."JANE") STOP 4
|
||||
+ IF (S%NIL.NEQV..FALSE.) STOP 5
|
||||
+ END SUBROUTINE
|
||||
+
|
||||
+ PROGRAM sequence_att_common
|
||||
+ USE SEQ
|
||||
+ IMPLICIT NONE
|
||||
+ TYPE (STRUCT1) S1
|
||||
+ TYPE (STRUCT1) S2
|
||||
+ TYPE (STRUCT1) S3 ! { dg-error "Derived type variable" }
|
||||
+
|
||||
+ EQUIVALENCE (S1,S2) ! { dg-error "Derived type variable" }
|
||||
+ COMMON /BLOCK1/ S3
|
||||
+
|
||||
+ S1%ID = 5
|
||||
+ S1%TYPE = 1000
|
||||
+ S1%DEFVAL = -99
|
||||
+ S1%NAME = "JANE"
|
||||
+ S1%NIL = .FALSE.
|
||||
+
|
||||
+ IF (S2%ID.NE.5) STOP 1
|
||||
+ IF (S2%TYPE.NE.1000) STOP 2
|
||||
+ IF (S2%DEFVAL.NE.-99) STOP 3
|
||||
+ IF (S2%NAME.NE."JANE") STOP 4
|
||||
+ IF (S2%NIL.NEQV..FALSE.) STOP 5
|
||||
+
|
||||
+ S3 = S1
|
||||
+
|
||||
+ CALL A
|
||||
+
|
||||
+ END
|
||||
--
|
||||
2.27.0
|
||||
|
||||
305
SOURCES/gcc11-fortran-flogical-as-integer.patch
Normal file
305
SOURCES/gcc11-fortran-flogical-as-integer.patch
Normal file
@ -0,0 +1,305 @@
|
||||
From 9b45f3063dfd2b893e7963a4828c1b0afecdc68a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 12:41:46 +0000
|
||||
Subject: [PATCH 02/10] Convert LOGICAL to INTEGER for arithmetic ops, and vice
|
||||
versa
|
||||
|
||||
We allow converting LOGICAL types to INTEGER when doing arithmetic
|
||||
operations, and converting INTEGER types to LOGICAL for use in
|
||||
boolean operations.
|
||||
|
||||
This feature is enabled with the -flogical-as-integer flag.
|
||||
|
||||
Note: using this feature will disable bitwise logical operations enabled by
|
||||
-fdec.
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++
|
||||
gcc/fortran/resolve.c | 55 ++++++++++++++++++-
|
||||
.../logical_to_integer_and_vice_versa_1.f | 31 +++++++++++
|
||||
.../logical_to_integer_and_vice_versa_2.f | 31 +++++++++++
|
||||
.../logical_to_integer_and_vice_versa_3.f | 33 +++++++++++
|
||||
.../logical_to_integer_and_vice_versa_4.f | 33 +++++++++++
|
||||
6 files changed, 186 insertions(+), 1 deletion(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 52bd522051e..c4da248f07c 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -497,6 +497,10 @@ fdec-static
|
||||
Fortran Var(flag_dec_static)
|
||||
Enable DEC-style STATIC and AUTOMATIC attributes.
|
||||
|
||||
+flogical-as-integer
|
||||
+Fortran Var(flag_logical_as_integer)
|
||||
+Convert from integer to logical or logical to integer for arithmetic operations.
|
||||
+
|
||||
fdefault-double-8
|
||||
Fortran Var(flag_default_double)
|
||||
Set the default double precision kind to an 8 byte wide type.
|
||||
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
|
||||
index c075d0fa0c4..4b90cb59902 100644
|
||||
--- a/gcc/fortran/resolve.c
|
||||
+++ b/gcc/fortran/resolve.c
|
||||
@@ -3915,7 +3915,6 @@ lookup_uop_fuzzy (const char *op, gfc_symtree *uop)
|
||||
return gfc_closest_fuzzy_match (op, candidates);
|
||||
}
|
||||
|
||||
-
|
||||
/* Callback finding an impure function as an operand to an .and. or
|
||||
.or. expression. Remember the last function warned about to
|
||||
avoid double warnings when recursing. */
|
||||
@@ -3975,6 +3974,22 @@ convert_hollerith_to_character (gfc_expr *e)
|
||||
}
|
||||
}
|
||||
|
||||
+/* If E is a logical, convert it to an integer and issue a warning
|
||||
+ for the conversion. */
|
||||
+
|
||||
+static void
|
||||
+convert_integer_to_logical (gfc_expr *e)
|
||||
+{
|
||||
+ if (e->ts.type == BT_INTEGER)
|
||||
+ {
|
||||
+ /* Convert to LOGICAL */
|
||||
+ gfc_typespec t;
|
||||
+ t.type = BT_LOGICAL;
|
||||
+ t.kind = 1;
|
||||
+ gfc_convert_type_warn (e, &t, 2, 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Convert to numeric and issue a warning for the conversion. */
|
||||
|
||||
static void
|
||||
@@ -3987,6 +4002,22 @@ convert_to_numeric (gfc_expr *a, gfc_expr *b)
|
||||
gfc_convert_type_warn (a, &t, 2, 1);
|
||||
}
|
||||
|
||||
+/* If E is a logical, convert it to an integer and issue a warning
|
||||
+ for the conversion. */
|
||||
+
|
||||
+static void
|
||||
+convert_logical_to_integer (gfc_expr *e)
|
||||
+{
|
||||
+ if (e->ts.type == BT_LOGICAL)
|
||||
+ {
|
||||
+ /* Convert to INTEGER */
|
||||
+ gfc_typespec t;
|
||||
+ t.type = BT_INTEGER;
|
||||
+ t.kind = 1;
|
||||
+ gfc_convert_type_warn (e, &t, 2, 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Resolve an operator expression node. This can involve replacing the
|
||||
operation with a user defined function call. */
|
||||
|
||||
@@ -4072,6 +4103,12 @@ resolve_operator (gfc_expr *e)
|
||||
case INTRINSIC_TIMES:
|
||||
case INTRINSIC_DIVIDE:
|
||||
case INTRINSIC_POWER:
|
||||
+ if (flag_logical_as_integer)
|
||||
+ {
|
||||
+ convert_logical_to_integer (op1);
|
||||
+ convert_logical_to_integer (op2);
|
||||
+ }
|
||||
+
|
||||
if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
|
||||
{
|
||||
gfc_type_convert_binary (e, 1);
|
||||
@@ -4108,6 +4145,13 @@ resolve_operator (gfc_expr *e)
|
||||
case INTRINSIC_OR:
|
||||
case INTRINSIC_EQV:
|
||||
case INTRINSIC_NEQV:
|
||||
+
|
||||
+ if (flag_logical_as_integer)
|
||||
+ {
|
||||
+ convert_integer_to_logical (op1);
|
||||
+ convert_integer_to_logical (op2);
|
||||
+ }
|
||||
+
|
||||
if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
|
||||
{
|
||||
e->ts.type = BT_LOGICAL;
|
||||
@@ -4158,6 +4202,9 @@ resolve_operator (gfc_expr *e)
|
||||
goto simplify_op;
|
||||
}
|
||||
|
||||
+ if (flag_logical_as_integer)
|
||||
+ convert_integer_to_logical (op1);
|
||||
+
|
||||
if (op1->ts.type == BT_LOGICAL)
|
||||
{
|
||||
e->ts.type = BT_LOGICAL;
|
||||
@@ -4198,6 +4245,12 @@ resolve_operator (gfc_expr *e)
|
||||
convert_hollerith_to_character (op2);
|
||||
}
|
||||
|
||||
+ if (flag_logical_as_integer)
|
||||
+ {
|
||||
+ convert_logical_to_integer (op1);
|
||||
+ convert_logical_to_integer (op2);
|
||||
+ }
|
||||
+
|
||||
if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
|
||||
&& op1->ts.kind == op2->ts.kind)
|
||||
{
|
||||
diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
|
||||
new file mode 100644
|
||||
index 00000000000..938a91d9e9a
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
|
||||
@@ -0,0 +1,31 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-std=legacy -flogical-as-integer" }
|
||||
+!
|
||||
+! Test conversion between logical and integer for logical operators
|
||||
+!
|
||||
+! Test case contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
+! Modified for -flogical-as-integer by Mark Eggleston
|
||||
+! <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+ PROGRAM logical_integer_conversion
|
||||
+ LOGICAL lpos /.true./
|
||||
+ INTEGER ineg/0/
|
||||
+ INTEGER ires
|
||||
+ LOGICAL lres
|
||||
+
|
||||
+ ! Test Logicals converted to Integers
|
||||
+ if ((lpos.AND.ineg).EQ.1) STOP 3
|
||||
+ if ((ineg.AND.lpos).NE.0) STOP 4
|
||||
+ ires = (.true..AND.0)
|
||||
+ if (ires.NE.0) STOP 5
|
||||
+ ires = (1.AND..false.)
|
||||
+ if (ires.EQ.1) STOP 6
|
||||
+
|
||||
+ ! Test Integers converted to Logicals
|
||||
+ if (lpos.EQ.ineg) STOP 7
|
||||
+ if (ineg.EQ.lpos) STOP 8
|
||||
+ lres = (.true..EQ.0)
|
||||
+ if (lres) STOP 9
|
||||
+ lres = (1.EQ..false.)
|
||||
+ if (lres) STOP 10
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
|
||||
new file mode 100644
|
||||
index 00000000000..9f146202ba5
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
|
||||
@@ -0,0 +1,31 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=legacy -flogical-as-integer -fno-logical-as-integer" }
|
||||
+!
|
||||
+! Based on logical_to_integer_and_vice_versa_1.f but with option disabled
|
||||
+! to test for error messages.
|
||||
+!
|
||||
+! Test case contributed by by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+!
|
||||
+ PROGRAM logical_integer_conversion
|
||||
+ LOGICAL lpos /.true./
|
||||
+ INTEGER ineg/0/
|
||||
+ INTEGER ires
|
||||
+ LOGICAL lres
|
||||
+
|
||||
+ ! Test Logicals converted to Integers
|
||||
+ if ((lpos.AND.ineg).EQ.1) STOP 3 ! { dg-error "Operands of logical operator" }
|
||||
+ if ((ineg.AND.lpos).NE.0) STOP 4 ! { dg-error "Operands of logical operator" }
|
||||
+ ires = (.true..AND.0) ! { dg-error "Operands of logical operator" }
|
||||
+ if (ires.NE.0) STOP 5
|
||||
+ ires = (1.AND..false.) ! { dg-error "Operands of logical operator" }
|
||||
+ if (ires.EQ.1) STOP 6
|
||||
+
|
||||
+ ! Test Integers converted to Logicals
|
||||
+ if (lpos.EQ.ineg) STOP 7 ! { dg-error "Operands of comparison operator" }
|
||||
+ if (ineg.EQ.lpos) STOP 8 ! { dg-error "Operands of comparison operator" }
|
||||
+ lres = (.true..EQ.0) ! { dg-error "Operands of comparison operator" }
|
||||
+ if (lres) STOP 9
|
||||
+ lres = (1.EQ..false.) ! { dg-error "Operands of comparison operator" }
|
||||
+ if (lres) STOP 10
|
||||
+ END
|
||||
diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
|
||||
new file mode 100644
|
||||
index 00000000000..446873eb2dc
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
|
||||
@@ -0,0 +1,33 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=legacy -flogical-as-integer" }
|
||||
+!
|
||||
+! Test conversion between logical and integer for logical operators
|
||||
+!
|
||||
+ program test
|
||||
+ logical f /.false./
|
||||
+ logical t /.true./
|
||||
+ real x
|
||||
+
|
||||
+ x = 7.7
|
||||
+ x = x + t*3.0
|
||||
+ if (abs(x - 10.7).gt.0.00001) stop 1
|
||||
+ x = x + .false.*5.0
|
||||
+ if (abs(x - 10.7).gt.0.00001) stop 2
|
||||
+ x = x - .true.*5.0
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 3
|
||||
+ x = x + t
|
||||
+ if (abs(x - 6.7).gt.0.00001) stop 4
|
||||
+ x = x + f
|
||||
+ if (abs(x - 6.7).gt.0.00001) stop 5
|
||||
+ x = x - t
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 6
|
||||
+ x = x - f
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 7
|
||||
+ x = x**.true.
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 8
|
||||
+ x = x**.false.
|
||||
+ if (abs(x - 1.0).gt.0.00001) stop 9
|
||||
+ x = x/t
|
||||
+ if (abs(x - 1.0).gt.0.00001) stop 10
|
||||
+ if ((x/.false.).le.huge(x)) stop 11
|
||||
+ end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
|
||||
new file mode 100644
|
||||
index 00000000000..4301a4988d8
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
|
||||
@@ -0,0 +1,33 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=legacy -flogical-as-integer -fno-logical-as-integer" }
|
||||
+!
|
||||
+! Test conversion between logical and integer for logical operators
|
||||
+!
|
||||
+ program test
|
||||
+ logical f /.false./
|
||||
+ logical t /.true./
|
||||
+ real x
|
||||
+
|
||||
+ x = 7.7
|
||||
+ x = x + t*3.0 ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 10.7).gt.0.00001) stop 1
|
||||
+ x = x + .false.*5.0 ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 10.7).gt.0.00001) stop 2
|
||||
+ x = x - .true.*5.0 ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 3
|
||||
+ x = x + t ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 6.7).gt.0.00001) stop 4
|
||||
+ x = x + f ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 6.7).gt.0.00001) stop 5
|
||||
+ x = x - t ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 6
|
||||
+ x = x - f ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 7
|
||||
+ x = x**.true. ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 5.7).gt.0.00001) stop 8
|
||||
+ x = x**.false. ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 1.0).gt.0.00001) stop 9
|
||||
+ x = x/t ! { dg-error "Operands of binary numeric" }
|
||||
+ if (abs(x - 1.0).gt.0.00001) stop 10
|
||||
+ if ((x/.false.).le.huge(x)) stop 11 ! { dg-error "Operands of binary numeric" }
|
||||
+ end
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
--- libada/Makefile.in.jj 2009-01-14 12:07:35.000000000 +0100
|
||||
+++ libada/Makefile.in 2009-01-15 14:25:33.000000000 +0100
|
||||
@@ -66,18 +66,40 @@ libsubdir := $(libdir)/gcc/$(target_nonc
|
||||
--- libada/Makefile.in.jj 2019-01-09 13:01:18.015608205 +0100
|
||||
+++ libada/Makefile.in 2019-01-11 18:16:23.441726931 +0100
|
||||
@@ -71,18 +71,40 @@ version := $(shell @get_gcc_base_ver@ $(
|
||||
libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)$(MULTISUBDIR)
|
||||
ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR))
|
||||
ADA_RTS_SUBDIR=./rts$(subst /,_,$(MULTISUBDIR))
|
||||
|
||||
+DEFAULTMULTIFLAGS :=
|
||||
+ifeq ($(MULTISUBDIR),)
|
||||
@ -45,17 +45,17 @@
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG)" \
|
||||
"THREAD_KIND=$(THREAD_KIND)" \
|
||||
"TRACE=$(TRACE)" \
|
||||
@@ -88,7 +110,7 @@ LIBADA_FLAGS_TO_PASS = \
|
||||
@@ -93,7 +115,7 @@ LIBADA_FLAGS_TO_PASS = \
|
||||
"exeext=.exeext.should.not.be.used " \
|
||||
'CC=the.host.compiler.should.not.be.needed' \
|
||||
"GCC_FOR_TARGET=$(CC)" \
|
||||
- "CFLAGS=$(CFLAGS)"
|
||||
+ "CFLAGS=$(CFLAGS) $(DEFAULTMULTIFLAGS)"
|
||||
|
||||
# Rules to build gnatlib.
|
||||
.PHONY: gnatlib gnatlib-plain gnatlib-sjlj gnatlib-zcx gnatlib-shared osconstool
|
||||
--- config-ml.in.jj 2010-06-30 09:50:44.000000000 +0200
|
||||
+++ config-ml.in 2010-07-02 21:24:17.994211151 +0200
|
||||
.PHONY: libada gnatlib gnatlib-shared gnatlib-sjlj gnatlib-zcx osconstool
|
||||
|
||||
--- config-ml.in.jj 2019-01-09 12:50:16.646501448 +0100
|
||||
+++ config-ml.in 2019-01-11 18:16:23.442726914 +0100
|
||||
@@ -511,6 +511,8 @@ multi-do:
|
||||
ADAFLAGS="$(ADAFLAGS) $${flags}" \
|
||||
prefix="$(prefix)" \
|
||||
@ -63,42 +63,44 @@
|
||||
+ mandir="$(mandir)" \
|
||||
+ infodir="$(infodir)" \
|
||||
GOCFLAGS="$(GOCFLAGS) $${flags}" \
|
||||
GDCFLAGS="$(GDCFLAGS) $${flags}" \
|
||||
CXXFLAGS="$(CXXFLAGS) $${flags}" \
|
||||
LIBCFLAGS="$(LIBCFLAGS) $${flags}" \
|
||||
--- libcpp/macro.c.jj 2015-01-14 11:01:34.000000000 +0100
|
||||
+++ libcpp/macro.c 2015-01-14 14:22:19.286949884 +0100
|
||||
@@ -2947,8 +2947,6 @@ create_iso_definition (cpp_reader *pfile
|
||||
cpp_token *token;
|
||||
const cpp_token *ctoken;
|
||||
--- libcpp/macro.c.jj 2019-01-09 13:01:21.420552123 +0100
|
||||
+++ libcpp/macro.c 2019-01-11 18:18:17.736876285 +0100
|
||||
@@ -3256,8 +3256,6 @@ static cpp_macro *
|
||||
create_iso_definition (cpp_reader *pfile)
|
||||
{
|
||||
bool following_paste_op = false;
|
||||
- const char *paste_op_error_msg =
|
||||
- N_("'##' cannot appear at either end of a macro expansion");
|
||||
unsigned int num_extra_tokens = 0;
|
||||
|
||||
/* Get the first token of the expansion (or the '(' of a
|
||||
@@ -3059,7 +3057,8 @@ create_iso_definition (cpp_reader *pfile
|
||||
unsigned nparms = 0;
|
||||
cpp_hashnode **params = NULL;
|
||||
@@ -3382,7 +3380,9 @@ create_iso_definition (cpp_reader *pfile
|
||||
function-like macros, but not at the end. */
|
||||
if (following_paste_op)
|
||||
{
|
||||
- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
|
||||
+ cpp_error (pfile, CPP_DL_ERROR,
|
||||
+ "'##' cannot appear at either end of a macro expansion");
|
||||
return false;
|
||||
+ "'##' cannot appear at either end of a macro "
|
||||
+ "expansion");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@@ -3072,7 +3071,8 @@ create_iso_definition (cpp_reader *pfile
|
||||
if (!vaopt_tracker.completed ())
|
||||
@@ -3397,7 +3397,9 @@ create_iso_definition (cpp_reader *pfile
|
||||
function-like macros, but not at the beginning. */
|
||||
if (macro->count == 1)
|
||||
{
|
||||
- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
|
||||
+ cpp_error (pfile, CPP_DL_ERROR,
|
||||
+ "'##' cannot appear at either end of a macro expansion");
|
||||
return false;
|
||||
+ "'##' cannot appear at either end of a macro "
|
||||
+ "expansion");
|
||||
goto out;
|
||||
}
|
||||
|
||||
--- libcpp/expr.c.jj 2015-01-14 11:01:34.000000000 +0100
|
||||
+++ libcpp/expr.c 2015-01-14 14:35:52.851002344 +0100
|
||||
@@ -672,16 +672,17 @@ cpp_classify_number (cpp_reader *pfile,
|
||||
--- libcpp/expr.c.jj 2019-01-09 13:01:22.415535734 +0100
|
||||
+++ libcpp/expr.c 2019-01-11 18:16:23.444726882 +0100
|
||||
@@ -803,16 +803,17 @@ cpp_classify_number (cpp_reader *pfile,
|
||||
if ((result & CPP_N_WIDTH) == CPP_N_LARGE
|
||||
&& CPP_OPTION (pfile, cpp_warn_long_long))
|
||||
{
|
||||
@ -121,4 +123,4 @@
|
||||
+ : N_("use of C99 long long integer constant"));
|
||||
}
|
||||
|
||||
result |= CPP_N_INTEGER;
|
||||
if ((result & CPP_N_SIZE_T) == CPP_N_SIZE_T
|
||||
@ -1,15 +1,15 @@
|
||||
--- gcc/Makefile.in.jj 2015-06-06 10:00:25.000000000 +0200
|
||||
+++ gcc/Makefile.in 2015-11-04 14:56:02.643536437 +0100
|
||||
@@ -1046,7 +1046,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
|
||||
@@ -1063,7 +1063,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
|
||||
# and the system's installed libraries.
|
||||
LIBS = @LIBS@ libcommon.a $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBBACKTRACE) \
|
||||
$(LIBIBERTY) $(LIBDECNUMBER) $(HOST_LIBS)
|
||||
-BACKENDLIBS = $(ISLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
|
||||
+BACKENDLIBS = $(if $(ISLLIBS),-ldl) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
|
||||
$(ZLIB)
|
||||
$(ZLIB) $(ZSTD_LIB)
|
||||
# Any system libraries needed just for GNAT.
|
||||
SYSLIBS = @GNAT_LIBEXC@
|
||||
@@ -2196,6 +2196,15 @@ $(out_object_file): $(out_file)
|
||||
@@ -2302,6 +2302,15 @@ $(out_object_file): $(out_file)
|
||||
$(common_out_object_file): $(common_out_file)
|
||||
$(COMPILE) $<
|
||||
$(POSTCOMPILE)
|
||||
@ -27,10 +27,10 @@
|
||||
# and compile them.
|
||||
--- gcc/graphite.h.jj 2016-01-27 12:44:06.000000000 +0100
|
||||
+++ gcc/graphite.h 2016-01-27 13:26:38.309876856 +0100
|
||||
@@ -39,6 +39,590 @@ along with GCC; see the file COPYING3.
|
||||
#include <isl/schedule_node.h>
|
||||
#include <isl/id.h>
|
||||
#include <isl/space.h>
|
||||
@@ -24,6 +24,591 @@ along with GCC; see the file COPYING3.
|
||||
|
||||
#include "sese.h"
|
||||
|
||||
+#include <isl/version.h>
|
||||
+#include <dlfcn.h>
|
||||
+
|
||||
@ -615,10 +615,11 @@
|
||||
+#define isl_version (*isl_pointers__.p_isl_version)
|
||||
+#define isl_options_get_on_error (*isl_pointers__.p_isl_options_get_on_error)
|
||||
+#define isl_ctx_reset_error (*isl_pointers__.p_isl_ctx_reset_error)
|
||||
|
||||
+
|
||||
typedef struct poly_dr *poly_dr_p;
|
||||
|
||||
@@ -461,5 +1045,6 @@ extern void build_scops (vec<scop_p> *);
|
||||
typedef struct poly_bb *poly_bb_p;
|
||||
@@ -448,5 +1033,6 @@ extern tree cached_scalar_evolution_in_r
|
||||
extern void dot_all_sese (FILE *, vec<sese_l> &);
|
||||
extern void dot_sese (sese_l &);
|
||||
extern void dot_cfg ();
|
||||
71
SOURCES/gcc11-isl-dl2.patch
Normal file
71
SOURCES/gcc11-isl-dl2.patch
Normal file
@ -0,0 +1,71 @@
|
||||
2011-04-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* toplev.c (toplev_main_argv): New variable.
|
||||
(toplev_main): Initialize it.
|
||||
* graphite.c (init_isl_pointers): Load libisl.so.15 from gcc's private
|
||||
directory.
|
||||
|
||||
--- gcc/toplev.c.jj 2008-12-09 23:59:10.000000000 +0100
|
||||
+++ gcc/toplev.c 2009-01-27 14:33:52.000000000 +0100
|
||||
@@ -117,6 +117,8 @@ static void compile_file (void);
|
||||
/* True if we don't need a backend (e.g. preprocessing only). */
|
||||
static bool no_backend;
|
||||
|
||||
+const char **toplev_main_argv;
|
||||
+
|
||||
/* Decoded options, and number of such options. */
|
||||
struct cl_decoded_option *save_decoded_options;
|
||||
unsigned int save_decoded_options_count;
|
||||
@@ -2287,6 +2289,8 @@ toplev::main (int argc, char **argv)
|
||||
|
||||
expandargv (&argc, &argv);
|
||||
|
||||
+ toplev_main_argv = CONST_CAST2 (const char **, char **, argv);
|
||||
+
|
||||
/* Initialization of GCC's environment, and diagnostics. */
|
||||
general_init (argv[0], m_init_signals);
|
||||
|
||||
--- gcc/graphite.c.jj 2010-12-01 10:24:32.000000000 -0500
|
||||
+++ gcc/graphite.c 2010-12-01 11:46:07.832118193 -0500
|
||||
@@ -64,11 +64,39 @@ __typeof (isl_pointers__) isl_pointers__
|
||||
static bool
|
||||
init_isl_pointers (void)
|
||||
{
|
||||
- void *h;
|
||||
+ void *h = NULL;
|
||||
+ extern const char **toplev_main_argv;
|
||||
+ char *buf, *p;
|
||||
+ size_t len;
|
||||
|
||||
if (isl_pointers__.inited)
|
||||
return isl_pointers__.h != NULL;
|
||||
- h = dlopen ("libisl.so.15", RTLD_LAZY);
|
||||
+ len = progname - toplev_main_argv[0];
|
||||
+ buf = XALLOCAVAR (char, len + sizeof "libisl.so.15");
|
||||
+ memcpy (buf, toplev_main_argv[0], len);
|
||||
+ strcpy (buf + len, "libisl.so.15");
|
||||
+ len += sizeof "libisl.so.15";
|
||||
+ p = strstr (buf, "/libexec/");
|
||||
+ if (p != NULL)
|
||||
+ {
|
||||
+ while (1)
|
||||
+ {
|
||||
+ char *q = strstr (p + 8, "/libexec/");
|
||||
+ if (q == NULL)
|
||||
+ break;
|
||||
+ p = q;
|
||||
+ }
|
||||
+ memmove (p + 4, p + 8, len - (p + 8 - buf));
|
||||
+ h = dlopen (buf, RTLD_LAZY);
|
||||
+ if (h == NULL)
|
||||
+ {
|
||||
+ len = progname - toplev_main_argv[0];
|
||||
+ memcpy (buf, toplev_main_argv[0], len);
|
||||
+ strcpy (buf + len, "libisl.so.15");
|
||||
+ }
|
||||
+ }
|
||||
+ if (h == NULL)
|
||||
+ h = dlopen (buf, RTLD_LAZY);
|
||||
isl_pointers__.h = h;
|
||||
if (h == NULL)
|
||||
return false;
|
||||
45
SOURCES/gcc11-libgcc-link.patch
Normal file
45
SOURCES/gcc11-libgcc-link.patch
Normal file
@ -0,0 +1,45 @@
|
||||
libgcc: Honor LDFLAGS_FOR_TARGET when linking libgcc_s
|
||||
|
||||
When building gcc with some specific LDFLAGS_FOR_TARGET, e.g.
|
||||
LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now
|
||||
those flags propagate info linking of target shared libraries,
|
||||
e.g. lib{ubsan,tsan,stdc++,quadmath,objc,lsan,itm,gphobos,gdruntime,gomp,go,gfortran,atomic,asan}.so.*
|
||||
but there is one important exception, libgcc_s.so.* linking ignores it.
|
||||
|
||||
The following patch fixes that.
|
||||
|
||||
Bootstrapped/regtested on x86_64-linux with LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now
|
||||
and verified that libgcc_s.so.* is BIND_NOW when it previously wasn't, and
|
||||
without any LDFLAGS_FOR_TARGET on x86_64-linux and i686-linux.
|
||||
There on x86_64-linux I've verified that the libgcc_s.so.1 linking command
|
||||
line for -m64 is identical except for whitespace to one without the patch,
|
||||
and for -m32 multilib $(LDFLAGS) actually do supply there an extra -m32
|
||||
that also repeats later in the @multilib_flags@, which should be harmless.
|
||||
|
||||
2021-08-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/t-slibgcc (SHLIB_LINK): Add $(LDFLAGS).
|
||||
* config/t-slibgcc-vms (SHLIB_LINK): Likewise.
|
||||
|
||||
--- libgcc/config/t-slibgcc
|
||||
+++ libgcc/config/t-slibgcc
|
||||
@@ -32,7 +32,7 @@ SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
|
||||
|
||||
SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
- $(SHLIB_LDFLAGS) \
|
||||
+ $(SHLIB_LDFLAGS) $(LDFLAGS) \
|
||||
-o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
|
||||
$(SHLIB_OBJS) $(SHLIB_LC) && \
|
||||
rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \
|
||||
--- libgcc/config/t-slibgcc-vms
|
||||
+++ libgcc/config/t-slibgcc-vms
|
||||
@@ -22,7 +22,7 @@ SHLIB_LINK = \
|
||||
objdump --syms $(SHLIB_OBJS) | \
|
||||
$(SHLIB_SYMVEC) >> SYMVEC_$$$$.opt ; \
|
||||
echo "case_sensitive=NO" >> SYMVEC_$$$$.opt; \
|
||||
- $(CC) $(LIBGCC2_CFLAGS) -nodefaultlibs \
|
||||
+ $(CC) $(LIBGCC2_CFLAGS) $(LDFLAGS) -nodefaultlibs \
|
||||
-shared --for-linker=/noinform -o $(SHLIB_NAME) $(SHLIB_OBJS) \
|
||||
--for-linker=SYMVEC_$$$$.opt \
|
||||
--for-linker=gsmatch=equal,$(shlib_version)
|
||||
51
SOURCES/gcc11-libgfortran-flush.patch
Normal file
51
SOURCES/gcc11-libgfortran-flush.patch
Normal file
@ -0,0 +1,51 @@
|
||||
commit c14f38d4292ec22462a4080841d526f87428130a
|
||||
Author: Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
Date: Thu Dec 16 15:33:17 2021 +0100
|
||||
|
||||
Fix FLUSH IOSTAT value
|
||||
|
||||
PR libfortran/101255
|
||||
|
||||
libgfortran/ChangeLog:
|
||||
|
||||
* io/file_pos.c: Fix error code.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gfortran.dg/iostat_5.f90: New file.
|
||||
|
||||
diff --git a/gcc/testsuite/gfortran.dg/iostat_5.f90 b/gcc/testsuite/gfortran.dg/iostat_5.f90
|
||||
new file mode 100644
|
||||
index 00000000000..1e72dfdf7e1
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/iostat_5.f90
|
||||
@@ -0,0 +1,16 @@
|
||||
+! PR libfortran/101255
|
||||
+! { dg-do run }
|
||||
+
|
||||
+program test
|
||||
+ use ISO_FORTRAN_ENV, only: IOSTAT_EOR, IOSTAT_END
|
||||
+ implicit none
|
||||
+ character(len=50) :: err
|
||||
+ integer :: i
|
||||
+
|
||||
+ err = ""
|
||||
+ flush(99, iostat=i, iomsg=err)
|
||||
+
|
||||
+ if (err == "") stop 1
|
||||
+ if (i >= 0) stop 2
|
||||
+ if (i == IOSTAT_EOR .or. i == IOSTAT_END) stop 3
|
||||
+end
|
||||
diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c
|
||||
index 7e71ca577e0..4ed1698f17a 100644
|
||||
--- a/libgfortran/io/file_pos.c
|
||||
+++ b/libgfortran/io/file_pos.c
|
||||
@@ -527,7 +527,7 @@ st_flush (st_parameter_filepos *fpp)
|
||||
}
|
||||
else
|
||||
/* FLUSH on unconnected unit is illegal: F95 std., 9.3.5. */
|
||||
- generate_error (&fpp->common, LIBERROR_BAD_OPTION,
|
||||
+ generate_error (&fpp->common, -LIBERROR_BAD_UNIT,
|
||||
"Specified UNIT in FLUSH is not connected");
|
||||
|
||||
if (needs_unlock)
|
||||
@ -4,7 +4,7 @@
|
||||
<a class="link" href="https://www.fsf.org" target="_top">FSF
|
||||
</a>
|
||||
</p><p>
|
||||
+ Release 8.5.0
|
||||
+ Release 11.5.0
|
||||
+ </p><p>
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation
|
||||
@ -17,7 +17,7 @@
|
||||
</p><p>
|
||||
- The API documentation, rendered into HTML, can be viewed online
|
||||
+ The API documentation, rendered into HTML, can be viewed locally
|
||||
+ <a class="link" href="api/index.html" target="_top">for the 8.5.0 release</a>,
|
||||
+ <a class="link" href="api/index.html" target="_top">for the 11.5.0 release</a>,
|
||||
+ online
|
||||
<a class="link" href="http://gcc.gnu.org/onlinedocs/" target="_top">for each GCC release</a>
|
||||
and
|
||||
@ -1,19 +1,16 @@
|
||||
The change is based on:
|
||||
|
||||
commit 190c644c06369766aa2537851ddbf83b1231b65b
|
||||
Author: Philipp Fent <fent@in.tum.de>
|
||||
Date: Sun Sep 4 20:47:34 2022 +0200
|
||||
|
||||
libstdc++: Fix pretty printer tests of tuple indexes
|
||||
|
||||
but it is adapted to GCC8 since it does not have the tuple inheritance change,
|
||||
which is:
|
||||
|
||||
commit 91e6226f880b048275a7ceedef716e159c7cefd9
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Fri Aug 7 17:13:56 2020 +0100
|
||||
|
||||
libstdc++: Remove inheritance from elements in std::tuple
|
||||
|
||||
Signed-off-by: Philipp Fent <fent@in.tum.de>
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
* testsuite/libstdc++-prettyprinters/48362.cc: Fix expected
|
||||
tuple indices.
|
||||
* testsuite/libstdc++-prettyprinters/cxx11.cc: Likewise.
|
||||
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/48362.cc
|
||||
index cc91803e247..af335d0d3c7 100644
|
||||
@ -23,8 +20,8 @@ index cc91803e247..af335d0d3c7 100644
|
||||
// { dg-final { note-test t1 {empty std::tuple} } }
|
||||
|
||||
std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
|
||||
-// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = {<std::(__8::)?tuple<>> = empty std::tuple, <No data fields>}}} } }
|
||||
+// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = {<std::(__8::)?tuple<>> = empty std::tuple, <No data fields>}}} } }
|
||||
-// { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = empty std::tuple}} } }
|
||||
+// { dg-final { regexp-test t2 {std::tuple containing = {\[0\] = "Johnny", \[1\] = 5, \[2\] = empty std::tuple}} } }
|
||||
|
||||
std::cout << "\n";
|
||||
return 0; // Mark SPOT
|
||||
270
SOURCES/gcc11-libstdc++-prettyprinter-update-15-tests.patch
Normal file
270
SOURCES/gcc11-libstdc++-prettyprinter-update-15-tests.patch
Normal file
@ -0,0 +1,270 @@
|
||||
.../testsuite/libstdc++-prettyprinters/compat.cc | 10 +++----
|
||||
.../testsuite/libstdc++-prettyprinters/cxx11.cc | 33 +++++++++++++++++-----
|
||||
.../testsuite/libstdc++-prettyprinters/cxx17.cc | 27 ++++++++----------
|
||||
.../libstdc++-prettyprinters/filesystem-ts.cc | 2 +-
|
||||
.../libstdc++-prettyprinters/libfundts.cc | 25 ++++++++--------
|
||||
5 files changed, 58 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
index 35243e5f892..2ef5979834f 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
@@ -1,7 +1,7 @@
|
||||
// { dg-options "-g -O0" }
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
-// Copyright (C) 2014-2021 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -102,13 +102,13 @@ main()
|
||||
using std::optional;
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
|
||||
|
||||
__builtin_puts("");
|
||||
return 0; // Mark SPOT
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
index 0545076fb6f..23f6d97ddd4 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
@@ -1,7 +1,7 @@
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-options "-g -O0" }
|
||||
|
||||
-// Copyright (C) 2011-2021 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2011-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <iostream>
|
||||
#include <future>
|
||||
#include <initializer_list>
|
||||
+#include <atomic>
|
||||
#include "../util/testsuite_allocator.h" // NullablePointer
|
||||
|
||||
typedef std::tuple<int, int> ExTuple;
|
||||
@@ -62,6 +63,11 @@ struct datum
|
||||
|
||||
std::unique_ptr<datum> global;
|
||||
|
||||
+struct custom_cat : std::error_category {
|
||||
+ const char* name() const noexcept { return "miaow"; }
|
||||
+ std::string message(int) const { return ""; }
|
||||
+};
|
||||
+
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -165,9 +171,9 @@ main()
|
||||
// { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
|
||||
|
||||
ExTuple tpl(6,7);
|
||||
-// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
|
||||
+// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
|
||||
ExTuple &rtpl = tpl;
|
||||
-// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
|
||||
+// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
|
||||
|
||||
std::error_code e0;
|
||||
// { dg-final { note-test e0 {std::error_code = { }} } }
|
||||
@@ -178,10 +184,7 @@ main()
|
||||
std::error_condition ecinval = std::make_error_condition(std::errc::invalid_argument);
|
||||
// { dg-final { note-test ecinval {std::error_condition = {"generic": EINVAL}} } }
|
||||
|
||||
- struct custom_cat : std::error_category {
|
||||
- const char* name() const noexcept { return "miaow"; }
|
||||
- std::string message(int) const { return ""; }
|
||||
- } cat;
|
||||
+ custom_cat cat;
|
||||
std::error_code emiaow(42, cat);
|
||||
// { dg-final { note-test emiaow {std::error_code = {custom_cat: 42}} } }
|
||||
std::error_condition ecmiaow(42, cat);
|
||||
@@ -197,6 +200,22 @@ main()
|
||||
std::initializer_list<int> il = {3, 4};
|
||||
// { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} } }
|
||||
|
||||
+ std::atomic<int> ai{100};
|
||||
+ // { dg-final { note-test ai {std::atomic<int> = { 100 }} } }
|
||||
+ long l{};
|
||||
+ std::atomic<long*> ap{&l};
|
||||
+ // { dg-final { regexp-test ap {std::atomic.long \*. = { 0x.* }} } }
|
||||
+ struct Value { int i, j; };
|
||||
+ std::atomic<Value> av{{8, 9}};
|
||||
+ // { dg-final { note-test av {std::atomic<Value> = { {i = 8, j = 9} }} } }
|
||||
+
|
||||
+ std::integral_constant<int, 1> one;
|
||||
+ // { dg-final { note-test one {std::integral_constant<int, 1>} } }
|
||||
+ std::integral_constant<bool, true> truth;
|
||||
+ // { dg-final { note-test truth {std::true_type} } }
|
||||
+ std::integral_constant<bool, 0> lies;
|
||||
+ // { dg-final { note-test lies {std::false_type} } }
|
||||
+
|
||||
placeholder(""); // Mark SPOT
|
||||
use(efl);
|
||||
use(fl);
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
index 72c66d3b785..6dd2b60c0a5 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
@@ -1,7 +1,7 @@
|
||||
// { dg-options "-g -O0" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
-// Copyright (C) 2014-2021 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -18,9 +18,6 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
-// Type printers only recognize the old std::string for now.
|
||||
-#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
-
|
||||
#include <filesystem>
|
||||
#include <any>
|
||||
#include <optional>
|
||||
@@ -53,18 +50,18 @@ main()
|
||||
// { dg-final { note-test str "\"string\"" } }
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
|
||||
optional<std::map<int, double>> om;
|
||||
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
|
||||
-// { dg-final { regexp-test om {std::optional<std::(__debug::)?map<int, double>> containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
+// { dg-final { regexp-test om {std::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
optional<std::string> os{ "stringy" };
|
||||
-// { dg-final { note-test os {std::optional<std::string> = {[contained value] = "stringy"}} } }
|
||||
+// { dg-final { note-test os {std::optional = {[contained value] = "stringy"}} } }
|
||||
|
||||
any a;
|
||||
// { dg-final { note-test a {std::any [no contained value]} } }
|
||||
@@ -86,18 +83,18 @@ main()
|
||||
|
||||
struct S { operator int() { throw 42; }};
|
||||
variant<float, int, string_view> v0;
|
||||
-// { dg-final { note-test v0 {std::variant<float, int, std::string_view> [index 0] = {0}} } }
|
||||
+// { dg-final { note-test v0 {std::variant [index 0] = {0}} } }
|
||||
variant<float, int, string_view> v1{ 0.5f };
|
||||
-// { dg-final { note-test v1 {std::variant<float, int, std::string_view> [index 0] = {0.5}} } }
|
||||
+// { dg-final { note-test v1 {std::variant [index 0] = {0.5}} } }
|
||||
variant<float, X, string_view> v2;
|
||||
try {
|
||||
v2.emplace<1>(S());
|
||||
} catch (int) { }
|
||||
-// { dg-final { note-test v2 {std::variant<float, X, std::string_view> [no contained value]} } }
|
||||
+// { dg-final { note-test v2 {std::variant [no contained value]} } }
|
||||
variant<float, int, string_view> v3{ 3 };
|
||||
-// { dg-final { note-test v3 {std::variant<float, int, std::string_view> [index 1] = {3}} } }
|
||||
+// { dg-final { note-test v3 {std::variant [index 1] = {3}} } }
|
||||
variant<float, int, string_view> v4{ str };
|
||||
-// { dg-final { note-test v4 {std::variant<float, int, std::string_view> [index 2] = {"string"}} } }
|
||||
+// { dg-final { note-test v4 {std::variant [index 2] = {"string"}} } }
|
||||
|
||||
map<int, string_view> m{ {1, "one"} };
|
||||
map<int, string_view>::node_type n0;
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
index 00d100bd066..3221f2df90d 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
@@ -2,7 +2,7 @@
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-filesystem-ts "" }
|
||||
|
||||
-// Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
index 85005c0617f..bfb86885457 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
@@ -1,7 +1,7 @@
|
||||
// { dg-do run { target c++14 } }
|
||||
// { dg-options "-g -O0" }
|
||||
|
||||
-// Copyright (C) 2014-2021 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -18,9 +18,6 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
-// Type printers only recognize the old std::string for now.
|
||||
-#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
-
|
||||
#include <experimental/any>
|
||||
#include <experimental/optional>
|
||||
#include <experimental/string_view>
|
||||
@@ -35,22 +32,28 @@ using std::experimental::string_view;
|
||||
int
|
||||
main()
|
||||
{
|
||||
+ // Ensure debug info for std::string is issued in the local
|
||||
+ // translation unit, so that GDB won't pick up any alternate
|
||||
+ // std::string notion that might be present in libstdc++.so.
|
||||
+ std::string bah = "hi";
|
||||
+ (void)bah;
|
||||
+
|
||||
string_view str = "string";
|
||||
// { dg-final { note-test str "\"string\"" } }
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::experimental::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::experimental::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::experimental::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::experimental::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::experimental::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::experimental::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::experimental::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::experimental::optional = {[contained value] = 0x0}} } }
|
||||
optional<std::map<int, double>> om;
|
||||
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
|
||||
-// { dg-final { regexp-test om {std::experimental::optional<std::(__debug::)?map<int, double>> containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
+// { dg-final { regexp-test om {std::experimental::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
optional<std::string> os{ "stringy" };
|
||||
-// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} { xfail { c++20 || debug_mode } } } }
|
||||
+// { dg-final { note-test os {std::experimental::optional = {[contained value] = "stringy"}} } }
|
||||
|
||||
any a;
|
||||
// { dg-final { note-test a {std::experimental::any [no contained value]} } }
|
||||
@@ -61,7 +64,7 @@ main()
|
||||
any ap = (void*)nullptr;
|
||||
// { dg-final { note-test ap {std::experimental::any containing void * = {[contained value] = 0x0}} } }
|
||||
any as = *os;
|
||||
-// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} { xfail { c++20 || debug_mode } } } }
|
||||
+// { dg-final { note-test as {std::experimental::any containing std::string = {[contained value] = "stringy"}} } }
|
||||
any as2("stringiest");
|
||||
// { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
|
||||
any am = *om;
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,6 @@
|
||||
2010-02-08 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* config/rs6000/sysv4.h (LINK_EH_SPEC): Pass --no-add-needed to the
|
||||
linker.
|
||||
* config/gnu-user.h (LINK_EH_SPEC): Likewise.
|
||||
* config/gnu-user.h (LINK_EH_SPEC): Pass --no-add-needed to the linker.
|
||||
* config/alpha/elf.h (LINK_EH_SPEC): Likewise.
|
||||
* config/ia64/linux.h (LINK_EH_SPEC): Likewise.
|
||||
|
||||
@ -28,7 +26,7 @@
|
||||
#define TARGET_INIT_LIBFUNCS ia64_soft_fp_init_libfuncs
|
||||
--- gcc/config/gnu-user.h.jj 2011-01-03 12:53:03.739057299 +0100
|
||||
+++ gcc/config/gnu-user.h 2011-01-04 18:14:10.932814884 +0100
|
||||
@@ -133,7 +133,7 @@ see the files COPYING3 and COPYING.RUNTI
|
||||
@@ -106,7 +106,7 @@ see the files COPYING3 and COPYING.RUNTI
|
||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
@ -36,15 +34,4 @@
|
||||
+#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||
--- gcc/config/rs6000/sysv4.h.jj 2011-01-03 13:02:18.255994215 +0100
|
||||
+++ gcc/config/rs6000/sysv4.h 2011-01-04 18:14:10.933888871 +0100
|
||||
@@ -816,7 +816,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEF
|
||||
-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
-# define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
|
||||
+# define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
|
||||
#define GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC \
|
||||
850
SOURCES/gcc11-pie.patch
Normal file
850
SOURCES/gcc11-pie.patch
Normal file
@ -0,0 +1,850 @@
|
||||
From 088d8e322811394203220663c3b9c925980d57a2 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Polacek <polacek@redhat.com>
|
||||
Date: Tue, 1 Feb 2022 18:27:16 -0500
|
||||
Subject: [PATCH] configure: Implement --enable-host-pie
|
||||
|
||||
This patch implements the --enable-host-pie configure option which
|
||||
makes the compiler executables PIE. This can be used to enhance
|
||||
protection against ROP attacks, and can be viewed as part of a wider
|
||||
trend to harden binaries.
|
||||
|
||||
It is similar to the option --enable-host-shared, except that --e-h-s
|
||||
won't add -shared to the linker flags whereas --e-h-p will add -pie.
|
||||
It is different from --enable-default-pie because that option just
|
||||
adds an implicit -fPIE/-pie when the compiler is invoked, but the
|
||||
compiler itself isn't PIE.
|
||||
|
||||
Since r12-5768-gfe7c3ecf, PCH works well with PIE, so there are no PCH
|
||||
regressions.
|
||||
|
||||
I plan to add an option to link with -Wl,-z,now.
|
||||
|
||||
c++tools/ChangeLog:
|
||||
|
||||
* Makefile.in: Rename PIEFLAG to PICFLAG. Set LD_PICFLAG. Use it.
|
||||
Use pic/libiberty.a if PICFLAG is set.
|
||||
* configure.ac (--enable-default-pie): Set PICFLAG instead of PIEFLAG.
|
||||
(--enable-host-pie): New check.
|
||||
* configure: Regenerate.
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* Makefile.in: Set LD_PICFLAG. Use it. Set enable_host_pie.
|
||||
Remove NO_PIE_CFLAGS and NO_PIE_FLAG. Pass LD_PICFLAG to
|
||||
ALL_LINKERFLAGS. Use the "pic" build of libiberty if --enable-host-pie.
|
||||
* configure.ac (--enable-host-shared): Don't set PICFLAG here.
|
||||
(--enable-host-pie): New check. Set PICFLAG and LD_PICFLAG after this
|
||||
check.
|
||||
* configure: Regenerate.
|
||||
* doc/install.texi: Document --enable-host-pie.
|
||||
|
||||
libcody/ChangeLog:
|
||||
|
||||
* Makefile.in: Pass LD_PICFLAG to LDFLAGS.
|
||||
* configure.ac (--enable-host-shared): Don't set PICFLAG here.
|
||||
(--enable-host-pie): New check. Set PICFLAG and LD_PICFLAG after this
|
||||
check.
|
||||
* configure: Regenerate.
|
||||
|
||||
libcpp/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-shared): Don't set PICFLAG here.
|
||||
(--enable-host-pie): New check. Set PICFLAG after this check.
|
||||
* configure: Regenerate.
|
||||
|
||||
libdecnumber/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-shared): Don't set PICFLAG here.
|
||||
(--enable-host-pie): New check. Set PICFLAG after this check.
|
||||
* configure: Regenerate.
|
||||
|
||||
zlib/ChangeLog:
|
||||
|
||||
* configure.ac (--enable-host-shared): Don't set PICFLAG here.
|
||||
(--enable-host-pie): New check. Set PICFLAG after this check.
|
||||
* configure: Regenerate.
|
||||
---
|
||||
c++tools/Makefile.in | 11 ++++++---
|
||||
c++tools/configure | 17 +++++++++++---
|
||||
c++tools/configure.ac | 11 +++++++--
|
||||
gcc/Makefile.in | 29 ++++++++++++++----------
|
||||
gcc/configure | 47 +++++++++++++++++++++++++++------------
|
||||
gcc/configure.ac | 36 +++++++++++++++++++++---------
|
||||
gcc/d/Make-lang.in | 2 +-
|
||||
gcc/doc/install.texi | 16 +++++++++++--
|
||||
libcody/Makefile.in | 2 +-
|
||||
libcody/configure | 30 ++++++++++++++++++++++++-
|
||||
libcody/configure.ac | 26 ++++++++++++++++++++--
|
||||
libcpp/configure | 22 +++++++++++++++++-
|
||||
libcpp/configure.ac | 19 ++++++++++++++--
|
||||
libdecnumber/configure | 22 +++++++++++++++++-
|
||||
libdecnumber/configure.ac | 19 ++++++++++++++--
|
||||
zlib/configure | 30 ++++++++++++++++++++-----
|
||||
zlib/configure.ac | 21 ++++++++++++++---
|
||||
17 files changed, 295 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/c++tools/Makefile.in b/c++tools/Makefile.in
|
||||
index d6a33613732..4d5a5b0522b 100644
|
||||
--- a/c++tools/Makefile.in
|
||||
+++ b/c++tools/Makefile.in
|
||||
@@ -28,8 +28,9 @@ AUTOCONF := @AUTOCONF@
|
||||
AUTOHEADER := @AUTOHEADER@
|
||||
CXX := @CXX@
|
||||
CXXFLAGS := @CXXFLAGS@
|
||||
-PIEFLAG := @PIEFLAG@
|
||||
-CXXOPTS := $(CXXFLAGS) $(PIEFLAG) -fno-exceptions -fno-rtti
|
||||
+PICFLAG := @PICFLAG@
|
||||
+LD_PICFLAG := @LD_PICFLAG@
|
||||
+CXXOPTS := $(CXXFLAGS) $(PICFLAG) -fno-exceptions -fno-rtti
|
||||
LDFLAGS := @LDFLAGS@
|
||||
exeext := @EXEEXT@
|
||||
LIBIBERTY := ../libiberty/libiberty.a
|
||||
@@ -87,11 +88,15 @@ ifeq (@CXX_AUX_TOOLS@,yes)
|
||||
|
||||
all::g++-mapper-server$(exeext)
|
||||
|
||||
+ifneq ($(PICFLAG),)
|
||||
+override LIBIBERTY := ../libiberty/pic/libiberty.a
|
||||
+endif
|
||||
+
|
||||
MAPPER.O := server.o resolver.o
|
||||
CODYLIB = ../libcody/libcody.a
|
||||
CXXINC += -I$(srcdir)/../libcody -I$(srcdir)/../include -I$(srcdir)/../gcc -I.
|
||||
g++-mapper-server$(exeext): $(MAPPER.O) $(CODYLIB)
|
||||
- +$(CXX) $(LDFLAGS) $(PIEFLAG) -o $@ $^ $(VERSION.O) $(LIBIBERTY) $(NETLIBS)
|
||||
+ +$(CXX) $(LDFLAGS) $(PICFLAG) $(LD_PICFLAG) -o $@ $^ $(VERSION.O) $(LIBIBERTY) $(NETLIBS)
|
||||
|
||||
# copy to gcc dir so tests there can run
|
||||
all::../gcc/g++-mapper-server$(exeext)
|
||||
diff --git a/c++tools/configure b/c++tools/configure
|
||||
index 742816e4253..88087009383 100755
|
||||
--- a/c++tools/configure
|
||||
+++ b/c++tools/configure
|
||||
@@ -630,7 +630,8 @@ CPP
|
||||
EGREP
|
||||
GREP
|
||||
CXXCPP
|
||||
-PIEFLAG
|
||||
+LD_PICFLAG
|
||||
+PICFLAG
|
||||
MAINTAINER
|
||||
CXX_AUX_TOOLS
|
||||
AUTOHEADER
|
||||
@@ -700,6 +701,7 @@ enable_c___tools
|
||||
enable_maintainer_mode
|
||||
enable_checking
|
||||
enable_default_pie
|
||||
+enable_host_pie
|
||||
with_gcc_major_version_only
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@@ -1333,6 +1335,7 @@ Optional Features:
|
||||
only specific categories of checks. Categories are:
|
||||
yes,no,all,none,release.
|
||||
--enable-default-pie enable Position Independent Executable as default
|
||||
+ --enable-host-pie build host code as PIE
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@@ -2990,12 +2993,20 @@ fi
|
||||
# Check whether --enable-default-pie was given.
|
||||
# Check whether --enable-default-pie was given.
|
||||
if test "${enable_default_pie+set}" = set; then :
|
||||
- enableval=$enable_default_pie; PIEFLAG=-fPIE
|
||||
+ enableval=$enable_default_pie; PICFLAG=-fPIE
|
||||
else
|
||||
- PIEFLAG=
|
||||
+ PICFLAG=
|
||||
fi
|
||||
|
||||
|
||||
+# Enable --enable-host-pie
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie; PICFLAG=-fPIE; LD_PICFLAG=-pie
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
|
||||
# Check if O_CLOEXEC is defined by fcntl
|
||||
|
||||
diff --git a/c++tools/configure.ac b/c++tools/configure.ac
|
||||
index 6662b5ad7c9..1e42689f2eb 100644
|
||||
--- a/c++tools/configure.ac
|
||||
+++ b/c++tools/configure.ac
|
||||
@@ -102,8 +102,15 @@ fi
|
||||
AC_ARG_ENABLE(default-pie,
|
||||
[AS_HELP_STRING([--enable-default-pie],
|
||||
[enable Position Independent Executable as default])],
|
||||
-[PIEFLAG=-fPIE], [PIEFLAG=])
|
||||
-AC_SUBST([PIEFLAG])
|
||||
+[PICFLAG=-fPIE], [PICFLAG=])
|
||||
+
|
||||
+# Enable --enable-host-pie
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])],
|
||||
+[PICFLAG=-fPIE; LD_PICFLAG=-pie], [])
|
||||
+AC_SUBST(PICFLAG)
|
||||
+AC_SUBST(LD_PICFLAG)
|
||||
|
||||
# Check if O_CLOEXEC is defined by fcntl
|
||||
AC_CACHE_CHECK(for O_CLOEXEC, ac_cv_o_cloexec, [
|
||||
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
|
||||
index 31ff95500c9..151dbfa54ec 100644
|
||||
--- a/gcc/Makefile.in
|
||||
+++ b/gcc/Makefile.in
|
||||
@@ -155,6 +155,9 @@ LDFLAGS = @LDFLAGS@
|
||||
# Should we build position-independent host code?
|
||||
PICFLAG = @PICFLAG@
|
||||
|
||||
+# The linker flag for the above.
|
||||
+LD_PICFLAG = @LD_PICFLAG@
|
||||
+
|
||||
# Flags to determine code coverage. When coverage is disabled, this will
|
||||
# contain the optimization flags, as you normally want code coverage
|
||||
# without optimization.
|
||||
@@ -263,18 +266,17 @@ LINKER = $(CC)
|
||||
LINKER_FLAGS = $(CFLAGS)
|
||||
endif
|
||||
|
||||
+enable_host_pie = @enable_host_pie@
|
||||
+
|
||||
# Enable Intel CET on Intel CET enabled host if needed.
|
||||
CET_HOST_FLAGS = @CET_HOST_FLAGS@
|
||||
COMPILER += $(CET_HOST_FLAGS)
|
||||
|
||||
-NO_PIE_CFLAGS = @NO_PIE_CFLAGS@
|
||||
-NO_PIE_FLAG = @NO_PIE_FLAG@
|
||||
-
|
||||
-# We don't want to compile the compilers with -fPIE, it make PCH fail.
|
||||
-COMPILER += $(NO_PIE_CFLAGS)
|
||||
+# Maybe compile the compilers with -fPIE or -fPIC.
|
||||
+COMPILER += $(PICFLAG)
|
||||
|
||||
-# Link with -no-pie since we compile the compiler with -fno-PIE.
|
||||
-LINKER += $(NO_PIE_FLAG)
|
||||
+# Link with -pie, or -no-pie, depending on the above.
|
||||
+LINKER += $(LD_PICFLAG)
|
||||
|
||||
# Like LINKER, but use a mutex for serializing front end links.
|
||||
ifeq (@DO_LINK_MUTEX@,true)
|
||||
@@ -1057,18 +1059,21 @@ ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS)
|
||||
ALL_COMPILERFLAGS = $(ALL_CXXFLAGS)
|
||||
|
||||
# This is the variable to use when using $(LINKER).
|
||||
-ALL_LINKERFLAGS = $(ALL_CXXFLAGS)
|
||||
+ALL_LINKERFLAGS = $(ALL_CXXFLAGS) $(LD_PICFLAG)
|
||||
|
||||
# Build and host support libraries.
|
||||
|
||||
-# Use the "pic" build of libiberty if --enable-host-shared, unless we are
|
||||
-# building for mingw.
|
||||
+# Use the "pic" build of libiberty if --enable-host-shared or --enable-host-pie,
|
||||
+# unless we are building for mingw.
|
||||
LIBIBERTY_PICDIR=$(if $(findstring mingw,$(target)),,pic)
|
||||
-ifeq ($(enable_host_shared),yes)
|
||||
+ifneq ($(enable_host_shared)$(enable_host_pie),)
|
||||
LIBIBERTY = ../libiberty/$(LIBIBERTY_PICDIR)/libiberty.a
|
||||
-BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/$(LIBIBERTY_PICDIR)/libiberty.a
|
||||
else
|
||||
LIBIBERTY = ../libiberty/libiberty.a
|
||||
+endif
|
||||
+ifeq ($(enable_host_shared),yes)
|
||||
+BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/$(LIBIBERTY_PICDIR)/libiberty.a
|
||||
+else
|
||||
BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/libiberty.a
|
||||
endif
|
||||
|
||||
diff --git a/gcc/configure b/gcc/configure
|
||||
index 258b17a226e..bd4fe1fd6ca 100755
|
||||
--- a/gcc/configure
|
||||
+++ b/gcc/configure
|
||||
@@ -632,10 +632,10 @@ ac_includes_default="\
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
CET_HOST_FLAGS
|
||||
-NO_PIE_FLAG
|
||||
-NO_PIE_CFLAGS
|
||||
-enable_default_pie
|
||||
+LD_PICFLAG
|
||||
PICFLAG
|
||||
+enable_default_pie
|
||||
+enable_host_pie
|
||||
enable_host_shared
|
||||
enable_plugin
|
||||
pluginlibs
|
||||
@@ -1025,6 +1025,7 @@ enable_link_serialization
|
||||
enable_version_specific_runtime_libs
|
||||
enable_plugin
|
||||
enable_host_shared
|
||||
+enable_host_pie
|
||||
enable_libquadmath_support
|
||||
with_linker_hash_style
|
||||
with_diagnostics_color
|
||||
@@ -1787,6 +1788,7 @@ Optional Features:
|
||||
in a compiler-specific directory
|
||||
--enable-plugin enable plugin support
|
||||
--enable-host-shared build host code as shared libraries
|
||||
+ --enable-host-pie build host code as PIE
|
||||
--disable-libquadmath-support
|
||||
disable libquadmath support for Fortran
|
||||
--enable-default-pie enable Position Independent Executable as default
|
||||
@@ -32221,13 +32223,17 @@ fi
|
||||
# Enable --enable-host-shared
|
||||
# Check whether --enable-host-shared was given.
|
||||
if test "${enable_host_shared+set}" = set; then :
|
||||
- enableval=$enable_host_shared; PICFLAG=-fPIC
|
||||
-else
|
||||
- PICFLAG=
|
||||
+ enableval=$enable_host_shared;
|
||||
fi
|
||||
|
||||
|
||||
|
||||
+# Enable --enable-host-pie
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie;
|
||||
+fi
|
||||
+
|
||||
|
||||
|
||||
# Check whether --enable-libquadmath-support was given.
|
||||
@@ -32381,10 +32387,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_c_no_fpie" >&5
|
||||
$as_echo "$gcc_cv_c_no_fpie" >&6; }
|
||||
-if test "$gcc_cv_c_no_fpie" = "yes"; then
|
||||
- NO_PIE_CFLAGS="-fno-PIE"
|
||||
-fi
|
||||
-
|
||||
|
||||
# Check if -no-pie works.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -no-pie option" >&5
|
||||
@@ -32409,11 +32411,28 @@ rm -f core conftest.err conftest.$ac_objext \
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_no_pie" >&5
|
||||
$as_echo "$gcc_cv_no_pie" >&6; }
|
||||
-if test "$gcc_cv_no_pie" = "yes"; then
|
||||
- NO_PIE_FLAG="-no-pie"
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+elif test x$gcc_cv_c_no_fpie = xyes; then
|
||||
+ PICFLAG=-fno-PIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
+fi
|
||||
+
|
||||
+if test x$enable_host_pie = xyes; then
|
||||
+ LD_PICFLAG=-pie
|
||||
+elif test x$gcc_cv_no_pie = xyes; then
|
||||
+ LD_PICFLAG=-no-pie
|
||||
+else
|
||||
+ LD_PICFLAG=
|
||||
fi
|
||||
|
||||
|
||||
+
|
||||
+
|
||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||
# Check whether --enable-cet was given.
|
||||
if test "${enable_cet+set}" = set; then :
|
||||
diff --git a/gcc/configure.ac b/gcc/configure.ac
|
||||
index 06750cee977..dca995aeec7 100644
|
||||
--- a/gcc/configure.ac
|
||||
+++ b/gcc/configure.ac
|
||||
@@ -7488,11 +7488,14 @@ fi
|
||||
# Enable --enable-host-shared
|
||||
AC_ARG_ENABLE(host-shared,
|
||||
[AS_HELP_STRING([--enable-host-shared],
|
||||
- [build host code as shared libraries])],
|
||||
-[PICFLAG=-fPIC], [PICFLAG=])
|
||||
+ [build host code as shared libraries])])
|
||||
AC_SUBST(enable_host_shared)
|
||||
-AC_SUBST(PICFLAG)
|
||||
|
||||
+# Enable --enable-host-pie
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])])
|
||||
+AC_SUBST(enable_host_pie)
|
||||
|
||||
AC_ARG_ENABLE(libquadmath-support,
|
||||
[AS_HELP_STRING([--disable-libquadmath-support],
|
||||
@@ -7614,10 +7617,6 @@ AC_CACHE_CHECK([for -fno-PIE option],
|
||||
[gcc_cv_c_no_fpie=yes],
|
||||
[gcc_cv_c_no_fpie=no])
|
||||
CXXFLAGS="$saved_CXXFLAGS"])
|
||||
-if test "$gcc_cv_c_no_fpie" = "yes"; then
|
||||
- NO_PIE_CFLAGS="-fno-PIE"
|
||||
-fi
|
||||
-AC_SUBST([NO_PIE_CFLAGS])
|
||||
|
||||
# Check if -no-pie works.
|
||||
AC_CACHE_CHECK([for -no-pie option],
|
||||
@@ -7628,10 +7627,27 @@ AC_CACHE_CHECK([for -no-pie option],
|
||||
[gcc_cv_no_pie=yes],
|
||||
[gcc_cv_no_pie=no])
|
||||
LDFLAGS="$saved_LDFLAGS"])
|
||||
-if test "$gcc_cv_no_pie" = "yes"; then
|
||||
- NO_PIE_FLAG="-no-pie"
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+elif test x$gcc_cv_c_no_fpie = xyes; then
|
||||
+ PICFLAG=-fno-PIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
fi
|
||||
-AC_SUBST([NO_PIE_FLAG])
|
||||
+
|
||||
+if test x$enable_host_pie = xyes; then
|
||||
+ LD_PICFLAG=-pie
|
||||
+elif test x$gcc_cv_no_pie = xyes; then
|
||||
+ LD_PICFLAG=-no-pie
|
||||
+else
|
||||
+ LD_PICFLAG=
|
||||
+fi
|
||||
+
|
||||
+AC_SUBST([PICFLAG])
|
||||
+AC_SUBST([LD_PICFLAG])
|
||||
|
||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||
GCC_CET_HOST_FLAGS(CET_HOST_FLAGS)
|
||||
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
|
||||
index 93eae1f2582..be6985646b2 100644
|
||||
--- a/gcc/doc/install.texi
|
||||
+++ b/gcc/doc/install.texi
|
||||
@@ -1021,14 +1021,26 @@ code.
|
||||
|
||||
@item --enable-host-shared
|
||||
Specify that the @emph{host} code should be built into position-independent
|
||||
-machine code (with -fPIC), allowing it to be used within shared libraries,
|
||||
-but yielding a slightly slower compiler.
|
||||
+machine code (with @option{-fPIC}), allowing it to be used within shared
|
||||
+libraries, but yielding a slightly slower compiler.
|
||||
|
||||
This option is required when building the libgccjit.so library.
|
||||
|
||||
Contrast with @option{--enable-shared}, which affects @emph{target}
|
||||
libraries.
|
||||
|
||||
+@item --enable-host-pie
|
||||
+Specify that the @emph{host} executables should be built into
|
||||
+position-independent executables (with @option{-fPIE} and @option{-pie}),
|
||||
+yielding a slightly slower compiler (but faster than
|
||||
+@option{--enable-host-shared}). Position-independent executables are loaded
|
||||
+at random addresses each time they are executed, therefore provide additional
|
||||
+protection against Return Oriented Programming (ROP) attacks.
|
||||
+
|
||||
+@option{--enable-host-pie}) may be used with @option{--enable-host-shared}),
|
||||
+in which case @option{-fPIC} is used when compiling, and @option{-pie} when
|
||||
+linking.
|
||||
+
|
||||
@item @anchor{with-gnu-as}--with-gnu-as
|
||||
Specify that the compiler should assume that the
|
||||
assembler it finds is the GNU assembler. However, this does not modify
|
||||
diff --git a/libcody/Makefile.in b/libcody/Makefile.in
|
||||
index 7eaf8ace8ce..0ff1625a39f 100644
|
||||
--- a/libcody/Makefile.in
|
||||
+++ b/libcody/Makefile.in
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
CXXOPTS += $(filter-out -DHAVE_CONFIG_H,@DEFS@) -include config.h
|
||||
|
||||
# Linker options
|
||||
-LDFLAGS := @LDFLAGS@
|
||||
+LDFLAGS := @LDFLAGS@ @LD_PICFLAG@
|
||||
LIBS := @LIBS@
|
||||
|
||||
# Per-source & per-directory compile flags (warning: recursive)
|
||||
diff --git a/libcody/configure b/libcody/configure
|
||||
index da52a5cfca5..0e536c0ccb0 100755
|
||||
--- a/libcody/configure
|
||||
+++ b/libcody/configure
|
||||
@@ -591,7 +591,10 @@ configure_args
|
||||
AR
|
||||
RANLIB
|
||||
EXCEPTIONS
|
||||
+LD_PICFLAG
|
||||
PICFLAG
|
||||
+enable_host_pie
|
||||
+enable_host_shared
|
||||
OBJEXT
|
||||
EXEEXT
|
||||
ac_ct_CXX
|
||||
@@ -653,6 +656,7 @@ enable_maintainer_mode
|
||||
with_compiler
|
||||
enable_checking
|
||||
enable_host_shared
|
||||
+enable_host_pie
|
||||
enable_exceptions
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@@ -1286,6 +1290,7 @@ Optional Features:
|
||||
yes,no,all,none,release. Flags are: misc,valgrind or
|
||||
other strings
|
||||
--enable-host-shared build host code as shared libraries
|
||||
+ --enable-host-pie build host code as PIE
|
||||
--enable-exceptions enable exceptions & rtti
|
||||
|
||||
Optional Packages:
|
||||
@@ -2635,11 +2640,34 @@ fi
|
||||
# Enable --enable-host-shared.
|
||||
# Check whether --enable-host-shared was given.
|
||||
if test "${enable_host_shared+set}" = set; then :
|
||||
- enableval=$enable_host_shared; PICFLAG=-fPIC
|
||||
+ enableval=$enable_host_shared;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
+if test x$enable_host_pie = xyes; then
|
||||
+ LD_PICFLAG=-pie
|
||||
+else
|
||||
+ LD_PICFLAG=
|
||||
+fi
|
||||
+
|
||||
+
|
||||
|
||||
|
||||
# Check whether --enable-exceptions was given.
|
||||
diff --git a/libcody/configure.ac b/libcody/configure.ac
|
||||
index 960191ecb72..14e8dd4a226 100644
|
||||
--- a/libcody/configure.ac
|
||||
+++ b/libcody/configure.ac
|
||||
@@ -63,9 +63,31 @@ fi
|
||||
# Enable --enable-host-shared.
|
||||
AC_ARG_ENABLE(host-shared,
|
||||
[AS_HELP_STRING([--enable-host-shared],
|
||||
- [build host code as shared libraries])],
|
||||
-[PICFLAG=-fPIC], [PICFLAG=])
|
||||
+ [build host code as shared libraries])])
|
||||
+AC_SUBST(enable_host_shared)
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])])
|
||||
+AC_SUBST(enable_host_pie)
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
+fi
|
||||
+
|
||||
+if test x$enable_host_pie = xyes; then
|
||||
+ LD_PICFLAG=-pie
|
||||
+else
|
||||
+ LD_PICFLAG=
|
||||
+fi
|
||||
+
|
||||
AC_SUBST(PICFLAG)
|
||||
+AC_SUBST(LD_PICFLAG)
|
||||
|
||||
NMS_ENABLE_EXCEPTIONS
|
||||
|
||||
diff --git a/libcpp/configure b/libcpp/configure
|
||||
index 75145390215..85168273cd1 100755
|
||||
--- a/libcpp/configure
|
||||
+++ b/libcpp/configure
|
||||
@@ -625,6 +625,8 @@ ac_includes_default="\
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
CET_HOST_FLAGS
|
||||
PICFLAG
|
||||
+enable_host_pie
|
||||
+enable_host_shared
|
||||
MAINT
|
||||
USED_CATALOGS
|
||||
PACKAGE
|
||||
@@ -738,6 +740,7 @@ enable_maintainer_mode
|
||||
enable_checking
|
||||
enable_canonical_system_headers
|
||||
enable_host_shared
|
||||
+enable_host_pie
|
||||
enable_cet
|
||||
enable_valgrind_annotations
|
||||
'
|
||||
@@ -1379,6 +1382,7 @@ Optional Features:
|
||||
--enable-canonical-system-headers
|
||||
enable or disable system headers canonicalization
|
||||
--enable-host-shared build host code as shared libraries
|
||||
+ --enable-host-pie build host code as PIE
|
||||
--enable-cet enable Intel CET in host libraries [default=auto]
|
||||
--enable-valgrind-annotations
|
||||
enable valgrind runtime interaction
|
||||
@@ -7605,7 +7609,23 @@ esac
|
||||
# Enable --enable-host-shared.
|
||||
# Check whether --enable-host-shared was given.
|
||||
if test "${enable_host_shared+set}" = set; then :
|
||||
- enableval=$enable_host_shared; PICFLAG=-fPIC
|
||||
+ enableval=$enable_host_shared;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
else
|
||||
PICFLAG=
|
||||
fi
|
||||
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
|
||||
index 9b6042518e5..d25bf5f414f 100644
|
||||
--- a/libcpp/configure.ac
|
||||
+++ b/libcpp/configure.ac
|
||||
@@ -211,8 +211,23 @@ esac
|
||||
# Enable --enable-host-shared.
|
||||
AC_ARG_ENABLE(host-shared,
|
||||
[AS_HELP_STRING([--enable-host-shared],
|
||||
- [build host code as shared libraries])],
|
||||
-[PICFLAG=-fPIC], [PICFLAG=])
|
||||
+ [build host code as shared libraries])])
|
||||
+AC_SUBST(enable_host_shared)
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])])
|
||||
+AC_SUBST(enable_host_pie)
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
+fi
|
||||
+
|
||||
AC_SUBST(PICFLAG)
|
||||
|
||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||
diff --git a/libdecnumber/configure b/libdecnumber/configure
|
||||
index da5302f9315..d805fdeab5a 100755
|
||||
--- a/libdecnumber/configure
|
||||
+++ b/libdecnumber/configure
|
||||
@@ -626,6 +626,8 @@ ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
CET_HOST_FLAGS
|
||||
PICFLAG
|
||||
+enable_host_pie
|
||||
+enable_host_shared
|
||||
ADDITIONAL_OBJS
|
||||
enable_decimal_float
|
||||
target_os
|
||||
@@ -706,6 +708,7 @@ enable_werror_always
|
||||
enable_maintainer_mode
|
||||
enable_decimal_float
|
||||
enable_host_shared
|
||||
+enable_host_pie
|
||||
enable_cet
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@@ -1338,6 +1341,7 @@ Optional Features:
|
||||
or 'dpd' choses which decimal floating point format
|
||||
to use
|
||||
--enable-host-shared build host code as shared libraries
|
||||
+ --enable-host-pie build host code as PIE
|
||||
--enable-cet enable Intel CET in host libraries [default=auto]
|
||||
|
||||
Some influential environment variables:
|
||||
@@ -5185,7 +5189,23 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
|
||||
# Enable --enable-host-shared.
|
||||
# Check whether --enable-host-shared was given.
|
||||
if test "${enable_host_shared+set}" = set; then :
|
||||
- enableval=$enable_host_shared; PICFLAG=-fPIC
|
||||
+ enableval=$enable_host_shared;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
else
|
||||
PICFLAG=
|
||||
fi
|
||||
diff --git a/libdecnumber/configure.ac b/libdecnumber/configure.ac
|
||||
index 0794031ec83..14f67f926d1 100644
|
||||
--- a/libdecnumber/configure.ac
|
||||
+++ b/libdecnumber/configure.ac
|
||||
@@ -100,8 +100,23 @@ AC_C_BIGENDIAN
|
||||
# Enable --enable-host-shared.
|
||||
AC_ARG_ENABLE(host-shared,
|
||||
[AS_HELP_STRING([--enable-host-shared],
|
||||
- [build host code as shared libraries])],
|
||||
-[PICFLAG=-fPIC], [PICFLAG=])
|
||||
+ [build host code as shared libraries])])
|
||||
+AC_SUBST(enable_host_shared)
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])])
|
||||
+AC_SUBST(enable_host_pie)
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
+fi
|
||||
+
|
||||
AC_SUBST(PICFLAG)
|
||||
|
||||
# Enable Intel CET on Intel CET enabled host if jit is enabled.
|
||||
diff --git a/zlib/configure b/zlib/configure
|
||||
index f489f31bc70..0dfc1982844 100755
|
||||
--- a/zlib/configure
|
||||
+++ b/zlib/configure
|
||||
@@ -635,6 +635,8 @@ am__EXEEXT_TRUE
|
||||
LTLIBOBJS
|
||||
LIBOBJS
|
||||
PICFLAG
|
||||
+enable_host_pie
|
||||
+enable_host_shared
|
||||
TARGET_LIBRARY_FALSE
|
||||
TARGET_LIBRARY_TRUE
|
||||
toolexeclibdir
|
||||
@@ -778,6 +780,7 @@ with_gnu_ld
|
||||
enable_libtool_lock
|
||||
with_toolexeclibdir
|
||||
enable_host_shared
|
||||
+enable_host_pie
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
host_alias
|
||||
@@ -1420,6 +1423,7 @@ Optional Features:
|
||||
optimize for fast installation [default=yes]
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--enable-host-shared build host code as shared libraries
|
||||
+ --enable-host-pie build host code as PIE
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@@ -4169,7 +4173,7 @@ case "$host" in
|
||||
case "$enable_cet" in
|
||||
auto)
|
||||
# Check if target supports multi-byte NOPs
|
||||
- # and if assembler supports CET insn.
|
||||
+ # and if compiler and assembler support CET insn.
|
||||
cet_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fcf-protection"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
@@ -11524,15 +11528,31 @@ else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
+# Enable --enable-host-shared.
|
||||
# Check whether --enable-host-shared was given.
|
||||
if test "${enable_host_shared+set}" = set; then :
|
||||
- enableval=$enable_host_shared; PICFLAG=-fPIC
|
||||
+ enableval=$enable_host_shared;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+# Check whether --enable-host-pie was given.
|
||||
+if test "${enable_host_pie+set}" = set; then :
|
||||
+ enableval=$enable_host_pie;
|
||||
+fi
|
||||
+
|
||||
+
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
else
|
||||
PICFLAG=
|
||||
fi
|
||||
|
||||
|
||||
-
|
||||
ac_config_files="$ac_config_files Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
diff --git a/zlib/configure.ac b/zlib/configure.ac
|
||||
index be1cfe29651..adf7aad4e51 100644
|
||||
--- a/zlib/configure.ac
|
||||
+++ b/zlib/configure.ac
|
||||
@@ -122,11 +122,26 @@ else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
+# Enable --enable-host-shared.
|
||||
AC_ARG_ENABLE(host-shared,
|
||||
[AS_HELP_STRING([--enable-host-shared],
|
||||
- [build host code as shared libraries])],
|
||||
-[PICFLAG=-fPIC], [PICFLAG=])
|
||||
-AC_SUBST(PICFLAG)
|
||||
+ [build host code as shared libraries])])
|
||||
+AC_SUBST(enable_host_shared)
|
||||
+
|
||||
+# Enable --enable-host-pie.
|
||||
+AC_ARG_ENABLE(host-pie,
|
||||
+[AS_HELP_STRING([--enable-host-pie],
|
||||
+ [build host code as PIE])])
|
||||
+AC_SUBST(enable_host_pie)
|
||||
+
|
||||
+if test x$enable_host_shared = xyes; then
|
||||
+ PICFLAG=-fPIC
|
||||
+elif test x$enable_host_pie = xyes; then
|
||||
+ PICFLAG=-fPIE
|
||||
+else
|
||||
+ PICFLAG=
|
||||
+fi
|
||||
|
||||
+AC_SUBST(PICFLAG)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
base-commit: ee50b4383a0dca88172c3a821418344bd7391956
|
||||
--
|
||||
2.34.1
|
||||
|
||||
66
SOURCES/gcc11-pr101786.patch
Normal file
66
SOURCES/gcc11-pr101786.patch
Normal file
@ -0,0 +1,66 @@
|
||||
c++: Optimize constinit thread_local vars [PR101786]
|
||||
|
||||
The paper that introduced constinit mentioned in rationale that constinit
|
||||
can be used on externs as well and that it can be used to avoid the
|
||||
thread_local initialization wrappers, because the standard requires that
|
||||
if constinit is present on any declaration, it is also present on the
|
||||
initialization declaration, even if it is in some other TU etc.
|
||||
|
||||
There is a small problem though, we use the tls wrappers not just if
|
||||
the thread_local variable needs dynamic initialization, but also when
|
||||
it has static initialization, but non-trivial destructor, as the
|
||||
"dynamic initialization" in that case needs to register the destructor.
|
||||
|
||||
So, the following patch optimizes constinit thread_local vars only
|
||||
if we can prove they will not have non-trivial destructors. That includes
|
||||
the case where we have incomplete type where we don't know and need to
|
||||
conservatively assume the type will have non-trivial destructor at the
|
||||
initializing declaration side.
|
||||
|
||||
2021-08-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/101786
|
||||
* decl2.c (var_defined_without_dynamic_init): Return true for
|
||||
DECL_DECLARED_CONSTINIT_P with complete type and trivial destructor.
|
||||
|
||||
* g++.dg/cpp2a/constinit16.C: New test.
|
||||
|
||||
--- gcc/cp/decl2.c
|
||||
+++ gcc/cp/decl2.c
|
||||
@@ -3447,6 +3447,12 @@ set_guard (tree guard)
|
||||
static bool
|
||||
var_defined_without_dynamic_init (tree var)
|
||||
{
|
||||
+ /* constinit vars are guaranteed to not have dynamic initializer,
|
||||
+ but still registering the destructor counts as dynamic initialization. */
|
||||
+ if (DECL_DECLARED_CONSTINIT_P (var)
|
||||
+ && COMPLETE_TYPE_P (TREE_TYPE (var))
|
||||
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
|
||||
+ return true;
|
||||
/* If it's defined in another TU, we can't tell. */
|
||||
if (DECL_EXTERNAL (var))
|
||||
return false;
|
||||
--- gcc/testsuite/g++.dg/cpp2a/constinit16.C
|
||||
+++ gcc/testsuite/g++.dg/cpp2a/constinit16.C
|
||||
@@ -0,0 +1,21 @@
|
||||
+// PR c++/101786
|
||||
+// { dg-do compile { target c++20 } }
|
||||
+// { dg-add-options tls }
|
||||
+// { dg-require-alias "" }
|
||||
+// { dg-require-effective-target tls_runtime }
|
||||
+// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar1" } }
|
||||
+// { dg-final { scan-assembler "_ZTH17mythreadlocalvar2" } }
|
||||
+// { dg-final { scan-assembler-not "_ZTH17mythreadlocalvar3" } }
|
||||
+// { dg-final { scan-assembler "_ZTH17mythreadlocalvar4" } }
|
||||
+
|
||||
+extern thread_local constinit int mythreadlocalvar1;
|
||||
+struct S;
|
||||
+extern thread_local constinit S mythreadlocalvar2;
|
||||
+struct T { int t; };
|
||||
+extern thread_local constinit T mythreadlocalvar3;
|
||||
+struct U { int u; ~U (); };
|
||||
+extern thread_local constinit U mythreadlocalvar4;
|
||||
+int foo () { return mythreadlocalvar1; }
|
||||
+S *bar () { return &mythreadlocalvar2; }
|
||||
+T *baz () { return &mythreadlocalvar3; }
|
||||
+U *qux () { return &mythreadlocalvar4; }
|
||||
105
SOURCES/gcc11-pr105157.patch
Normal file
105
SOURCES/gcc11-pr105157.patch
Normal file
@ -0,0 +1,105 @@
|
||||
The original patch had
|
||||
#define TARGET_CPU_NBITS 8
|
||||
but I've changed it to
|
||||
#define TARGET_CPU_NBITS 7
|
||||
|
||||
commit 5522dec054cb940fe83661b96249aa12c54c1d77
|
||||
Author: Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
Date: Fri Apr 8 15:12:23 2022 +0100
|
||||
|
||||
aarch64: PR target/105157 Increase number of cores TARGET_CPU_DEFAULT can encode
|
||||
|
||||
This addresses the compile-time increase seen in the PR target/105157. This was
|
||||
being caused by selecting the wrong core tuning, as when we added the latest
|
||||
AArch64 the TARGET_CPU_generic tuning was pushed beyond the 0x3f mask we used
|
||||
to encode both target cpu and attributes into TARGET_CPU_DEFAULT.
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
PR target/105157
|
||||
* config.gcc: Shift ext_mask by TARGET_CPU_NBITS.
|
||||
* config/aarch64/aarch64.h (TARGET_CPU_NBITS): New macro.
|
||||
(TARGET_CPU_MASK): Likewise.
|
||||
(TARGET_CPU_DEFAULT): Use TARGET_CPU_NBITS.
|
||||
* config/aarch64/aarch64.cc (aarch64_get_tune_cpu): Use TARGET_CPU_MASK.
|
||||
(aarch64_get_arch): Likewise.
|
||||
(aarch64_override_options): Use TARGET_CPU_NBITS.
|
||||
|
||||
--- a/gcc/config.gcc
|
||||
+++ b/gcc/config.gcc
|
||||
@@ -4261,7 +4261,7 @@ case "${target}" in
|
||||
ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'`
|
||||
done
|
||||
|
||||
- ext_mask="(("$ext_mask") << 6)"
|
||||
+ ext_mask="(("$ext_mask") << TARGET_CPU_NBITS)"
|
||||
if [ x"$base_id" != x ]; then
|
||||
target_cpu_cname="TARGET_CPU_$base_id | $ext_mask"
|
||||
fi
|
||||
--- a/gcc/config/aarch64/aarch64.c
|
||||
+++ b/gcc/config/aarch64/aarch64.c
|
||||
@@ -18053,6 +18053,9 @@ aarch64_validate_mtune (const char *str, const struct processor **res)
|
||||
return false;
|
||||
}
|
||||
|
||||
+static_assert (TARGET_CPU_generic < TARGET_CPU_MASK,
|
||||
+ "TARGET_CPU_NBITS is big enough");
|
||||
+
|
||||
/* Return the CPU corresponding to the enum CPU.
|
||||
If it doesn't specify a cpu, return the default. */
|
||||
|
||||
@@ -18062,12 +18065,12 @@ aarch64_get_tune_cpu (enum aarch64_processor cpu)
|
||||
if (cpu != aarch64_none)
|
||||
return &all_cores[cpu];
|
||||
|
||||
- /* The & 0x3f is to extract the bottom 6 bits that encode the
|
||||
- default cpu as selected by the --with-cpu GCC configure option
|
||||
+ /* The & TARGET_CPU_MASK is to extract the bottom TARGET_CPU_NBITS bits that
|
||||
+ encode the default cpu as selected by the --with-cpu GCC configure option
|
||||
in config.gcc.
|
||||
???: The whole TARGET_CPU_DEFAULT and AARCH64_CPU_DEFAULT_FLAGS
|
||||
flags mechanism should be reworked to make it more sane. */
|
||||
- return &all_cores[TARGET_CPU_DEFAULT & 0x3f];
|
||||
+ return &all_cores[TARGET_CPU_DEFAULT & TARGET_CPU_MASK];
|
||||
}
|
||||
|
||||
/* Return the architecture corresponding to the enum ARCH.
|
||||
@@ -18079,7 +18082,8 @@ aarch64_get_arch (enum aarch64_arch arch)
|
||||
if (arch != aarch64_no_arch)
|
||||
return &all_architectures[arch];
|
||||
|
||||
- const struct processor *cpu = &all_cores[TARGET_CPU_DEFAULT & 0x3f];
|
||||
+ const struct processor *cpu
|
||||
+ = &all_cores[TARGET_CPU_DEFAULT & TARGET_CPU_MASK];
|
||||
|
||||
return &all_architectures[cpu->arch];
|
||||
}
|
||||
@@ -18166,7 +18170,7 @@ aarch64_override_options (void)
|
||||
{
|
||||
/* Get default configure-time CPU. */
|
||||
selected_cpu = aarch64_get_tune_cpu (aarch64_none);
|
||||
- aarch64_isa_flags = TARGET_CPU_DEFAULT >> 6;
|
||||
+ aarch64_isa_flags = TARGET_CPU_DEFAULT >> TARGET_CPU_NBITS;
|
||||
}
|
||||
|
||||
if (selected_tune)
|
||||
--- a/gcc/config/aarch64/aarch64.h
|
||||
+++ b/gcc/config/aarch64/aarch64.h
|
||||
@@ -813,10 +813,16 @@ enum target_cpus
|
||||
TARGET_CPU_generic
|
||||
};
|
||||
|
||||
+/* Define how many bits are used to represent the CPU in TARGET_CPU_DEFAULT.
|
||||
+ This needs to be big enough to fit the value of TARGET_CPU_generic.
|
||||
+ All bits after this are used to represent the AARCH64_CPU_DEFAULT_FLAGS. */
|
||||
+#define TARGET_CPU_NBITS 7
|
||||
+#define TARGET_CPU_MASK ((1 << TARGET_CPU_NBITS) - 1)
|
||||
+
|
||||
/* If there is no CPU defined at configure, use generic as default. */
|
||||
#ifndef TARGET_CPU_DEFAULT
|
||||
#define TARGET_CPU_DEFAULT \
|
||||
- (TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << 6))
|
||||
+ (TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << TARGET_CPU_NBITS))
|
||||
#endif
|
||||
|
||||
/* If inserting NOP before a mult-accumulate insn remember to adjust the
|
||||
107
SOURCES/gcc11-pr113960.patch
Normal file
107
SOURCES/gcc11-pr113960.patch
Normal file
@ -0,0 +1,107 @@
|
||||
commit 6f5dcea85a31845ec6f4b6886734b0f02e013718
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Tue Feb 27 17:50:34 2024 +0000
|
||||
|
||||
libstdc++: Fix conditions for using memcmp in std::lexicographical_compare_three_way [PR113960]
|
||||
|
||||
The change in r11-2981-g2f983fa69005b6 meant that
|
||||
std::lexicographical_compare_three_way started to use memcmp for
|
||||
unsigned integers on big endian targets, but for that to be valid we
|
||||
need the two value types to have the same size and we need to use that
|
||||
size to compute the length passed to memcmp.
|
||||
|
||||
I already defined a __is_memcmp_ordered_with trait that does the right
|
||||
checks, std::lexicographical_compare_three_way just needs to use it.
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/113960
|
||||
* include/bits/stl_algobase.h (__is_byte_iter): Replace with ...
|
||||
(__memcmp_ordered_with): New concept.
|
||||
(lexicographical_compare_three_way): Use __memcmp_ordered_with
|
||||
instead of __is_byte_iter. Use correct length for memcmp.
|
||||
* testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc:
|
||||
New test.
|
||||
|
||||
(cherry picked from commit f5cdda8acb06c20335855ed353ab9a441c12128a)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
|
||||
index 7664301a208..6e648e48ad0 100644
|
||||
--- a/libstdc++-v3/include/bits/stl_algobase.h
|
||||
+++ b/libstdc++-v3/include/bits/stl_algobase.h
|
||||
@@ -1780,11 +1780,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
|
||||
}
|
||||
|
||||
#if __cpp_lib_three_way_comparison
|
||||
- // Iter points to a contiguous range of unsigned narrow character type
|
||||
- // or std::byte, suitable for comparison by memcmp.
|
||||
- template<typename _Iter>
|
||||
- concept __is_byte_iter = contiguous_iterator<_Iter>
|
||||
- && __is_memcmp_ordered<iter_value_t<_Iter>>::__value;
|
||||
+ // Both iterators refer to contiguous ranges of unsigned narrow characters,
|
||||
+ // or std::byte, or big-endian unsigned integers, suitable for comparison
|
||||
+ // using memcmp.
|
||||
+ template<typename _Iter1, typename _Iter2>
|
||||
+ concept __memcmp_ordered_with
|
||||
+ = (__is_memcmp_ordered_with<iter_value_t<_Iter1>,
|
||||
+ iter_value_t<_Iter2>>::__value)
|
||||
+ && contiguous_iterator<_Iter1> && contiguous_iterator<_Iter2>;
|
||||
|
||||
// Return a struct with two members, initialized to the smaller of x and y
|
||||
// (or x if they compare equal) and the result of the comparison x <=> y.
|
||||
@@ -1834,20 +1837,20 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
|
||||
if (!std::is_constant_evaluated())
|
||||
if constexpr (same_as<_Comp, __detail::_Synth3way>
|
||||
|| same_as<_Comp, compare_three_way>)
|
||||
- if constexpr (__is_byte_iter<_InputIter1>)
|
||||
- if constexpr (__is_byte_iter<_InputIter2>)
|
||||
- {
|
||||
- const auto [__len, __lencmp] = _GLIBCXX_STD_A::
|
||||
- __min_cmp(__last1 - __first1, __last2 - __first2);
|
||||
- if (__len)
|
||||
- {
|
||||
- const auto __c
|
||||
- = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;
|
||||
- if (__c != 0)
|
||||
- return __c;
|
||||
- }
|
||||
- return __lencmp;
|
||||
- }
|
||||
+ if constexpr (__memcmp_ordered_with<_InputIter1, _InputIter2>)
|
||||
+ {
|
||||
+ const auto [__len, __lencmp] = _GLIBCXX_STD_A::
|
||||
+ __min_cmp(__last1 - __first1, __last2 - __first2);
|
||||
+ if (__len)
|
||||
+ {
|
||||
+ const auto __blen = __len * sizeof(*__first1);
|
||||
+ const auto __c
|
||||
+ = __builtin_memcmp(&*__first1, &*__first2, __blen) <=> 0;
|
||||
+ if (__c != 0)
|
||||
+ return __c;
|
||||
+ }
|
||||
+ return __lencmp;
|
||||
+ }
|
||||
#endif // is_constant_evaluated
|
||||
while (__first1 != __last1)
|
||||
{
|
||||
diff --git a/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc
|
||||
new file mode 100644
|
||||
index 00000000000..d51ae1a3d50
|
||||
--- /dev/null
|
||||
+++ b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc
|
||||
@@ -0,0 +1,15 @@
|
||||
+// { dg-do run { target c++20 } }
|
||||
+
|
||||
+// PR libstdc++/113960
|
||||
+// std::map with std::vector as input overwrites itself with c++20, on s390x
|
||||
+
|
||||
+#include <algorithm>
|
||||
+#include <testsuite_hooks.h>
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ unsigned short a1[] { 1, 2, 3 };
|
||||
+ unsigned short a2[] { 1, 2, 4 };
|
||||
+ // Incorrect memcmp comparison for big endian targets.
|
||||
+ VERIFY( std::lexicographical_compare_three_way(a1, a1+3, a2, a2+3) < 0 );
|
||||
+}
|
||||
65
SOURCES/gcc11-pr116034.patch
Normal file
65
SOURCES/gcc11-pr116034.patch
Normal file
@ -0,0 +1,65 @@
|
||||
commit 084768c865cd50a6f7ff177db2dbdbb7aadaeee0
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Tue Jul 23 10:50:29 2024 +0200
|
||||
|
||||
ssa: Fix up maybe_rewrite_mem_ref_base complex type handling [PR116034]
|
||||
|
||||
The folding into REALPART_EXPR is correct, used only when the mem_offset
|
||||
is zero, but for IMAGPART_EXPR it didn't check the exact offset value (just
|
||||
that it is not 0).
|
||||
The following patch fixes that by using IMAGPART_EXPR only if the offset
|
||||
is right and using BITFIELD_REF or whatever else otherwise.
|
||||
|
||||
2024-07-23 Jakub Jelinek <jakub@redhat.com>
|
||||
Andrew Pinski <quic_apinski@quicinc.com>
|
||||
|
||||
PR tree-optimization/116034
|
||||
* tree-ssa.c (maybe_rewrite_mem_ref_base): Only use IMAGPART_EXPR
|
||||
if MEM_REF offset is equal to element type size.
|
||||
|
||||
* gcc.dg/pr116034.c: New test.
|
||||
|
||||
(cherry picked from commit b9cefd67a2a464a3c9413e6b3f28e7dc7a9ef162)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr116034.c b/gcc/testsuite/gcc.dg/pr116034.c
|
||||
new file mode 100644
|
||||
index 00000000000..9a31de03424
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/pr116034.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* PR tree-optimization/116034 */
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-options "-O1 -fno-strict-aliasing" } */
|
||||
+
|
||||
+int g;
|
||||
+
|
||||
+static inline int
|
||||
+foo (_Complex unsigned short c)
|
||||
+{
|
||||
+ __builtin_memmove (&g, 1 + (char *) &c, 2);
|
||||
+ return g;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ if (__SIZEOF_SHORT__ == 2
|
||||
+ && __CHAR_BIT__ == 8
|
||||
+ && (foo (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ ? 0x100 : 1)
|
||||
+ != (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__ ? 1 : 0x100)))
|
||||
+ __builtin_abort ();
|
||||
+}
|
||||
--- a/gcc/tree-ssa.c
|
||||
+++ b/gcc/tree-ssa.c
|
||||
@@ -1506,7 +1506,10 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (sym)) == COMPLEX_TYPE
|
||||
&& useless_type_conversion_p (TREE_TYPE (*tp),
|
||||
- TREE_TYPE (TREE_TYPE (sym))))
|
||||
+ TREE_TYPE (TREE_TYPE (sym)))
|
||||
+ && (integer_zerop (TREE_OPERAND (*tp, 1))
|
||||
+ || tree_int_cst_equal (TREE_OPERAND (*tp, 1),
|
||||
+ TYPE_SIZE_UNIT (TREE_TYPE (*tp)))))
|
||||
{
|
||||
*tp = build1 (integer_zerop (TREE_OPERAND (*tp, 1))
|
||||
? REALPART_EXPR : IMAGPART_EXPR,
|
||||
@ -1,6 +1,5 @@
|
||||
Original patch (taken from GCC 12 branch version) edited for GCC 8 to
|
||||
use .c rather than .cc filenames and to update aarch64.c changes to
|
||||
apply to GCC 8.
|
||||
Original patch (taken from GCC 12 branch version) edited for GCC 11 to
|
||||
use .c rather than .cc filenames.
|
||||
|
||||
commit 587b370c8492aadaab14c57e242c66778cc78891
|
||||
Author: Richard Sandiford <richard.sandiford@arm.com>
|
||||
@ -26,7 +25,7 @@ index be0d958dcf6b..72d737d62228 100644
|
||||
--- a/gcc/config/aarch64/aarch64.c
|
||||
+++ b/gcc/config/aarch64/aarch64.c
|
||||
@@ -27541,6 +27541,16 @@ aarch64_test_fractional_cost ()
|
||||
ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
|
||||
ASSERT_EQ (cf (1, 2).as_double (), 0.5);
|
||||
}
|
||||
|
||||
+/* Test SVE arithmetic folding. */
|
||||
@ -42,9 +41,10 @@ index be0d958dcf6b..72d737d62228 100644
|
||||
/* Run all target-specific selftests. */
|
||||
|
||||
static void
|
||||
@@ -27548,5 +27558,6 @@ aarch64_run_selftests (void)
|
||||
@@ -27548,6 +27558,7 @@ aarch64_run_selftests (void)
|
||||
{
|
||||
aarch64_test_loading_full_dump ();
|
||||
aarch64_test_fractional_cost ();
|
||||
+ aarch64_test_sve_folding ();
|
||||
}
|
||||
|
||||
403
SOURCES/gcc11-pr99888.patch
Normal file
403
SOURCES/gcc11-pr99888.patch
Normal file
@ -0,0 +1,403 @@
|
||||
From c23b5006d3ffeda1a9edf5fd817765a6da3696ca Mon Sep 17 00:00:00 2001
|
||||
From: Kewen Lin <linkw@linux.ibm.com>
|
||||
Date: Fri, 30 Sep 2022 07:16:49 -0500
|
||||
Subject: [PATCH] rs6000: Rework ELFv2 support for -fpatchable-function-entry*
|
||||
[PR99888]
|
||||
|
||||
As PR99888 and its related show, the current support for
|
||||
-fpatchable-function-entry on powerpc ELFv2 doesn't work
|
||||
well with global entry existence. For example, with one
|
||||
command line option -fpatchable-function-entry=3,2, it got
|
||||
below w/o this patch:
|
||||
|
||||
.LPFE1:
|
||||
nop
|
||||
nop
|
||||
.type foo, @function
|
||||
foo:
|
||||
nop
|
||||
.LFB0:
|
||||
.cfi_startproc
|
||||
.LCF0:
|
||||
0: addis 2,12,.TOC.-.LCF0@ha
|
||||
addi 2,2,.TOC.-.LCF0@l
|
||||
.localentry foo,.-foo
|
||||
|
||||
, the assembly is unexpected since the patched nops have
|
||||
no effects when being entered from local entry.
|
||||
|
||||
This patch is to update the nops patched before and after
|
||||
local entry, it looks like:
|
||||
|
||||
.type foo, @function
|
||||
foo:
|
||||
.LFB0:
|
||||
.cfi_startproc
|
||||
.LCF0:
|
||||
0: addis 2,12,.TOC.-.LCF0@ha
|
||||
addi 2,2,.TOC.-.LCF0@l
|
||||
nop
|
||||
nop
|
||||
.localentry foo,.-foo
|
||||
nop
|
||||
|
||||
PR target/99888
|
||||
PR target/105649
|
||||
|
||||
Backported to GCC 11: renamed source files from .cc back to .c
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* doc/invoke.texi (option -fpatchable-function-entry): Adjust the
|
||||
documentation for PowerPC ELFv2 ABI dual entry points.
|
||||
* config/rs6000/rs6000-internal.h
|
||||
(rs6000_print_patchable_function_entry): New function declaration.
|
||||
* config/rs6000/rs6000-logue.c (rs6000_output_function_prologue):
|
||||
Support patchable-function-entry by emitting nops before and after
|
||||
local entry for the function that needs global entry.
|
||||
* config/rs6000/rs6000.c (rs6000_print_patchable_function_entry): Skip
|
||||
the function that needs global entry till global entry has been
|
||||
emitted.
|
||||
* config/rs6000/rs6000.h (struct machine_function): New bool member
|
||||
global_entry_emitted.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gcc.target/powerpc/pr99888-1.c: New test.
|
||||
* gcc.target/powerpc/pr99888-2.c: New test.
|
||||
* gcc.target/powerpc/pr99888-3.c: New test.
|
||||
* gcc.target/powerpc/pr99888-4.c: New test.
|
||||
* gcc.target/powerpc/pr99888-5.c: New test.
|
||||
* gcc.target/powerpc/pr99888-6.c: New test.
|
||||
* c-c++-common/patchable_function_entry-default.c: Adjust for
|
||||
powerpc_elfv2 to avoid compilation error.
|
||||
---
|
||||
gcc/config/rs6000/rs6000-internal.h | 4 ++
|
||||
gcc/config/rs6000/rs6000-logue.c | 32 ++++++++++++++
|
||||
gcc/config/rs6000/rs6000.c | 10 ++++-
|
||||
gcc/config/rs6000/rs6000.h | 4 ++
|
||||
gcc/doc/invoke.texi | 8 +++-
|
||||
.../patchable_function_entry-default.c | 3 ++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-1.c | 43 +++++++++++++++++++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-2.c | 43 +++++++++++++++++++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-3.c | 11 +++++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-4.c | 13 ++++++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-5.c | 13 ++++++
|
||||
gcc/testsuite/gcc.target/powerpc/pr99888-6.c | 14 ++++++
|
||||
12 files changed, 194 insertions(+), 4 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-1.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-2.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-3.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-4.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-5.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99888-6.c
|
||||
|
||||
diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
|
||||
index b9e82c0468d0..e75b8d5c7e88 100644
|
||||
--- a/gcc/config/rs6000/rs6000-internal.h
|
||||
+++ b/gcc/config/rs6000/rs6000-internal.h
|
||||
@@ -182,6 +182,10 @@ extern tree rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
|
||||
tree *args ATTRIBUTE_UNUSED,
|
||||
bool ignore ATTRIBUTE_UNUSED);
|
||||
|
||||
+extern void rs6000_print_patchable_function_entry (FILE *,
|
||||
+ unsigned HOST_WIDE_INT,
|
||||
+ bool);
|
||||
+
|
||||
extern bool rs6000_passes_float;
|
||||
extern bool rs6000_passes_long_double;
|
||||
extern bool rs6000_passes_vector;
|
||||
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
|
||||
index a11d020ccd0c..3621cb501c70 100644
|
||||
--- a/gcc/config/rs6000/rs6000-logue.c
|
||||
+++ b/gcc/config/rs6000/rs6000-logue.c
|
||||
@@ -4009,11 +4009,43 @@ rs6000_output_function_prologue (FILE *file)
|
||||
fprintf (file, "\tadd 2,2,12\n");
|
||||
}
|
||||
|
||||
+ unsigned short patch_area_size = crtl->patch_area_size;
|
||||
+ unsigned short patch_area_entry = crtl->patch_area_entry;
|
||||
+ /* Need to emit the patching area. */
|
||||
+ if (patch_area_size > 0)
|
||||
+ {
|
||||
+ cfun->machine->global_entry_emitted = true;
|
||||
+ /* As ELFv2 ABI shows, the allowable bytes between the global
|
||||
+ and local entry points are 0, 4, 8, 16, 32 and 64 when
|
||||
+ there is a local entry point. Considering there are two
|
||||
+ non-prefixed instructions for global entry point prologue
|
||||
+ (8 bytes), the count for patchable nops before local entry
|
||||
+ point would be 2, 6 and 14. It's possible to support those
|
||||
+ other counts of nops by not making a local entry point, but
|
||||
+ we don't have clear use cases for them, so leave them
|
||||
+ unsupported for now. */
|
||||
+ if (patch_area_entry > 0)
|
||||
+ {
|
||||
+ if (patch_area_entry != 2
|
||||
+ && patch_area_entry != 6
|
||||
+ && patch_area_entry != 14)
|
||||
+ error ("unsupported number of nops before function entry (%u)",
|
||||
+ patch_area_entry);
|
||||
+ rs6000_print_patchable_function_entry (file, patch_area_entry,
|
||||
+ true);
|
||||
+ patch_area_size -= patch_area_entry;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
fputs ("\t.localentry\t", file);
|
||||
assemble_name (file, name);
|
||||
fputs (",.-", file);
|
||||
assemble_name (file, name);
|
||||
fputs ("\n", file);
|
||||
+ /* Emit the nops after local entry. */
|
||||
+ if (patch_area_size > 0)
|
||||
+ rs6000_print_patchable_function_entry (file, patch_area_size,
|
||||
+ patch_area_entry == 0);
|
||||
}
|
||||
|
||||
else if (rs6000_pcrel_p ())
|
||||
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
|
||||
index bbe21eacc6b9..b9496d7f2680 100644
|
||||
--- a/gcc/config/rs6000/rs6000.c
|
||||
+++ b/gcc/config/rs6000/rs6000.c
|
||||
@@ -14930,8 +14930,14 @@ rs6000_print_patchable_function_entry (FILE *file,
|
||||
if (!(TARGET_64BIT && DEFAULT_ABI != ABI_ELFv2)
|
||||
&& HAVE_GAS_SECTION_LINK_ORDER)
|
||||
flags |= SECTION_LINK_ORDER;
|
||||
- default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
|
||||
- flags);
|
||||
+ bool global_entry_needed_p = rs6000_global_entry_point_prologue_needed_p ();
|
||||
+ /* For a function which needs global entry point, we will emit the
|
||||
+ patchable area before and after local entry point under the control of
|
||||
+ cfun->machine->global_entry_emitted, see the handling in function
|
||||
+ rs6000_output_function_prologue. */
|
||||
+ if (!global_entry_needed_p || cfun->machine->global_entry_emitted)
|
||||
+ default_print_patchable_function_entry_1 (file, patch_area_size, record_p,
|
||||
+ flags);
|
||||
}
|
||||
|
||||
enum rtx_code
|
||||
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
|
||||
index eb7b21584970..b4df22b60303 100644
|
||||
--- a/gcc/config/rs6000/rs6000.h
|
||||
+++ b/gcc/config/rs6000/rs6000.h
|
||||
@@ -2435,6 +2435,10 @@ typedef struct GTY(()) machine_function
|
||||
bool lr_is_wrapped_separately;
|
||||
bool toc_is_wrapped_separately;
|
||||
bool mma_return_type_error;
|
||||
+ /* Indicate global entry is emitted, only useful when the function requires
|
||||
+ global entry. It helps to control the patchable area before and after
|
||||
+ local entry. */
|
||||
+ bool global_entry_emitted;
|
||||
} machine_function;
|
||||
#endif
|
||||
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 2ac9cfc35f92..518bfdf0867d 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -16884,9 +16884,13 @@ the area size or to remove it completely on a single function.
|
||||
If @code{N=0}, no pad location is recorded.
|
||||
|
||||
The NOP instructions are inserted at---and maybe before, depending on
|
||||
-@var{M}---the function entry address, even before the prologue.
|
||||
+@var{M}---the function entry address, even before the prologue. On
|
||||
+PowerPC with the ELFv2 ABI, for a function with dual entry points,
|
||||
+the local entry point is this function entry address.
|
||||
|
||||
-The maximum value of @var{N} and @var{M} is 65535.
|
||||
+The maximum value of @var{N} and @var{M} is 65535. On PowerPC with the
|
||||
+ELFv2 ABI, for a function with dual entry points, the supported values
|
||||
+for @var{M} are 0, 2, 6 and 14.
|
||||
@end table
|
||||
|
||||
|
||||
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-default.c b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
||||
index 7036f7bfbea4..a501efccb194 100644
|
||||
--- a/gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
||||
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
||||
@@ -1,6 +1,9 @@
|
||||
/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
||||
/* { dg-options "-O2 -fpatchable-function-entry=3,1" } */
|
||||
/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
||||
+/* See PR99888, one single preceding nop isn't allowed on powerpc_elfv2,
|
||||
+ so overriding with two preceding nops to make it pass there. */
|
||||
+/* { dg-additional-options "-fpatchable-function-entry=3,2" { target powerpc_elfv2 } } */
|
||||
/* { dg-final { scan-assembler-times "nop|NOP|SWYM" 3 { target { ! { alpha*-*-* } } } } } */
|
||||
/* { dg-final { scan-assembler-times "bis" 3 { target alpha*-*-* } } } */
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-1.c b/gcc/testsuite/gcc.target/powerpc/pr99888-1.c
|
||||
new file mode 100644
|
||||
index 000000000000..9370b4e74388
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-1.c
|
||||
@@ -0,0 +1,43 @@
|
||||
+/* Verify no errors for different nops after local entry on ELFv2. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (1, 0)))
|
||||
+int test1 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (2, 0)))
|
||||
+int test2 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (3, 0)))
|
||||
+int test3 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (4, 0)))
|
||||
+int test4 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (5, 0)))
|
||||
+int test5 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (6, 0)))
|
||||
+int test6 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (7, 0)))
|
||||
+int test7 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (8, 0)))
|
||||
+int test8 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-2.c b/gcc/testsuite/gcc.target/powerpc/pr99888-2.c
|
||||
new file mode 100644
|
||||
index 000000000000..450617126023
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-2.c
|
||||
@@ -0,0 +1,43 @@
|
||||
+/* Verify no errors for 2, 6 and 14 nops before local entry on ELFv2. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (2, 2)))
|
||||
+int test1 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (4, 2)))
|
||||
+int test2 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (6, 6)))
|
||||
+int test3 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (8, 6)))
|
||||
+int test4 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (16, 6)))
|
||||
+int test5 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (14, 14)))
|
||||
+int test6 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (28, 14)))
|
||||
+int test7 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
+__attribute__ ((noipa, patchable_function_entry (64, 14)))
|
||||
+int test8 (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-3.c b/gcc/testsuite/gcc.target/powerpc/pr99888-3.c
|
||||
new file mode 100644
|
||||
index 000000000000..4531ae32036d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-3.c
|
||||
@@ -0,0 +1,11 @@
|
||||
+/* { dg-options "-fpatchable-function-entry=1" } */
|
||||
+
|
||||
+/* Verify no errors on ELFv2, using command line option instead of
|
||||
+ function attribute. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+int test (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-4.c b/gcc/testsuite/gcc.target/powerpc/pr99888-4.c
|
||||
new file mode 100644
|
||||
index 000000000000..00a8d4d316e0
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-4.c
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* { dg-require-effective-target powerpc_elfv2 } */
|
||||
+/* There is no global entry point prologue with pcrel. */
|
||||
+/* { dg-options "-mno-pcrel -fpatchable-function-entry=1,1" } */
|
||||
+
|
||||
+/* Verify one error emitted for unexpected 1 nop before local
|
||||
+ entry. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+int test (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+/* { dg-error "unsupported number of nops before function entry \\(1\\)" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-5.c b/gcc/testsuite/gcc.target/powerpc/pr99888-5.c
|
||||
new file mode 100644
|
||||
index 000000000000..39d3b4465f11
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-5.c
|
||||
@@ -0,0 +1,13 @@
|
||||
+/* { dg-require-effective-target powerpc_elfv2 } */
|
||||
+/* There is no global entry point prologue with pcrel. */
|
||||
+/* { dg-options "-mno-pcrel -fpatchable-function-entry=7,3" } */
|
||||
+
|
||||
+/* Verify one error emitted for unexpected 3 nops before local
|
||||
+ entry. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+int test (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+/* { dg-error "unsupported number of nops before function entry \\(3\\)" "" { target *-*-* } .-1 } */
|
||||
diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-6.c b/gcc/testsuite/gcc.target/powerpc/pr99888-6.c
|
||||
new file mode 100644
|
||||
index 000000000000..c6c18dcc7ac0
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/powerpc/pr99888-6.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-require-effective-target powerpc_elfv2 } */
|
||||
+/* There is no global entry point prologue with pcrel. */
|
||||
+/* { dg-options "-mno-pcrel" } */
|
||||
+
|
||||
+/* Verify one error emitted for unexpected 4 nops before local
|
||||
+ entry. */
|
||||
+
|
||||
+extern int a;
|
||||
+
|
||||
+__attribute__ ((patchable_function_entry (20, 4)))
|
||||
+int test (int b) {
|
||||
+ return a + b;
|
||||
+}
|
||||
+/* { dg-error "unsupported number of nops before function entry \\(4\\)" "" { target *-*-* } .-1 } */
|
||||
--
|
||||
2.43.5
|
||||
|
||||
@ -1,9 +1,43 @@
|
||||
This patch backports support for PCH with PIE from upstream trunk.
|
||||
|
||||
It squashes two commits:
|
||||
|
||||
commit e4641191287ca613529d78a906afe4f029c1c3cd
|
||||
Author: Iain Sandoe <iain@sandoe.co.uk>
|
||||
Date: Sat Nov 13 12:26:16 2021 +0000
|
||||
|
||||
PCH: Make the save and restore diagnostics more robust.
|
||||
|
||||
When saving, if we cannot obtain a suitable memory segment there
|
||||
is no point in continuing, so exit with an error.
|
||||
|
||||
When reading in the PCH, we have a situation that the read-in
|
||||
data will replace the line tables used by the diagnostics output.
|
||||
However, the state of the read-oin line tables is indeterminate
|
||||
at some points where diagnostics might be needed.
|
||||
|
||||
To make this more robust, we save the existing line tables at
|
||||
the start and, once we have read in the pointer to the new one,
|
||||
put that to one side and restore the original table. This
|
||||
avoids compiler hangs if the read or memory acquisition code
|
||||
issues an assert, fatal_error, segv etc.
|
||||
|
||||
Once the read is complete, we swap in the new line table that
|
||||
came from the PCH.
|
||||
|
||||
If the read-in PCH is corrupted then we still have a broken
|
||||
compilation w.r.t any future diagnostics - but there is little
|
||||
that can be done about that without more careful validation of
|
||||
the file.
|
||||
|
||||
and
|
||||
|
||||
commit fe7c3ecff1f9c0520090a77fa824d8c5d9dbec12
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Fri Dec 3 11:03:30 2021 +0100
|
||||
|
||||
pch: Add support for PCH for relocatable executables [PR71934]
|
||||
|
||||
|
||||
So, if we want to make PCH work for PIEs, I'd say we can:
|
||||
1) add a new GTY option, say callback, which would act like
|
||||
skip for non-PCH and for PCH would make us skip it but
|
||||
@ -21,118 +55,19 @@ Date: Fri Dec 3 11:03:30 2021 +0100
|
||||
5) maybe add a gengtype warning if it sees in GTY tracked
|
||||
structure a function pointer without that new callback
|
||||
option
|
||||
|
||||
|
||||
Here is 1), 2), 3) implemented.
|
||||
|
||||
|
||||
Note, on stdc++.h.gch/O2g.gch there are just those 10 relocations without
|
||||
the second patch, with it a few more, but nothing huge. And for non-PIEs
|
||||
there isn't really any extra work on the load side except freading two scalar
|
||||
values and fseek.
|
||||
|
||||
2021-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR pch/71934
|
||||
gcc/
|
||||
* ggc.h (gt_pch_note_callback): Declare.
|
||||
* gengtype.h (enum typekind): Add TYPE_CALLBACK.
|
||||
(callback_type): Declare.
|
||||
* gengtype.c (dbgprint_count_type_at): Handle TYPE_CALLBACK.
|
||||
(callback_type): New variable.
|
||||
(process_gc_options): Add CALLBACK argument, handle callback
|
||||
option.
|
||||
(set_gc_used_type): Adjust process_gc_options caller, if callback,
|
||||
set type to &callback_type.
|
||||
(output_mangled_typename): Handle TYPE_CALLBACK.
|
||||
(walk_type): Likewise. Handle callback option.
|
||||
(write_types_process_field): Handle TYPE_CALLBACK.
|
||||
(write_types_local_user_process_field): Likewise.
|
||||
(write_types_local_process_field): Likewise.
|
||||
(write_root): Likewise.
|
||||
(dump_typekind): Likewise.
|
||||
(dump_type): Likewise.
|
||||
* gengtype-state.c (type_lineloc): Handle TYPE_CALLBACK.
|
||||
(state_writer::write_state_callback_type): New method.
|
||||
(state_writer::write_state_type): Handle TYPE_CALLBACK.
|
||||
(read_state_callback_type): New function.
|
||||
(read_state_type): Handle TYPE_CALLBACK.
|
||||
* ggc-common.c (callback_vec): New variable.
|
||||
(gt_pch_note_callback): New function.
|
||||
(gt_pch_save): Stream out gt_pch_save function address and relocation
|
||||
table.
|
||||
(gt_pch_restore): Stream in saved gt_pch_save function address and
|
||||
relocation table and apply relocations if needed.
|
||||
* doc/gty.texi (callback): Document new GTY option.
|
||||
* varasm.c (get_unnamed_section): Change callback argument's type and
|
||||
last argument's type from const void * to const char *.
|
||||
(output_section_asm_op): Change argument's type from const void *
|
||||
to const char *, remove unnecessary cast.
|
||||
* tree-core.h (struct tree_translation_unit_decl): Drop GTY((skip))
|
||||
from language member.
|
||||
* output.h (unnamed_section_callback): Change argument type from
|
||||
const void * to const char *.
|
||||
(struct unnamed_section): Use GTY((callback)) instead of GTY((skip))
|
||||
for callback member. Change data member type from const void *
|
||||
to const char *.
|
||||
(struct noswitch_section): Use GTY((callback)) instead of GTY((skip))
|
||||
for callback member.
|
||||
(get_unnamed_section): Change callback argument's type and
|
||||
last argument's type from const void * to const char *.
|
||||
(output_section_asm_op): Change argument's type from const void *
|
||||
to const char *.
|
||||
* config/avr/avr.c (avr_output_progmem_section_asm_op): Likewise.
|
||||
Remove unneeded cast.
|
||||
* config/darwin.c (output_objc_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
* config/pa/pa.c (som_output_text_section_asm_op): Likewise.
|
||||
(som_output_comdat_data_section_asm_op): Likewise.
|
||||
* config/rs6000/rs6000.c (rs6000_elf_output_toc_section_asm_op):
|
||||
Likewise.
|
||||
(rs6000_xcoff_output_readonly_section_asm_op): Likewise. Instead
|
||||
of dereferencing directive hardcode variable names and decide based on
|
||||
whether directive is NULL or not.
|
||||
(rs6000_xcoff_output_readwrite_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
(rs6000_xcoff_output_tls_section_asm_op): Likewise. Instead
|
||||
of dereferencing directive hardcode variable names and decide based on
|
||||
whether directive is NULL or not.
|
||||
(rs6000_xcoff_output_toc_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
(rs6000_xcoff_asm_init_sections): Adjust get_unnamed_section callers.
|
||||
gcc/c-family/
|
||||
* c-pch.c (struct c_pch_validity): Remove pch_init member.
|
||||
(pch_init): Don't initialize v.pch_init.
|
||||
(c_common_valid_pch): Don't warn and punt if .text addresses change.
|
||||
libcpp/
|
||||
* include/line-map.h (class line_maps): Add GTY((callback)) to
|
||||
reallocator and round_alloc_size members.
|
||||
|
||||
commit 4dc6d19222581c77a174d44d97507d234fb7e39b
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon Dec 6 11:18:58 2021 +0100
|
||||
|
||||
avr: Fix AVR build [PR71934]
|
||||
|
||||
On Mon, Dec 06, 2021 at 11:00:30AM +0100, Martin Liška wrote:
|
||||
> Jakub, I think the patch broke avr-linux target:
|
||||
>
|
||||
> g++ -fno-PIE -c -g -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-erro
|
||||
> /home/marxin/Programming/gcc/gcc/config/avr/avr.c: In function ‘void avr_output_data_section_asm_op(const void*)’:
|
||||
> /home/marxin/Programming/gcc/gcc/config/avr/avr.c:10097:26: error: invalid conversion from ‘const void*’ to ‘const char*’ [-fpermissive]
|
||||
|
||||
This patch fixes that.
|
||||
|
||||
2021-12-06 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR pch/71934
|
||||
* config/avr/avr.c (avr_output_data_section_asm_op,
|
||||
avr_output_bss_section_asm_op): Change argument type from const void *
|
||||
to const char *.
|
||||
|
||||
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
|
||||
index 5da60423354..2cafa1387bb 100644
|
||||
index fd94c3799ac..eebfa1df0bc 100644
|
||||
--- a/gcc/c-family/c-pch.c
|
||||
+++ b/gcc/c-family/c-pch.c
|
||||
@@ -58,7 +58,6 @@ struct c_pch_validity
|
||||
@@ -54,7 +54,6 @@ struct c_pch_validity
|
||||
{
|
||||
unsigned char debug_info_type;
|
||||
signed char match[MATCH_SIZE];
|
||||
@ -140,7 +75,7 @@ index 5da60423354..2cafa1387bb 100644
|
||||
size_t target_data_length;
|
||||
};
|
||||
|
||||
@@ -123,7 +122,6 @@ pch_init (void)
|
||||
@@ -117,7 +116,6 @@ pch_init (void)
|
||||
gcc_assert (v.match[i] == *pch_matching[i].flag_var);
|
||||
}
|
||||
}
|
||||
@ -148,7 +83,7 @@ index 5da60423354..2cafa1387bb 100644
|
||||
target_validity = targetm.get_pch_validity (&v.target_data_length);
|
||||
|
||||
if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
|
||||
@@ -287,20 +285,6 @@ c_common_valid_pch (cpp_reader *pfile, c
|
||||
@@ -275,19 +273,6 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,8 +95,7 @@ index 5da60423354..2cafa1387bb 100644
|
||||
- check one function. */
|
||||
- if (v.pch_init != &pch_init)
|
||||
- {
|
||||
- if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
- cpp_error (pfile, CPP_DL_WARNING,
|
||||
- cpp_warning (pfile, CPP_W_INVALID_PCH,
|
||||
- "%s: had text segment at different address", name);
|
||||
- return 2;
|
||||
- }
|
||||
@ -170,10 +104,10 @@ index 5da60423354..2cafa1387bb 100644
|
||||
{
|
||||
void *this_file_data = xmalloc (v.target_data_length);
|
||||
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
|
||||
index 200701a583c..6ba038881d6 100644
|
||||
index 3a250dfb960..4d29e80dcc9 100644
|
||||
--- a/gcc/config/avr/avr.c
|
||||
+++ b/gcc/config/avr/avr.c
|
||||
@@ -10114,10 +10114,9 @@ avr_output_bss_section_asm_op (const void *data)
|
||||
@@ -10221,10 +10221,9 @@ avr_output_bss_section_asm_op (const void *data)
|
||||
/* Unnamed section callback for progmem*.data sections. */
|
||||
|
||||
static void
|
||||
@ -187,10 +121,10 @@ index 200701a583c..6ba038881d6 100644
|
||||
|
||||
|
||||
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
|
||||
index c5ba7927ce1..8ad5b26c980 100644
|
||||
index 5d173919ee0..0c8aea148dc 100644
|
||||
--- a/gcc/config/darwin.c
|
||||
+++ b/gcc/config/darwin.c
|
||||
@@ -134,7 +134,7 @@ int emit_aligned_common = false;
|
||||
@@ -128,7 +128,7 @@ int emit_aligned_common = false;
|
||||
DIRECTIVE is as for output_section_asm_op. */
|
||||
|
||||
static void
|
||||
@ -200,10 +134,10 @@ index c5ba7927ce1..8ad5b26c980 100644
|
||||
static bool been_here = false;
|
||||
|
||||
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
|
||||
index f22d25a4066..2b10ef34061 100644
|
||||
index 341c5f0d765..8ac9c4b3a44 100644
|
||||
--- a/gcc/config/pa/pa.c
|
||||
+++ b/gcc/config/pa/pa.c
|
||||
@@ -10009,7 +10009,7 @@ pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
@@ -10011,7 +10011,7 @@ pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
to the default text subspace. */
|
||||
|
||||
static void
|
||||
@ -212,7 +146,7 @@ index f22d25a4066..2b10ef34061 100644
|
||||
{
|
||||
gcc_assert (TARGET_SOM);
|
||||
if (TARGET_GAS)
|
||||
@@ -10053,7 +10053,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
@@ -10055,7 +10055,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
sections. This function is only used with SOM. */
|
||||
|
||||
static void
|
||||
@ -222,10 +156,10 @@ index f22d25a4066..2b10ef34061 100644
|
||||
in_section = NULL;
|
||||
output_section_asm_op (data);
|
||||
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
|
||||
index 945157b1c1a..34089743759 100644
|
||||
index 9b1c3a8b5ea..fa245a8714c 100644
|
||||
--- a/gcc/config/rs6000/rs6000.c
|
||||
+++ b/gcc/config/rs6000/rs6000.c
|
||||
@@ -20599,7 +20599,7 @@ rs6000_ms_bitfield_layout_p (const_tree record_type)
|
||||
@@ -20232,7 +20232,7 @@ rs6000_ms_bitfield_layout_p (const_tree record_type)
|
||||
/* A get_unnamed_section callback, used for switching to toc_section. */
|
||||
|
||||
static void
|
||||
@ -234,7 +168,7 @@ index 945157b1c1a..34089743759 100644
|
||||
{
|
||||
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
|
||||
&& TARGET_MINIMAL_TOC)
|
||||
@@ -21303,35 +21303,39 @@ rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
|
||||
@@ -20936,35 +20936,39 @@ rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
|
||||
points to the section string variable. */
|
||||
|
||||
static void
|
||||
@ -281,7 +215,7 @@ index 945157b1c1a..34089743759 100644
|
||||
{
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
{
|
||||
@@ -21358,26 +21362,26 @@ rs6000_xcoff_asm_init_sections (void)
|
||||
@@ -20991,26 +20995,26 @@ rs6000_xcoff_asm_init_sections (void)
|
||||
{
|
||||
read_only_data_section
|
||||
= get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
|
||||
@ -314,10 +248,10 @@ index 945157b1c1a..34089743759 100644
|
||||
toc_section
|
||||
= get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
|
||||
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
|
||||
index b996ff2c44e..ca2c8404894 100644
|
||||
index aaf97ae9ad5..0154bd86fe9 100644
|
||||
--- a/gcc/doc/gty.texi
|
||||
+++ b/gcc/doc/gty.texi
|
||||
@@ -205,6 +205,15 @@ If @code{skip} is applied to a field, the type machinery will ignore it.
|
||||
@@ -197,6 +197,15 @@ If @code{skip} is applied to a field, the type machinery will ignore it.
|
||||
This is somewhat dangerous; the only safe use is in a union when one
|
||||
field really isn't ever used.
|
||||
|
||||
@ -334,7 +268,7 @@ index b996ff2c44e..ca2c8404894 100644
|
||||
@item for_user
|
||||
|
||||
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
|
||||
index ac9d536963f..36a96e84574 100644
|
||||
index 891f2e18a61..fb99729bc0e 100644
|
||||
--- a/gcc/gengtype-state.c
|
||||
+++ b/gcc/gengtype-state.c
|
||||
@@ -57,6 +57,7 @@ type_lineloc (const_type_p ty)
|
||||
@ -412,10 +346,10 @@ index ac9d536963f..36a96e84574 100644
|
||||
{
|
||||
*current = XCNEW (struct type);
|
||||
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
|
||||
index a77cfd92bfa..b9daaa43689 100644
|
||||
index 98d4626f87e..91eacc26932 100644
|
||||
--- a/gcc/gengtype.c
|
||||
+++ b/gcc/gengtype.c
|
||||
@@ -172,6 +172,7 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
@@ -167,6 +167,7 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0;
|
||||
int nb_lang_struct = 0;
|
||||
int nb_user_struct = 0, nb_undefined = 0;
|
||||
@ -423,7 +357,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
type_p p = NULL;
|
||||
for (p = t; p; p = p->next)
|
||||
{
|
||||
@@ -202,6 +203,9 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
@@ -197,6 +198,9 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
case TYPE_ARRAY:
|
||||
nb_array++;
|
||||
break;
|
||||
@ -433,7 +367,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
case TYPE_LANG_STRUCT:
|
||||
nb_lang_struct++;
|
||||
break;
|
||||
@@ -217,6 +221,8 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
@@ -212,6 +216,8 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union);
|
||||
if (nb_pointer > 0 || nb_array > 0)
|
||||
fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array);
|
||||
@ -442,7 +376,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
if (nb_lang_struct > 0)
|
||||
fprintf (stderr, "@@%%@@ %d lang_structs\n", nb_lang_struct);
|
||||
if (nb_user_struct > 0)
|
||||
@@ -495,6 +501,10 @@ struct type scalar_char = {
|
||||
@@ -490,6 +496,10 @@ struct type scalar_char = {
|
||||
TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
|
||||
};
|
||||
|
||||
@ -453,7 +387,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
/* Lists of various things. */
|
||||
|
||||
pair_p typedefs = NULL;
|
||||
@@ -1464,7 +1474,7 @@ static void set_gc_used (pair_p);
|
||||
@@ -1459,7 +1469,7 @@ static void set_gc_used (pair_p);
|
||||
|
||||
static void
|
||||
process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
|
||||
@ -462,7 +396,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
{
|
||||
options_p o;
|
||||
for (o = opt; o; o = o->next)
|
||||
@@ -1478,6 +1488,8 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
|
||||
@@ -1473,6 +1483,8 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
|
||||
*length = 1;
|
||||
else if (strcmp (o->name, "skip") == 0)
|
||||
*skip = 1;
|
||||
@ -471,7 +405,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
else if (strcmp (o->name, "nested_ptr") == 0
|
||||
&& o->kind == OPTION_NESTED)
|
||||
*nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type;
|
||||
@@ -1526,7 +1538,7 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
@@ -1521,7 +1533,7 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
type_p dummy2;
|
||||
bool allow_undefined_field_types = (t->kind == TYPE_USER_STRUCT);
|
||||
|
||||
@ -480,7 +414,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
&dummy2);
|
||||
|
||||
if (t->u.s.base_class)
|
||||
@@ -1542,9 +1554,10 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
@@ -1537,9 +1549,10 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
int maybe_undef = 0;
|
||||
int length = 0;
|
||||
int skip = 0;
|
||||
@ -492,7 +426,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
|
||||
if (nested_ptr && f->type->kind == TYPE_POINTER)
|
||||
set_gc_used_type (nested_ptr, GC_POINTED_TO);
|
||||
@@ -1554,6 +1567,8 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
@@ -1549,6 +1562,8 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
|
||||
else if (skip)
|
||||
; /* target type is not used through this field */
|
||||
@ -501,7 +435,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
else
|
||||
set_gc_used_type (f->type, GC_USED, allow_undefined_field_types);
|
||||
}
|
||||
@@ -2519,6 +2534,7 @@ output_mangled_typename (outf_p of, const_type_p t)
|
||||
@@ -2512,6 +2527,7 @@ output_mangled_typename (outf_p of, const_type_p t)
|
||||
{
|
||||
case TYPE_NONE:
|
||||
case TYPE_UNDEFINED:
|
||||
@ -509,7 +443,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
case TYPE_POINTER:
|
||||
@@ -2719,6 +2735,8 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
@@ -2712,6 +2728,8 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
;
|
||||
else if (strcmp (oo->name, "for_user") == 0)
|
||||
;
|
||||
@ -518,7 +452,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
else
|
||||
error_at_line (d->line, "unknown option `%s'\n", oo->name);
|
||||
|
||||
@@ -2744,6 +2762,7 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
@@ -2737,6 +2755,7 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
{
|
||||
case TYPE_SCALAR:
|
||||
case TYPE_STRING:
|
||||
@ -526,7 +460,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
d->process_field (t, d);
|
||||
break;
|
||||
|
||||
@@ -3275,6 +3294,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
|
||||
@@ -3268,6 +3287,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
|
||||
break;
|
||||
|
||||
case TYPE_SCALAR:
|
||||
@ -534,7 +468,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
break;
|
||||
|
||||
case TYPE_ARRAY:
|
||||
@@ -3820,6 +3840,7 @@ write_types_local_user_process_field (type_p f, const struct walk_type_data *d)
|
||||
@@ -3813,6 +3833,7 @@ write_types_local_user_process_field (type_p f, const struct walk_type_data *d)
|
||||
break;
|
||||
|
||||
case TYPE_SCALAR:
|
||||
@ -542,7 +476,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
break;
|
||||
|
||||
case TYPE_ARRAY:
|
||||
@@ -3906,6 +3927,13 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d)
|
||||
@@ -3899,6 +3920,13 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d)
|
||||
case TYPE_SCALAR:
|
||||
break;
|
||||
|
||||
@ -556,7 +490,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_NONE:
|
||||
case TYPE_UNDEFINED:
|
||||
@@ -4434,6 +4462,7 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
||||
@@ -4427,6 +4455,7 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
||||
case TYPE_UNDEFINED:
|
||||
case TYPE_UNION:
|
||||
case TYPE_LANG_STRUCT:
|
||||
@ -564,7 +498,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
error_at_line (line, "global `%s' is unimplemented type", name);
|
||||
}
|
||||
}
|
||||
@@ -4728,6 +4757,9 @@ dump_typekind (int indent, enum typekind kind)
|
||||
@@ -4721,6 +4750,9 @@ dump_typekind (int indent, enum typekind kind)
|
||||
case TYPE_ARRAY:
|
||||
printf ("TYPE_ARRAY");
|
||||
break;
|
||||
@ -574,7 +508,7 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
case TYPE_LANG_STRUCT:
|
||||
printf ("TYPE_LANG_STRUCT");
|
||||
break;
|
||||
@@ -4894,6 +4926,7 @@ dump_type (int indent, type_p t)
|
||||
@@ -4887,6 +4919,7 @@ dump_type (int indent, type_p t)
|
||||
t->u.scalar_is_char ? "true" : "false");
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
@ -583,10 +517,10 @@ index a77cfd92bfa..b9daaa43689 100644
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
|
||||
index 8a7a54957ea..8fa7064ca85 100644
|
||||
index 4fe8f0f7232..c32faba2995 100644
|
||||
--- a/gcc/gengtype.h
|
||||
+++ b/gcc/gengtype.h
|
||||
@@ -154,6 +154,9 @@ enum typekind {
|
||||
@@ -149,6 +149,9 @@ enum typekind {
|
||||
TYPE_UNION, /* Type for GTY-ed discriminated unions. */
|
||||
TYPE_POINTER, /* Pointer type to GTY-ed type. */
|
||||
TYPE_ARRAY, /* Array of GTY-ed types. */
|
||||
@ -596,7 +530,7 @@ index 8a7a54957ea..8fa7064ca85 100644
|
||||
TYPE_LANG_STRUCT, /* GCC front-end language specific structs.
|
||||
Various languages may have homonymous but
|
||||
different structs. */
|
||||
@@ -331,6 +334,9 @@ extern struct type string_type;
|
||||
@@ -326,6 +329,9 @@ extern struct type string_type;
|
||||
extern struct type scalar_nonchar;
|
||||
extern struct type scalar_char;
|
||||
|
||||
@ -607,10 +541,10 @@ index 8a7a54957ea..8fa7064ca85 100644
|
||||
specific one. */
|
||||
#define UNION_P(x) \
|
||||
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
|
||||
index b6abed1d9a2..7c998e95473 100644
|
||||
index 357bda13f97..88e1af4ba4a 100644
|
||||
--- a/gcc/ggc-common.c
|
||||
+++ b/gcc/ggc-common.c
|
||||
@@ -256,6 +256,7 @@ saving_hasher::equal (const ptr_data *p1
|
||||
@@ -249,6 +249,7 @@ saving_hasher::equal (const ptr_data *p1, const void *p2)
|
||||
}
|
||||
|
||||
static hash_table<saving_hasher> *saving_htab;
|
||||
@ -618,7 +552,7 @@ index b6abed1d9a2..7c998e95473 100644
|
||||
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
@@ -288,6 +289,23 @@ gt_pch_note_object (void *obj, void *not
|
||||
@@ -281,6 +282,23 @@ gt_pch_note_object (void *obj, void *note_ptr_cookie,
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -642,7 +576,18 @@ index b6abed1d9a2..7c998e95473 100644
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
void
|
||||
@@ -582,10 +600,20 @@ gt_pch_save (FILE *f)
|
||||
@@ -443,6 +461,10 @@ gt_pch_save (FILE *f)
|
||||
(The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
|
||||
HOST_HOOKS_GT_PCH_USE_ADDRESS.) */
|
||||
mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f));
|
||||
+ /* If the host cannot supply any suitable address for this, we are stuck. */
|
||||
+ if (mmi.preferred_base == NULL)
|
||||
+ fatal_error (input_location,
|
||||
+ "cannot write PCH file: required memory segment unavailable");
|
||||
|
||||
ggc_pch_this_base (state.d, mmi.preferred_base);
|
||||
|
||||
@@ -575,10 +597,20 @@ gt_pch_save (FILE *f)
|
||||
ggc_pch_finish (state.d, state.f);
|
||||
gt_pch_fixup_stringpool ();
|
||||
|
||||
@ -663,7 +608,64 @@ index b6abed1d9a2..7c998e95473 100644
|
||||
}
|
||||
|
||||
/* Read the state of the compiler back in from F. */
|
||||
@@ -639,6 +667,30 @@ gt_pch_restore (FILE *f)
|
||||
@@ -592,6 +624,13 @@ gt_pch_restore (FILE *f)
|
||||
struct mmap_info mmi;
|
||||
int result;
|
||||
|
||||
+ /* We are about to reload the line maps along with the rest of the PCH
|
||||
+ data, which means that the (loaded) ones cannot be guaranteed to be
|
||||
+ in any valid state for reporting diagnostics that happen during the
|
||||
+ load. Save the current table (and use it during the loading process
|
||||
+ below). */
|
||||
+ class line_maps *save_line_table = line_table;
|
||||
+
|
||||
/* Delete any deletable objects. This makes ggc_pch_read much
|
||||
faster, as it can be sure that no GCable objects remain other
|
||||
than the ones just read in. */
|
||||
@@ -606,20 +645,40 @@ gt_pch_restore (FILE *f)
|
||||
fatal_error (input_location, "cannot read PCH file: %m");
|
||||
|
||||
/* Read in all the global pointers, in 6 easy loops. */
|
||||
+ bool error_reading_pointers = false;
|
||||
for (rt = gt_ggc_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
if (fread ((char *)rti->base + rti->stride * i,
|
||||
sizeof (void *), 1, f) != 1)
|
||||
- fatal_error (input_location, "cannot read PCH file: %m");
|
||||
+ error_reading_pointers = true;
|
||||
+
|
||||
+ /* Stash the newly read-in line table pointer - it does not point to
|
||||
+ anything meaningful yet, so swap the old one back in. */
|
||||
+ class line_maps *new_line_table = line_table;
|
||||
+ line_table = save_line_table;
|
||||
+ if (error_reading_pointers)
|
||||
+ fatal_error (input_location, "cannot read PCH file: %m");
|
||||
|
||||
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
|
||||
fatal_error (input_location, "cannot read PCH file: %m");
|
||||
|
||||
result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size,
|
||||
fileno (f), mmi.offset);
|
||||
+
|
||||
+ /* We could not mmap or otherwise allocate the required memory at the
|
||||
+ address needed. */
|
||||
if (result < 0)
|
||||
- fatal_error (input_location, "had to relocate PCH");
|
||||
+ {
|
||||
+ sorry_at (input_location, "PCH relocation is not yet supported");
|
||||
+ /* There is no point in continuing from here, we will only end up
|
||||
+ with a crashed (most likely hanging) compiler. */
|
||||
+ exit (-1);
|
||||
+ }
|
||||
+
|
||||
+ /* (0) We allocated memory, but did not mmap the file, so we need to read
|
||||
+ the data in manually. (>0) Otherwise the mmap succeed for the address
|
||||
+ we wanted. */
|
||||
if (result == 0)
|
||||
{
|
||||
if (fseek (f, mmi.offset, SEEK_SET) != 0
|
||||
@@ -632,6 +691,34 @@ gt_pch_restore (FILE *f)
|
||||
ggc_pch_read (f, mmi.preferred_base);
|
||||
|
||||
gt_pch_restore_stringpool ();
|
||||
@ -691,11 +693,15 @@ index b6abed1d9a2..7c998e95473 100644
|
||||
+ }
|
||||
+ else if (fseek (f, num_callbacks * sizeof (void *), SEEK_CUR) != 0)
|
||||
+ fatal_error (input_location, "cannot read PCH file: %m");
|
||||
+
|
||||
+ /* Barring corruption of the PCH file, the restored line table should be
|
||||
+ complete and usable. */
|
||||
+ line_table = new_line_table;
|
||||
}
|
||||
|
||||
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
|
||||
diff --git a/gcc/ggc.h b/gcc/ggc.h
|
||||
index 5e921d957fd..c005f7e0412 100644
|
||||
index 65f6cb4d19d..3339394b547 100644
|
||||
--- a/gcc/ggc.h
|
||||
+++ b/gcc/ggc.h
|
||||
@@ -46,6 +46,10 @@ typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
|
||||
@ -710,10 +716,10 @@ index 5e921d957fd..c005f7e0412 100644
|
||||
function. */
|
||||
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
|
||||
diff --git a/gcc/output.h b/gcc/output.h
|
||||
index 8f6f15308f4..4a23795bf7e 100644
|
||||
index 2bfeed93c56..7412407c2c0 100644
|
||||
--- a/gcc/output.h
|
||||
+++ b/gcc/output.h
|
||||
@@ -456,7 +456,7 @@ struct GTY(()) named_section {
|
||||
@@ -458,7 +458,7 @@ struct GTY(()) named_section {
|
||||
|
||||
/* A callback that writes the assembly code for switching to an unnamed
|
||||
section. The argument provides callback-specific data. */
|
||||
@ -722,7 +728,7 @@ index 8f6f15308f4..4a23795bf7e 100644
|
||||
|
||||
/* Information about a SECTION_UNNAMED section. */
|
||||
struct GTY(()) unnamed_section {
|
||||
@@ -464,8 +464,8 @@ struct GTY(()) unnamed_section {
|
||||
@@ -466,8 +466,8 @@ struct GTY(()) unnamed_section {
|
||||
|
||||
/* The callback used to switch to the section, and the data that
|
||||
should be passed to the callback. */
|
||||
@ -733,7 +739,7 @@ index 8f6f15308f4..4a23795bf7e 100644
|
||||
|
||||
/* The next entry in the chain of unnamed sections. */
|
||||
section *next;
|
||||
@@ -489,7 +489,7 @@ struct GTY(()) noswitch_section {
|
||||
@@ -491,7 +491,7 @@ struct GTY(()) noswitch_section {
|
||||
struct section_common common;
|
||||
|
||||
/* The callback used to assemble decls in this section. */
|
||||
@ -742,7 +748,7 @@ index 8f6f15308f4..4a23795bf7e 100644
|
||||
};
|
||||
|
||||
/* Information about a section, which may be named or unnamed. */
|
||||
@@ -524,8 +524,8 @@ extern GTY(()) section *bss_noswitch_sec
|
||||
@@ -526,8 +526,8 @@ extern GTY(()) section *bss_noswitch_section;
|
||||
extern GTY(()) section *in_section;
|
||||
extern GTY(()) bool in_cold_section_p;
|
||||
|
||||
@ -750,23 +756,23 @@ index 8f6f15308f4..4a23795bf7e 100644
|
||||
- const void *);
|
||||
+extern section *get_unnamed_section (unsigned int, void (*) (const char *),
|
||||
+ const char *);
|
||||
extern section *get_section (const char *, unsigned int, tree);
|
||||
extern section *get_section (const char *, unsigned int, tree,
|
||||
bool not_existing = false);
|
||||
extern section *get_named_section (tree, const char *, int);
|
||||
extern section *get_variable_section (tree, bool);
|
||||
@@ -546,7 +546,7 @@ extern section *get_cdtor_priority_secti
|
||||
@@ -549,7 +549,7 @@ extern section *get_cdtor_priority_section (int, bool);
|
||||
|
||||
extern bool unlikely_text_section_p (section *);
|
||||
extern void switch_to_section (section *);
|
||||
extern void switch_to_section (section *, tree = nullptr);
|
||||
-extern void output_section_asm_op (const void *);
|
||||
+extern void output_section_asm_op (const char *);
|
||||
|
||||
extern void record_tm_clone_pair (tree, tree);
|
||||
extern void finish_tm_clone_pairs (void);
|
||||
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
|
||||
index 8ab119dc9a2..91ae5237d7e 100644
|
||||
index c31b8ebf249..e2fd2e67440 100644
|
||||
--- a/gcc/tree-core.h
|
||||
+++ b/gcc/tree-core.h
|
||||
@@ -1961,7 +1961,7 @@ struct GTY(()) tree_function_decl {
|
||||
@@ -1927,7 +1927,7 @@ struct GTY(()) tree_function_decl {
|
||||
struct GTY(()) tree_translation_unit_decl {
|
||||
struct tree_decl_common common;
|
||||
/* Source language of this translation unit. Used for DWARF output. */
|
||||
@ -776,7 +782,7 @@ index 8ab119dc9a2..91ae5237d7e 100644
|
||||
/* TODO: Root of a partial DWARF tree for global types and decls. */
|
||||
};
|
||||
diff --git a/gcc/varasm.c b/gcc/varasm.c
|
||||
index 9315e2c6936..aff93ca5de9 100644
|
||||
index a7ef9b8d9fe..baf9f1ba0e4 100644
|
||||
--- a/gcc/varasm.c
|
||||
+++ b/gcc/varasm.c
|
||||
@@ -250,8 +250,8 @@ object_block_hasher::hash (object_block *old)
|
||||
@ -790,7 +796,7 @@ index 9315e2c6936..aff93ca5de9 100644
|
||||
{
|
||||
section *sect;
|
||||
|
||||
@@ -7778,9 +7778,9 @@ file_end_indicate_split_stack (void)
|
||||
@@ -7753,9 +7753,9 @@ file_end_indicate_split_stack (void)
|
||||
a get_unnamed_section callback. */
|
||||
|
||||
void
|
||||
@ -803,13 +809,13 @@ index 9315e2c6936..aff93ca5de9 100644
|
||||
|
||||
/* Emit assembly code to switch to section NEW_SECTION. Do nothing if
|
||||
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
|
||||
index 8b5e2f82982..bc40e333579 100644
|
||||
index 7d964172469..1073542681d 100644
|
||||
--- a/libcpp/include/line-map.h
|
||||
+++ b/libcpp/include/line-map.h
|
||||
@@ -758,11 +758,11 @@ struct GTY(()) line_maps {
|
||||
@@ -803,11 +803,11 @@ public:
|
||||
unsigned int max_column_hint;
|
||||
|
||||
/* If non-null, the allocator to use when resizing 'maps'. If null,
|
||||
xrealloc is used. */
|
||||
/* The allocator to use when resizing 'maps', defaults to xrealloc. */
|
||||
- line_map_realloc reallocator;
|
||||
+ line_map_realloc GTY((callback)) reallocator;
|
||||
|
||||
@ -820,25 +826,3 @@ index 8b5e2f82982..bc40e333579 100644
|
||||
|
||||
struct location_adhoc_data_map location_adhoc_data_map;
|
||||
|
||||
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
|
||||
index 6ba038881d6..1c2f7d564e7 100644
|
||||
--- a/gcc/config/avr/avr.c
|
||||
+++ b/gcc/config/avr/avr.c
|
||||
@@ -10089,7 +10089,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
|
||||
to track need of __do_copy_data. */
|
||||
|
||||
static void
|
||||
-avr_output_data_section_asm_op (const void *data)
|
||||
+avr_output_data_section_asm_op (const char *data)
|
||||
{
|
||||
avr_need_copy_data_p = true;
|
||||
|
||||
@@ -10102,7 +10102,7 @@ avr_output_data_section_asm_op (const void *data)
|
||||
to track need of __do_clear_bss. */
|
||||
|
||||
static void
|
||||
-avr_output_bss_section_asm_op (const void *data)
|
||||
+avr_output_bss_section_asm_op (const char *data)
|
||||
{
|
||||
avr_need_clear_bss_p = true;
|
||||
|
||||
@ -12,7 +12,7 @@ these notes only confer that there is no other annobin markup.
|
||||
|
||||
--- libgcc/Makefile.in 2018-01-13 13:05:41.000000000 +0100
|
||||
+++ libgcc/Makefile.in 2018-07-25 13:15:02.036226940 +0200
|
||||
@@ -244,6 +244,7 @@
|
||||
@@ -246,6 +246,7 @@ LIBGCC2_DEBUG_CFLAGS = -g
|
||||
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
|
||||
$(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
|
||||
-fbuilding-libgcc -fno-stack-protector \
|
||||
@ -20,12 +20,11 @@ these notes only confer that there is no other annobin markup.
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
|
||||
# Additional options to use when compiling libgcc2.a.
|
||||
@@ -297,6 +298,7 @@
|
||||
@@ -301,6 +302,7 @@ CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(IN
|
||||
$(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
|
||||
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
|
||||
-fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
|
||||
+ -Wa,--generate-missing-build-notes=yes \
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
$(INHIBIT_LIBC_CFLAGS) $(USE_TM_CLONE_REGISTRY)
|
||||
|
||||
# Extra flags to use when compiling crt{begin,end}.o.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
commit 1467907e405bc18fb6935b5d432cfa5f936e838d
|
||||
commit 36ffb2e0293d1bbef30e3553a431679de00549b9
|
||||
Author: Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
Date: Thu Mar 30 13:57:54 2023 +0200
|
||||
Date: Wed Feb 1 08:59:42 2023 +0100
|
||||
|
||||
IBM zSystems: Make stack_tie to work with hard frame pointer
|
||||
|
||||
@ -24,13 +24,11 @@ Date: Thu Mar 30 13:57:54 2023 +0200
|
||||
(s390_emit_prologue): Emit stack_tie when frame-pointer is needed.
|
||||
* config/s390/s390.md (stack_tie): Add a register operand and
|
||||
rename to ...
|
||||
(stack_tiesi, stack_tiedi): ... this.
|
||||
(@stack_tie<mode>): ... this.
|
||||
|
||||
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
|
||||
index 20424537558..952c708be7a 100644
|
||||
--- a/gcc/config/s390/s390.c
|
||||
+++ b/gcc/config/s390/s390.c
|
||||
@@ -10921,9 +10921,7 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
@@ -10898,9 +10898,7 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
int i;
|
||||
|
||||
addr = plus_constant (Pmode, base, offset);
|
||||
@ -41,7 +39,7 @@ index 20424537558..952c708be7a 100644
|
||||
|
||||
/* Special-case single register. */
|
||||
if (first == last)
|
||||
@@ -11035,8 +11033,7 @@ restore_gprs (rtx base, int offset, int first, int last)
|
||||
@@ -11012,8 +11010,7 @@ restore_gprs (rtx base, int offset, int first, int last)
|
||||
rtx addr, insn;
|
||||
|
||||
addr = plus_constant (Pmode, base, offset);
|
||||
@ -51,7 +49,7 @@ index 20424537558..952c708be7a 100644
|
||||
|
||||
/* Special-case single register. */
|
||||
if (first == last)
|
||||
@@ -11105,10 +11102,14 @@ s390_load_got (void)
|
||||
@@ -11062,10 +11059,11 @@ s390_load_got (void)
|
||||
static void
|
||||
s390_emit_stack_tie (void)
|
||||
{
|
||||
@ -60,17 +58,14 @@ index 20424537558..952c708be7a 100644
|
||||
-
|
||||
- emit_insn (gen_stack_tie (mem));
|
||||
+ rtx mem = gen_frame_mem (BLKmode, stack_pointer_rtx);
|
||||
+ rtx stack_reg = (frame_pointer_needed
|
||||
+ ? hard_frame_pointer_rtx
|
||||
+ : stack_pointer_rtx);
|
||||
+ if (TARGET_64BIT)
|
||||
+ emit_insn (gen_stack_tiedi (mem, stack_reg));
|
||||
+ if (frame_pointer_needed)
|
||||
+ emit_insn (gen_stack_tie (Pmode, mem, hard_frame_pointer_rtx));
|
||||
+ else
|
||||
+ emit_insn (gen_stack_tiesi (mem, stack_reg));
|
||||
+ emit_insn (gen_stack_tie (Pmode, mem, stack_pointer_rtx));
|
||||
}
|
||||
|
||||
/* Copy GPRS into FPR save slots. */
|
||||
@@ -11701,6 +11702,7 @@ s390_emit_prologue (void)
|
||||
@@ -11676,6 +11674,7 @@ s390_emit_prologue (void)
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
@ -79,28 +74,19 @@ index 20424537558..952c708be7a 100644
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
|
||||
index 7114609b676..f235df3a25d 100644
|
||||
index 4828aa08be6..00d39608e1d 100644
|
||||
--- a/gcc/config/s390/s390.md
|
||||
+++ b/gcc/config/s390/s390.md
|
||||
@@ -11366,10 +11366,19 @@
|
||||
@@ -11590,9 +11590,10 @@ (define_insn "stack_protect_test<mode>"
|
||||
; This is used in s390_emit_prologue in order to prevent insns
|
||||
; adjusting the stack pointer to be moved over insns writing stack
|
||||
; slots using a copy of the stack pointer in a different register.
|
||||
-(define_insn "stack_tie"
|
||||
+(define_insn "stack_tiesi"
|
||||
+(define_insn "@stack_tie<mode>"
|
||||
[(set (match_operand:BLK 0 "memory_operand" "+m")
|
||||
- (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
|
||||
+ (unspec:BLK [(match_dup 0)
|
||||
+ (match_operand:SI 1 "register_operand" "r")] UNSPEC_TIE))]
|
||||
+ "!TARGET_64BIT"
|
||||
+ (match_operand:P 1 "register_operand" "r")] UNSPEC_TIE))]
|
||||
""
|
||||
+ [(set_attr "length" "0")])
|
||||
+
|
||||
+(define_insn "stack_tiedi"
|
||||
+ [(set (match_operand:BLK 0 "memory_operand" "+m")
|
||||
+ (unspec:BLK [(match_dup 0)
|
||||
+ (match_operand:DI 1 "register_operand" "r")] UNSPEC_TIE))]
|
||||
+ "TARGET_64BIT"
|
||||
""
|
||||
[(set_attr "length" "0")])
|
||||
|
||||
@ -411,10 +411,10 @@ Date: Wed Feb 1 08:59:42 2023 +0100
|
||||
-
|
||||
- /* If f4 and f6 are call clobbered they are saved due to
|
||||
- stdargs and therefore are not frame related. */
|
||||
- if (!call_really_used_regs[i])
|
||||
- if (!call_used_regs[i])
|
||||
- RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
|
||||
else if (!TARGET_PACKED_STACK || call_used_regs[i])
|
||||
offset += 8;
|
||||
@@ -11491,11 +11603,10 @@ s390_emit_prologue (void)
|
||||
for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
|
||||
@ -463,9 +463,9 @@ index 57d1b95bd65..344aa551f44 100644
|
||||
--- a/gcc/config/s390/s390.opt
|
||||
+++ b/gcc/config/s390/s390.opt
|
||||
@@ -321,3 +321,7 @@ and the default behavior is to emit separate multiplication and addition
|
||||
-mindirect-branch* or -mfunction-return* options. The sections
|
||||
consist of an array of 32 bit elements. Each entry holds the offset
|
||||
from the entry to the patched location.
|
||||
instructions for long doubles in vector registers, because measurements show
|
||||
that this improves performance. This option allows overriding it for testing
|
||||
purposes.
|
||||
+
|
||||
+mpreserve-args
|
||||
+Target Var(s390_preserve_args_p) Init(0)
|
||||
197
SOURCES/gcc11-stringify-__VA_OPT__-2.patch
Normal file
197
SOURCES/gcc11-stringify-__VA_OPT__-2.patch
Normal file
@ -0,0 +1,197 @@
|
||||
libcpp: Fix up #__VA_OPT__ handling [PR103415]
|
||||
|
||||
stringify_arg uses pfile->u_buff to create the string literal.
|
||||
Unfortunately, paste_tokens -> _cpp_lex_direct -> lex_number -> _cpp_unaligned_alloc
|
||||
can in some cases use pfile->u_buff too, which results in losing everything
|
||||
prepared for the string literal until the token pasting.
|
||||
|
||||
The following patch fixes that by not calling paste_token during the
|
||||
construction of the string literal, but doing that before. All the tokens
|
||||
we are processing have been pushed into a token buffer using
|
||||
tokens_buff_add_token so it is fine if we paste some of them in that buffer
|
||||
(successful pasting creates a new token in that buffer), move following
|
||||
tokens if any to make it contiguous, pop (throw away) the extra tokens at
|
||||
the end and then do stringify_arg.
|
||||
|
||||
Also, paste_tokens now copies over PREV_WHITE and PREV_FALLTHROUGH flags
|
||||
from the original lhs token to the replacement token. Copying that way
|
||||
the PREV_WHITE flag is needed for the #__VA_OPT__ handling and copying
|
||||
over PREV_FALLTHROUGH fixes the new Wimplicit-fallthrough-38.c test.
|
||||
|
||||
2021-12-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR preprocessor/103415
|
||||
libcpp/
|
||||
* macro.c (stringify_arg): Remove va_opt argument and va_opt handling.
|
||||
(paste_tokens): On successful paste or in PREV_WHITE and
|
||||
PREV_FALLTHROUGH flags from the *plhs token to the new token.
|
||||
(replace_args): Adjust stringify_arg callers. For #__VA_OPT__,
|
||||
perform token pasting in a separate loop before stringify_arg call.
|
||||
gcc/testsuite/
|
||||
* c-c++-common/cpp/va-opt-8.c: New test.
|
||||
* c-c++-common/Wimplicit-fallthrough-38.c: New test.
|
||||
|
||||
--- libcpp/macro.c.jj
|
||||
+++ libcpp/macro.c
|
||||
@@ -295,7 +295,7 @@ static cpp_context *next_context (cpp_re
|
||||
static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
|
||||
static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
|
||||
static const cpp_token *stringify_arg (cpp_reader *, const cpp_token **,
|
||||
- unsigned int, bool);
|
||||
+ unsigned int);
|
||||
static void paste_all_tokens (cpp_reader *, const cpp_token *);
|
||||
static bool paste_tokens (cpp_reader *, location_t,
|
||||
const cpp_token **, const cpp_token *);
|
||||
@@ -826,8 +826,7 @@ cpp_quote_string (uchar *dest, const uch
|
||||
/* Convert a token sequence FIRST to FIRST+COUNT-1 to a single string token
|
||||
according to the rules of the ISO C #-operator. */
|
||||
static const cpp_token *
|
||||
-stringify_arg (cpp_reader *pfile, const cpp_token **first, unsigned int count,
|
||||
- bool va_opt)
|
||||
+stringify_arg (cpp_reader *pfile, const cpp_token **first, unsigned int count)
|
||||
{
|
||||
unsigned char *dest;
|
||||
unsigned int i, escape_it, backslash_count = 0;
|
||||
@@ -844,24 +843,6 @@ stringify_arg (cpp_reader *pfile, const
|
||||
{
|
||||
const cpp_token *token = first[i];
|
||||
|
||||
- if (va_opt && (token->flags & PASTE_LEFT))
|
||||
- {
|
||||
- location_t virt_loc = pfile->invocation_location;
|
||||
- const cpp_token *rhs;
|
||||
- do
|
||||
- {
|
||||
- if (i == count)
|
||||
- abort ();
|
||||
- rhs = first[++i];
|
||||
- if (!paste_tokens (pfile, virt_loc, &token, rhs))
|
||||
- {
|
||||
- --i;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- while (rhs->flags & PASTE_LEFT);
|
||||
- }
|
||||
-
|
||||
if (token->type == CPP_PADDING)
|
||||
{
|
||||
if (source == NULL
|
||||
@@ -995,6 +976,7 @@ paste_tokens (cpp_reader *pfile, locatio
|
||||
return false;
|
||||
}
|
||||
|
||||
+ lhs->flags |= (*plhs)->flags & (PREV_WHITE | PREV_FALLTHROUGH);
|
||||
*plhs = lhs;
|
||||
_cpp_pop_buffer (pfile);
|
||||
return true;
|
||||
@@ -1937,8 +1919,7 @@ replace_args (cpp_reader *pfile, cpp_has
|
||||
if (src->flags & STRINGIFY_ARG)
|
||||
{
|
||||
if (!arg->stringified)
|
||||
- arg->stringified = stringify_arg (pfile, arg->first, arg->count,
|
||||
- false);
|
||||
+ arg->stringified = stringify_arg (pfile, arg->first, arg->count);
|
||||
}
|
||||
else if ((src->flags & PASTE_LEFT)
|
||||
|| (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
|
||||
@@ -2065,11 +2046,46 @@ replace_args (cpp_reader *pfile, cpp_has
|
||||
{
|
||||
unsigned int count
|
||||
= start ? paste_flag - start : tokens_buff_count (buff);
|
||||
- const cpp_token *t
|
||||
- = stringify_arg (pfile,
|
||||
- start ? start + 1
|
||||
- : (const cpp_token **) (buff->base),
|
||||
- count, true);
|
||||
+ const cpp_token **first
|
||||
+ = start ? start + 1
|
||||
+ : (const cpp_token **) (buff->base);
|
||||
+ unsigned int i, j;
|
||||
+
|
||||
+ /* Paste any tokens that need to be pasted before calling
|
||||
+ stringify_arg, because stringify_arg uses pfile->u_buff
|
||||
+ which paste_tokens can use as well. */
|
||||
+ for (i = 0, j = 0; i < count; i++, j++)
|
||||
+ {
|
||||
+ const cpp_token *token = first[i];
|
||||
+
|
||||
+ if (token->flags & PASTE_LEFT)
|
||||
+ {
|
||||
+ location_t virt_loc = pfile->invocation_location;
|
||||
+ const cpp_token *rhs;
|
||||
+ do
|
||||
+ {
|
||||
+ if (i == count)
|
||||
+ abort ();
|
||||
+ rhs = first[++i];
|
||||
+ if (!paste_tokens (pfile, virt_loc, &token, rhs))
|
||||
+ {
|
||||
+ --i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ while (rhs->flags & PASTE_LEFT);
|
||||
+ }
|
||||
+
|
||||
+ first[j] = token;
|
||||
+ }
|
||||
+ if (j != i)
|
||||
+ {
|
||||
+ while (i-- != j)
|
||||
+ tokens_buff_remove_last_token (buff);
|
||||
+ count = j;
|
||||
+ }
|
||||
+
|
||||
+ const cpp_token *t = stringify_arg (pfile, first, count);
|
||||
while (count--)
|
||||
tokens_buff_remove_last_token (buff);
|
||||
if (src->flags & PASTE_LEFT)
|
||||
--- gcc/testsuite/c-c++-common/cpp/va-opt-8.c.jj
|
||||
+++ gcc/testsuite/c-c++-common/cpp/va-opt-8.c
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* PR preprocessor/103415 */
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-options "-std=gnu99" { target c } } */
|
||||
+/* { dg-options "-std=c++20" { target c++ } } */
|
||||
+
|
||||
+#define n(x, ...) = #__VA_OPT__(x##3)
|
||||
+#define o(x, ...) #__VA_OPT__(x##__VA_ARGS__##9)
|
||||
+const char *c n(1 2, 4);
|
||||
+const char *d = o(5 6, 7 8);
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ if (__builtin_strcmp (c, "1 23")
|
||||
+ || __builtin_strcmp (d, "5 67 89"))
|
||||
+ __builtin_abort ();
|
||||
+ return 0;
|
||||
+}
|
||||
--- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-38.c.jj
|
||||
+++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-38.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-Wimplicit-fallthrough=3" } */
|
||||
+
|
||||
+#define FOO \
|
||||
+int \
|
||||
+foo (int a) \
|
||||
+{ \
|
||||
+ switch (a) \
|
||||
+ { \
|
||||
+ case 1: \
|
||||
+ ++a; \
|
||||
+ /* FALLTHRU */ \
|
||||
+ case 2: \
|
||||
+ ++a; \
|
||||
+ /* FALLTHRU */ \
|
||||
+ ca##se 3: \
|
||||
+ ++a; \
|
||||
+ default: \
|
||||
+ break; \
|
||||
+ } \
|
||||
+ return a; \
|
||||
+}
|
||||
+
|
||||
+FOO
|
||||
307
SOURCES/gcc11-stringify-__VA_OPT__.patch
Normal file
307
SOURCES/gcc11-stringify-__VA_OPT__.patch
Normal file
@ -0,0 +1,307 @@
|
||||
c++: Add C++20 #__VA_OPT__ support
|
||||
|
||||
The following patch implements C++20 # __VA_OPT__ (...) support.
|
||||
Testcases cover what I came up with myself and what LLVM has for #__VA_OPT__
|
||||
in its testsuite and the string literals are identical between the two
|
||||
compilers on the va-opt-5.c testcase.
|
||||
|
||||
2021-08-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
libcpp/
|
||||
* macro.c (vaopt_state): Add m_stringify member.
|
||||
(vaopt_state::vaopt_state): Initialize it.
|
||||
(vaopt_state::update): Overwrite it.
|
||||
(vaopt_state::stringify): New method.
|
||||
(stringify_arg): Replace arg argument with first, count arguments
|
||||
and add va_opt argument. Use first instead of arg->first and
|
||||
count instead of arg->count, for va_opt add paste_tokens handling.
|
||||
(paste_tokens): Fix up len calculation. Don't spell rhs twice,
|
||||
instead use %.*s to supply lhs and rhs spelling lengths. Don't call
|
||||
_cpp_backup_tokens here.
|
||||
(paste_all_tokens): Call it here instead.
|
||||
(replace_args): Adjust stringify_arg caller. For vaopt_state::END
|
||||
if stringify is true handle __VA_OPT__ stringification.
|
||||
(create_iso_definition): Handle # __VA_OPT__ similarly to # macro_arg.
|
||||
gcc/testsuite/
|
||||
* c-c++-common/cpp/va-opt-5.c: New test.
|
||||
* c-c++-common/cpp/va-opt-6.c: New test.
|
||||
|
||||
--- libcpp/macro.c
|
||||
+++ libcpp/macro.c
|
||||
@@ -118,6 +118,7 @@ class vaopt_state {
|
||||
m_arg (arg),
|
||||
m_variadic (is_variadic),
|
||||
m_last_was_paste (false),
|
||||
+ m_stringify (false),
|
||||
m_state (0),
|
||||
m_paste_location (0),
|
||||
m_location (0),
|
||||
@@ -145,6 +146,7 @@ class vaopt_state {
|
||||
}
|
||||
++m_state;
|
||||
m_location = token->src_loc;
|
||||
+ m_stringify = (token->flags & STRINGIFY_ARG) != 0;
|
||||
return BEGIN;
|
||||
}
|
||||
else if (m_state == 1)
|
||||
@@ -234,6 +236,12 @@ class vaopt_state {
|
||||
return m_state == 0;
|
||||
}
|
||||
|
||||
+ /* Return true for # __VA_OPT__. */
|
||||
+ bool stringify () const
|
||||
+ {
|
||||
+ return m_stringify;
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
|
||||
/* The cpp_reader. */
|
||||
@@ -247,6 +255,8 @@ class vaopt_state {
|
||||
/* If true, the previous token was ##. This is used to detect when
|
||||
a paste occurs at the end of the sequence. */
|
||||
bool m_last_was_paste;
|
||||
+ /* True for #__VA_OPT__. */
|
||||
+ bool m_stringify;
|
||||
|
||||
/* The state variable:
|
||||
0 means not parsing
|
||||
@@ -284,7 +294,8 @@ static _cpp_buff *collect_args (cpp_read
|
||||
static cpp_context *next_context (cpp_reader *);
|
||||
static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
|
||||
static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
|
||||
-static const cpp_token *stringify_arg (cpp_reader *, macro_arg *);
|
||||
+static const cpp_token *stringify_arg (cpp_reader *, const cpp_token **,
|
||||
+ unsigned int, bool);
|
||||
static void paste_all_tokens (cpp_reader *, const cpp_token *);
|
||||
static bool paste_tokens (cpp_reader *, location_t,
|
||||
const cpp_token **, const cpp_token *);
|
||||
@@ -812,10 +823,11 @@ cpp_quote_string (uchar *dest, const uch
|
||||
return dest;
|
||||
}
|
||||
|
||||
-/* Convert a token sequence ARG to a single string token according to
|
||||
- the rules of the ISO C #-operator. */
|
||||
+/* Convert a token sequence FIRST to FIRST+COUNT-1 to a single string token
|
||||
+ according to the rules of the ISO C #-operator. */
|
||||
static const cpp_token *
|
||||
-stringify_arg (cpp_reader *pfile, macro_arg *arg)
|
||||
+stringify_arg (cpp_reader *pfile, const cpp_token **first, unsigned int count,
|
||||
+ bool va_opt)
|
||||
{
|
||||
unsigned char *dest;
|
||||
unsigned int i, escape_it, backslash_count = 0;
|
||||
@@ -828,9 +840,27 @@ stringify_arg (cpp_reader *pfile, macro_
|
||||
*dest++ = '"';
|
||||
|
||||
/* Loop, reading in the argument's tokens. */
|
||||
- for (i = 0; i < arg->count; i++)
|
||||
+ for (i = 0; i < count; i++)
|
||||
{
|
||||
- const cpp_token *token = arg->first[i];
|
||||
+ const cpp_token *token = first[i];
|
||||
+
|
||||
+ if (va_opt && (token->flags & PASTE_LEFT))
|
||||
+ {
|
||||
+ location_t virt_loc = pfile->invocation_location;
|
||||
+ const cpp_token *rhs;
|
||||
+ do
|
||||
+ {
|
||||
+ if (i == count)
|
||||
+ abort ();
|
||||
+ rhs = first[++i];
|
||||
+ if (!paste_tokens (pfile, virt_loc, &token, rhs))
|
||||
+ {
|
||||
+ --i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ while (rhs->flags & PASTE_LEFT);
|
||||
+ }
|
||||
|
||||
if (token->type == CPP_PADDING)
|
||||
{
|
||||
@@ -917,7 +947,7 @@ paste_tokens (cpp_reader *pfile, locatio
|
||||
cpp_token *lhs;
|
||||
unsigned int len;
|
||||
|
||||
- len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1;
|
||||
+ len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 2;
|
||||
buf = (unsigned char *) alloca (len);
|
||||
end = lhsend = cpp_spell_token (pfile, *plhs, buf, true);
|
||||
|
||||
@@ -943,8 +973,10 @@ paste_tokens (cpp_reader *pfile, locatio
|
||||
location_t saved_loc = lhs->src_loc;
|
||||
|
||||
_cpp_pop_buffer (pfile);
|
||||
- _cpp_backup_tokens (pfile, 1);
|
||||
- *lhsend = '\0';
|
||||
+
|
||||
+ unsigned char *rhsstart = lhsend;
|
||||
+ if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
|
||||
+ rhsstart++;
|
||||
|
||||
/* We have to remove the PASTE_LEFT flag from the old lhs, but
|
||||
we want to keep the new location. */
|
||||
@@ -956,8 +988,10 @@ paste_tokens (cpp_reader *pfile, locatio
|
||||
/* Mandatory error for all apart from assembler. */
|
||||
if (CPP_OPTION (pfile, lang) != CLK_ASM)
|
||||
cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
|
||||
- "pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
|
||||
- buf, cpp_token_as_text (pfile, rhs));
|
||||
+ "pasting \"%.*s\" and \"%.*s\" does not give "
|
||||
+ "a valid preprocessing token",
|
||||
+ (int) (lhsend - buf), buf,
|
||||
+ (int) (end - rhsstart), rhsstart);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1067,10 @@ paste_all_tokens (cpp_reader *pfile, con
|
||||
abort ();
|
||||
}
|
||||
if (!paste_tokens (pfile, virt_loc, &lhs, rhs))
|
||||
- break;
|
||||
+ {
|
||||
+ _cpp_backup_tokens (pfile, 1);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
while (rhs->flags & PASTE_LEFT);
|
||||
|
||||
@@ -1900,7 +1937,8 @@ replace_args (cpp_reader *pfile, cpp_has
|
||||
if (src->flags & STRINGIFY_ARG)
|
||||
{
|
||||
if (!arg->stringified)
|
||||
- arg->stringified = stringify_arg (pfile, arg);
|
||||
+ arg->stringified = stringify_arg (pfile, arg->first, arg->count,
|
||||
+ false);
|
||||
}
|
||||
else if ((src->flags & PASTE_LEFT)
|
||||
|| (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
|
||||
@@ -2023,6 +2061,24 @@ replace_args (cpp_reader *pfile, cpp_has
|
||||
paste_flag = tokens_buff_last_token_ptr (buff);
|
||||
}
|
||||
|
||||
+ if (vaopt_tracker.stringify ())
|
||||
+ {
|
||||
+ unsigned int count
|
||||
+ = start ? paste_flag - start : tokens_buff_count (buff);
|
||||
+ const cpp_token *t
|
||||
+ = stringify_arg (pfile,
|
||||
+ start ? start + 1
|
||||
+ : (const cpp_token **) (buff->base),
|
||||
+ count, true);
|
||||
+ while (count--)
|
||||
+ tokens_buff_remove_last_token (buff);
|
||||
+ if (src->flags & PASTE_LEFT)
|
||||
+ copy_paste_flag (pfile, &t, src);
|
||||
+ tokens_buff_add_token (buff, virt_locs,
|
||||
+ t, t->src_loc, t->src_loc,
|
||||
+ NULL, 0);
|
||||
+ continue;
|
||||
+ }
|
||||
if (start && paste_flag == start && (*start)->flags & PASTE_LEFT)
|
||||
/* If __VA_OPT__ expands to nothing (either because __VA_ARGS__
|
||||
is empty or because it is __VA_OPT__() ), drop PASTE_LEFT
|
||||
@@ -3584,7 +3640,10 @@ create_iso_definition (cpp_reader *pfile
|
||||
function-like macros when lexing the subsequent token. */
|
||||
if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like)
|
||||
{
|
||||
- if (token->type == CPP_MACRO_ARG)
|
||||
+ if (token->type == CPP_MACRO_ARG
|
||||
+ || (macro->variadic
|
||||
+ && token->type == CPP_NAME
|
||||
+ && token->val.node.node == pfile->spec_nodes.n__VA_OPT__))
|
||||
{
|
||||
if (token->flags & PREV_WHITE)
|
||||
token->flags |= SP_PREV_WHITE;
|
||||
--- gcc/testsuite/c-c++-common/cpp/va-opt-5.c
|
||||
+++ gcc/testsuite/c-c++-common/cpp/va-opt-5.c
|
||||
@@ -0,0 +1,67 @@
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-options "-std=gnu99" { target c } } */
|
||||
+/* { dg-options "-std=c++20" { target c++ } } */
|
||||
+
|
||||
+#define lparen (
|
||||
+#define a0 fooa0
|
||||
+#define a1 fooa1 a0
|
||||
+#define a2 fooa2 a1
|
||||
+#define a3 fooa3 a2
|
||||
+#define a() b lparen )
|
||||
+#define b() c lparen )
|
||||
+#define c() d lparen )
|
||||
+#define g h
|
||||
+#define i(j) j
|
||||
+#define f(...) #__VA_OPT__(g i(0))
|
||||
+#define k(x,...) # __VA_OPT__(x) #x #__VA_OPT__(__VA_ARGS__)
|
||||
+#define l(x,...) #__VA_OPT__(a1 x)
|
||||
+#define m(x,...) "a()" #__VA_OPT__(a3 __VA_ARGS__ x ## __VA_ARGS__ ## x ## c a3) "a()"
|
||||
+#define n(x,...) = #__VA_OPT__(a3 __VA_ARGS__ x ## __VA_ARGS__ ## x ## c a3) #x #__VA_OPT__(a0 __VA_ARGS__ x ## __VA_ARGS__ ## x ## c a0) ;
|
||||
+#define o(x, ...) #__VA_OPT__(x##x x##x)
|
||||
+#define p(x, ...) #__VA_OPT__(_Pragma ("foobar"))
|
||||
+#define q(...) #__VA_OPT__(/* foo */x/* bar */)
|
||||
+const char *v1 = f();
|
||||
+const char *v2 = f(123);
|
||||
+const char *v3 = k(1);
|
||||
+const char *v4 = k(1, 2, 3 );
|
||||
+const char *v5 = l(a());
|
||||
+const char *v6 = l(a1 a(), 1);
|
||||
+const char *v7 = m();
|
||||
+const char *v8 = m(,);
|
||||
+const char *v9 = m(,a3);
|
||||
+const char *v10 = m(a3,a(),a0);
|
||||
+const char *v11 n()
|
||||
+const char *v12 n(,)
|
||||
+const char *v13 n(,a0)
|
||||
+const char *v14 n(a0, a(),a0)
|
||||
+const char *v15 = o(, 0);
|
||||
+const char *v16 = p(0);
|
||||
+const char *v17 = p(0, 1);
|
||||
+const char *v18 = q();
|
||||
+const char *v19 = q(1);
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ if (__builtin_strcmp (v1, "")
|
||||
+ || __builtin_strcmp (v2, "g i(0)")
|
||||
+ || __builtin_strcmp (v3, "1")
|
||||
+ || __builtin_strcmp (v4, "112, 3")
|
||||
+ || __builtin_strcmp (v5, "")
|
||||
+ || __builtin_strcmp (v6, "a1 fooa1 fooa0 b ( )")
|
||||
+ || __builtin_strcmp (v7, "a()a()")
|
||||
+ || __builtin_strcmp (v8, "a()a()")
|
||||
+ || __builtin_strcmp (v9, "a()a3 fooa3 fooa2 fooa1 fooa0 a3c a3a()")
|
||||
+ || __builtin_strcmp (v10, "a()a3 b ( ),fooa0 a3a(),a0a3c a3a()")
|
||||
+ || __builtin_strcmp (v11, "")
|
||||
+ || __builtin_strcmp (v12, "")
|
||||
+ || __builtin_strcmp (v13, "a3 fooa0 a0c a3a0 fooa0 a0c a0")
|
||||
+ || __builtin_strcmp (v14, "a3 b ( ),fooa0 a0a(),a0a0c a3a0a0 b ( ),fooa0 a0a(),a0a0c a0")
|
||||
+ || __builtin_strcmp (v15, "")
|
||||
+ || __builtin_strcmp (v16, "")
|
||||
+ || __builtin_strcmp (v17, "_Pragma (\"foobar\")")
|
||||
+ || __builtin_strcmp (v18, "")
|
||||
+ || __builtin_strcmp (v19, "x"))
|
||||
+ __builtin_abort ();
|
||||
+ return 0;
|
||||
+}
|
||||
--- gcc/testsuite/c-c++-common/cpp/va-opt-6.c
|
||||
+++ gcc/testsuite/c-c++-common/cpp/va-opt-6.c
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* { dg-do preprocess } */
|
||||
+/* { dg-options "-std=gnu99" { target c } } */
|
||||
+/* { dg-options "-std=c++20" { target c++ } } */
|
||||
+
|
||||
+#define a ""
|
||||
+#define b(...) a ## #__VA_OPT__(1) /* { dg-error "pasting \"a\" and \"\"\"\" does not give a valid preprocessing token" } */
|
||||
+#define c(...) a ## #__VA_OPT__(1) /* { dg-error "pasting \"a\" and \"\"1\"\" does not give a valid preprocessing token" } */
|
||||
+#define d(...) #__VA_OPT__(1) ## !
|
||||
+#define e(...) #__VA_OPT__(1) ## !
|
||||
+#define f(...) #__VA_OPT__(. ## !)
|
||||
+#define g(...) #__VA_OPT__(. ## !)
|
||||
+b()
|
||||
+c(1)
|
||||
+d( ) /* { dg-error "pasting \"\"\"\" and \"!\" does not give a valid preprocessing token" } */
|
||||
+e( 1 ) /* { dg-error "pasting \"\"1\"\" and \"!\" does not give a valid preprocessing token" } */
|
||||
+f()
|
||||
+g(0) /* { dg-error "pasting \".\" and \"!\" does not give a valid preprocessing token" } */
|
||||
348
SOURCES/gcc11-testsuite-aarch64-add-fno-stack-protector.patch
Normal file
348
SOURCES/gcc11-testsuite-aarch64-add-fno-stack-protector.patch
Normal file
@ -0,0 +1,348 @@
|
||||
From 3439b79cb7f97464d65316a94d40d49505fb2150 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Polacek <polacek@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 15:34:24 -0500
|
||||
Subject: [PATCH] aarch64: add -fno-stack-protector to tests
|
||||
|
||||
These tests fail when the testsuite is executed with -fstack-protector-strong.
|
||||
To avoid this, this patch adds -fno-stack-protector to dg-options.
|
||||
|
||||
---
|
||||
gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-12.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-11.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-12.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-13.c | 4 ++--
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-14.c | 4 ++--
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-15.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-2.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-5.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-6.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-8.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/stack-check-prologue-9.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/sve/struct_vect_24.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_1.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_10.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_11.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_13.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_15.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_2.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_4.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_6.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_7.c | 2 +-
|
||||
gcc/testsuite/gcc.target/aarch64/test_frame_8.c | 2 +-
|
||||
30 files changed, 32 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c
|
||||
index 1e46755a39a..50d7d7a2d5d 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_2.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer -fno-stack-protector" } */
|
||||
|
||||
/* Check that we split unaligned LDP/STP into base and aligned offset. */
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-12.c b/gcc/testsuite/gcc.target/aarch64/stack-check-12.c
|
||||
index be5a57a9ec6..e1a4c67b041 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-12.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-12.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-asynchronous-unwind-tables -fno-unwind-tables" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
typedef unsigned __attribute__((mode(DI))) uint64_t;
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-11.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-11.c
|
||||
index 741f2f5fadc..d57aece05bb 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-11.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-11.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE (6 * 64 * 1024) + (1 * 32 * 1024)
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-12.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-12.c
|
||||
index ece68003ade..895d130e4fa 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-12.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-12.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
void
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-13.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-13.c
|
||||
index 0fc900c6943..1f1a6c497be 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-13.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-13.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
void h (void) __attribute__ ((noreturn));
|
||||
@@ -17,4 +17,4 @@ f (void)
|
||||
|
||||
/* SIZE is more than 1 guard-size, but only one 64KB page is used, expect only 1
|
||||
probe. Leaf function and omitting leaf pointers, tail call to noreturn which
|
||||
- may only omit an epilogue and not a prologue. Checking for LR saving. */
|
||||
\ No newline at end of file
|
||||
+ may only omit an epilogue and not a prologue. Checking for LR saving. */
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-14.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-14.c
|
||||
index ea733f861e7..facb3cb72a7 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-14.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-14.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
void h (void) __attribute__ ((noreturn));
|
||||
@@ -21,4 +21,4 @@ f (void)
|
||||
probe at 1024 and one implicit probe due to LR being saved. Leaf function
|
||||
and omitting leaf pointers, tail call to noreturn which may only omit an
|
||||
epilogue and not a prologue and control flow in between. Checking for
|
||||
- LR saving. */
|
||||
\ No newline at end of file
|
||||
+ LR saving. */
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-15.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-15.c
|
||||
index 63df4a5609a..f2ac60a6214 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-15.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-15.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fomit-frame-pointer -momit-leaf-frame-pointer -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
void g (volatile int *x) ;
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
|
||||
index f0ec1389771..1cf6fbbb085 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-17.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fno-stack-protector" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
void f(int, ...);
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
|
||||
index 6383bec5ebc..2e06346c158 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-18.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection -fomit-frame-pointer --param stack-clash-protection-guard-size=12 -fno-stack-protector" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
void f(int, ...);
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-2.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-2.c
|
||||
index 61c52a251a7..b37f62cad27 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-2.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE 2 * 1024
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-5.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-5.c
|
||||
index 2ee16350127..34a438671d0 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-5.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-5.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE 64 * 1024
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-6.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-6.c
|
||||
index 3c9b606cbe0..a4e34e2fe6a 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-6.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-6.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE 65 * 1024
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-8.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-8.c
|
||||
index 333f5fcc360..277dce4c71e 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-8.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-8.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE 128 * 1024
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-9.c b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-9.c
|
||||
index a3ff89b5581..a21305541c1 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-9.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/stack-check-prologue-9.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
|
||||
#define SIZE 6 * 64 * 1024
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/struct_vect_24.c b/gcc/testsuite/gcc.target/aarch64/sve/struct_vect_24.c
|
||||
index 68a9d5e3d2e..19be6de0c2e 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/sve/struct_vect_24.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sve/struct_vect_24.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
-/* { dg-options "-O3 -fopenmp-simd -fstack-clash-protection --param stack-clash-protection-guard-size=16" } */
|
||||
+/* { dg-options "-O3 -fopenmp-simd -fstack-clash-protection --param stack-clash-protection-guard-size=16 -fno-stack-protector" } */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
|
||||
index f906b073545..c9b8822b4b1 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* optimized code should use "str !" for stack adjustment. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
|
||||
index c54ab2d0ccb..fe5cbd9ed05 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
|
||||
@@ -7,7 +7,7 @@
|
||||
* Use a single stack adjustment, no writeback. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_11.c b/gcc/testsuite/gcc.target/aarch64/test_frame_11.c
|
||||
index f162cc091e0..11cf471168d 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_11.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_11.c
|
||||
@@ -5,7 +5,7 @@
|
||||
* optimized code should use "stp !" for stack adjustment. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 --save-temps" } */
|
||||
+/* { dg-options "-O2 --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_13.c b/gcc/testsuite/gcc.target/aarch64/test_frame_13.c
|
||||
index 74b3370fa46..ec56963c038 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_13.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_13.c
|
||||
@@ -5,7 +5,7 @@
|
||||
* Use a single stack adjustment, no writeback. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 --save-temps" } */
|
||||
+/* { dg-options "-O2 --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_15.c b/gcc/testsuite/gcc.target/aarch64/test_frame_15.c
|
||||
index bed6714b4fe..4247008de8e 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_15.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_15.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* Use a single stack adjustment, no writeback. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 --save-temps" } */
|
||||
+/* { dg-options "-O2 --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
|
||||
index 0d715314cb8..9c4243b6480 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* optimized code should use "stp !" for stack adjustment. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
|
||||
index b41229c42f4..8d0bed93e44 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* we can use "stp !" to optimize stack adjustment. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
|
||||
index 56259c945d2..2944a8bbe16 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* use a single stack adjustment, no writeback. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
|
||||
index 5702656a5da..ca371632d81 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* use a single stack adjustment, no writeback. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
|
||||
index 75a68b41e08..084e8fac373 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
|
||||
@@ -5,7 +5,7 @@
|
||||
* number of callee-saved reg == 1. */
|
||||
|
||||
/* { dg-do run } */
|
||||
-/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps -fno-stack-protector" } */
|
||||
|
||||
#include "test_frame_common.h"
|
||||
|
||||
|
||||
base-commit: 1bd15d87031e8bf8fe9585fbc166b315303f676c
|
||||
--
|
||||
2.43.0
|
||||
|
||||
134
SOURCES/gcc11-testsuite-fixes-2.patch
Normal file
134
SOURCES/gcc11-testsuite-fixes-2.patch
Normal file
@ -0,0 +1,134 @@
|
||||
commit 74833b3165865a9373506f447720cf20f29c20c8
|
||||
Author: Christophe Lyon <christophe.lyon@arm.com>
|
||||
Date: Tue Jan 17 13:10:10 2023 +0000
|
||||
|
||||
aarch64: add -fno-stack-protector to some tests [PR108411]
|
||||
|
||||
As discussed in the PR, these recently added tests fail when the
|
||||
testsuite is executed with -fstack-protector-strong. To avoid this,
|
||||
this patch adds -fno-stack-protector to dg-options.
|
||||
|
||||
PR target/108411
|
||||
gcc/testsuite
|
||||
* g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C: Add
|
||||
-fno-stack-protector.
|
||||
* g++.target/aarch64/bitfield-abi-warning-align16-O2.C: Likewise.
|
||||
* g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C: Likewise.
|
||||
* g++.target/aarch64/bitfield-abi-warning-align32-O2.C: Likewise.
|
||||
* g++.target/aarch64/bitfield-abi-warning-align8-O2.C: Likewise.
|
||||
* gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c: Likewise.
|
||||
* gcc.target/aarch64/bitfield-abi-warning-align16-O2.c: Likewise.
|
||||
* gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c: Likewise.
|
||||
* gcc.target/aarch64/bitfield-abi-warning-align32-O2.c: Likewise.
|
||||
* gcc.target/aarch64/bitfield-abi-warning-align8-O2.c: Likewise.
|
||||
|
||||
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
|
||||
index 443cd458b4c..52f9cdd1ee9 100644
|
||||
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
|
||||
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2-extra.C
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps -Wno-narrowing" } */
|
||||
|
||||
#define ALIGN 16
|
||||
//#define EXTRA
|
||||
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
|
||||
index 76a7e3d0ad4..9ff4e46645b 100644
|
||||
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
|
||||
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align16-O2.C
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps -Wno-narrowing" } */
|
||||
|
||||
#define ALIGN 16
|
||||
#define EXTRA
|
||||
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
|
||||
index 6f8f54f41ff..55dcbfe4b7c 100644
|
||||
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
|
||||
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2-extra.C
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps -Wno-narrowing" } */
|
||||
|
||||
#define ALIGN 32
|
||||
//#define EXTRA
|
||||
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
|
||||
index 6b8ad5fbea1..6bb8778ee90 100644
|
||||
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
|
||||
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align32-O2.C
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps -Wno-narrowing" } */
|
||||
|
||||
#define ALIGN 32
|
||||
#define EXTRA
|
||||
diff --git a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
|
||||
index b1764d97ea0..41bcc894a2b 100644
|
||||
--- a/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
|
||||
+++ b/gcc/testsuite/g++.target/aarch64/bitfield-abi-warning-align8-O2.C
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps -Wno-narrowing" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps -Wno-narrowing" } */
|
||||
|
||||
#define ALIGN 8
|
||||
#define EXTRA
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
|
||||
index f248a129509..3b2c932ac23 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2-extra.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps" } */
|
||||
|
||||
#define ALIGN 16
|
||||
//#define EXTRA
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
|
||||
index 22ee5ec4c92..ee5d6faa428 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align16-O2.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps" } */
|
||||
|
||||
#define ALIGN 16
|
||||
#define EXTRA
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
|
||||
index a8a50b35e8e..6d4a883a96e 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2-extra.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps" } */
|
||||
|
||||
#define ALIGN 32
|
||||
//#define EXTRA
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
|
||||
index e872de3dbe0..331daba354c 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align32-O2.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps" } */
|
||||
|
||||
#define ALIGN 32
|
||||
#define EXTRA
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
|
||||
index cb2a945a819..e6d45f5dd5c 100644
|
||||
--- a/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/bitfield-abi-warning-align8-O2.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
-/* { dg-options "-O2 -save-temps" } */
|
||||
+/* { dg-options "-O2 -fno-stack-protector -save-temps" } */
|
||||
|
||||
#define ALIGN 8
|
||||
#define EXTRA
|
||||
150
SOURCES/gcc11-testsuite-fixes-3.patch
Normal file
150
SOURCES/gcc11-testsuite-fixes-3.patch
Normal file
@ -0,0 +1,150 @@
|
||||
commit f1b1d515aa5836844cdb45e8bb2b941784f78fd2
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon Apr 22 18:00:06 2024 +0200
|
||||
|
||||
libstdc++: Workaround kernel-headers on s390x-linux
|
||||
|
||||
We see
|
||||
FAIL: 17_intro/headers/c++1998/all_attributes.cc (test for excess errors)
|
||||
FAIL: 17_intro/headers/c++2011/all_attributes.cc (test for excess errors)
|
||||
FAIL: 17_intro/headers/c++2014/all_attributes.cc (test for excess errors)
|
||||
FAIL: 17_intro/headers/c++2017/all_attributes.cc (test for excess errors)
|
||||
FAIL: 17_intro/headers/c++2020/all_attributes.cc (test for excess errors)
|
||||
FAIL: 17_intro/names.cc -std=gnu++17 (test for excess errors)
|
||||
on s390x-linux.
|
||||
The first 5 are due to kernel-headers not using uglified attribute names,
|
||||
where <asm/types.h> contains
|
||||
__attribute__((packed, aligned(4)))
|
||||
I've filed a downstream bugreport for this in
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=2276084
|
||||
(not really sure where to report kernel-headers issues upstream), while the
|
||||
last one is due to <sys/ucontext.h> from glibc containing:
|
||||
#ifdef __USE_MISC
|
||||
# define __ctx(fld) fld
|
||||
#else
|
||||
# define __ctx(fld) __ ## fld
|
||||
#endif
|
||||
...
|
||||
typedef union
|
||||
{
|
||||
double __ctx(d);
|
||||
float __ctx(f);
|
||||
} fpreg_t;
|
||||
and g++ predefining -D_GNU_SOURCE which implies define __USE_MISC.
|
||||
|
||||
The following patch adds a workaround for this on the libstdc++ testsuite
|
||||
side.
|
||||
|
||||
2024-04-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/17_intro/names.cc (d, f): Undefine on s390*-linux*.
|
||||
* testsuite/17_intro/headers/c++1998/all_attributes.cc (packed): Don't
|
||||
define on s390.
|
||||
* testsuite/17_intro/headers/c++2011/all_attributes.cc (packed):
|
||||
Likewise.
|
||||
* testsuite/17_intro/headers/c++2014/all_attributes.cc (packed):
|
||||
Likewise.
|
||||
* testsuite/17_intro/headers/c++2017/all_attributes.cc (packed):
|
||||
Likewise.
|
||||
* testsuite/17_intro/headers/c++2020/all_attributes.cc (packed):
|
||||
Likewise.
|
||||
|
||||
(cherry picked from commit cf5f7791056b3ed993bc8024be767a86157514a9)
|
||||
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
|
||||
index 74268b6a482..658063bd0a4 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
|
||||
@@ -29,7 +29,11 @@
|
||||
# define noreturn 1
|
||||
# define visibility 1
|
||||
#endif
|
||||
+#ifndef __s390__
|
||||
+// kernel-headers <asm/types.h> uses __attribute__((packed,aligned(4))) on
|
||||
+// S390.
|
||||
#define packed 1
|
||||
+#endif
|
||||
#define pure 1
|
||||
// glibc's sysdeps/unix/sysv/linux/arm/sys/ucontext.h uses this on ARM.
|
||||
#ifndef __arm__
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
|
||||
index 5d0c5fe8177..f1bcc1fbbc8 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
|
||||
@@ -29,7 +29,11 @@
|
||||
# define visibility 1
|
||||
#endif
|
||||
#define no_unique_address 1
|
||||
+#ifndef __s390__
|
||||
+// kernel-headers <asm/types.h> uses __attribute__((packed,aligned(4))) on
|
||||
+// S390.
|
||||
#define packed 1
|
||||
+#endif
|
||||
#define pure 1
|
||||
// glibc's sysdeps/unix/sysv/linux/arm/sys/ucontext.h uses this on ARM.
|
||||
#ifndef __arm__
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
|
||||
index 3cac2190ec7..48e7ef64afb 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
|
||||
@@ -29,7 +29,11 @@
|
||||
# define visibility 1
|
||||
#endif
|
||||
#define no_unique_address 1
|
||||
+#ifndef __s390__
|
||||
+// kernel-headers <asm/types.h> uses __attribute__((packed,aligned(4))) on
|
||||
+// S390.
|
||||
#define packed 1
|
||||
+#endif
|
||||
#define pure 1
|
||||
// glibc's sysdeps/unix/sysv/linux/arm/sys/ucontext.h uses this on ARM.
|
||||
#ifndef __arm__
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
|
||||
index f607532aa90..03e4e23c686 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
|
||||
@@ -28,7 +28,11 @@
|
||||
# define visibility 1
|
||||
#endif
|
||||
#define no_unique_address 1
|
||||
+#ifndef __s390__
|
||||
+// kernel-headers <asm/types.h> uses __attribute__((packed,aligned(4))) on
|
||||
+// S390.
|
||||
#define packed 1
|
||||
+#endif
|
||||
#define pure 1
|
||||
// glibc's sysdeps/unix/sysv/linux/arm/sys/ucontext.h uses this on ARM.
|
||||
#ifndef __arm__
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
|
||||
index 5732633c7e4..7375dc88bb1 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
|
||||
@@ -27,7 +27,11 @@
|
||||
# define cold 1
|
||||
# define visibility 1
|
||||
#endif
|
||||
+#ifndef __s390__
|
||||
+// kernel-headers <asm/types.h> uses __attribute__((packed,aligned(4))) on
|
||||
+// S390.
|
||||
#define packed 1
|
||||
+#endif
|
||||
#define pure 1
|
||||
// glibc's sysdeps/unix/sysv/linux/arm/sys/ucontext.h uses this on ARM.
|
||||
#ifndef __arm__
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
index eb4d064177c..864bc20f146 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
@@ -267,6 +267,12 @@
|
||||
#undef u
|
||||
#endif
|
||||
|
||||
+#if defined (__linux__) && defined (__s390__)
|
||||
+// <sys/ucontext.h> defines fpreg_t::d and fpreg_t::f
|
||||
+#undef d
|
||||
+#undef f
|
||||
+#endif
|
||||
+
|
||||
#if defined (__linux__) && defined (__sparc__)
|
||||
#undef y
|
||||
#endif
|
||||
38
SOURCES/gcc11-testsuite-fixes-4.patch
Normal file
38
SOURCES/gcc11-testsuite-fixes-4.patch
Normal file
@ -0,0 +1,38 @@
|
||||
commit 181f40f5cf8510a16191e4768dadbe2cb7a5c095
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Wed Jul 24 18:00:05 2024 +0200
|
||||
|
||||
testsuite: Fix up pr116034.c test for big/pdp endian [PR116061]
|
||||
|
||||
Didn't notice the memmove is into an int variable, so the test
|
||||
was still failing on big endian.
|
||||
|
||||
2024-07-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/116034
|
||||
PR testsuite/116061
|
||||
* gcc.dg/pr116034.c (g): Change type from int to unsigned short.
|
||||
(foo): Guard memmove call on __SIZEOF_SHORT__ == 2.
|
||||
|
||||
(cherry picked from commit 69e69847e21a8d951ab5f09fd3421449564dba31)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr116034.c b/gcc/testsuite/gcc.dg/pr116034.c
|
||||
index 9a31de03424..955b4c9e86b 100644
|
||||
--- a/gcc/testsuite/gcc.dg/pr116034.c
|
||||
+++ b/gcc/testsuite/gcc.dg/pr116034.c
|
||||
@@ -2,12 +2,13 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O1 -fno-strict-aliasing" } */
|
||||
|
||||
-int g;
|
||||
+unsigned short int g;
|
||||
|
||||
static inline int
|
||||
foo (_Complex unsigned short c)
|
||||
{
|
||||
- __builtin_memmove (&g, 1 + (char *) &c, 2);
|
||||
+ if (__SIZEOF_SHORT__ == 2)
|
||||
+ __builtin_memmove (&g, 1 + (char *) &c, 2);
|
||||
return g;
|
||||
}
|
||||
|
||||
22
SOURCES/gcc11-testsuite-fixes.patch
Normal file
22
SOURCES/gcc11-testsuite-fixes.patch
Normal file
@ -0,0 +1,22 @@
|
||||
diff --git a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
|
||||
index b0277b3f4d1..425daff317a 100644
|
||||
--- a/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
|
||||
+++ b/libstdc++-v3/testsuite/26_numerics/gcd/gcd_neg.cc
|
||||
@@ -53,3 +53,6 @@ test01()
|
||||
// { dg-prune-output "does not have integral type" }
|
||||
// { dg-prune-output "non-integral type" }
|
||||
// { dg-prune-output "invalid specialization" }
|
||||
+// These show up with -Wp,-D_GLIBCXX_ASSERTIONS.
|
||||
+// { dg-prune-output "invalid operands" }
|
||||
+// { dg-prune-output "wrong type argument" }
|
||||
diff --git a/libstdc++-v3/testsuite/26_numerics/lcm/lcm_neg.cc b/libstdc++-v3/testsuite/26_numerics/lcm/lcm_neg.cc
|
||||
index 8cabfe2ea2f..a14d373c461 100644
|
||||
--- a/libstdc++-v3/testsuite/26_numerics/lcm/lcm_neg.cc
|
||||
+++ b/libstdc++-v3/testsuite/26_numerics/lcm/lcm_neg.cc
|
||||
@@ -53,3 +53,6 @@ test01()
|
||||
// { dg-prune-output "does not have integral type" }
|
||||
// { dg-prune-output "non-integral type" }
|
||||
// { dg-prune-output "invalid specialization" }
|
||||
+// These show up with -Wp,-D_GLIBCXX_ASSERTIONS.
|
||||
+// { dg-prune-output "invalid operands" }
|
||||
+// { dg-prune-output "wrong type argument" }
|
||||
@ -1,59 +0,0 @@
|
||||
2024-04-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-vect-stmts.c (vectorizable_call): For j == 0 use
|
||||
vargs.safe_grow (nargs) rather than vargs.create (nargs), for j != 0
|
||||
remove vargs.truncate (0). Instead of vargs.quick_push store into
|
||||
vargs[i]. Use vargs[i] instead of gimple_call_arg (new_stmt, i)
|
||||
if j != 0.
|
||||
|
||||
* gcc.c-torture/compile/20240418.c: New test.
|
||||
|
||||
--- gcc/tree-vect-stmts.c.jj 2021-04-22 15:48:48.228178359 +0200
|
||||
+++ gcc/tree-vect-stmts.c 2024-04-18 13:21:46.104061529 +0200
|
||||
@@ -3242,9 +3242,7 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
{
|
||||
/* Build argument list for the vectorized call. */
|
||||
if (j == 0)
|
||||
- vargs.create (nargs);
|
||||
- else
|
||||
- vargs.truncate (0);
|
||||
+ vargs.safe_grow (nargs);
|
||||
|
||||
if (slp_node)
|
||||
{
|
||||
@@ -3252,7 +3250,7 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
vec<tree> vec_oprnds0;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
- vargs.quick_push (gimple_call_arg (stmt, i));
|
||||
+ vargs[i] = gimple_call_arg (stmt, i);
|
||||
vect_get_slp_defs (vargs, slp_node, &vec_defs);
|
||||
vec_oprnds0 = vec_defs[0];
|
||||
|
||||
@@ -3314,13 +3312,10 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
vec_oprnd0
|
||||
= vect_get_vec_def_for_operand (op, stmt);
|
||||
else
|
||||
- {
|
||||
- vec_oprnd0 = gimple_call_arg (new_stmt, i);
|
||||
- vec_oprnd0
|
||||
- = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
|
||||
- }
|
||||
+ vec_oprnd0
|
||||
+ = vect_get_vec_def_for_stmt_copy (dt[i], vargs[i]);
|
||||
|
||||
- vargs.quick_push (vec_oprnd0);
|
||||
+ vargs[i] = vec_oprnd0;
|
||||
}
|
||||
|
||||
if (gimple_call_internal_p (stmt)
|
||||
--- gcc/testsuite/gcc.c-torture/compile/20240418.c.jj 2024-04-18 13:24:10.180065661 +0200
|
||||
+++ gcc/testsuite/gcc.c-torture/compile/20240418.c 2024-04-18 13:19:12.166194018 +0200
|
||||
@@ -0,0 +1,7 @@
|
||||
+void
|
||||
+foo (signed char *p, unsigned long long *q)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i <= 64; i++)
|
||||
+ *p++ = __builtin_popcountll (*q++);
|
||||
+}
|
||||
@ -1,105 +0,0 @@
|
||||
From 9c108bb84d3a2447dac730c455df658be0a2c751 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Sandiford <richard.sandiford@arm.com>
|
||||
Date: Tue, 17 Aug 2021 15:15:27 +0100
|
||||
Subject: [PATCH] aarch64: Add -mtune=neoverse-512tvb
|
||||
To: gcc-patches@gcc.gnu.org
|
||||
|
||||
This patch adds an option to tune for Neoverse cores that have
|
||||
a total vector bandwidth of 512 bits (4x128 for Advanced SIMD
|
||||
and a vector-length-dependent equivalent for SVE). This is intended
|
||||
to be a compromise between tuning aggressively for a single core like
|
||||
Neoverse V1 (which can be too narrow) and tuning for AArch64 cores
|
||||
in general (which can be too wide).
|
||||
|
||||
-mcpu=neoverse-512tvb is equivalent to -mcpu=neoverse-v1
|
||||
-mtune=neoverse-512tvb.
|
||||
|
||||
gcc/
|
||||
* doc/invoke.texi: Document -mtune=neoverse-512tvb and
|
||||
-mcpu=neoverse-512tvb.
|
||||
* config/aarch64/aarch64-cores.def (neoverse-512tvb): New entry.
|
||||
* config/aarch64/aarch64-tune.md: Regenerate.
|
||||
|
||||
(cherry picked from commit 048039c49b96875144f67e7789fdea54abf7710b)
|
||||
---
|
||||
gcc/config/aarch64/aarch64-cores.def | 1 +
|
||||
gcc/config/aarch64/aarch64-tune.md | 2 +-
|
||||
gcc/doc/invoke.texi | 25 ++++++++++++++++++++++---
|
||||
3 files changed, 24 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
|
||||
index dfb839c01cc..f348d31e22e 100644
|
||||
--- a/gcc/config/aarch64/aarch64-cores.def
|
||||
+++ b/gcc/config/aarch64/aarch64-cores.def
|
||||
@@ -99,6 +99,7 @@ AARCH64_CORE("saphira", saphira, falkor, 8_3A, AARCH64_FL_FOR_ARCH8_3
|
||||
/* ARM ('A') cores. */
|
||||
AARCH64_CORE("zeus", zeus, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1)
|
||||
AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1)
|
||||
+AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, INVALID_IMP, INVALID_CORE, -1)
|
||||
|
||||
/* Armv8.5-A Architecture Processors. */
|
||||
AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversen2, 0x41, 0xd49, -1)
|
||||
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
|
||||
index 2d7c9aa4740..09b76480f0b 100644
|
||||
--- a/gcc/config/aarch64/aarch64-tune.md
|
||||
+++ b/gcc/config/aarch64/aarch64-tune.md
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- buffer-read-only: t -*-
|
||||
;; Generated automatically by gentune.sh from aarch64-cores.def
|
||||
(define_attr "tune"
|
||||
- "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,xgene1,falkor,qdf24xx,exynosm1,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,ares,neoversen1,saphira,zeus,neoversev1,neoversen2,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55"
|
||||
+ "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,xgene1,falkor,qdf24xx,exynosm1,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,ares,neoversen1,saphira,zeus,neoversev1,neoverse512tvb,neoversen2,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55"
|
||||
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 78ca7738df2..68fda03281a 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -14772,9 +14772,9 @@ performance of the code. Permissible values for this option are:
|
||||
@samp{generic}, @samp{cortex-a35}, @samp{cortex-a53}, @samp{cortex-a55},
|
||||
@samp{cortex-a57}, @samp{cortex-a72}, @samp{cortex-a73}, @samp{cortex-a75},
|
||||
@samp{cortex-a76}, @samp{ares}, @samp{neoverse-n1}, @samp{neoverse-n2},
|
||||
-@samp{neoverse-v1}, @samp{zeus}, @samp{exynos-m1}, @samp{falkor},
|
||||
-@samp{qdf24xx}, @samp{saphira}, @samp{xgene1}, @samp{vulcan}, @samp{thunderx},
|
||||
-@samp{thunderxt88}, @samp{thunderxt88p1}, @samp{thunderxt81},
|
||||
+@samp{neoverse-v1}, @samp{zeus}, @samp{neoverse-512tvb}, @samp{exynos-m1},
|
||||
+@samp{falkor}, @samp{qdf24xx}, @samp{saphira}, @samp{xgene1}, @samp{vulcan},
|
||||
+@samp{thunderx}, @samp{thunderxt88}, @samp{thunderxt88p1}, @samp{thunderxt81},
|
||||
@samp{thunderxt83}, @samp{thunderx2t99}, @samp{cortex-a57.cortex-a53},
|
||||
@samp{cortex-a72.cortex-a53}, @samp{cortex-a73.cortex-a35},
|
||||
@samp{cortex-a73.cortex-a53}, @samp{cortex-a75.cortex-a55},
|
||||
@@ -14785,6 +14785,15 @@ The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
|
||||
@samp{cortex-a75.cortex-a55} specify that GCC should tune for a
|
||||
big.LITTLE system.
|
||||
|
||||
+The value @samp{neoverse-512tvb} specifies that GCC should tune
|
||||
+for Neoverse cores that (a) implement SVE and (b) have a total vector
|
||||
+bandwidth of 512 bits per cycle. In other words, the option tells GCC to
|
||||
+tune for Neoverse cores that can execute 4 128-bit Advanced SIMD arithmetic
|
||||
+instructions a cycle and that can execute an equivalent number of SVE
|
||||
+arithmetic instructions per cycle (2 for 256-bit SVE, 4 for 128-bit SVE).
|
||||
+This is more general than tuning for a specific core like Neoverse V1
|
||||
+but is more specific than the default tuning described below.
|
||||
+
|
||||
Additionally on native AArch64 GNU/Linux systems the value
|
||||
@samp{native} tunes performance to the host system. This option has no effect
|
||||
if the compiler is unable to recognize the processor of the host system.
|
||||
@@ -14814,6 +14823,16 @@ by @option{-mtune}). Where this option is used in conjunction
|
||||
with @option{-march} or @option{-mtune}, those options take precedence
|
||||
over the appropriate part of this option.
|
||||
|
||||
+@option{-mcpu=neoverse-512tvb} is special in that it does not refer
|
||||
+to a specific core, but instead refers to all Neoverse cores that
|
||||
+(a) implement SVE and (b) have a total vector bandwidth of 512 bits
|
||||
+a cycle. Unless overridden by @option{-march},
|
||||
+@option{-mcpu=neoverse-512tvb} generates code that can run on a
|
||||
+Neoverse V1 core, since Neoverse V1 is the first Neoverse core with
|
||||
+these properties. Unless overridden by @option{-mtune},
|
||||
+@option{-mcpu=neoverse-512tvb} tunes code in the same way as for
|
||||
+@option{-mtune=neoverse-512tvb}.
|
||||
+
|
||||
@item -moverride=@var{string}
|
||||
@opindex moverride
|
||||
Override tuning decisions made by the back-end in response to a
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@ -1,294 +0,0 @@
|
||||
From 88bf1c3910e4cf97dcb85c6d32291c23e572a516 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 27 Oct 2021 07:48:54 -0700
|
||||
Subject: [PATCH 1/4] x86: Add -mharden-sls=[none|all|return|indirect-branch]
|
||||
|
||||
Add -mharden-sls= to mitigate against straight line speculation (SLS)
|
||||
for function return and indirect branch by adding an INT3 instruction
|
||||
after function return and indirect branch.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386-opts.h (harden_sls): New enum.
|
||||
* config/i386/i386.c (output_indirect_thunk): Mitigate against
|
||||
SLS for function return.
|
||||
(ix86_output_function_return): Likewise.
|
||||
(ix86_output_jmp_thunk_or_indirect): Mitigate against indirect
|
||||
branch.
|
||||
(ix86_output_indirect_jmp): Likewise.
|
||||
(ix86_output_call_insn): Likewise.
|
||||
* config/i386/i386.opt: Add -mharden-sls=.
|
||||
* doc/invoke.texi: Document -mharden-sls=.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/102952
|
||||
* gcc.target/i386/harden-sls-1.c: New test.
|
||||
* gcc.target/i386/harden-sls-2.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-3.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-4.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-5.c: Likewise.
|
||||
|
||||
(cherry picked from commit 53a643f8568067d7700a9f2facc8ba39974973d3)
|
||||
---
|
||||
gcc/config/i386/i386-opts.h | 7 +++++++
|
||||
gcc/config/i386/i386.c | 22 +++++++++++++++-----
|
||||
gcc/config/i386/i386.opt | 20 ++++++++++++++++++
|
||||
gcc/doc/invoke.texi | 10 ++++++++-
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-1.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-2.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-3.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-4.c | 16 ++++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-5.c | 17 +++++++++++++++
|
||||
9 files changed, 128 insertions(+), 6 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
|
||||
index 46366cbfa72..34718b6d52c 100644
|
||||
--- a/gcc/config/i386/i386-opts.h
|
||||
+++ b/gcc/config/i386/i386-opts.h
|
||||
@@ -119,4 +119,11 @@ enum indirect_branch {
|
||||
indirect_branch_thunk_extern
|
||||
};
|
||||
|
||||
+enum harden_sls {
|
||||
+ harden_sls_none = 0,
|
||||
+ harden_sls_return = 1 << 0,
|
||||
+ harden_sls_indirect_branch = 1 << 1,
|
||||
+ harden_sls_all = harden_sls_return | harden_sls_indirect_branch
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 31502774ef3..eb9303f8742 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -10977,6 +10977,9 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
|
||||
fputs ("\tbnd ret\n", asm_out_file);
|
||||
else
|
||||
fputs ("\tret\n", asm_out_file);
|
||||
+
|
||||
+ if ((ix86_harden_sls & harden_sls_return))
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
|
||||
/* Output a funtion with a call and return thunk for indirect branch.
|
||||
@@ -28728,6 +28731,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
fprintf (asm_out_file, "\tjmp\t");
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
+ if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
@@ -28973,10 +28978,10 @@ ix86_output_indirect_jmp (rtx call_op)
|
||||
gcc_unreachable ();
|
||||
|
||||
ix86_output_indirect_branch (call_op, "%0", true);
|
||||
- return "";
|
||||
}
|
||||
else
|
||||
- return "%!jmp\t%A0";
|
||||
+ output_asm_insn ("%!jmp\t%A0", &call_op);
|
||||
+ return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output function return. CALL_OP is the jump target. Add a REP
|
||||
@@ -29018,9 +29023,11 @@ ix86_output_function_return (bool long_p)
|
||||
}
|
||||
|
||||
if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))
|
||||
- return "%!ret";
|
||||
+ output_asm_insn ("%!ret", NULL);
|
||||
+ else
|
||||
+ output_asm_insn ("rep%; ret", NULL);
|
||||
|
||||
- return "rep%; ret";
|
||||
+ return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output indirect function return. RET_OP is the function return
|
||||
@@ -29158,7 +29165,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
|
||||
if (output_indirect_p && !direct_p)
|
||||
ix86_output_indirect_branch (call_op, xasm, true);
|
||||
else
|
||||
- output_asm_insn (xasm, &call_op);
|
||||
+ {
|
||||
+ output_asm_insn (xasm, &call_op);
|
||||
+ if (!direct_p
|
||||
+ && (ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ return "int3";
|
||||
+ }
|
||||
return "";
|
||||
}
|
||||
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index d9bd909a885..3ae48609e25 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1055,3 +1055,23 @@ Support MOVDIRI built-in functions and code generation.
|
||||
mmovdir64b
|
||||
Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save
|
||||
Support MOVDIR64B built-in functions and code generation.
|
||||
+
|
||||
+mharden-sls=
|
||||
+Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none)
|
||||
+Generate code to mitigate against straight line speculation.
|
||||
+
|
||||
+Enum
|
||||
+Name(harden_sls) Type(enum harden_sls)
|
||||
+Known choices for mitigation against straight line speculation with -mharden-sls=:
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(none) Value(harden_sls_none)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(return) Value(harden_sls_return)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(all) Value(harden_sls_all)
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 78ca7738df2..1e20efd6969 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -1284,7 +1284,7 @@ See RS/6000 and PowerPC Options.
|
||||
-mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
|
||||
-mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
|
||||
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
|
||||
--mindirect-branch-register}
|
||||
+-mindirect-branch-register -mharden-sls=@var{choice}}
|
||||
|
||||
@emph{x86 Windows Options}
|
||||
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
|
||||
@@ -28036,6 +28036,14 @@ not be reachable in the large code model.
|
||||
@opindex -mindirect-branch-register
|
||||
Force indirect call and jump via register.
|
||||
|
||||
+@item -mharden-sls=@var{choice}
|
||||
+@opindex mharden-sls
|
||||
+Generate code to mitigate against straight line speculation (SLS) with
|
||||
+@var{choice}. The default is @samp{none} which disables all SLS
|
||||
+hardening. @samp{return} enables SLS hardening for function return.
|
||||
+@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
+@samp{all} enables all SLS hardening.
|
||||
+
|
||||
@end table
|
||||
|
||||
These @samp{-m} switches are supported in addition to the above
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..6f70dc94a23
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void foo (void);
|
||||
+
|
||||
+void
|
||||
+bar (void)
|
||||
+{
|
||||
+ foo ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */
|
||||
+/* { dg-final { scan-assembler-not {int3} } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
new file mode 100644
|
||||
index 00000000000..a7c59078d03
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
new file mode 100644
|
||||
index 00000000000..1a6056b6d7b
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 2 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
new file mode 100644
|
||||
index 00000000000..f70dd1379d3
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
@@ -0,0 +1,16 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" { target { ! x32 } } } } */
|
||||
+/* { dg-final { scan-assembler "movl\[ \t\]+fptr\\(%rip\\), %eax" { target x32 } } } */
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rax" { target x32 } } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-5.c b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
new file mode 100644
|
||||
index 00000000000..613c44c6f82
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -mharden-sls=return" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+typedef void (*dispatch_t)(long offset);
|
||||
+
|
||||
+dispatch_t dispatch;
|
||||
+
|
||||
+int
|
||||
+male_indirect_jump (long offset)
|
||||
+{
|
||||
+ dispatch(offset);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "ret" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
From 0df8313a0a5d8533f2487e21d7b42e9adee28f18 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 27 Oct 2021 06:27:15 -0700
|
||||
Subject: [PATCH 2/4] x86: Add -mindirect-branch-cs-prefix
|
||||
|
||||
Add -mindirect-branch-cs-prefix to add CS prefix to call and jmp to
|
||||
indirect thunk with branch target in r8-r15 registers so that the call
|
||||
and jmp instruction length is 6 bytes to allow them to be replaced with
|
||||
"lfence; call *%r8-r15" or "lfence; jmp *%r8-r15" at run-time.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386.c (ix86_output_jmp_thunk_or_indirect): Emit
|
||||
CS prefix for -mindirect-branch-cs-prefix.
|
||||
(ix86_output_indirect_branch_via_reg): Likewise.
|
||||
* config/i386/i386.opt: Add -mindirect-branch-cs-prefix.
|
||||
* doc/invoke.texi: Document -mindirect-branch-cs-prefix.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/102952
|
||||
* gcc.target/i386/indirect-thunk-cs-prefix-1.c: New test.
|
||||
* gcc.target/i386/indirect-thunk-cs-prefix-2.c: Likewise.
|
||||
|
||||
(cherry picked from commit 2196a681d7810ad8b227bf983f38ba716620545e)
|
||||
---
|
||||
gcc/config/i386/i386.c | 14 ++++++++++++--
|
||||
gcc/config/i386/i386.opt | 4 ++++
|
||||
gcc/doc/invoke.texi | 10 +++++++++-
|
||||
.../gcc.target/i386/indirect-thunk-cs-prefix-1.c | 14 ++++++++++++++
|
||||
.../gcc.target/i386/indirect-thunk-cs-prefix-2.c | 15 +++++++++++++++
|
||||
5 files changed, 54 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index eb9303f8742..8442dd0daea 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -28728,7 +28728,12 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t");
|
||||
else
|
||||
- fprintf (asm_out_file, "\tjmp\t");
|
||||
+ {
|
||||
+ if (REX_INT_REGNO_P (regno)
|
||||
+ && ix86_indirect_branch_cs_prefix)
|
||||
+ fprintf (asm_out_file, "\tcs\n");
|
||||
+ fprintf (asm_out_file, "\tjmp\t");
|
||||
+ }
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
@@ -28787,7 +28792,12 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd call\t");
|
||||
else
|
||||
- fprintf (asm_out_file, "\tcall\t");
|
||||
+ {
|
||||
+ if (REX_INT_REGNO_P (regno)
|
||||
+ && ix86_indirect_branch_cs_prefix)
|
||||
+ fprintf (asm_out_file, "\tcs\n");
|
||||
+ fprintf (asm_out_file, "\tcall\t");
|
||||
+ }
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
return;
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index 3ae48609e25..9f67ef558dc 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1044,6 +1044,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)
|
||||
EnumValue
|
||||
Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
|
||||
|
||||
+mindirect-branch-cs-prefix
|
||||
+Target Var(ix86_indirect_branch_cs_prefix) Init(0)
|
||||
+Add CS prefix to call and jmp to indirect thunk with branch target in r8-r15 registers.
|
||||
+
|
||||
mindirect-branch-register
|
||||
Target Report Var(ix86_indirect_branch_register) Init(0)
|
||||
Force indirect call and jump via register.
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 1e20efd6969..605cd4b93f1 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -1284,7 +1284,8 @@ See RS/6000 and PowerPC Options.
|
||||
-mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
|
||||
-mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
|
||||
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
|
||||
--mindirect-branch-register -mharden-sls=@var{choice}}
|
||||
+-mindirect-branch-register -mharden-sls=@var{choice} @gol
|
||||
+-mindirect-branch-cs-prefix}
|
||||
|
||||
@emph{x86 Windows Options}
|
||||
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
|
||||
@@ -28044,6 +28045,13 @@ hardening. @samp{return} enables SLS hardening for function return.
|
||||
@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
@samp{all} enables all SLS hardening.
|
||||
|
||||
+@item -mindirect-branch-cs-prefix
|
||||
+@opindex mindirect-branch-cs-prefix
|
||||
+Add CS prefix to call and jmp to indirect thunk with branch target in
|
||||
+r8-r15 registers so that the call and jmp instruction length is 6 bytes
|
||||
+to allow them to be replaced with @samp{lfence; call *%r8-r15} or
|
||||
+@samp{lfence; jmp *%r8-r15} at run-time.
|
||||
+
|
||||
@end table
|
||||
|
||||
These @samp{-m} switches are supported in addition to the above
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..db2f3416823
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "jmp\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "\tcs" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
new file mode 100644
|
||||
index 00000000000..adfc39a49d4
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*bar) (void);
|
||||
+
|
||||
+int
|
||||
+foo (void)
|
||||
+{
|
||||
+ bar ();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "call\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "\tcs" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
||||
@ -1,108 +0,0 @@
|
||||
From 621de498ee19e1f2642eebde707430254c0459c0 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 5 Jan 2022 16:33:16 -0800
|
||||
Subject: [PATCH 3/4] x86: Rename -harden-sls=indirect-branch to
|
||||
-harden-sls=indirect-jmp
|
||||
|
||||
Indirect branch also includes indirect call instructions. Rename
|
||||
-harden-sls=indirect-branch to -harden-sls=indirect-jmp to match its
|
||||
intended behavior.
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386-opts.h (harden_sls): Replace
|
||||
harden_sls_indirect_branch with harden_sls_indirect_jmp.
|
||||
* config/i386/i386.c (ix86_output_jmp_thunk_or_indirect):
|
||||
Likewise.
|
||||
(ix86_output_indirect_jmp): Likewise.
|
||||
(ix86_output_call_insn): Likewise.
|
||||
* config/i386/i386.opt: Replace indirect-branch with
|
||||
indirect-jmp. Replace harden_sls_indirect_branch with
|
||||
harden_sls_indirect_jmp.
|
||||
* doc/invoke.texi (-harden-sls=): Replace indirect-branch with
|
||||
indirect-jmp.
|
||||
|
||||
(cherry picked from commit ed8060950c64f2e449aaf90e438aa26d0d9d0b31)
|
||||
---
|
||||
gcc/config/i386/i386-opts.h | 4 ++--
|
||||
gcc/config/i386/i386.c | 6 +++---
|
||||
gcc/config/i386/i386.opt | 2 +-
|
||||
gcc/doc/invoke.texi | 4 ++--
|
||||
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
|
||||
index 34718b6d52c..47facc254cd 100644
|
||||
--- a/gcc/config/i386/i386-opts.h
|
||||
+++ b/gcc/config/i386/i386-opts.h
|
||||
@@ -122,8 +122,8 @@ enum indirect_branch {
|
||||
enum harden_sls {
|
||||
harden_sls_none = 0,
|
||||
harden_sls_return = 1 << 0,
|
||||
- harden_sls_indirect_branch = 1 << 1,
|
||||
- harden_sls_all = harden_sls_return | harden_sls_indirect_branch
|
||||
+ harden_sls_indirect_jmp = 1 << 1,
|
||||
+ harden_sls_all = harden_sls_return | harden_sls_indirect_jmp
|
||||
};
|
||||
|
||||
#endif
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 8442dd0daea..3bc14e20105 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -28736,7 +28736,7 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
}
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
- if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ if ((ix86_harden_sls & harden_sls_indirect_jmp))
|
||||
fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
else
|
||||
@@ -28991,7 +28991,7 @@ ix86_output_indirect_jmp (rtx call_op)
|
||||
}
|
||||
else
|
||||
output_asm_insn ("%!jmp\t%A0", &call_op);
|
||||
- return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : "";
|
||||
+ return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output function return. CALL_OP is the jump target. Add a REP
|
||||
@@ -29178,7 +29178,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
|
||||
{
|
||||
output_asm_insn (xasm, &call_op);
|
||||
if (!direct_p
|
||||
- && (ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ && (ix86_harden_sls & harden_sls_indirect_jmp))
|
||||
return "int3";
|
||||
}
|
||||
return "";
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index 9f67ef558dc..7a5c7b9369a 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1075,7 +1075,7 @@ EnumValue
|
||||
Enum(harden_sls) String(return) Value(harden_sls_return)
|
||||
|
||||
EnumValue
|
||||
-Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch)
|
||||
+Enum(harden_sls) String(indirect-jmp) Value(harden_sls_indirect_jmp)
|
||||
|
||||
EnumValue
|
||||
Enum(harden_sls) String(all) Value(harden_sls_all)
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 605cd4b93f1..20d8e3fd782 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -28041,8 +28041,8 @@ Force indirect call and jump via register.
|
||||
@opindex mharden-sls
|
||||
Generate code to mitigate against straight line speculation (SLS) with
|
||||
@var{choice}. The default is @samp{none} which disables all SLS
|
||||
-hardening. @samp{return} enables SLS hardening for function return.
|
||||
-@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
+hardening. @samp{return} enables SLS hardening for function returns.
|
||||
+@samp{indirect-jmp} enables SLS hardening for indirect jumps.
|
||||
@samp{all} enables all SLS hardening.
|
||||
|
||||
@item -mindirect-branch-cs-prefix
|
||||
--
|
||||
2.36.1
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From 5a5e7890cefa112e95e1de9800d8081c2a38a1da Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 5 Jan 2022 18:04:21 -0800
|
||||
Subject: [PATCH 4/4] x86: Generate INT3 for __builtin_eh_return
|
||||
|
||||
Generate INT3 after indirect jmp in exception return for -fcf-protection
|
||||
with -mharden-sls=indirect-jmp.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/103925
|
||||
* config/i386/i386.c (ix86_output_indirect_function_return):
|
||||
Generate INT3 after indirect jmp for -mharden-sls=indirect-jmp.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/103925
|
||||
* gcc.target/i386/harden-sls-6.c: New test.
|
||||
|
||||
(cherry picked from commit c2e5c4feed32c808591b5278f680bbabe63eb225)
|
||||
---
|
||||
gcc/config/i386/i386.c | 9 ++++++---
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-6.c | 18 ++++++++++++++++++
|
||||
2 files changed, 24 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 3bc14e20105..dbc3d462fda 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -29083,11 +29083,14 @@ ix86_output_indirect_function_return (rtx ret_op)
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
-
|
||||
- return "";
|
||||
}
|
||||
else
|
||||
- return "%!jmp\t%A0";
|
||||
+ {
|
||||
+ output_asm_insn ("%!jmp\t%A0", &ret_op);
|
||||
+ if (ix86_harden_sls & harden_sls_indirect_jmp)
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
+ }
|
||||
+ return "";
|
||||
}
|
||||
|
||||
/* Split simple return with popping POPC bytes from stack to indirect
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-6.c b/gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
new file mode 100644
|
||||
index 00000000000..9068eb64008
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -fcf-protection -mharden-sls=indirect-jmp" } */
|
||||
+
|
||||
+struct _Unwind_Context _Unwind_Resume_or_Rethrow_this_context;
|
||||
+
|
||||
+void offset (int);
|
||||
+
|
||||
+struct _Unwind_Context {
|
||||
+ void *reg[7];
|
||||
+} _Unwind_Resume_or_Rethrow() {
|
||||
+ struct _Unwind_Context cur_contextcur_context =
|
||||
+ _Unwind_Resume_or_Rethrow_this_context;
|
||||
+ offset(0);
|
||||
+ __builtin_eh_return ((long) offset, 0);
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rcx" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
--- libgomp/configure.tgt.jj 2008-01-10 20:53:48.000000000 +0100
|
||||
+++ libgomp/configure.tgt 2008-03-27 12:44:51.000000000 +0100
|
||||
@@ -67,7 +67,7 @@ if test $enable_linux_futex = yes; then
|
||||
;;
|
||||
*)
|
||||
if test -z "$with_arch"; then
|
||||
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
|
||||
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic"
|
||||
fi
|
||||
esac
|
||||
;;
|
||||
@ -1,14 +0,0 @@
|
||||
--- libgcc/config/t-slibgcc.mp 2018-10-03 16:07:00.336990246 -0400
|
||||
+++ libgcc/config/t-slibgcc 2018-10-03 16:06:26.719946740 -0400
|
||||
@@ -30,9 +30,10 @@ SHLIB_LC = -lc
|
||||
SHLIB_MAKE_SOLINK = $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
|
||||
SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
|
||||
+SHLIB_EXTRA_LDFLAGS = -Wl,-z,relro -Wl,-z,now
|
||||
|
||||
SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
- $(SHLIB_LDFLAGS) \
|
||||
+ $(SHLIB_LDFLAGS) $(SHLIB_EXTRA_LDFLAGS) \
|
||||
-o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
|
||||
$(SHLIB_OBJS) $(SHLIB_LC) && \
|
||||
rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \
|
||||
@ -1,516 +0,0 @@
|
||||
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
|
||||
index d93dcfa..f47565c 100644
|
||||
--- a/gcc/fortran/io.c
|
||||
+++ b/gcc/fortran/io.c
|
||||
@@ -909,6 +909,13 @@ data_desc:
|
||||
|
||||
if (u != FMT_POSINT)
|
||||
{
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume a default width based on the variable size. */
|
||||
+ saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
format_locus.nextc += format_string_pos;
|
||||
gfc_error ("Positive width required in format "
|
||||
"specifier %s at %L", token_to_string (t),
|
||||
@@ -1030,6 +1037,13 @@ data_desc:
|
||||
goto fail;
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume the default width is expected here and continue lexing. */
|
||||
+ value = 0; /* It doesn't matter what we set the value to here. */
|
||||
+ saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
error = nonneg_required;
|
||||
goto syntax;
|
||||
}
|
||||
@@ -1099,8 +1113,17 @@ data_desc:
|
||||
goto fail;
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
- error = nonneg_required;
|
||||
- goto syntax;
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume the default width is expected here and continue lexing. */
|
||||
+ value = 0; /* It doesn't matter what we set the value to here. */
|
||||
+ saved_token = t;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ error = nonneg_required;
|
||||
+ goto syntax;
|
||||
+ }
|
||||
}
|
||||
else if (is_input && t == FMT_ZERO)
|
||||
{
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..b087b8f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
|
||||
@@ -0,0 +1,43 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+!
|
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float
|
||||
+! values to a higher precision than the type can actually store, the results
|
||||
+! are implementation dependent: some platforms print zeros, others print random
|
||||
+! numbers. Don't depend on this behaviour in tests because they will not be
|
||||
+! portable.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+
|
||||
+ real*4 :: real_4
|
||||
+ real*8 :: real_8
|
||||
+ real*16 :: real_16
|
||||
+ integer :: len
|
||||
+
|
||||
+ real_4 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 4.1799998:") call abort
|
||||
+
|
||||
+ real_4 = 0.00000018
|
||||
+ write(buffer, '(A, F, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.0000002:") call abort
|
||||
+
|
||||
+ real_8 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_8,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 27) call abort
|
||||
+
|
||||
+ real_16 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_16,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 44) call abort
|
||||
+end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..3d3a476
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
|
||||
@@ -0,0 +1,48 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+!
|
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float
|
||||
+! values to a higher precision than the type can actually store, the results
|
||||
+! are implementation dependent: some platforms print zeros, others print random
|
||||
+! numbers. Don't depend on this behaviour in tests because they will not be
|
||||
+! portable.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+
|
||||
+ real*4 :: real_4
|
||||
+ real*8 :: real_8
|
||||
+ real*16 :: real_16
|
||||
+ integer :: len
|
||||
+
|
||||
+ real_4 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 4.180000 :") call abort
|
||||
+
|
||||
+ real_4 = 0.00000018
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.1800000E-06:") call abort
|
||||
+
|
||||
+ real_4 = 18000000.4
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.1800000E+08:") call abort
|
||||
+
|
||||
+ real_8 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_8,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 27) call abort
|
||||
+
|
||||
+ real_16 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_16,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 44) call abort
|
||||
+end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..ac4e165
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
|
||||
@@ -0,0 +1,38 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+ character(1) :: colon
|
||||
+
|
||||
+ integer*2 :: integer_2
|
||||
+ integer*4 :: integer_4
|
||||
+ integer*8 :: integer_8
|
||||
+
|
||||
+ write(buffer, '(A, I, A)') ':',12340,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 12340:") call abort
|
||||
+
|
||||
+ read(buffer, '(A1, I, A1)') colon, integer_4, colon
|
||||
+ if (integer_4.ne.12340) call abort
|
||||
+
|
||||
+ integer_2 = -99
|
||||
+ write(buffer, '(A, I, A)') ':',integer_2,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": -99:") call abort
|
||||
+
|
||||
+ integer_8 = -11112222
|
||||
+ write(buffer, '(A, I, A)') ':',integer_8,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": -11112222:") call abort
|
||||
+
|
||||
+! If the width is 7 and there are 7 leading zeroes, the result should be zero.
|
||||
+ integer_2 = 789
|
||||
+ buffer = '0000000789'
|
||||
+ read(buffer, '(I)') integer_2
|
||||
+ if (integer_2.ne.0) call abort
|
||||
+end
|
||||
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
|
||||
index c2abdd7..692b1ff 100644
|
||||
--- a/libgfortran/io/format.c
|
||||
+++ b/libgfortran/io/format.c
|
||||
@@ -956,12 +956,33 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
*seen_dd = true;
|
||||
if (u != FMT_POSINT && u != FMT_ZERO)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.real.w = DEFAULT_WIDTH;
|
||||
+ tail->u.real.d = 0;
|
||||
+ tail->u.real.e = -1;
|
||||
+ fmt->saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = nonneg_required;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
+ else if (u == FMT_ZERO)
|
||||
+ {
|
||||
+ fmt->error = posint_required;
|
||||
+ goto finished;
|
||||
+ }
|
||||
else if (u != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.real.w = DEFAULT_WIDTH;
|
||||
+ tail->u.real.d = 0;
|
||||
+ tail->u.real.e = -1;
|
||||
+ fmt->saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = posint_required;
|
||||
goto finished;
|
||||
}
|
||||
@@ -1099,6 +1120,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
{
|
||||
if (t != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.integer.w = DEFAULT_WIDTH;
|
||||
+ tail->u.integer.m = -1;
|
||||
+ fmt->saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = posint_required;
|
||||
goto finished;
|
||||
}
|
||||
@@ -1107,6 +1135,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
{
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.integer.w = DEFAULT_WIDTH;
|
||||
+ tail->u.integer.m = -1;
|
||||
+ fmt->saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = nonneg_required;
|
||||
goto finished;
|
||||
}
|
||||
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
|
||||
index 5583183..d1d08e8 100644
|
||||
--- a/libgfortran/io/io.h
|
||||
+++ b/libgfortran/io/io.h
|
||||
@@ -981,5 +981,55 @@ memset4 (gfc_char4_t *p, gfc_char4_t c, int k)
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
+/* Used in width fields to indicate that the default should be used */
|
||||
+#define DEFAULT_WIDTH -1
|
||||
+
|
||||
+/* Defaults for certain format field descriptors. These are decided based on
|
||||
+ * the type of the value being formatted.
|
||||
+ *
|
||||
+ * The behaviour here is modelled on the Oracle Fortran compiler. At the time
|
||||
+ * of writing, the details were available at this URL:
|
||||
+ *
|
||||
+ * https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnc3/index.html#z4000743746d
|
||||
+ */
|
||||
+
|
||||
+static inline int
|
||||
+default_width_for_integer (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ case 2: return 7;
|
||||
+ case 4: return 12;
|
||||
+ case 8: return 23;
|
||||
+ case 16: return 44;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+default_width_for_float (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 4: return 15;
|
||||
+ case 8: return 25;
|
||||
+ case 16: return 42;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+default_precision_for_float (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 4: return 7;
|
||||
+ case 8: return 16;
|
||||
+ case 16: return 33;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
|
||||
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
|
||||
index 2c9de48..e911e35 100644
|
||||
--- a/libgfortran/io/read.c
|
||||
+++ b/libgfortran/io/read.c
|
||||
@@ -629,6 +629,12 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
|
||||
|
||||
w = f->u.w;
|
||||
|
||||
+ /* This is a legacy extension, and the frontend will only allow such cases
|
||||
+ * through when -fdec-format-defaults is passed.
|
||||
+ */
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (length);
|
||||
+
|
||||
p = read_block_form (dtp, &w);
|
||||
|
||||
if (p == NULL)
|
||||
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
|
||||
index a7307a8..c8e52fb 100644
|
||||
--- a/libgfortran/io/write.c
|
||||
+++ b/libgfortran/io/write.c
|
||||
@@ -684,9 +684,8 @@ write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
|
||||
p[wlen - 1] = (n) ? 'T' : 'F';
|
||||
}
|
||||
|
||||
-
|
||||
static void
|
||||
-write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
|
||||
+write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
|
||||
{
|
||||
int w, m, digits, nzero, nblank;
|
||||
char *p;
|
||||
@@ -719,6 +718,9 @@ write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
|
||||
/* Select a width if none was specified. The idea here is to always
|
||||
print something. */
|
||||
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (len);
|
||||
+
|
||||
if (w == 0)
|
||||
w = ((digits < m) ? m : digits);
|
||||
|
||||
@@ -845,6 +847,8 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
|
||||
|
||||
/* Select a width if none was specified. The idea here is to always
|
||||
print something. */
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (len);
|
||||
|
||||
if (w == 0)
|
||||
w = ((digits < m) ? m : digits) + nsign;
|
||||
@@ -1187,13 +1191,13 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = btoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = btoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,13 +1212,13 @@ write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = otoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = otoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,13 +1232,13 @@ write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = ztoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1504,7 +1508,7 @@ size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
|
||||
{
|
||||
int size;
|
||||
|
||||
- if (f->format == FMT_F && f->u.real.w == 0)
|
||||
+ if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
|
||||
index 7f0aa1d..73dc910 100644
|
||||
--- a/libgfortran/io/write_float.def
|
||||
+++ b/libgfortran/io/write_float.def
|
||||
@@ -113,7 +113,8 @@ determine_precision (st_parameter_dt * d
|
||||
static void
|
||||
build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer,
|
||||
size_t size, int nprinted, int precision, int sign_bit,
|
||||
- bool zero_flag, int npad, char *result, size_t *len)
|
||||
+ bool zero_flag, int npad, int default_width, char *result,
|
||||
+ size_t *len)
|
||||
{
|
||||
char *put;
|
||||
char *digits;
|
||||
@@ -132,8 +133,17 @@ build_float_string (st_parameter_dt *dtp
|
||||
sign_t sign;
|
||||
|
||||
ft = f->format;
|
||||
- w = f->u.real.w;
|
||||
- d = f->u.real.d;
|
||||
+ if (f->u.real.w == DEFAULT_WIDTH)
|
||||
+ /* This codepath can only be reached with -fdec-format-defaults. */
|
||||
+ {
|
||||
+ w = default_width;
|
||||
+ d = precision;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ w = f->u.real.w;
|
||||
+ d = f->u.real.d;
|
||||
+ }
|
||||
p = dtp->u.p.scale_factor;
|
||||
*len = 0;
|
||||
|
||||
@@ -959,6 +969,11 @@ determine_en_precision (st_parameter_dt
|
||||
int save_scale_factor;\
|
||||
volatile GFC_REAL_ ## x temp;\
|
||||
save_scale_factor = dtp->u.p.scale_factor;\
|
||||
+ if (w == DEFAULT_WIDTH)\
|
||||
+ {\
|
||||
+ w = default_width;\
|
||||
+ d = precision;\
|
||||
+ }\
|
||||
switch (dtp->u.p.current_unit->round_status)\
|
||||
{\
|
||||
case ROUND_ZERO:\
|
||||
@@ -1034,7 +1049,8 @@ determine_en_precision (st_parameter_dt
|
||||
nprinted = FDTOA(y,precision,m);\
|
||||
}\
|
||||
build_float_string (dtp, &newf, buffer, size, nprinted, precision,\
|
||||
- sign_bit, zero_flag, npad, result, res_len);\
|
||||
+ sign_bit, zero_flag, npad, default_width,\
|
||||
+ result, res_len);\
|
||||
dtp->u.p.scale_factor = save_scale_factor;\
|
||||
}\
|
||||
else\
|
||||
@@ -1044,7 +1060,8 @@ determine_en_precision (st_parameter_dt
|
||||
else\
|
||||
nprinted = DTOA(y,precision,m);\
|
||||
build_float_string (dtp, f, buffer, size, nprinted, precision,\
|
||||
- sign_bit, zero_flag, npad, result, res_len);\
|
||||
+ sign_bit, zero_flag, npad, default_width,\
|
||||
+ result, res_len);\
|
||||
}\
|
||||
}\
|
||||
|
||||
@@ -1058,6 +1075,16 @@ get_float_string (st_parameter_dt *dtp,
|
||||
{
|
||||
int sign_bit, nprinted;
|
||||
bool zero_flag;
|
||||
+ int default_width = 0;
|
||||
+
|
||||
+ if (f->u.real.w == DEFAULT_WIDTH)
|
||||
+ /* This codepath can only be reached with -fdec-format-defaults. The default
|
||||
+ * values are based on those used in the Oracle Fortran compiler.
|
||||
+ */
|
||||
+ {
|
||||
+ default_width = default_width_for_float (kind);
|
||||
+ precision = default_precision_for_float (kind);
|
||||
+ }
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
--- libgomp/testsuite/libgomp-test-support.exp.in.jj 2018-04-25 09:40:31.323655308 +0200
|
||||
+++ libgomp/testsuite/libgomp-test-support.exp.in 2019-04-25 20:01:50.028243827 +0200
|
||||
@@ -2,4 +2,5 @@ set cuda_driver_include "@CUDA_DRIVER_IN
|
||||
set cuda_driver_lib "@CUDA_DRIVER_LIB@"
|
||||
set hsa_runtime_lib "@HSA_RUNTIME_LIB@"
|
||||
|
||||
+set offload_plugins "@offload_plugins@"
|
||||
set offload_targets "@offload_targets@"
|
||||
--- libgomp/testsuite/lib/libgomp.exp.jj 2018-04-25 09:40:31.584655429 +0200
|
||||
+++ libgomp/testsuite/lib/libgomp.exp 2019-05-24 11:41:51.015822702 +0200
|
||||
@@ -40,7 +40,7 @@ load_file libgomp-test-support.exp
|
||||
# Populate offload_targets_s (offloading targets separated by a space), and
|
||||
# offload_targets_s_openacc (the same, but with OpenACC names; OpenACC spells
|
||||
# some of them a little differently).
|
||||
-set offload_targets_s [split $offload_targets ","]
|
||||
+set offload_targets_s [split $offload_plugins ","]
|
||||
set offload_targets_s_openacc {}
|
||||
foreach offload_target_openacc $offload_targets_s {
|
||||
# Translate to OpenACC names, or skip if not yet supported.
|
||||
@@ -137,8 +137,8 @@ proc libgomp_init { args } {
|
||||
|
||||
# Add liboffloadmic build directory in LD_LIBRARY_PATH to support
|
||||
# non-fallback testing for Intel MIC targets
|
||||
- global offload_targets
|
||||
- if { [string match "*,intelmic,*" ",$offload_targets,"] } {
|
||||
+ global offload_plugins
|
||||
+ if { [string match "*,intelmic,*" ",$offload_plugins,"] } {
|
||||
append always_ld_library_path ":${blddir}/../liboffloadmic/.libs"
|
||||
append always_ld_library_path ":${blddir}/../liboffloadmic/plugin/.libs"
|
||||
# libstdc++ is required by liboffloadmic
|
||||
@@ -362,8 +362,8 @@ proc check_effective_target_offload_devi
|
||||
# Return 1 if configured for nvptx offloading.
|
||||
|
||||
proc check_effective_target_openacc_nvidia_accel_configured { } {
|
||||
- global offload_targets
|
||||
- if { ![string match "*,nvptx,*" ",$offload_targets,"] } {
|
||||
+ global offload_plugins
|
||||
+ if { ![string match "*,nvptx,*" ",$offload_plugins,"] } {
|
||||
return 0
|
||||
}
|
||||
# PR libgomp/65099: Currently, we only support offloading in 64-bit
|
||||
@ -1,61 +0,0 @@
|
||||
commit 79fa567e234585dc6a71f9bd069101c993513f3e
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Thu Apr 22 15:46:51 2021 +0100
|
||||
|
||||
libstdc++: Reject std::make_shared<T[]> [PR 99006]
|
||||
|
||||
Prior to C++20 it should be ill-formed to use std::make_shared with an
|
||||
array type (and we don't support the C++20 feature to make it valid yet
|
||||
anyway).
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/99006
|
||||
* include/bits/shared_ptr.h (allocate_shared): Assert that _Tp
|
||||
is not an array type.
|
||||
* include/bits/shared_ptr_base.h (__allocate_shared): Likewise.
|
||||
* testsuite/20_util/shared_ptr/creation/99006.cc: New test.
|
||||
|
||||
(cherry picked from commit 55650236cd97d81f42f9fdb4f6bcb12babafe51f)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h
|
||||
index 281600b2901..4ddc52ae723 100644
|
||||
--- a/libstdc++-v3/include/bits/shared_ptr.h
|
||||
+++ b/libstdc++-v3/include/bits/shared_ptr.h
|
||||
@@ -698,6 +698,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline shared_ptr<_Tp>
|
||||
allocate_shared(const _Alloc& __a, _Args&&... __args)
|
||||
{
|
||||
+ static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
|
||||
+
|
||||
return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
index 0367c2d51a5..8af6e9fb11c 100644
|
||||
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
@@ -1822,6 +1822,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline __shared_ptr<_Tp, _Lp>
|
||||
__allocate_shared(const _Alloc& __a, _Args&&... __args)
|
||||
{
|
||||
+ static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
|
||||
+
|
||||
return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc
|
||||
new file mode 100644
|
||||
index 00000000000..d5f7a5da5e9
|
||||
--- /dev/null
|
||||
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc
|
||||
@@ -0,0 +1,9 @@
|
||||
+// FIXME: This should use { target { ! c++20 } }
|
||||
+// { dg-do compile }
|
||||
+
|
||||
+#include <memory>
|
||||
+
|
||||
+auto p = std::make_shared<int[]>(2); // { dg-error "here" }
|
||||
+auto q = std::make_shared<int[2]>(1, 2); // { dg-error "here" }
|
||||
+
|
||||
+// { dg-prune-output "static assertion failed" }
|
||||
@ -1,27 +0,0 @@
|
||||
NullablePointer support not available, so drop these tests.
|
||||
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc.new
|
||||
index 2f75d12..6fb19c3 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
@@ -145,20 +145,6 @@ main()
|
||||
std::unique_ptr<data>& rarrptr = arrptr;
|
||||
// { dg-final { regexp-test rarrptr {std::unique_ptr.datum \[\]. = {get\(\) = 0x.*}} } }
|
||||
|
||||
- struct Deleter
|
||||
- {
|
||||
- int deleter_member = -1;
|
||||
- using pointer = __gnu_test::NullablePointer<void>;
|
||||
- void operator()(pointer) const noexcept { }
|
||||
- };
|
||||
- static_assert( !std::is_empty<Deleter>(), "Deleter is not empty" );
|
||||
- static_assert( std::is_empty<Deleter::pointer>(), "but pointer is empty" );
|
||||
-
|
||||
- std::unique_ptr<int, Deleter> empty_ptr;
|
||||
-// { dg-final { note-test empty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
|
||||
- std::unique_ptr<int, Deleter>& rempty_ptr = empty_ptr;
|
||||
-// { dg-final { note-test rempty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
|
||||
-
|
||||
struct Deleter_pr103086
|
||||
{
|
||||
int deleter_member = -1;
|
||||
@ -1,44 +0,0 @@
|
||||
Revert this commit for libstdc++-prettyprinters (only cxx17, 91997
|
||||
doesn't exist in this tree) since gcc8 does not default to c++17. The
|
||||
context has been adapted but the change should be exact:
|
||||
|
||||
commit 0498d2d09a2364aae1e6b5e085c8ebb8fc517684
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Mon May 10 16:22:54 2021 +0100
|
||||
|
||||
libstdc++: Remove redundant -std=gnu++17 option from remaining tests
|
||||
|
||||
Also remove the filesystem tests since it's not supported by RHEL8 gcc.
|
||||
|
||||
diff --git b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
index 72c66d3b785..98e21e963fe 100644
|
||||
--- b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
+++ a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
@@ -1,4 +1,4 @@
|
||||
-// { dg-options "-g -O0" }
|
||||
+// { dg-options "-g -O0 -std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
@@ -18,7 +18,6 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
-#include <filesystem>
|
||||
#include <any>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
@@ -120,13 +119,6 @@ main()
|
||||
// { dg-final { regexp-test q {std::shared_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
|
||||
// { dg-final { regexp-test wq {std::weak_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
|
||||
|
||||
- std::filesystem::path path0;
|
||||
-// { dg-final { note-test path0 {filesystem::path ""} } }
|
||||
- std::filesystem::path path1("filename");
|
||||
-// { dg-final { note-test path1 {filesystem::path "filename"} } }
|
||||
- std::filesystem::path path2("/dir/.");
|
||||
-// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
|
||||
-
|
||||
std::cout << "\n";
|
||||
return 0; // Mark SPOT
|
||||
}
|
||||
@ -1,458 +0,0 @@
|
||||
.../testsuite/libstdc++-prettyprinters/compat.cc | 11 +-
|
||||
.../testsuite/libstdc++-prettyprinters/cxx11.cc | 129 +++++++++++++++------
|
||||
.../testsuite/libstdc++-prettyprinters/cxx17.cc | 50 +++++---
|
||||
.../libstdc++-prettyprinters/filesystem-ts.cc | 8 +-
|
||||
.../libstdc++-prettyprinters/libfundts.cc | 26 +++--
|
||||
5 files changed, 146 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
index 81e0ce7213f..2ef5979834f 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/compat.cc
|
||||
@@ -1,8 +1,7 @@
|
||||
// { dg-options "-g -O0" }
|
||||
// { dg-do run { target c++11 } }
|
||||
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
|
||||
|
||||
-// Copyright (C) 2014-2019 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -103,13 +102,13 @@ main()
|
||||
using std::optional;
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
|
||||
|
||||
__builtin_puts("");
|
||||
return 0; // Mark SPOT
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
index 9a90d8d91db..23f6d97ddd4 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
|
||||
@@ -1,8 +1,7 @@
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-options "-g -O0" }
|
||||
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
|
||||
|
||||
-// Copyright (C) 2011-2018 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2011-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -25,6 +24,10 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
+#include <future>
|
||||
+#include <initializer_list>
|
||||
+#include <atomic>
|
||||
+#include "../util/testsuite_allocator.h" // NullablePointer
|
||||
|
||||
typedef std::tuple<int, int> ExTuple;
|
||||
|
||||
@@ -60,84 +63,74 @@ struct datum
|
||||
|
||||
std::unique_ptr<datum> global;
|
||||
|
||||
-struct Deleter
|
||||
-{
|
||||
- // Deleter is not an empty class:
|
||||
- int deleter_member = -1;
|
||||
- // But pointer is an empty class:
|
||||
- struct pointer
|
||||
- {
|
||||
- pointer(const void* = nullptr) { }
|
||||
- explicit operator bool() const noexcept { return false; }
|
||||
- friend bool operator==(pointer, pointer) noexcept { return true; }
|
||||
- friend bool operator!=(pointer, pointer) noexcept { return false; }
|
||||
- };
|
||||
- void operator()(pointer) const noexcept { }
|
||||
+struct custom_cat : std::error_category {
|
||||
+ const char* name() const noexcept { return "miaow"; }
|
||||
+ std::string message(int) const { return ""; }
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::forward_list<int> efl;
|
||||
-// { dg-final { note-test efl "empty std::forward_list" } }
|
||||
+// { dg-final { regexp-test efl "empty std::(__debug::)?forward_list" } }
|
||||
|
||||
std::forward_list<int> &refl = efl;
|
||||
-// { dg-final { note-test refl "empty std::forward_list" } }
|
||||
+// { dg-final { regexp-test refl "empty std::(__debug::)?forward_list" } }
|
||||
|
||||
std::forward_list<int> fl;
|
||||
fl.push_front(2);
|
||||
fl.push_front(1);
|
||||
-// { dg-final { note-test fl {std::forward_list = {[0] = 1, [1] = 2}} } }
|
||||
+// { dg-final { regexp-test fl {std::(__debug::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
|
||||
|
||||
std::forward_list<int> &rfl = fl;
|
||||
-// { dg-final { note-test rfl {std::forward_list = {[0] = 1, [1] = 2}} } }
|
||||
+// { dg-final { regexp-test rfl {std::(__debug::)?forward_list = {\[0\] = 1, \[1\] = 2}} } }
|
||||
|
||||
std::unordered_map<int, std::string> eum;
|
||||
-// { dg-final { note-test eum "std::unordered_map with 0 elements" } }
|
||||
+// { dg-final { regexp-test eum "std::(__debug::)?unordered_map with 0 elements" } }
|
||||
std::unordered_map<int, std::string> &reum = eum;
|
||||
-// { dg-final { note-test reum "std::unordered_map with 0 elements" } }
|
||||
+// { dg-final { regexp-test reum "std::(__debug::)?unordered_map with 0 elements" } }
|
||||
|
||||
std::unordered_multimap<int, std::string> eumm;
|
||||
-// { dg-final { note-test eumm "std::unordered_multimap with 0 elements" } }
|
||||
+// { dg-final { regexp-test eumm "std::(__debug::)?unordered_multimap with 0 elements" } }
|
||||
std::unordered_multimap<int, std::string> &reumm = eumm;
|
||||
-// { dg-final { note-test reumm "std::unordered_multimap with 0 elements" } }
|
||||
+// { dg-final { regexp-test reumm "std::(__debug::)?unordered_multimap with 0 elements" } }
|
||||
|
||||
std::unordered_set<int> eus;
|
||||
-// { dg-final { note-test eus "std::unordered_set with 0 elements" } }
|
||||
+// { dg-final { regexp-test eus "std::(__debug::)?unordered_set with 0 elements" } }
|
||||
std::unordered_set<int> &reus = eus;
|
||||
-// { dg-final { note-test reus "std::unordered_set with 0 elements" } }
|
||||
+// { dg-final { regexp-test reus "std::(__debug::)?unordered_set with 0 elements" } }
|
||||
|
||||
std::unordered_multiset<int> eums;
|
||||
-// { dg-final { note-test eums "std::unordered_multiset with 0 elements" } }
|
||||
+// { dg-final { regexp-test eums "std::(__debug::)?unordered_multiset with 0 elements" } }
|
||||
std::unordered_multiset<int> &reums = eums;
|
||||
-// { dg-final { note-test reums "std::unordered_multiset with 0 elements" } }
|
||||
+// { dg-final { regexp-test reums "std::(__debug::)?unordered_multiset with 0 elements" } }
|
||||
|
||||
std::unordered_map<int, std::string> uom;
|
||||
uom[5] = "three";
|
||||
uom[3] = "seven";
|
||||
-// { dg-final { note-test uom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
|
||||
+// { dg-final { regexp-test uom {std::(__debug::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
|
||||
|
||||
std::unordered_map<int, std::string> &ruom = uom;
|
||||
-// { dg-final { note-test ruom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
|
||||
+// { dg-final { regexp-test ruom {std::(__debug::)?unordered_map with 2 elements = {\[3\] = "seven", \[5\] = "three"}} } }
|
||||
|
||||
std::unordered_multimap<int, std::string> uomm;
|
||||
uomm.insert(std::pair<int, std::string> (5, "three"));
|
||||
uomm.insert(std::pair<int, std::string> (5, "seven"));
|
||||
-// { dg-final { note-test uomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
|
||||
+// { dg-final { regexp-test uomm {std::(__debug::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
|
||||
std::unordered_multimap<int, std::string> &ruomm = uomm;
|
||||
-// { dg-final { note-test ruomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
|
||||
+// { dg-final { regexp-test ruomm {std::(__debug::)?unordered_multimap with 2 elements = {\[5\] = "seven", \[5\] = "three"}} } }
|
||||
|
||||
std::unordered_set<int> uos;
|
||||
uos.insert(5);
|
||||
-// { dg-final { note-test uos {std::unordered_set with 1 element = {[0] = 5}} } }
|
||||
+// { dg-final { regexp-test uos {std::(__debug::)?unordered_set with 1 element = {\[0\] = 5}} } }
|
||||
std::unordered_set<int> &ruos = uos;
|
||||
-// { dg-final { note-test ruos {std::unordered_set with 1 element = {[0] = 5}} } }
|
||||
+// { dg-final { regexp-test ruos {std::(__debug::)?unordered_set with 1 element = {\[0\] = 5}} } }
|
||||
|
||||
std::unordered_multiset<int> uoms;
|
||||
uoms.insert(5);
|
||||
-// { dg-final { note-test uoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
|
||||
+// { dg-final { regexp-test uoms {std::(__debug::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
|
||||
std::unordered_multiset<int> &ruoms = uoms;
|
||||
-// { dg-final { note-test ruoms {std::unordered_multiset with 1 element = {[0] = 5}} } }
|
||||
+// { dg-final { regexp-test ruoms {std::(__debug::)?unordered_multiset with 1 element = {\[0\] = 5}} } }
|
||||
|
||||
std::unique_ptr<datum> uptr (new datum);
|
||||
uptr->s = "hi bob";
|
||||
@@ -152,15 +145,77 @@ main()
|
||||
std::unique_ptr<data>& rarrptr = arrptr;
|
||||
// { dg-final { regexp-test rarrptr {std::unique_ptr.datum \[\]. = {get\(\) = 0x.*}} } }
|
||||
|
||||
+ struct Deleter
|
||||
+ {
|
||||
+ int deleter_member = -1;
|
||||
+ using pointer = __gnu_test::NullablePointer<void>;
|
||||
+ void operator()(pointer) const noexcept { }
|
||||
+ };
|
||||
+ static_assert( !std::is_empty<Deleter>(), "Deleter is not empty" );
|
||||
+ static_assert( std::is_empty<Deleter::pointer>(), "but pointer is empty" );
|
||||
+
|
||||
std::unique_ptr<int, Deleter> empty_ptr;
|
||||
// { dg-final { note-test empty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
|
||||
std::unique_ptr<int, Deleter>& rempty_ptr = empty_ptr;
|
||||
// { dg-final { note-test rempty_ptr {std::unique_ptr<int> = {get() = {<No data fields>}}} } }
|
||||
|
||||
+ struct Deleter_pr103086
|
||||
+ {
|
||||
+ int deleter_member = -1;
|
||||
+ void operator()(int*) const noexcept { }
|
||||
+ };
|
||||
+
|
||||
+ std::unique_ptr<int, Deleter_pr103086> uniq_ptr;
|
||||
+// { dg-final { note-test uniq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
|
||||
+ std::unique_ptr<int, Deleter_pr103086>& runiq_ptr = uniq_ptr;
|
||||
+// { dg-final { note-test runiq_ptr {std::unique_ptr<int> = {get() = 0x0}} } }
|
||||
+
|
||||
ExTuple tpl(6,7);
|
||||
-// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
|
||||
+// { dg-final { note-test tpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
|
||||
ExTuple &rtpl = tpl;
|
||||
-// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
|
||||
+// { dg-final { note-test rtpl {std::tuple containing = {[0] = 6, [1] = 7}} } }
|
||||
+
|
||||
+ std::error_code e0;
|
||||
+ // { dg-final { note-test e0 {std::error_code = { }} } }
|
||||
+ std::error_condition ec0;
|
||||
+ // { dg-final { note-test ec0 {std::error_condition = { }} } }
|
||||
+ std::error_code einval = std::make_error_code(std::errc::invalid_argument);
|
||||
+ // { dg-final { note-test einval {std::error_code = {"generic": EINVAL}} } }
|
||||
+ std::error_condition ecinval = std::make_error_condition(std::errc::invalid_argument);
|
||||
+ // { dg-final { note-test ecinval {std::error_condition = {"generic": EINVAL}} } }
|
||||
+
|
||||
+ custom_cat cat;
|
||||
+ std::error_code emiaow(42, cat);
|
||||
+ // { dg-final { note-test emiaow {std::error_code = {custom_cat: 42}} } }
|
||||
+ std::error_condition ecmiaow(42, cat);
|
||||
+ // { dg-final { note-test ecmiaow {std::error_condition = {custom_cat: 42}} } }
|
||||
+
|
||||
+ std::error_code ecio = std::make_error_code(std::io_errc::stream);
|
||||
+ // { dg-final { note-test ecio {std::error_code = {"io": stream}} } }
|
||||
+ std::error_code ecfut0 = std::make_error_code(std::future_errc{});
|
||||
+ // { dg-final { note-test ecfut0 {std::error_code = {"future": 0}} } }
|
||||
+
|
||||
+ std::initializer_list<int> emptyIl = {};
|
||||
+ // { dg-final { note-test emptyIl {std::initializer_list of length 0} } }
|
||||
+ std::initializer_list<int> il = {3, 4};
|
||||
+ // { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} } }
|
||||
+
|
||||
+ std::atomic<int> ai{100};
|
||||
+ // { dg-final { note-test ai {std::atomic<int> = { 100 }} } }
|
||||
+ long l{};
|
||||
+ std::atomic<long*> ap{&l};
|
||||
+ // { dg-final { regexp-test ap {std::atomic.long \*. = { 0x.* }} } }
|
||||
+ struct Value { int i, j; };
|
||||
+ std::atomic<Value> av{{8, 9}};
|
||||
+ // { dg-final { note-test av {std::atomic<Value> = { {i = 8, j = 9} }} } }
|
||||
+
|
||||
+ std::integral_constant<int, 1> one;
|
||||
+ // { dg-final { note-test one {std::integral_constant<int, 1>} } }
|
||||
+ std::integral_constant<bool, true> truth;
|
||||
+ // { dg-final { note-test truth {std::true_type} } }
|
||||
+ std::integral_constant<bool, 0> lies;
|
||||
+ // { dg-final { note-test lies {std::false_type} } }
|
||||
+
|
||||
placeholder(""); // Mark SPOT
|
||||
use(efl);
|
||||
use(fl);
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
index 0c7cb4c9bb6..6dd2b60c0a5 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx17.cc
|
||||
@@ -1,8 +1,7 @@
|
||||
-// { dg-options "-g -O0 -std=gnu++17" }
|
||||
+// { dg-options "-g -O0" }
|
||||
// { dg-do run { target c++17 } }
|
||||
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
|
||||
|
||||
-// Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -19,9 +18,7 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
-// Type printers only recognize the old std::string for now.
|
||||
-#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
-
|
||||
+#include <filesystem>
|
||||
#include <any>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
@@ -41,6 +38,11 @@ using std::unordered_set;
|
||||
using std::shared_ptr;
|
||||
using std::weak_ptr;
|
||||
|
||||
+struct X {
|
||||
+ X(int) { }
|
||||
+ X(const X&) { } // not trivially-copyable
|
||||
+};
|
||||
+
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -48,18 +50,18 @@ main()
|
||||
// { dg-final { note-test str "\"string\"" } }
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::optional = {[contained value] = 0x0}} } }
|
||||
optional<std::map<int, double>> om;
|
||||
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
|
||||
-// { dg-final { note-test om {std::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
|
||||
+// { dg-final { regexp-test om {std::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
optional<std::string> os{ "stringy" };
|
||||
-// { dg-final { note-test os {std::optional<std::string> = {[contained value] = "stringy"}} } }
|
||||
+// { dg-final { note-test os {std::optional = {[contained value] = "stringy"}} } }
|
||||
|
||||
any a;
|
||||
// { dg-final { note-test a {std::any [no contained value]} } }
|
||||
@@ -74,22 +76,25 @@ main()
|
||||
any as2("stringiest");
|
||||
// { dg-final { regexp-test as2 {std::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
|
||||
any am = *om;
|
||||
-// { dg-final { note-test am {std::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
|
||||
+// { dg-final { regexp-test am {std::any containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
+ struct local_type { int i = 99; };
|
||||
+ any al = local_type{};
|
||||
+// { dg-final { note-test al {std::any containing local_type = {[contained value] = {i = 99}}} } }
|
||||
|
||||
struct S { operator int() { throw 42; }};
|
||||
variant<float, int, string_view> v0;
|
||||
-// { dg-final { note-test v0 {std::variant<float, int, std::string_view> [index 0] = {0}} } }
|
||||
+// { dg-final { note-test v0 {std::variant [index 0] = {0}} } }
|
||||
variant<float, int, string_view> v1{ 0.5f };
|
||||
-// { dg-final { note-test v1 {std::variant<float, int, std::string_view> [index 0] = {0.5}} } }
|
||||
- variant<float, int, string_view> v2;
|
||||
+// { dg-final { note-test v1 {std::variant [index 0] = {0.5}} } }
|
||||
+ variant<float, X, string_view> v2;
|
||||
try {
|
||||
v2.emplace<1>(S());
|
||||
} catch (int) { }
|
||||
-// { dg-final { note-test v2 {std::variant<float, int, std::string_view> [no contained value]} } }
|
||||
+// { dg-final { note-test v2 {std::variant [no contained value]} } }
|
||||
variant<float, int, string_view> v3{ 3 };
|
||||
-// { dg-final { note-test v3 {std::variant<float, int, std::string_view> [index 1] = {3}} } }
|
||||
+// { dg-final { note-test v3 {std::variant [index 1] = {3}} } }
|
||||
variant<float, int, string_view> v4{ str };
|
||||
-// { dg-final { note-test v4 {std::variant<float, int, std::string_view> [index 2] = {"string"}} } }
|
||||
+// { dg-final { note-test v4 {std::variant [index 2] = {"string"}} } }
|
||||
|
||||
map<int, string_view> m{ {1, "one"} };
|
||||
map<int, string_view>::node_type n0;
|
||||
@@ -115,6 +120,13 @@ main()
|
||||
// { dg-final { regexp-test q {std::shared_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
|
||||
// { dg-final { regexp-test wq {std::weak_ptr.int \[2\]. \(use count 2, weak count 1\) = {get\(\) = 0x.*}} } }
|
||||
|
||||
+ std::filesystem::path path0;
|
||||
+// { dg-final { note-test path0 {filesystem::path ""} } }
|
||||
+ std::filesystem::path path1("filename");
|
||||
+// { dg-final { note-test path1 {filesystem::path "filename"} } }
|
||||
+ std::filesystem::path path2("/dir/.");
|
||||
+// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
|
||||
+
|
||||
std::cout << "\n";
|
||||
return 0; // Mark SPOT
|
||||
}
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
index 8a1398f6c85..3221f2df90d 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/filesystem-ts.cc
|
||||
@@ -2,7 +2,7 @@
|
||||
// { dg-do run { target c++11 } }
|
||||
// { dg-require-filesystem-ts "" }
|
||||
|
||||
-// Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2020-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -26,11 +26,11 @@ int
|
||||
main()
|
||||
{
|
||||
std::experimental::filesystem::path path0;
|
||||
-// { dg-final { note-test path0 {filesystem::path ""} } }
|
||||
+// { dg-final { note-test path0 {experimental::filesystem::path ""} } }
|
||||
std::experimental::filesystem::path path1("filename");
|
||||
-// { dg-final { note-test path1 {filesystem::path "filename"} } }
|
||||
+// { dg-final { note-test path1 {experimental::filesystem::path "filename"} } }
|
||||
std::experimental::filesystem::path path2("/dir/.");
|
||||
-// { dg-final { note-test path2 {filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
|
||||
+// { dg-final { note-test path2 {experimental::filesystem::path "/dir/." = {[root-directory] = "/", [1] = "dir", [2] = "."}} } }
|
||||
|
||||
std::cout << "\n";
|
||||
return 0; // Mark SPOT
|
||||
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
index ea13ebe71ee..bfb86885457 100644
|
||||
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc
|
||||
@@ -1,8 +1,7 @@
|
||||
// { dg-do run { target c++14 } }
|
||||
// { dg-options "-g -O0" }
|
||||
-// { dg-skip-if "" { *-*-* } { "-D_GLIBCXX_PROFILE" } }
|
||||
|
||||
-// Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
||||
+// Copyright (C) 2014-2025 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
@@ -19,9 +18,6 @@
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
-// Type printers only recognize the old std::string for now.
|
||||
-#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
-
|
||||
#include <experimental/any>
|
||||
#include <experimental/optional>
|
||||
#include <experimental/string_view>
|
||||
@@ -36,22 +32,28 @@ using std::experimental::string_view;
|
||||
int
|
||||
main()
|
||||
{
|
||||
+ // Ensure debug info for std::string is issued in the local
|
||||
+ // translation unit, so that GDB won't pick up any alternate
|
||||
+ // std::string notion that might be present in libstdc++.so.
|
||||
+ std::string bah = "hi";
|
||||
+ (void)bah;
|
||||
+
|
||||
string_view str = "string";
|
||||
// { dg-final { note-test str "\"string\"" } }
|
||||
|
||||
optional<int> o;
|
||||
-// { dg-final { note-test o {std::experimental::optional<int> [no contained value]} } }
|
||||
+// { dg-final { note-test o {std::experimental::optional [no contained value]} } }
|
||||
optional<bool> ob{false};
|
||||
-// { dg-final { note-test ob {std::experimental::optional<bool> = {[contained value] = false}} } }
|
||||
+// { dg-final { note-test ob {std::experimental::optional = {[contained value] = false}} } }
|
||||
optional<int> oi{5};
|
||||
-// { dg-final { note-test oi {std::experimental::optional<int> = {[contained value] = 5}} } }
|
||||
+// { dg-final { note-test oi {std::experimental::optional = {[contained value] = 5}} } }
|
||||
optional<void*> op{nullptr};
|
||||
-// { dg-final { note-test op {std::experimental::optional<void *> = {[contained value] = 0x0}} } }
|
||||
+// { dg-final { note-test op {std::experimental::optional = {[contained value] = 0x0}} } }
|
||||
optional<std::map<int, double>> om;
|
||||
om = std::map<int, double>{ {1, 2.}, {3, 4.}, {5, 6.} };
|
||||
-// { dg-final { note-test om {std::experimental::optional<std::map<int, double>> containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
|
||||
+// { dg-final { regexp-test om {std::experimental::optional containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
optional<std::string> os{ "stringy" };
|
||||
-// { dg-final { note-test os {std::experimental::optional<std::string> = {[contained value] = "stringy"}} } }
|
||||
+// { dg-final { note-test os {std::experimental::optional = {[contained value] = "stringy"}} } }
|
||||
|
||||
any a;
|
||||
// { dg-final { note-test a {std::experimental::any [no contained value]} } }
|
||||
@@ -66,7 +68,7 @@ main()
|
||||
any as2("stringiest");
|
||||
// { dg-final { regexp-test as2 {std::experimental::any containing const char \* = {\[contained value\] = 0x[[:xdigit:]]+ "stringiest"}} } }
|
||||
any am = *om;
|
||||
-// { dg-final { note-test am {std::experimental::any containing std::map with 3 elements = {[1] = 2, [3] = 4, [5] = 6}} } }
|
||||
+// { dg-final { regexp-test am {std::experimental::any containing std::(__debug::)?map with 3 elements = {\[1\] = 2, \[3\] = 4, \[5\] = 6}} } }
|
||||
|
||||
std::cout << "\n";
|
||||
return 0; // Mark SPOT
|
||||
@ -1,17 +0,0 @@
|
||||
2018-04-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/i386/i386.opt (mcet): Remporarily re-add as alias to -mshstk.
|
||||
|
||||
--- gcc/config/i386/i386.opt (revision 259613)
|
||||
+++ gcc/config/i386/i386.opt (revision 259612)
|
||||
@@ -1006,6 +1006,10 @@ mgeneral-regs-only
|
||||
Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
|
||||
Generate code which uses only the general registers.
|
||||
|
||||
+mcet
|
||||
+Target Undocumented Alias(mshstk)
|
||||
+;; Deprecated
|
||||
+
|
||||
mshstk
|
||||
Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
|
||||
Enable shadow stack built-in functions from Control-flow Enforcement
|
||||
@ -1,74 +0,0 @@
|
||||
commit ba374dfb937a8ac1c7c4740913331951a924f88b
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Wed May 12 10:38:35 2021 +0200
|
||||
|
||||
expand: Don't reuse DEBUG_EXPRs with vector type if they have different modes [PR100508]
|
||||
|
||||
The inliner doesn't remap DEBUG_EXPR_DECLs, so the same decls can appear
|
||||
in multiple functions.
|
||||
Furthermore, expansion reuses corresponding DEBUG_EXPRs too, so they again
|
||||
can be reused in multiple functions.
|
||||
Neither of that is a major problem, DEBUG_EXPRs are just magic value holders
|
||||
and what value they stand for is independent in each function and driven by
|
||||
what debug stmts or DEBUG_INSNs they are bound to.
|
||||
Except for DEBUG_EXPR*s with vector types, TYPE_MODE can be either BLKmode
|
||||
or some vector mode depending on whether current function's enabled ISAs
|
||||
support that vector mode or not. On the following testcase, we expand it
|
||||
first in foo function without AVX2 enabled and so the DEBUG_EXPR is
|
||||
BLKmode, but later the same DEBUG_EXPR_DECL is used in a simd clone with
|
||||
AVX2 enabled and expansion ICEs because of a mode mismatch.
|
||||
|
||||
The following patch fixes that by forcing recreation of a DEBUG_EXPR if
|
||||
there is a mode mismatch for vector typed DEBUG_EXPR_DECL, DEBUG_EXPRs
|
||||
will be still reused in between functions otherwise and within the same
|
||||
function the mode should be always the same.
|
||||
|
||||
2021-05-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/100508
|
||||
* cfgexpand.c (expand_debug_expr): For DEBUG_EXPR_DECL with vector
|
||||
type, don't reuse DECL_RTL if it has different mode, instead force
|
||||
creation of a new DEBUG_EXPR.
|
||||
|
||||
* gcc.dg/gomp/pr100508.c: New test.
|
||||
|
||||
(cherry picked from commit 19040050aa2c8ee890fc58dda48639fc91bf0af0)
|
||||
|
||||
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
|
||||
index b1535e15d28..a7d05202184 100644
|
||||
--- a/gcc/cfgexpand.c
|
||||
+++ b/gcc/cfgexpand.c
|
||||
@@ -4358,7 +4358,12 @@ expand_debug_expr (tree exp)
|
||||
op0 = DECL_RTL_IF_SET (exp);
|
||||
|
||||
if (op0)
|
||||
- return op0;
|
||||
+ {
|
||||
+ if (GET_MODE (op0) != mode)
|
||||
+ gcc_assert (VECTOR_TYPE_P (TREE_TYPE (exp)));
|
||||
+ else
|
||||
+ return op0;
|
||||
+ }
|
||||
|
||||
op0 = gen_rtx_DEBUG_EXPR (mode);
|
||||
DEBUG_EXPR_TREE_DECL (op0) = exp;
|
||||
diff --git a/gcc/testsuite/gcc.dg/gomp/pr100508.c b/gcc/testsuite/gcc.dg/gomp/pr100508.c
|
||||
new file mode 100644
|
||||
index 00000000000..c3fa2fc258e
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/gomp/pr100508.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* PR middle-end/100508 */
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -g -fopenmp-simd" } */
|
||||
+
|
||||
+typedef int __attribute__((__vector_size__(32))) V;
|
||||
+V j;
|
||||
+
|
||||
+#pragma omp declare simd
|
||||
+int
|
||||
+foo (void)
|
||||
+{
|
||||
+ V m = j;
|
||||
+ return 0;
|
||||
+}
|
||||
@ -1,137 +0,0 @@
|
||||
commit ebfe8b28d40746ff33724bd5b9ade2552e619213
|
||||
Author: Jason Merrill <jason@redhat.com>
|
||||
Date: Thu May 27 23:54:52 2021 -0400
|
||||
|
||||
c++: 'this' adjustment for devirtualized call
|
||||
|
||||
My patch for 95719 made us do a better job of finding the actual virtual
|
||||
function we want to call, but didn't update the 'this' pointer adjustment to
|
||||
match.
|
||||
|
||||
This backport also incorporates a bit of the r11-1638 reorganization.
|
||||
|
||||
PR c++/100797
|
||||
PR c++/95719
|
||||
|
||||
gcc/cp/ChangeLog:
|
||||
|
||||
* call.c (build_over_call): Adjust base_binfo in
|
||||
resolves_to_fixed_type_p case.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* g++.dg/inherit/virtual15.C: New test.
|
||||
* g++.dg/inherit/virtual15a.C: New test.
|
||||
|
||||
--- gcc/cp/call.c
|
||||
+++ gcc/cp/call.c
|
||||
@@ -8309,19 +8309,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
|| CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
|
||||
flags |= LOOKUP_NONVIRTUAL;
|
||||
|
||||
- /* If we know the dynamic type of the object, look up the final overrider
|
||||
- in the BINFO. */
|
||||
- if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
|
||||
- && resolves_to_fixed_type_p (arg))
|
||||
- {
|
||||
- tree binfo = cand->conversion_path;
|
||||
- if (BINFO_TYPE (binfo) != DECL_CONTEXT (fn))
|
||||
- binfo = lookup_base (binfo, DECL_CONTEXT (fn), ba_unique,
|
||||
- NULL, complain);
|
||||
- fn = lookup_vfn_in_binfo (DECL_VINDEX (fn), binfo);
|
||||
- flags |= LOOKUP_NONVIRTUAL;
|
||||
- }
|
||||
-
|
||||
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
|
||||
X is called for an object that is not of type X, or of a type
|
||||
derived from X, the behavior is undefined.
|
||||
@@ -8331,10 +8318,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
gcc_assert (TYPE_PTR_P (parmtype));
|
||||
/* Convert to the base in which the function was declared. */
|
||||
gcc_assert (cand->conversion_path != NULL_TREE);
|
||||
- converted_arg = build_base_path (PLUS_EXPR,
|
||||
- arg,
|
||||
- cand->conversion_path,
|
||||
- 1, complain);
|
||||
/* Check that the base class is accessible. */
|
||||
if (!accessible_base_p (TREE_TYPE (argtype),
|
||||
BINFO_TYPE (cand->conversion_path), true))
|
||||
@@ -8349,10 +8332,33 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
/* If fn was found by a using declaration, the conversion path
|
||||
will be to the derived class, not the base declaring fn. We
|
||||
must convert from derived to base. */
|
||||
- base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
|
||||
+ base_binfo = lookup_base (cand->conversion_path,
|
||||
TREE_TYPE (parmtype), ba_unique,
|
||||
NULL, complain);
|
||||
- converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
||||
+
|
||||
+ /* If we know the dynamic type of the object, look up the final overrider
|
||||
+ in the BINFO. */
|
||||
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
|
||||
+ && resolves_to_fixed_type_p (arg))
|
||||
+ {
|
||||
+ tree ov = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
|
||||
+
|
||||
+ /* And unwind base_binfo to match. If we don't find the type we're
|
||||
+ looking for in BINFO_INHERITANCE_CHAIN, we're looking at diamond
|
||||
+ inheritance; for now do a normal virtual call in that case. */
|
||||
+ tree octx = DECL_CONTEXT (ov);
|
||||
+ tree obinfo = base_binfo;
|
||||
+ while (obinfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (obinfo), octx))
|
||||
+ obinfo = BINFO_INHERITANCE_CHAIN (obinfo);
|
||||
+ if (obinfo)
|
||||
+ {
|
||||
+ fn = ov;
|
||||
+ base_binfo = obinfo;
|
||||
+ flags |= LOOKUP_NONVIRTUAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ converted_arg = build_base_path (PLUS_EXPR, arg,
|
||||
base_binfo, 1, complain);
|
||||
|
||||
argarray[j++] = converted_arg;
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/inherit/virtual15.C
|
||||
@@ -0,0 +1,18 @@
|
||||
+// PR c++/100797
|
||||
+// { dg-do run }
|
||||
+
|
||||
+bool ok = false;
|
||||
+struct S1 { virtual ~S1() {} };
|
||||
+struct S2 { virtual void f1() = 0; };
|
||||
+struct S3: S1, S2 {
|
||||
+ void f1() { f2(); }
|
||||
+ virtual void f2() = 0;
|
||||
+};
|
||||
+struct S4: S3 {
|
||||
+ void f2() { ok = true; }
|
||||
+ using S2::f1;
|
||||
+};
|
||||
+int main() {
|
||||
+ S4().f1();
|
||||
+ if (!ok) __builtin_abort ();
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/inherit/virtual15a.C
|
||||
@@ -0,0 +1,19 @@
|
||||
+// PR c++/100797 plus diamond inheritance
|
||||
+// { dg-do run }
|
||||
+
|
||||
+bool ok = false;
|
||||
+struct S1 { virtual ~S1() {} };
|
||||
+struct S2 { virtual void f1() = 0; };
|
||||
+struct S3: S1, virtual S2 {
|
||||
+ void f1() { f2(); }
|
||||
+ virtual void f2() = 0;
|
||||
+};
|
||||
+struct SX: virtual S2 { };
|
||||
+struct S4: SX, S3 {
|
||||
+ void f2() { ok = true; }
|
||||
+ using S2::f1;
|
||||
+};
|
||||
+int main() {
|
||||
+ S4().f1();
|
||||
+ if (!ok) __builtin_abort ();
|
||||
+}
|
||||
@ -1,98 +0,0 @@
|
||||
From b005000525ab0a5116d21217c41fb1da5bd03796 Mon Sep 17 00:00:00 2001
|
||||
From: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Fri, 6 May 2022 21:19:17 +0100
|
||||
Subject: [PATCH] libstdc++: Fix deserialization for std::normal_distribution
|
||||
[PR105502]
|
||||
|
||||
This fixes a regression in std::normal_distribution deserialization that
|
||||
caused the object to be left unchanged if the __state_avail value read
|
||||
from the stream was false.
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/105502
|
||||
* include/bits/random.tcc
|
||||
(operator>>(basic_istream<C,T>&, normal_distribution<R>&)):
|
||||
Update state when __state_avail is false.
|
||||
* testsuite/26_numerics/random/normal_distribution/operators/serialize.cc:
|
||||
Check that deserialized object equals serialized one.
|
||||
|
||||
(cherry picked from commit 909ef4e2727ddc50a32d6ad379a1f1ccc1043c6a)
|
||||
---
|
||||
libstdc++-v3/include/bits/random.tcc | 2 +-
|
||||
.../operators/serialize.cc | 36 ++++++++++++++++++-
|
||||
2 files changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
|
||||
index 0a299baedc5..0f758671f69 100644
|
||||
--- a/libstdc++-v3/include/bits/random.tcc
|
||||
+++ b/libstdc++-v3/include/bits/random.tcc
|
||||
@@ -1941,7 +1941,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
bool __saved_avail;
|
||||
if (__is >> __mean >> __stddev >> __saved_avail)
|
||||
{
|
||||
- if (__saved_avail && (__is >> __x._M_saved))
|
||||
+ if (!__saved_avail || (__is >> __x._M_saved))
|
||||
{
|
||||
__x._M_saved_available = __saved_avail;
|
||||
__x.param(typename normal_distribution<_RealType>::
|
||||
diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
index a65d4004161..8cc70886bc7 100644
|
||||
--- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
+++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
+#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
@@ -37,10 +38,43 @@ test01()
|
||||
str << u;
|
||||
|
||||
str >> v;
|
||||
+ VERIFY( u == v );
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+test_pr105502()
|
||||
+{
|
||||
+ // PR libstdc++/105502 std::normal_distribution deserialization issue
|
||||
+ std::stringstream str;
|
||||
+ std::normal_distribution<> d{1, 2}, d2;
|
||||
+ std::minstd_rand0 g;
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
+
|
||||
+ (void) d(g); // sets d._M_saved_available = true
|
||||
+ str.str("");
|
||||
+ str.clear();
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
+
|
||||
+ (void) d(g); // sets d._M_saved_available = false
|
||||
+ str.str("");
|
||||
+ str.clear();
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
- return 0;
|
||||
+ test_pr105502();
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
commit e150cbf591759af10f3d57acbe0eb381aafa00de
|
||||
Author: Richard Biener <rguenther@suse.de>
|
||||
Date: Thu Aug 17 13:10:14 2023 +0200
|
||||
|
||||
tree-optimization/111039 - abnormals and bit test merging
|
||||
|
||||
The following guards the bit test merging code in if-combine against
|
||||
the appearance of SSA names used in abnormal PHIs.
|
||||
|
||||
PR tree-optimization/111039
|
||||
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check for
|
||||
SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
|
||||
|
||||
* gcc.dg/pr111039.c: New testcase.
|
||||
|
||||
(cherry picked from commit 482551a79a3d3f107f6239679ee74655cfe8707e)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr111039.c b/gcc/testsuite/gcc.dg/pr111039.c
|
||||
new file mode 100644
|
||||
index 00000000000..bec9983b35f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/pr111039.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O" } */
|
||||
+
|
||||
+int _setjmp ();
|
||||
+void abcd ();
|
||||
+void abcde ();
|
||||
+void compiler_corruption_function(int flags)
|
||||
+{
|
||||
+ int nowait = flags & 1048576, isexpand = flags & 8388608;
|
||||
+ abcd();
|
||||
+ _setjmp(flags);
|
||||
+ if (nowait && isexpand)
|
||||
+ flags &= 0;
|
||||
+ abcde();
|
||||
+}
|
||||
--- a/gcc/tree-ssa-ifcombine.c
|
||||
+++ b/gcc/tree-ssa-ifcombine.c
|
||||
@@ -407,6 +407,9 @@ ifcombine_ifandif (basic_block inner_con
|
||||
{
|
||||
tree t, t2;
|
||||
|
||||
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
|
||||
+ return false;
|
||||
+
|
||||
/* Do it. */
|
||||
gsi = gsi_for_stmt (inner_cond);
|
||||
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
|
||||
@@ -457,6 +460,10 @@ ifcombine_ifandif (basic_block inner_con
|
||||
gimple_stmt_iterator gsi;
|
||||
tree t;
|
||||
|
||||
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1)
|
||||
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2))
|
||||
+ return false;
|
||||
+
|
||||
/* Find the common name which is bit-tested. */
|
||||
if (name1 == name2)
|
||||
;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user