Compare commits
No commits in common. "imports/c8s/gcc-8.5.0-8.el8" and "c8" have entirely different histories.
imports/c8
...
c8
59
SOURCES/gcc8-RHEL-32886.patch
Normal file
59
SOURCES/gcc8-RHEL-32886.patch
Normal file
@ -0,0 +1,59 @@
|
||||
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++);
|
||||
+}
|
294
SOURCES/gcc8-harden-1.patch
Normal file
294
SOURCES/gcc8-harden-1.patch
Normal file
@ -0,0 +1,294 @@
|
||||
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
|
||||
|
155
SOURCES/gcc8-harden-2.patch
Normal file
155
SOURCES/gcc8-harden-2.patch
Normal file
@ -0,0 +1,155 @@
|
||||
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
|
||||
|
108
SOURCES/gcc8-harden-3.patch
Normal file
108
SOURCES/gcc8-harden-3.patch
Normal file
@ -0,0 +1,108 @@
|
||||
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
|
||||
|
75
SOURCES/gcc8-harden-4.patch
Normal file
75
SOURCES/gcc8-harden-4.patch
Normal file
@ -0,0 +1,75 @@
|
||||
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
|
||||
|
516
SOURCES/gcc8-libgfortran-default-values.patch
Normal file
516
SOURCES/gcc8-libgfortran-default-values.patch
Normal file
@ -0,0 +1,516 @@
|
||||
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)
|
||||
{
|
61
SOURCES/gcc8-libstdc++-make_shared.patch
Normal file
61
SOURCES/gcc8-libstdc++-make_shared.patch
Normal file
@ -0,0 +1,61 @@
|
||||
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" }
|
98
SOURCES/gcc8-pr105502.patch
Normal file
98
SOURCES/gcc8-pr105502.patch
Normal file
@ -0,0 +1,98 @@
|
||||
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
|
||||
|
61
SOURCES/gcc8-pr111039.patch
Normal file
61
SOURCES/gcc8-pr111039.patch
Normal file
@ -0,0 +1,61 @@
|
||||
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)
|
||||
;
|
68
SOURCES/gcc8-pr111070.patch
Normal file
68
SOURCES/gcc8-pr111070.patch
Normal file
@ -0,0 +1,68 @@
|
||||
commit ad42dcf501e41713047cf6c47cbb1dd9f01088a4
|
||||
Author: Richard Biener <rguenther@suse.de>
|
||||
Date: Mon Aug 21 09:01:00 2023 +0200
|
||||
|
||||
tree-optimization/111070 - fix ICE with recent ifcombine fix
|
||||
|
||||
We now got test coverage for non-SSA name bits so the following amends
|
||||
the SSA_NAME_OCCURS_IN_ABNORMAL_PHI checks.
|
||||
|
||||
PR tree-optimization/111070
|
||||
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check we have
|
||||
an SSA name before checking SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
|
||||
|
||||
* gcc.dg/pr111070.c: New testcase.
|
||||
|
||||
(cherry picked from commit 966b0a96523fb7adbf498ac71df5e033c70dc546)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr111070.c b/gcc/testsuite/gcc.dg/pr111070.c
|
||||
new file mode 100644
|
||||
index 00000000000..1ebc7adf782
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/pr111070.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O" } */
|
||||
+
|
||||
+/* common */
|
||||
+char c;
|
||||
+/* arrays must be 8 byte aligned, regardless of size */
|
||||
+char c_ary[1];
|
||||
+
|
||||
+/* data */
|
||||
+char d = 1;
|
||||
+char d_ary[1] = {1};
|
||||
+
|
||||
+int main ()
|
||||
+{
|
||||
+ if (((unsigned long)&c_ary[0] & 7) != 0)
|
||||
+ return 1;
|
||||
+ if (((unsigned long)&d_ary[0] & 7) != 0)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
--- a/gcc/tree-ssa-ifcombine.c
|
||||
+++ b/gcc/tree-ssa-ifcombine.c
|
||||
@@ -436,7 +436,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
|
||||
{
|
||||
tree t, t2;
|
||||
|
||||
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
|
||||
+ if (TREE_CODE (name1) == SSA_NAME
|
||||
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
|
||||
return false;
|
||||
|
||||
/* Do it. */
|
||||
@@ -495,8 +496,10 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
|
||||
gimple_stmt_iterator gsi;
|
||||
tree t;
|
||||
|
||||
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1)
|
||||
- || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2))
|
||||
+ if ((TREE_CODE (name1) == SSA_NAME
|
||||
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
|
||||
+ || (TREE_CODE (name2) == SSA_NAME
|
||||
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2)))
|
||||
return false;
|
||||
|
||||
/* Find the common name which is bit-tested. */
|
71
SOURCES/gcc8-pr87723.patch
Normal file
71
SOURCES/gcc8-pr87723.patch
Normal file
@ -0,0 +1,71 @@
|
||||
commit 8c21b0d164f33d9d47acc26f4f9b99b53e3b1945
|
||||
Author: Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
Date: Tue Nov 6 10:22:05 2018 +0000
|
||||
|
||||
S/390: Fix PR87723
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
2018-11-06 Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
|
||||
PR target/87723
|
||||
* config/s390/s390.md ("*r<noxa>sbg_di_rotl"): Remove mode
|
||||
attributes for operands 3 and 4.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
2018-11-06 Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
|
||||
PR target/87723
|
||||
* gcc.target/s390/pr87723.c: New test.
|
||||
|
||||
From-SVN: r265832
|
||||
|
||||
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
|
||||
index 8e7b285e1c3..4ffd438c07c 100644
|
||||
--- a/gcc/config/s390/s390.md
|
||||
+++ b/gcc/config/s390/s390.md
|
||||
@@ -4230,7 +4230,7 @@ (define_insn "*r<noxa>sbg_di_rotl"
|
||||
(match_operand:DI 4 "nonimmediate_operand" "0")))
|
||||
(clobber (reg:CC CC_REGNUM))]
|
||||
"TARGET_Z10"
|
||||
- "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
|
||||
+ "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
|
||||
[(set_attr "op_type" "RIE")])
|
||||
|
||||
; rosbg, rxsbg
|
||||
diff --git a/gcc/testsuite/gcc.target/s390/pr87723.c b/gcc/testsuite/gcc.target/s390/pr87723.c
|
||||
new file mode 100644
|
||||
index 00000000000..b0e8a5a3118
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/s390/pr87723.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O3 -march=z196 -m64 -mzarch" } */
|
||||
+
|
||||
+unsigned long a;
|
||||
+int b;
|
||||
+void c(char* i) {
|
||||
+ for (;;) {
|
||||
+ char g = 0;
|
||||
+ for (; g < 24; ++g)
|
||||
+ b = a << g | a >> 64 - g;
|
||||
+ {
|
||||
+ char *d = i;
|
||||
+ long h = b;
|
||||
+ char e = 0;
|
||||
+ for (; e < 8; ++e)
|
||||
+ d[e] = h;
|
||||
+ }
|
||||
+ char *d = i;
|
||||
+ signed e;
|
||||
+ unsigned long f = 0;
|
||||
+ e = 7;
|
||||
+ for (; e; --e) {
|
||||
+ f <<= 8;
|
||||
+ f |= d[e];
|
||||
+ }
|
||||
+ for (; e < 8; ++e)
|
||||
+ d[e] = f;
|
||||
+ }
|
||||
+}
|
77
SOURCES/gcc8-pr99074.patch
Normal file
77
SOURCES/gcc8-pr99074.patch
Normal file
@ -0,0 +1,77 @@
|
||||
commit 6d134ca4b963706f31251f061fc180e517b32546
|
||||
Author: Martin Sebor <msebor@redhat.com>
|
||||
Date: Tue Feb 23 14:09:00 2021 -0700
|
||||
|
||||
PR c++/99074 - crash in dynamic_cast<>() on null pointer
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR c++/99074
|
||||
* libsupc++/dyncast.cc (__dynamic_cast): Return null when
|
||||
first argument is null.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
PR c++/99074
|
||||
* g++.dg/warn/Wnonnull11.C: New test.
|
||||
|
||||
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull11.C b/gcc/testsuite/g++.dg/warn/Wnonnull11.C
|
||||
new file mode 100644
|
||||
index 00000000000..5f1b69d9a41
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull11.C
|
||||
@@ -0,0 +1,40 @@
|
||||
+/* PR c++/99074 - gcc 8 and above is crashing with dynamic_cast<>() on null
|
||||
+ pointer with optimization level -O1 and above
|
||||
+ { dg-do run }
|
||||
+ { dg-options "-O1 -Wall" } */
|
||||
+
|
||||
+class Base
|
||||
+{
|
||||
+public:
|
||||
+ virtual ~Base() {}
|
||||
+ virtual void op() = 0;
|
||||
+};
|
||||
+
|
||||
+class Object: public virtual Base { };
|
||||
+
|
||||
+class AbstractBase: public virtual Base
|
||||
+{
|
||||
+public:
|
||||
+ Object* _to_object ()
|
||||
+ {
|
||||
+ return dynamic_cast<Object*>(this); // { dg-warning "\\\[-Wnonnull" "" { xfail *-*-* } }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+class MyAbstractClass: public virtual AbstractBase
|
||||
+{
|
||||
+public:
|
||||
+ static MyAbstractClass* _nil () { return 0; }
|
||||
+};
|
||||
+
|
||||
+
|
||||
+int main ()
|
||||
+{
|
||||
+ MyAbstractClass *my_abs_type = MyAbstractClass::_nil ();
|
||||
+ AbstractBase *abs_base = my_abs_type;
|
||||
+ Object *obj = abs_base->_to_object ();
|
||||
+
|
||||
+ __builtin_printf ("object is: %p\n", obj);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/libstdc++-v3/libsupc++/dyncast.cc b/libstdc++-v3/libsupc++/dyncast.cc
|
||||
index b7d98495ad3..f8f707ee4d4 100644
|
||||
--- a/libstdc++-v3/libsupc++/dyncast.cc
|
||||
+++ b/libstdc++-v3/libsupc++/dyncast.cc
|
||||
@@ -47,6 +47,9 @@ __dynamic_cast (const void *src_ptr, // object started from
|
||||
const __class_type_info *dst_type, // desired target type
|
||||
ptrdiff_t src2dst) // how src and dst are related
|
||||
{
|
||||
+ if (!src_ptr)
|
||||
+ /* Handle precondition violations gracefully. */
|
||||
+ return NULL;
|
||||
const void *vtable = *static_cast <const void *const *> (src_ptr);
|
||||
const vtable_prefix *prefix =
|
||||
adjust_pointer <vtable_prefix> (vtable,
|
47
SOURCES/gcc8-pr99536.patch
Normal file
47
SOURCES/gcc8-pr99536.patch
Normal file
@ -0,0 +1,47 @@
|
||||
commit 29dad307b5d7cfdb6626c11c8e43ebff941c950b
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Thu Mar 11 16:43:51 2021 +0000
|
||||
|
||||
libstdc++: Initialize std::normal_distribution::_M_saved [PR 99536]
|
||||
|
||||
This avoids a false positive -Wmaybe-uninitialized warning, by
|
||||
initializing _M_saved on construction.
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/99536
|
||||
* include/bits/random.h (normal_distribution): Use
|
||||
default-initializer for _M_saved and _M_saved_available.
|
||||
|
||||
(cherry picked from commit 67e397660611990efd98f9e4106c1ee81f6803a4)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
|
||||
index b36781ed290..3385345d273 100644
|
||||
--- a/libstdc++-v3/include/bits/random.h
|
||||
+++ b/libstdc++-v3/include/bits/random.h
|
||||
@@ -1974,12 +1974,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
explicit
|
||||
normal_distribution(result_type __mean = result_type(0),
|
||||
result_type __stddev = result_type(1))
|
||||
- : _M_param(__mean, __stddev), _M_saved_available(false)
|
||||
+ : _M_param(__mean, __stddev)
|
||||
{ }
|
||||
|
||||
explicit
|
||||
normal_distribution(const param_type& __p)
|
||||
- : _M_param(__p), _M_saved_available(false)
|
||||
+ : _M_param(__p)
|
||||
{ }
|
||||
|
||||
/**
|
||||
@@ -2158,8 +2158,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
const param_type& __p);
|
||||
|
||||
param_type _M_param;
|
||||
- result_type _M_saved;
|
||||
- bool _M_saved_available;
|
||||
+ result_type _M_saved = 0;
|
||||
+ bool _M_saved_available = false;
|
||||
};
|
||||
|
||||
/**
|
456
SOURCES/gcc8-rh2001788.patch
Normal file
456
SOURCES/gcc8-rh2001788.patch
Normal file
@ -0,0 +1,456 @@
|
||||
commit ee3db7c8f844556d35a66b3732bad9f44a086491
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Mon Sep 27 20:44:24 2021 +0100
|
||||
|
||||
libstdc++: Fix handling of invalid ranges in std::regex [PR102447]
|
||||
|
||||
std::regex currently allows invalid bracket ranges such as [\w-a] which
|
||||
are only allowed by ECMAScript when in web browser compatibility mode.
|
||||
It should be an error, because the start of the range is a character
|
||||
class, not a single character. The current implementation of
|
||||
_Compiler::_M_expression_term does not provide a way to reject this,
|
||||
because we only remember a previous character, not whether we just
|
||||
processed a character class (or collating symbol etc.)
|
||||
|
||||
This patch replaces the pair<bool, CharT> used to emulate
|
||||
optional<CharT> with a custom class closer to pair<tribool,CharT>. That
|
||||
allows us to track three states, so that we can tell when we've just
|
||||
seen a character class.
|
||||
|
||||
With this additional state the code in _M_expression_term for processing
|
||||
the _S_token_bracket_dash can be improved to correctly reject the [\w-a]
|
||||
case, without regressing for valid cases such as [\w-] and [----].
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/102447
|
||||
* include/bits/regex_compiler.h (_Compiler::_BracketState): New
|
||||
class.
|
||||
(_Compiler::_BrackeyMatcher): New alias template.
|
||||
(_Compiler::_M_expression_term): Change pair<bool, CharT>
|
||||
parameter to _BracketState. Process first character for
|
||||
ECMAScript syntax as well as POSIX.
|
||||
* include/bits/regex_compiler.tcc
|
||||
(_Compiler::_M_insert_bracket_matcher): Pass _BracketState.
|
||||
(_Compiler::_M_expression_term): Use _BracketState to store
|
||||
state between calls. Improve handling of dashes in ranges.
|
||||
* testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc:
|
||||
Add more tests for ranges containing dashes. Check invalid
|
||||
ranges with character class at the beginning.
|
||||
|
||||
(cherry picked from commit 7ce3c230edf6e498e125c805a6dd313bf87dc439)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
|
||||
index 7e5c2073554..2eb1c3f7863 100644
|
||||
--- a/libstdc++-v3/include/bits/regex_compiler.h
|
||||
+++ b/libstdc++-v3/include/bits/regex_compiler.h
|
||||
@@ -122,13 +122,45 @@ namespace __detail
|
||||
void
|
||||
_M_insert_bracket_matcher(bool __neg);
|
||||
|
||||
- // Returns true if successfully matched one term and should continue.
|
||||
+ // Cache of the last atom seen in a bracketed range expression.
|
||||
+ struct _BracketState
|
||||
+ {
|
||||
+ enum class _Type : char { _None, _Char, _Class } _M_type = _Type::_None;
|
||||
+ _CharT _M_char;
|
||||
+
|
||||
+ void
|
||||
+ set(_CharT __c) noexcept { _M_type = _Type::_Char; _M_char = __c; }
|
||||
+
|
||||
+ _GLIBCXX_NODISCARD _CharT
|
||||
+ get() const noexcept { return _M_char; }
|
||||
+
|
||||
+ void
|
||||
+ reset(_Type __t = _Type::_None) noexcept { _M_type = __t; }
|
||||
+
|
||||
+ explicit operator bool() const noexcept
|
||||
+ { return _M_type != _Type::_None; }
|
||||
+
|
||||
+ // Previous token was a single character.
|
||||
+ _GLIBCXX_NODISCARD bool
|
||||
+ _M_is_char() const noexcept { return _M_type == _Type::_Char; }
|
||||
+
|
||||
+ // Previous token was a character class, equivalent class,
|
||||
+ // collating symbol etc.
|
||||
+ _GLIBCXX_NODISCARD bool
|
||||
+ _M_is_class() const noexcept { return _M_type == _Type::_Class; }
|
||||
+ };
|
||||
+
|
||||
+ template<bool __icase, bool __collate>
|
||||
+ using _BracketMatcher
|
||||
+ = std::__detail::_BracketMatcher<_TraitsT, __icase, __collate>;
|
||||
+
|
||||
+ // Returns true if successfully parsed one term and should continue
|
||||
+ // compiling a bracket expression.
|
||||
// Returns false if the compiler should move on.
|
||||
template<bool __icase, bool __collate>
|
||||
bool
|
||||
- _M_expression_term(pair<bool, _CharT>& __last_char,
|
||||
- _BracketMatcher<_TraitsT, __icase, __collate>&
|
||||
- __matcher);
|
||||
+ _M_expression_term(_BracketState& __last_char,
|
||||
+ _BracketMatcher<__icase, __collate>& __matcher);
|
||||
|
||||
int
|
||||
_M_cur_int_value(int __radix);
|
||||
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
index b1169428afb..5877d30ba52 100644
|
||||
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
@@ -140,7 +140,8 @@ namespace __detail
|
||||
return true;
|
||||
if (this->_M_atom())
|
||||
{
|
||||
- while (this->_M_quantifier());
|
||||
+ while (this->_M_quantifier())
|
||||
+ ;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -410,7 +411,7 @@ namespace __detail
|
||||
_M_insert_character_class_matcher()
|
||||
{
|
||||
__glibcxx_assert(_M_value.size() == 1);
|
||||
- _BracketMatcher<_TraitsT, __icase, __collate> __matcher
|
||||
+ _BracketMatcher<__icase, __collate> __matcher
|
||||
(_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits);
|
||||
__matcher._M_add_character_class(_M_value, false);
|
||||
__matcher._M_ready();
|
||||
@@ -424,25 +425,17 @@ namespace __detail
|
||||
_Compiler<_TraitsT>::
|
||||
_M_insert_bracket_matcher(bool __neg)
|
||||
{
|
||||
- _BracketMatcher<_TraitsT, __icase, __collate> __matcher(__neg, _M_traits);
|
||||
- pair<bool, _CharT> __last_char; // Optional<_CharT>
|
||||
- __last_char.first = false;
|
||||
- if (!(_M_flags & regex_constants::ECMAScript))
|
||||
- {
|
||||
- if (_M_try_char())
|
||||
- {
|
||||
- __last_char.first = true;
|
||||
- __last_char.second = _M_value[0];
|
||||
- }
|
||||
- else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
|
||||
- {
|
||||
- __last_char.first = true;
|
||||
- __last_char.second = '-';
|
||||
- }
|
||||
- }
|
||||
- while (_M_expression_term(__last_char, __matcher));
|
||||
- if (__last_char.first)
|
||||
- __matcher._M_add_char(__last_char.second);
|
||||
+ _BracketMatcher<__icase, __collate> __matcher(__neg, _M_traits);
|
||||
+ _BracketState __last_char;
|
||||
+ if (_M_try_char())
|
||||
+ __last_char.set(_M_value[0]);
|
||||
+ else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
|
||||
+ // Dash as first character is a normal character.
|
||||
+ __last_char.set('-');
|
||||
+ while (_M_expression_term(__last_char, __matcher))
|
||||
+ ;
|
||||
+ if (__last_char._M_is_char())
|
||||
+ __matcher._M_add_char(__last_char.get());
|
||||
__matcher._M_ready();
|
||||
_M_stack.push(_StateSeqT(
|
||||
*_M_nfa,
|
||||
@@ -453,27 +446,27 @@ namespace __detail
|
||||
template<bool __icase, bool __collate>
|
||||
bool
|
||||
_Compiler<_TraitsT>::
|
||||
- _M_expression_term(pair<bool, _CharT>& __last_char,
|
||||
- _BracketMatcher<_TraitsT, __icase, __collate>& __matcher)
|
||||
+ _M_expression_term(_BracketState& __last_char,
|
||||
+ _BracketMatcher<__icase, __collate>& __matcher)
|
||||
{
|
||||
if (_M_match_token(_ScannerT::_S_token_bracket_end))
|
||||
return false;
|
||||
|
||||
+ // Add any previously cached char into the matcher and update cache.
|
||||
const auto __push_char = [&](_CharT __ch)
|
||||
{
|
||||
- if (__last_char.first)
|
||||
- __matcher._M_add_char(__last_char.second);
|
||||
- else
|
||||
- __last_char.first = true;
|
||||
- __last_char.second = __ch;
|
||||
+ if (__last_char._M_is_char())
|
||||
+ __matcher._M_add_char(__last_char.get());
|
||||
+ __last_char.set(__ch);
|
||||
};
|
||||
- const auto __flush = [&]
|
||||
+ // Add any previously cached char into the matcher and update cache.
|
||||
+ const auto __push_class = [&]
|
||||
{
|
||||
- if (__last_char.first)
|
||||
- {
|
||||
- __matcher._M_add_char(__last_char.second);
|
||||
- __last_char.first = false;
|
||||
- }
|
||||
+ if (__last_char._M_is_char())
|
||||
+ __matcher._M_add_char(__last_char.get());
|
||||
+ // We don't cache anything here, just record that the last thing
|
||||
+ // processed was a character class (or similar).
|
||||
+ __last_char.reset(_BracketState::_Type::_Class);
|
||||
};
|
||||
|
||||
if (_M_match_token(_ScannerT::_S_token_collsymbol))
|
||||
@@ -482,16 +475,16 @@ namespace __detail
|
||||
if (__symbol.size() == 1)
|
||||
__push_char(__symbol[0]);
|
||||
else
|
||||
- __flush();
|
||||
+ __push_class();
|
||||
}
|
||||
else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
|
||||
{
|
||||
- __flush();
|
||||
+ __push_class();
|
||||
__matcher._M_add_equivalence_class(_M_value);
|
||||
}
|
||||
else if (_M_match_token(_ScannerT::_S_token_char_class_name))
|
||||
{
|
||||
- __flush();
|
||||
+ __push_class();
|
||||
__matcher._M_add_character_class(_M_value, false);
|
||||
}
|
||||
else if (_M_try_char())
|
||||
@@ -508,49 +501,50 @@ namespace __detail
|
||||
// It turns out that no one reads BNFs ;)
|
||||
else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
|
||||
{
|
||||
- if (!__last_char.first)
|
||||
+ if (_M_match_token(_ScannerT::_S_token_bracket_end))
|
||||
{
|
||||
- if (!(_M_flags & regex_constants::ECMAScript))
|
||||
- {
|
||||
- if (_M_match_token(_ScannerT::_S_token_bracket_end))
|
||||
- {
|
||||
- __push_char('-');
|
||||
- return false;
|
||||
- }
|
||||
- __throw_regex_error(
|
||||
- regex_constants::error_range,
|
||||
- "Unexpected dash in bracket expression. For POSIX syntax, "
|
||||
- "a dash is not treated literally only when it is at "
|
||||
- "beginning or end.");
|
||||
- }
|
||||
+ // For "-]" the dash is a literal character.
|
||||
__push_char('-');
|
||||
+ return false;
|
||||
}
|
||||
- else
|
||||
+ else if (__last_char._M_is_class())
|
||||
+ {
|
||||
+ // "\\w-" is invalid, start of range must be a single char.
|
||||
+ __throw_regex_error(regex_constants::error_range,
|
||||
+ "Invalid start of range in bracket expression.");
|
||||
+ }
|
||||
+ else if (__last_char._M_is_char())
|
||||
{
|
||||
if (_M_try_char())
|
||||
{
|
||||
- __matcher._M_make_range(__last_char.second, _M_value[0]);
|
||||
- __last_char.first = false;
|
||||
+ // "x-y"
|
||||
+ __matcher._M_make_range(__last_char.get(), _M_value[0]);
|
||||
+ __last_char.reset();
|
||||
}
|
||||
else if (_M_match_token(_ScannerT::_S_token_bracket_dash))
|
||||
{
|
||||
- __matcher._M_make_range(__last_char.second, '-');
|
||||
- __last_char.first = false;
|
||||
+ // "x--"
|
||||
+ __matcher._M_make_range(__last_char.get(), '-');
|
||||
+ __last_char.reset();
|
||||
}
|
||||
else
|
||||
- {
|
||||
- if (_M_scanner._M_get_token()
|
||||
- != _ScannerT::_S_token_bracket_end)
|
||||
- __throw_regex_error(
|
||||
- regex_constants::error_range,
|
||||
- "Character is expected after a dash.");
|
||||
- __push_char('-');
|
||||
- }
|
||||
+ __throw_regex_error(regex_constants::error_range,
|
||||
+ "Invalid end of range in bracket expression.");
|
||||
}
|
||||
+ else if (_M_flags & regex_constants::ECMAScript)
|
||||
+ {
|
||||
+ // A dash that is not part of an existing range. Might be the
|
||||
+ // start of a new range, or might just be a literal '-' char.
|
||||
+ // Only ECMAScript allows that in the middle of a bracket expr.
|
||||
+ __push_char('-');
|
||||
+ }
|
||||
+ else
|
||||
+ __throw_regex_error(regex_constants::error_range,
|
||||
+ "Invalid dash in bracket expression.");
|
||||
}
|
||||
else if (_M_match_token(_ScannerT::_S_token_quoted_class))
|
||||
{
|
||||
- __flush();
|
||||
+ __push_class();
|
||||
__matcher._M_add_character_class(_M_value,
|
||||
_M_ctype.is(_CtypeT::upper,
|
||||
_M_value[0]));
|
||||
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
|
||||
index 236ab663fc0..57088f5af83 100644
|
||||
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
|
||||
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/cstring_bracket_01.cc
|
||||
@@ -68,6 +68,16 @@ test01()
|
||||
void
|
||||
test02()
|
||||
{
|
||||
+ VERIFY(regex_match("-", regex("[-]", regex_constants::ECMAScript)));
|
||||
+ VERIFY(regex_match("-", regex("[--]", regex_constants::ECMAScript)));
|
||||
+ VERIFY(regex_match("-", regex("[---]", regex_constants::ECMAScript)));
|
||||
+ VERIFY(regex_match("-", regex("[----]", regex_constants::ECMAScript)));
|
||||
+ VERIFY(regex_match("-", regex("[-----]", regex_constants::ECMAScript)));
|
||||
+
|
||||
+ VERIFY(regex_match("-", regex("[-]", regex_constants::extended)));
|
||||
+ VERIFY(regex_match("-", regex("[--]", regex_constants::extended)));
|
||||
+ VERIFY(regex_match("-", regex("[---]", regex_constants::extended)));
|
||||
+ VERIFY(regex_match("-", regex("[----]", regex_constants::extended)));
|
||||
try
|
||||
{
|
||||
std::regex re("[-----]", std::regex::extended);
|
||||
@@ -77,7 +87,6 @@ test02()
|
||||
{
|
||||
VERIFY(e.code() == std::regex_constants::error_range);
|
||||
}
|
||||
- std::regex re("[-----]", std::regex::ECMAScript);
|
||||
|
||||
VERIFY(!regex_match("b", regex("[-ac]", regex_constants::extended)));
|
||||
VERIFY(!regex_match("b", regex("[ac-]", regex_constants::extended)));
|
||||
@@ -92,7 +101,27 @@ test02()
|
||||
}
|
||||
catch (const std::regex_error& e)
|
||||
{
|
||||
+ VERIFY(e.code() == std::regex_constants::error_range);
|
||||
+ }
|
||||
+ try
|
||||
+ {
|
||||
+ regex("[@--]", regex_constants::extended);
|
||||
+ VERIFY(false);
|
||||
}
|
||||
+ catch (const std::regex_error& e)
|
||||
+ {
|
||||
+ VERIFY(e.code() == std::regex_constants::error_range);
|
||||
+ }
|
||||
+ try
|
||||
+ {
|
||||
+ regex("[--%]", regex_constants::extended);
|
||||
+ VERIFY(false);
|
||||
+ }
|
||||
+ catch (const std::regex_error& e)
|
||||
+ {
|
||||
+ VERIFY(e.code() == std::regex_constants::error_range);
|
||||
+ }
|
||||
+
|
||||
VERIFY(regex_match("].", regex("[][.hyphen.]-0]*", regex_constants::extended)));
|
||||
}
|
||||
|
||||
@@ -157,6 +186,36 @@ test06()
|
||||
VERIFY(regex_match("a-", debian_cron_namespace_ok));
|
||||
}
|
||||
|
||||
+// libstdc++/102447
|
||||
+void
|
||||
+test07()
|
||||
+{
|
||||
+ VERIFY(regex_match("-", std::regex("[\\w-]", std::regex::ECMAScript)));
|
||||
+ VERIFY(regex_match("a", std::regex("[\\w-]", std::regex::ECMAScript)));
|
||||
+ VERIFY(regex_match("-", std::regex("[a-]", std::regex::ECMAScript)));
|
||||
+ VERIFY(regex_match("a", std::regex("[a-]", std::regex::ECMAScript)));
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ std::regex re("[\\w-a]", std::regex::ECMAScript);
|
||||
+ VERIFY(false);
|
||||
+ }
|
||||
+ catch (const std::regex_error& e)
|
||||
+ {
|
||||
+ VERIFY(e.code() == std::regex_constants::error_range);
|
||||
+ }
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ std::regex re("[\\w--]", std::regex::ECMAScript);
|
||||
+ VERIFY(false);
|
||||
+ }
|
||||
+ catch (const std::regex_error& e)
|
||||
+ {
|
||||
+ VERIFY(e.code() == std::regex_constants::error_range);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int
|
||||
main()
|
||||
{
|
||||
@@ -166,6 +225,7 @@ main()
|
||||
test04();
|
||||
test05();
|
||||
test06();
|
||||
+ test07();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit 1851cc4c5f2666dfdec53a2ada57095ffc59e08b
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Mon Dec 13 13:36:33 2021 +0000
|
||||
|
||||
libstdc++: Fix non-reserved name in <regex> header
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
* include/bits/regex_compiler.tcc (_Compiler::_M_match_token):
|
||||
Use reserved name for parameter.
|
||||
* testsuite/17_intro/names.cc: Check "token".
|
||||
|
||||
(cherry picked from commit b0e6a257f1862e217cdf19332ea0f7bad56dcddc)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
index 8af920e5fe9..b1169428afb 100644
|
||||
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
|
||||
@@ -586,9 +586,9 @@ namespace __detail
|
||||
template<typename _TraitsT>
|
||||
bool
|
||||
_Compiler<_TraitsT>::
|
||||
- _M_match_token(_TokenT token)
|
||||
+ _M_match_token(_TokenT __token)
|
||||
{
|
||||
- if (token == _M_scanner._M_get_token())
|
||||
+ if (__token == _M_scanner._M_get_token())
|
||||
{
|
||||
_M_value = _M_scanner._M_get_value();
|
||||
_M_scanner._M_advance();
|
||||
diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
index d758138dfb1..6c06aba7228 100644
|
||||
--- a/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
|
||||
@@ -99,6 +99,7 @@
|
||||
#define z (
|
||||
|
||||
#define tmp (
|
||||
+#define token (
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#define uses_allocator (
|
||||
--- a/libstdc++-v3/include/bits/c++config.orig 2022-07-08 15:06:14.083231445 -0400
|
||||
+++ b/libstdc++-v3/include/bits/c++config 2022-07-08 15:06:41.733247859 -0400
|
||||
@@ -99,6 +99,12 @@
|
||||
# define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11")))
|
||||
#endif
|
||||
|
||||
+// Macro to warn about unused results.
|
||||
+#if __cplusplus >= 201703L
|
||||
+# define _GLIBCXX_NODISCARD [[__nodiscard__]]
|
||||
+#else
|
||||
+# define _GLIBCXX_NODISCARD
|
||||
+#endif
|
||||
|
||||
#if __cplusplus
|
||||
|
101
SOURCES/gcc8-rh2028609.patch
Normal file
101
SOURCES/gcc8-rh2028609.patch
Normal file
@ -0,0 +1,101 @@
|
||||
The cprop_hardreg pass is built around the assumption that accessing a
|
||||
register in a narrower mode is the same as accessing the lowpart of
|
||||
the register. This unfortunately is not true for vector registers on
|
||||
IBM Z. This caused a miscompile of LLVM with GCC 8.5. The problem
|
||||
could not be reproduced with upstream GCC unfortunately but we have to
|
||||
assume that it is latent there. The right fix would require
|
||||
substantial changes to the cprop pass and is certainly something we
|
||||
would want for our platform. But since this would not be acceptable
|
||||
for older GCCs I'll go with what Vladimir proposed in the RedHat BZ
|
||||
and introduce a hopefully temporary and undocumented target hook to
|
||||
disable that specific transformation in regcprop.c.
|
||||
|
||||
--- a/gcc/config/s390/s390.c
|
||||
+++ b/gcc/config/s390/s390.c
|
||||
@@ -10488,6 +10488,18 @@ s390_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
+/* Implement TARGET_NARROW_MODE_REFERS_LOW_PART_P. */
|
||||
+
|
||||
+static bool
|
||||
+s390_narrow_mode_refers_low_part_p (unsigned int regno)
|
||||
+{
|
||||
+ if (reg_classes_intersect_p (VEC_REGS, REGNO_REG_CLASS (regno)))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Implement TARGET_MODES_TIEABLE_P. */
|
||||
|
||||
static bool
|
||||
@@ -16956,6 +16968,9 @@ s390_case_values_threshold (void)
|
||||
#undef TARGET_CASE_VALUES_THRESHOLD
|
||||
#define TARGET_CASE_VALUES_THRESHOLD s390_case_values_threshold
|
||||
|
||||
+#undef TARGET_NARROW_MODE_REFERS_LOW_PART_P
|
||||
+#define TARGET_NARROW_MODE_REFERS_LOW_PART_P s390_narrow_mode_refers_low_part_p
|
||||
+
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-s390.h"
|
||||
--- a/gcc/regcprop.c
|
||||
+++ b/gcc/regcprop.c
|
||||
@@ -426,7 +426,8 @@ maybe_mode_change (machine_mode orig_mode, machine_mode copy_mode,
|
||||
|
||||
if (orig_mode == new_mode)
|
||||
return gen_raw_REG (new_mode, regno);
|
||||
- else if (mode_change_ok (orig_mode, new_mode, regno))
|
||||
+ else if (mode_change_ok (orig_mode, new_mode, regno)
|
||||
+ && targetm.narrow_mode_refers_low_part_p (copy_regno))
|
||||
{
|
||||
int copy_nregs = hard_regno_nregs (copy_regno, copy_mode);
|
||||
int use_nregs = hard_regno_nregs (copy_regno, new_mode);
|
||||
--- a/gcc/target.def
|
||||
+++ b/gcc/target.def
|
||||
@@ -5446,6 +5446,16 @@ value that the middle-end intended.",
|
||||
bool, (machine_mode from, machine_mode to, reg_class_t rclass),
|
||||
hook_bool_mode_mode_reg_class_t_true)
|
||||
|
||||
+/* This hook is used to work around a problem in regcprop. Hardcoded
|
||||
+assumptions currently prevent it from working correctly for targets
|
||||
+where the low part of a multi-word register doesn't align to accessing
|
||||
+the register with a narrower mode. */
|
||||
+DEFHOOK_UNDOC
|
||||
+(narrow_mode_refers_low_part_p,
|
||||
+"",
|
||||
+bool, (unsigned int regno),
|
||||
+hook_bool_uint_true)
|
||||
+
|
||||
/* Change pseudo allocno class calculated by IRA. */
|
||||
DEFHOOK
|
||||
(ira_change_pseudo_allocno_class,
|
||||
--- a/gcc/hooks.h
|
||||
+++ b/gcc/hooks.h
|
||||
@@ -86,6 +86,7 @@ extern void hook_void_tree (tree);
|
||||
extern void hook_void_tree_treeptr (tree, tree *);
|
||||
extern void hook_void_int_int (int, int);
|
||||
extern void hook_void_gcc_optionsp (struct gcc_options *);
|
||||
+extern bool hook_bool_uint_true (unsigned int);
|
||||
extern bool hook_bool_uint_uintp_false (unsigned int, unsigned int *);
|
||||
|
||||
extern int hook_int_uint_mode_1 (unsigned int, machine_mode);
|
||||
--- a/gcc/hooks.c
|
||||
+++ b/gcc/hooks.c
|
||||
@@ -498,6 +498,14 @@ hook_void_gcc_optionsp (struct gcc_optio
|
||||
{
|
||||
}
|
||||
|
||||
+/* Generic hook that takes an unsigned int and returns true. */
|
||||
+
|
||||
+bool
|
||||
+hook_bool_uint_true (unsigned int)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Generic hook that takes an unsigned int, an unsigned int pointer and
|
||||
returns false. */
|
||||
|
103
SOURCES/gcc8-rh2117838.patch
Normal file
103
SOURCES/gcc8-rh2117838.patch
Normal file
@ -0,0 +1,103 @@
|
||||
diff --git a/gcc/testsuite/g++.dg/torture/phi-1.C b/gcc/testsuite/g++.dg/torture/phi-1.C
|
||||
new file mode 100644
|
||||
index 00000000000..69fb3d7ba38
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/torture/phi-1.C
|
||||
@@ -0,0 +1,28 @@
|
||||
+// { dg-do compile { target c++11 } }
|
||||
+// { dg-options "--param early-inlining-insns=14" }
|
||||
+
|
||||
+struct Element;
|
||||
+template <int _Nm> struct __array_traits { typedef Element _Type[_Nm]; };
|
||||
+template <int _Nm> struct array {
|
||||
+ typename __array_traits<_Nm>::_Type _M_elems;
|
||||
+};
|
||||
+bool logLevel();
|
||||
+struct LogCapture {
|
||||
+ void stream();
|
||||
+};
|
||||
+struct Element {
|
||||
+ Element();
|
||||
+ long data_;
|
||||
+};
|
||||
+using ElementArray = array<6>;
|
||||
+struct ElementManager {
|
||||
+ ElementManager();
|
||||
+ ElementArray array_;
|
||||
+};
|
||||
+static ElementArray makeArray() {
|
||||
+ if (logLevel())
|
||||
+ LogCapture().stream();
|
||||
+ ElementArray foo;
|
||||
+ return foo;
|
||||
+}
|
||||
+ElementManager::ElementManager() : array_(makeArray()) {}
|
||||
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
|
||||
index 84e58e66628..78c0c6a4189 100644
|
||||
--- a/gcc/tree-cfg.c
|
||||
+++ b/gcc/tree-cfg.c
|
||||
@@ -2944,35 +2944,6 @@ last_and_only_stmt (basic_block bb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE. */
|
||||
-
|
||||
-static void
|
||||
-reinstall_phi_args (edge new_edge, edge old_edge)
|
||||
-{
|
||||
- edge_var_map *vm;
|
||||
- int i;
|
||||
- gphi_iterator phis;
|
||||
-
|
||||
- vec<edge_var_map> *v = redirect_edge_var_map_vector (old_edge);
|
||||
- if (!v)
|
||||
- return;
|
||||
-
|
||||
- for (i = 0, phis = gsi_start_phis (new_edge->dest);
|
||||
- v->iterate (i, &vm) && !gsi_end_p (phis);
|
||||
- i++, gsi_next (&phis))
|
||||
- {
|
||||
- gphi *phi = phis.phi ();
|
||||
- tree result = redirect_edge_var_map_result (vm);
|
||||
- tree arg = redirect_edge_var_map_def (vm);
|
||||
-
|
||||
- gcc_assert (result == gimple_phi_result (phi));
|
||||
-
|
||||
- add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
|
||||
- }
|
||||
-
|
||||
- redirect_edge_var_map_clear (old_edge);
|
||||
-}
|
||||
-
|
||||
/* Returns the basic block after which the new basic block created
|
||||
by splitting edge EDGE_IN should be placed. Tries to keep the new block
|
||||
near its "logical" location. This is of most help to humans looking
|
||||
@@ -3012,11 +2983,24 @@ gimple_split_edge (edge edge_in)
|
||||
new_bb = create_empty_bb (after_bb);
|
||||
new_bb->count = edge_in->count ();
|
||||
|
||||
- e = redirect_edge_and_branch (edge_in, new_bb);
|
||||
- gcc_assert (e == edge_in);
|
||||
-
|
||||
+ /* We want to avoid re-allocating PHIs when we first
|
||||
+ add the fallthru edge from new_bb to dest but we also
|
||||
+ want to avoid changing PHI argument order when
|
||||
+ first redirecting edge_in away from dest. The former
|
||||
+ avoids changing PHI argument order by adding them
|
||||
+ last and then the redirection swapping it back into
|
||||
+ place by means of unordered remove.
|
||||
+ So hack around things by temporarily removing all PHIs
|
||||
+ from the destination during the edge redirection and then
|
||||
+ making sure the edges stay in order. */
|
||||
+ gimple_seq saved_phis = phi_nodes (dest);
|
||||
+ unsigned old_dest_idx = edge_in->dest_idx;
|
||||
+ set_phi_nodes (dest, NULL);
|
||||
new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU);
|
||||
- reinstall_phi_args (new_edge, e);
|
||||
+ e = redirect_edge_and_branch (edge_in, new_bb);
|
||||
+ gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx);
|
||||
+ /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here. */
|
||||
+ dest->il.gimple.phi_nodes = saved_phis;
|
||||
|
||||
return new_bb;
|
||||
}
|
110
SOURCES/gcc8-rh2137448.patch
Normal file
110
SOURCES/gcc8-rh2137448.patch
Normal file
@ -0,0 +1,110 @@
|
||||
commit 8b89515caca5149329c0cd20485e69e2d0f879d4
|
||||
Author: Marek Polacek <polacek@redhat.com>
|
||||
Date: Wed Dec 7 13:44:38 2022 -0500
|
||||
|
||||
strlen: Use D_S_U in maybe_set_strlen_range
|
||||
|
||||
This patch fixes #2137448 where the customer uses strlen on a buffer
|
||||
that was filled by converting the buffer to a struct and copying a string
|
||||
into a flexible array member of the struct.
|
||||
|
||||
This regressed with r262438 in the sense that the strlen was folded to 0.
|
||||
The strlen=0 result started with
|
||||
https://gcc.gnu.org/pipermail/gcc-patches/2018-July/501912.html
|
||||
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=715fcd73b66c639d9e0e3f3ef9c6ff9d621d7131
|
||||
which seems like an undesirable change. It was fixed (back to strlen=3) by
|
||||
https://gcc.gnu.org/legacy-ml/gcc-patches/2019-01/msg00069.html
|
||||
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=d4bf69750d31d08068f8242225b8fa06cdf11411
|
||||
but the changes are not backportable.
|
||||
|
||||
Instead, this patch makes maybe_set_strlen_range use DECL_SIZE_UNIT
|
||||
rather than TYPE_SIZE_UNIT, fixing the regression.
|
||||
|
||||
I could never reproduce the problem in C, only C++. C/C++ represent array
|
||||
type domains differently: C has
|
||||
|
||||
char[0:]
|
||||
|
||||
but C++
|
||||
|
||||
char[0:18446744073709551615]
|
||||
|
||||
I'm not sure if that explains it. In any case, I put the new test into
|
||||
c-c++-common/.
|
||||
|
||||
Also, the original test had
|
||||
|
||||
printf("strlen = %zu\n", strlen(q->name));
|
||||
|
||||
so naturally, for the testsuite, I wanted to convert that into
|
||||
|
||||
if (strlen(q->name) != ...)
|
||||
__builtin_abort ();
|
||||
|
||||
but then I could no longer reproduce the problem. After some poking
|
||||
I realized I want -fno-early-inlining.
|
||||
|
||||
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
diff --git a/gcc/testsuite/c-c++-common/torture/strlenopt-1.c b/gcc/testsuite/c-c++-common/torture/strlenopt-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..e8c11044119
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/c-c++-common/torture/strlenopt-1.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* { dg-do run } */
|
||||
+/* { dg-options "-fno-early-inlining" } */
|
||||
+
|
||||
+#define FORTIFY_SOURCE 2
|
||||
+
|
||||
+struct S {
|
||||
+ char skip;
|
||||
+ char name[0];
|
||||
+};
|
||||
+
|
||||
+static char static_buf[4];
|
||||
+
|
||||
+static void
|
||||
+print_name_len(void *p)
|
||||
+{
|
||||
+ struct S *q = (struct S *) p;
|
||||
+ if (__builtin_strlen(q->name) != 2)
|
||||
+ __builtin_abort ();
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(void)
|
||||
+{
|
||||
+ // treat static storage as struct
|
||||
+ struct S *c = (struct S *)static_buf;
|
||||
+ __builtin_strcpy(c->name, "aa");
|
||||
+
|
||||
+ // copy static storage to stack storage
|
||||
+ char stack_buf[4] = { 0 };
|
||||
+ __builtin_memcpy(stack_buf, static_buf, 4);
|
||||
+
|
||||
+ // static and stack both now contain ( 0, 'a', 'a', 0 }
|
||||
+
|
||||
+ // indirectly pass the stack storage to the length function
|
||||
+ char *s = (char *)stack_buf;
|
||||
+ print_name_len(s);
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
|
||||
index 55e82e7b638..da47046cc2a 100644
|
||||
--- a/gcc/tree-ssa-strlen.c
|
||||
+++ b/gcc/tree-ssa-strlen.c
|
||||
@@ -1200,8 +1200,11 @@ maybe_set_strlen_range (tree lhs, tree src)
|
||||
|| array_at_struct_end_p (src))
|
||||
return;
|
||||
|
||||
- tree type = TREE_TYPE (src);
|
||||
- if (tree size = TYPE_SIZE_UNIT (type))
|
||||
+ src = get_base_address (src);
|
||||
+ if (!DECL_P (src))
|
||||
+ return;
|
||||
+
|
||||
+ if (tree size = DECL_SIZE_UNIT (src))
|
||||
if (size && TREE_CODE (size) == INTEGER_CST)
|
||||
{
|
||||
wide_int max = wi::to_wide (size);
|
75
SOURCES/gcc8-rh2213753.patch
Normal file
75
SOURCES/gcc8-rh2213753.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 6f989c5c6e5f909996a117bb24ecac936e7526c1 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Polacek <polacek@redhat.com>
|
||||
Date: Wed, 14 Jun 2023 17:09:15 -0400
|
||||
Subject: [PATCH] final: fix for TLSLD references [BZ#2213753]
|
||||
|
||||
Patch by Jakub Jelinek.
|
||||
---
|
||||
gcc/final.c | 17 +++++++++++++++++
|
||||
gcc/testsuite/g++.dg/tls/bz2213753.C | 26 ++++++++++++++++++++++++++
|
||||
2 files changed, 43 insertions(+)
|
||||
create mode 100644 gcc/testsuite/g++.dg/tls/bz2213753.C
|
||||
|
||||
diff --git a/gcc/final.c b/gcc/final.c
|
||||
index 5a65a8ce07c..c783fbb83d7 100644
|
||||
--- a/gcc/final.c
|
||||
+++ b/gcc/final.c
|
||||
@@ -1691,6 +1691,23 @@ get_some_local_dynamic_name ()
|
||||
}
|
||||
}
|
||||
|
||||
+ /* If all the TLSLD references from current function were DCEd, try harder and pick
|
||||
+ name of any TLSLD symbol in current TU. */
|
||||
+ varpool_node *node;
|
||||
+ if (!this_is_asm_operands)
|
||||
+ FOR_EACH_VARIABLE (node)
|
||||
+ if (DECL_THREAD_LOCAL_P (node->decl)
|
||||
+ && TREE_STATIC (node->decl)
|
||||
+ && decl_tls_model (node->decl) == TLS_MODEL_LOCAL_DYNAMIC
|
||||
+ && DECL_RTL_SET_P (node->decl))
|
||||
+ {
|
||||
+ rtx rtl = DECL_RTL (node->decl);
|
||||
+ if (MEM_P (rtl)
|
||||
+ && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
|
||||
+ && SYMBOL_REF_TLS_MODEL (XEXP (rtl, 0)) == TLS_MODEL_LOCAL_DYNAMIC)
|
||||
+ return XSTR (XEXP (rtl, 0), 0);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/gcc/testsuite/g++.dg/tls/bz2213753.C b/gcc/testsuite/g++.dg/tls/bz2213753.C
|
||||
new file mode 100644
|
||||
index 00000000000..0c4742d8058
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/g++.dg/tls/bz2213753.C
|
||||
@@ -0,0 +1,26 @@
|
||||
+// RHBZ #2213753
|
||||
+// { dg-do compile { target c++11 } }
|
||||
+// { dg-require-effective-target fpic }
|
||||
+// { dg-require-effective-target shared }
|
||||
+// { dg-require-effective-target tls }
|
||||
+// { dg-options "-fPIC -O2" }
|
||||
+// { dg-add-options tls }
|
||||
+
|
||||
+struct A { ~A (); };
|
||||
+static thread_local int *t;
|
||||
+int a;
|
||||
+A::~A () { t = &a; }
|
||||
+long b;
|
||||
+
|
||||
+void *
|
||||
+foo ()
|
||||
+{
|
||||
+ void *c;
|
||||
+ if (t)
|
||||
+ {
|
||||
+ c = operator new (b);
|
||||
+ return c;
|
||||
+ }
|
||||
+ void *d = operator new (b);
|
||||
+ return d;
|
||||
+}
|
||||
--
|
||||
2.40.1
|
||||
|
91
SOURCES/gcc8-s390x-regarg-1.patch
Normal file
91
SOURCES/gcc8-s390x-regarg-1.patch
Normal file
@ -0,0 +1,91 @@
|
||||
commit ef5f7b89bbc352255595069eb870d6f30f1f9134
|
||||
Author: Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
Date: Wed Feb 1 08:59:41 2023 +0100
|
||||
|
||||
New reg note REG_CFA_NORESTORE
|
||||
|
||||
This patch introduces a new reg note which can be used to tell the CFI
|
||||
verification in dwarf2cfi that a register is stored without intending
|
||||
to restore from it.
|
||||
|
||||
This is useful when storing e.g. register contents to the stack and
|
||||
generate CFI for it although the register is not really supposed to be
|
||||
restored.
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* dwarf2cfi.c (dwarf2out_frame_debug_cfa_restore): Add
|
||||
EMIT_CFI parameter.
|
||||
(dwarf2out_frame_debug): Add case for REG_CFA_NORESTORE.
|
||||
* reg-notes.def (REG_CFA_NOTE): New reg note definition.
|
||||
|
||||
--- a/gcc/dwarf2cfi.c
|
||||
+++ b/gcc/dwarf2cfi.c
|
||||
@@ -1496,10 +1496,12 @@ dwarf2out_frame_debug_cfa_val_expression (rtx set)
|
||||
update_row_reg_save (cur_row, dwf_regno (dest), cfi);
|
||||
}
|
||||
|
||||
-/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */
|
||||
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE
|
||||
+ note. When called with EMIT_CFI set to false emitting a CFI
|
||||
+ statement is suppressed. */
|
||||
|
||||
static void
|
||||
-dwarf2out_frame_debug_cfa_restore (rtx reg)
|
||||
+dwarf2out_frame_debug_cfa_restore (rtx reg, bool emit_cfi)
|
||||
{
|
||||
gcc_assert (REG_P (reg));
|
||||
|
||||
@@ -1507,7 +1509,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
|
||||
if (!span)
|
||||
{
|
||||
unsigned int regno = dwf_regno (reg);
|
||||
- add_cfi_restore (regno);
|
||||
+ if (emit_cfi)
|
||||
+ add_cfi_restore (regno);
|
||||
update_row_reg_save (cur_row, regno, NULL);
|
||||
}
|
||||
else
|
||||
@@ -1522,7 +1525,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
|
||||
reg = XVECEXP (span, 0, par_index);
|
||||
gcc_assert (REG_P (reg));
|
||||
unsigned int regno = dwf_regno (reg);
|
||||
- add_cfi_restore (regno);
|
||||
+ if (emit_cfi)
|
||||
+ add_cfi_restore (regno);
|
||||
update_row_reg_save (cur_row, regno, NULL);
|
||||
}
|
||||
}
|
||||
@@ -2309,6 +2313,7 @@ dwarf2out_frame_debug (rtx_insn *insn)
|
||||
break;
|
||||
|
||||
case REG_CFA_RESTORE:
|
||||
+ case REG_CFA_NO_RESTORE:
|
||||
n = XEXP (note, 0);
|
||||
if (n == NULL)
|
||||
{
|
||||
@@ -2317,7 +2322,7 @@ dwarf2out_frame_debug (rtx_insn *insn)
|
||||
n = XVECEXP (n, 0, 0);
|
||||
n = XEXP (n, 0);
|
||||
}
|
||||
- dwarf2out_frame_debug_cfa_restore (n);
|
||||
+ dwarf2out_frame_debug_cfa_restore (n, REG_NOTE_KIND (note) == REG_CFA_RESTORE);
|
||||
handled_one = true;
|
||||
break;
|
||||
|
||||
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
|
||||
index 23de1f13ee9..1f74a605b3e 100644
|
||||
--- a/gcc/reg-notes.def
|
||||
+++ b/gcc/reg-notes.def
|
||||
@@ -157,6 +157,11 @@ REG_CFA_NOTE (CFA_VAL_EXPRESSION)
|
||||
first pattern is the register to be restored. */
|
||||
REG_CFA_NOTE (CFA_RESTORE)
|
||||
|
||||
+/* Like CFA_RESTORE but without actually emitting CFI. This can be
|
||||
+ used to tell the verification infrastructure that a register is
|
||||
+ saved without intending to restore it. */
|
||||
+REG_CFA_NOTE (CFA_NO_RESTORE)
|
||||
+
|
||||
/* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets
|
||||
vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized
|
||||
to the argument, if it is a MEM, it is ignored. */
|
106
SOURCES/gcc8-s390x-regarg-2.patch
Normal file
106
SOURCES/gcc8-s390x-regarg-2.patch
Normal file
@ -0,0 +1,106 @@
|
||||
commit 1467907e405bc18fb6935b5d432cfa5f936e838d
|
||||
Author: Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
Date: Thu Mar 30 13:57:54 2023 +0200
|
||||
|
||||
IBM zSystems: Make stack_tie to work with hard frame pointer
|
||||
|
||||
With this patch a scheduling barrier is created to prevent the insn
|
||||
setting up the frame-pointer and instructions which save GPRs to the
|
||||
stack to be swapped. Otherwise broken CFI information would be
|
||||
generated since the stack save insns would use a base register which
|
||||
is not currently declared as holding the CFA.
|
||||
|
||||
Without -mpreserve-args this did not happen because the store multiple
|
||||
we used for saving the GPRs would also cover the frame-pointer
|
||||
register and therefore creates a dependency on the frame-pointer
|
||||
hardreg. However, with this patch the stack_tie is emitted regardless
|
||||
of -mpreserve-args since this in general appears to be the safer
|
||||
approach.
|
||||
|
||||
* config/s390/s390.c (save_gprs): Use gen_frame_mem.
|
||||
(restore_gprs): Likewise.
|
||||
(s390_emit_stack_tie): Make the stack_tie to be dependent on the
|
||||
frame pointer if a frame-pointer is used.
|
||||
(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.
|
||||
|
||||
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)
|
||||
int i;
|
||||
|
||||
addr = plus_constant (Pmode, base, offset);
|
||||
- addr = gen_rtx_MEM (Pmode, addr);
|
||||
-
|
||||
- set_mem_alias_set (addr, get_frame_alias_set ());
|
||||
+ addr = gen_frame_mem (Pmode, addr);
|
||||
|
||||
/* Special-case single register. */
|
||||
if (first == last)
|
||||
@@ -11035,8 +11033,7 @@ restore_gprs (rtx base, int offset, int first, int last)
|
||||
rtx addr, insn;
|
||||
|
||||
addr = plus_constant (Pmode, base, offset);
|
||||
- addr = gen_rtx_MEM (Pmode, addr);
|
||||
- set_mem_alias_set (addr, get_frame_alias_set ());
|
||||
+ addr = gen_frame_mem (Pmode, addr);
|
||||
|
||||
/* Special-case single register. */
|
||||
if (first == last)
|
||||
@@ -11105,10 +11102,14 @@ s390_load_got (void)
|
||||
static void
|
||||
s390_emit_stack_tie (void)
|
||||
{
|
||||
- rtx mem = gen_frame_mem (BLKmode,
|
||||
- gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
|
||||
-
|
||||
- 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));
|
||||
+ else
|
||||
+ emit_insn (gen_stack_tiesi (mem, stack_reg));
|
||||
}
|
||||
|
||||
/* Copy GPRS into FPR save slots. */
|
||||
@@ -11701,6 +11702,7 @@ s390_emit_prologue (void)
|
||||
|
||||
if (frame_pointer_needed)
|
||||
{
|
||||
+ s390_emit_stack_tie ();
|
||||
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
|
||||
index 7114609b676..f235df3a25d 100644
|
||||
--- a/gcc/config/s390/s390.md
|
||||
+++ b/gcc/config/s390/s390.md
|
||||
@@ -11366,10 +11366,19 @@
|
||||
; 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"
|
||||
[(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"
|
||||
""
|
||||
+ [(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")])
|
||||
|
545
SOURCES/gcc8-s390x-regarg-3.patch
Normal file
545
SOURCES/gcc8-s390x-regarg-3.patch
Normal file
@ -0,0 +1,545 @@
|
||||
commit 8091199cdf4d0aa9c28e4526548ddc25d02898ca
|
||||
Author: Andreas Krebbel <krebbel@linux.ibm.com>
|
||||
Date: Wed Feb 1 08:59:42 2023 +0100
|
||||
|
||||
IBM zSystems: Save argument registers to the stack -mpreserve-args
|
||||
|
||||
This adds support for preserving the content of parameter registers to
|
||||
the stack and emit CFI for it. This useful for applications which want
|
||||
to implement their own stack unwinding and need access to function
|
||||
arguments.
|
||||
|
||||
With the -mpreserve-args option GPRs and FPRs are save to the stack
|
||||
slots which are reserved for stdargs in the register save area.
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* config/s390/s390.c (s390_restore_gpr_p): New function.
|
||||
(s390_preserve_gpr_arg_in_range_p): New function.
|
||||
(s390_preserve_gpr_arg_p): New function.
|
||||
(s390_preserve_fpr_arg_p): New function.
|
||||
(s390_register_info_stdarg_fpr): Rename to ...
|
||||
(s390_register_info_arg_fpr): ... this. Add -mpreserve-args handling.
|
||||
(s390_register_info_stdarg_gpr): Rename to ...
|
||||
(s390_register_info_arg_gpr): ... this. Add -mpreserve-args handling.
|
||||
(s390_register_info): Use the renamed functions above.
|
||||
(s390_optimize_register_info): Likewise.
|
||||
(save_fpr): Generate CFI for -mpreserve-args.
|
||||
(save_gprs): Generate CFI for -mpreserve-args. Drop return value.
|
||||
(s390_emit_prologue): Adjust to changed calling convention of save_gprs.
|
||||
(s390_optimize_prologue): Likewise.
|
||||
* config/s390/s390.opt: New option -mpreserve-args
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gcc.target/s390/preserve-args-1.c: New test.
|
||||
* gcc.target/s390/preserve-args-2.c: New test.
|
||||
|
||||
--- a/gcc/config/s390/s390.c
|
||||
+++ b/gcc/config/s390/s390.c
|
||||
@@ -411,6 +411,45 @@ struct s390_address
|
||||
#define FP_ARG_NUM_REG (TARGET_64BIT? 4 : 2)
|
||||
#define VEC_ARG_NUM_REG 8
|
||||
|
||||
+/* Return TRUE if GPR REGNO is supposed to be restored in the function
|
||||
+ epilogue. */
|
||||
+static inline bool
|
||||
+s390_restore_gpr_p (int regno)
|
||||
+{
|
||||
+ return (cfun_frame_layout.first_restore_gpr != -1
|
||||
+ && regno >= cfun_frame_layout.first_restore_gpr
|
||||
+ && regno <= cfun_frame_layout.last_restore_gpr);
|
||||
+}
|
||||
+
|
||||
+/* Return TRUE if any of the registers in range [FIRST, LAST] is saved
|
||||
+ because of -mpreserve-args. */
|
||||
+static inline bool
|
||||
+s390_preserve_gpr_arg_in_range_p (int first, int last)
|
||||
+{
|
||||
+ int num_arg_regs = MIN (crtl->args.info.gprs + cfun->va_list_gpr_size,
|
||||
+ GP_ARG_NUM_REG);
|
||||
+ return (num_arg_regs
|
||||
+ && s390_preserve_args_p
|
||||
+ && first <= GPR2_REGNUM + num_arg_regs - 1
|
||||
+ && last >= GPR2_REGNUM);
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+s390_preserve_gpr_arg_p (int regno)
|
||||
+{
|
||||
+ return s390_preserve_gpr_arg_in_range_p (regno, regno);
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+s390_preserve_fpr_arg_p (int regno)
|
||||
+{
|
||||
+ int num_arg_regs = MIN (crtl->args.info.fprs + cfun->va_list_fpr_size,
|
||||
+ FP_ARG_NUM_REG);
|
||||
+ return (s390_preserve_args_p
|
||||
+ && regno <= FPR0_REGNUM + num_arg_regs - 1
|
||||
+ && regno >= FPR0_REGNUM);
|
||||
+}
|
||||
+
|
||||
/* A couple of shortcuts. */
|
||||
#define CONST_OK_FOR_J(x) \
|
||||
CONST_OK_FOR_CONSTRAINT_P((x), 'J', "J")
|
||||
@@ -9893,61 +9932,89 @@ s390_register_info_gprtofpr ()
|
||||
}
|
||||
|
||||
/* Set the bits in fpr_bitmap for FPRs which need to be saved due to
|
||||
- stdarg.
|
||||
+ stdarg or -mpreserve-args.
|
||||
This is a helper routine for s390_register_info. */
|
||||
-
|
||||
static void
|
||||
-s390_register_info_stdarg_fpr ()
|
||||
+s390_register_info_arg_fpr ()
|
||||
{
|
||||
int i;
|
||||
- int min_fpr;
|
||||
- int max_fpr;
|
||||
+ int min_stdarg_fpr = INT_MAX, max_stdarg_fpr = -1;
|
||||
+ int min_preserve_fpr = INT_MAX, max_preserve_fpr = -1;
|
||||
+ int min_fpr, max_fpr;
|
||||
|
||||
/* Save the FP argument regs for stdarg. f0, f2 for 31 bit and
|
||||
f0-f4 for 64 bit. */
|
||||
- if (!cfun->stdarg
|
||||
- || !TARGET_HARD_FLOAT
|
||||
- || !cfun->va_list_fpr_size
|
||||
- || crtl->args.info.fprs >= FP_ARG_NUM_REG)
|
||||
- return;
|
||||
+ if (cfun->stdarg
|
||||
+ && TARGET_HARD_FLOAT
|
||||
+ && cfun->va_list_fpr_size
|
||||
+ && crtl->args.info.fprs < FP_ARG_NUM_REG)
|
||||
+ {
|
||||
+ min_stdarg_fpr = crtl->args.info.fprs;
|
||||
+ max_stdarg_fpr = min_stdarg_fpr + cfun->va_list_fpr_size - 1;
|
||||
+ if (max_stdarg_fpr >= FP_ARG_NUM_REG)
|
||||
+ max_stdarg_fpr = FP_ARG_NUM_REG - 1;
|
||||
+
|
||||
+ /* FPR argument regs start at f0. */
|
||||
+ min_stdarg_fpr += FPR0_REGNUM;
|
||||
+ max_stdarg_fpr += FPR0_REGNUM;
|
||||
+ }
|
||||
|
||||
- min_fpr = crtl->args.info.fprs;
|
||||
- max_fpr = min_fpr + cfun->va_list_fpr_size - 1;
|
||||
- if (max_fpr >= FP_ARG_NUM_REG)
|
||||
- max_fpr = FP_ARG_NUM_REG - 1;
|
||||
+ if (s390_preserve_args_p && crtl->args.info.fprs)
|
||||
+ {
|
||||
+ min_preserve_fpr = FPR0_REGNUM;
|
||||
+ max_preserve_fpr = MIN (FPR0_REGNUM + FP_ARG_NUM_REG - 1,
|
||||
+ FPR0_REGNUM + crtl->args.info.fprs - 1);
|
||||
+ }
|
||||
|
||||
- /* FPR argument regs start at f0. */
|
||||
- min_fpr += FPR0_REGNUM;
|
||||
- max_fpr += FPR0_REGNUM;
|
||||
+ min_fpr = MIN (min_stdarg_fpr, min_preserve_fpr);
|
||||
+ max_fpr = MAX (max_stdarg_fpr, max_preserve_fpr);
|
||||
+
|
||||
+ if (max_fpr == -1)
|
||||
+ return;
|
||||
|
||||
for (i = min_fpr; i <= max_fpr; i++)
|
||||
cfun_set_fpr_save (i);
|
||||
}
|
||||
|
||||
+
|
||||
/* Reserve the GPR save slots for GPRs which need to be saved due to
|
||||
- stdarg.
|
||||
+ stdarg or -mpreserve-args.
|
||||
This is a helper routine for s390_register_info. */
|
||||
|
||||
static void
|
||||
-s390_register_info_stdarg_gpr ()
|
||||
+s390_register_info_arg_gpr ()
|
||||
{
|
||||
int i;
|
||||
- int min_gpr;
|
||||
- int max_gpr;
|
||||
+ int min_stdarg_gpr = INT_MAX, max_stdarg_gpr = -1;
|
||||
+ int min_preserve_gpr = INT_MAX, max_preserve_gpr = -1;
|
||||
+ int min_gpr, max_gpr;
|
||||
|
||||
- if (!cfun->stdarg
|
||||
- || !cfun->va_list_gpr_size
|
||||
- || crtl->args.info.gprs >= GP_ARG_NUM_REG)
|
||||
- return;
|
||||
+ if (cfun->stdarg
|
||||
+ && cfun->va_list_gpr_size
|
||||
+ && crtl->args.info.gprs < GP_ARG_NUM_REG)
|
||||
+ {
|
||||
+ min_stdarg_gpr = crtl->args.info.gprs;
|
||||
+ max_stdarg_gpr = min_stdarg_gpr + cfun->va_list_gpr_size - 1;
|
||||
+ if (max_stdarg_gpr >= GP_ARG_NUM_REG)
|
||||
+ max_stdarg_gpr = GP_ARG_NUM_REG - 1;
|
||||
+
|
||||
+ /* GPR argument regs start at r2. */
|
||||
+ min_stdarg_gpr += GPR2_REGNUM;
|
||||
+ max_stdarg_gpr += GPR2_REGNUM;
|
||||
+ }
|
||||
+
|
||||
+ if (s390_preserve_args_p && crtl->args.info.gprs)
|
||||
+ {
|
||||
+ min_preserve_gpr = GPR2_REGNUM;
|
||||
+ max_preserve_gpr = MIN (GPR6_REGNUM,
|
||||
+ GPR2_REGNUM + crtl->args.info.gprs - 1);
|
||||
+ }
|
||||
|
||||
- min_gpr = crtl->args.info.gprs;
|
||||
- max_gpr = min_gpr + cfun->va_list_gpr_size - 1;
|
||||
- if (max_gpr >= GP_ARG_NUM_REG)
|
||||
- max_gpr = GP_ARG_NUM_REG - 1;
|
||||
+ min_gpr = MIN (min_stdarg_gpr, min_preserve_gpr);
|
||||
+ max_gpr = MAX (max_stdarg_gpr, max_preserve_gpr);
|
||||
|
||||
- /* GPR argument regs start at r2. */
|
||||
- min_gpr += GPR2_REGNUM;
|
||||
- max_gpr += GPR2_REGNUM;
|
||||
+ if (max_gpr == -1)
|
||||
+ return;
|
||||
|
||||
/* If r6 was supposed to be saved into an FPR and now needs to go to
|
||||
the stack for vararg we have to adjust the restore range to make
|
||||
@@ -10079,14 +10146,14 @@ s390_register_info ()
|
||||
if (clobbered_regs[i])
|
||||
cfun_gpr_save_slot (i) = SAVE_SLOT_STACK;
|
||||
|
||||
- s390_register_info_stdarg_fpr ();
|
||||
+ s390_register_info_arg_fpr ();
|
||||
s390_register_info_gprtofpr ();
|
||||
s390_register_info_set_ranges ();
|
||||
- /* stdarg functions might need to save GPRs 2 to 6. This might
|
||||
- override the GPR->FPR save decision made by
|
||||
- s390_register_info_gprtofpr for r6 since vararg regs must go to
|
||||
- the stack. */
|
||||
- s390_register_info_stdarg_gpr ();
|
||||
+
|
||||
+ /* Forcing argument registers to be saved on the stack might
|
||||
+ override the GPR->FPR save decision for r6 so this must come
|
||||
+ last. */
|
||||
+ s390_register_info_arg_gpr ();
|
||||
}
|
||||
|
||||
/* Return true if REGNO is a global register, but not one
|
||||
@@ -10141,7 +10208,7 @@ s390_optimize_register_info ()
|
||||
cfun_gpr_save_slot (i) = SAVE_SLOT_NONE;
|
||||
|
||||
s390_register_info_set_ranges ();
|
||||
- s390_register_info_stdarg_gpr ();
|
||||
+ s390_register_info_arg_gpr ();
|
||||
}
|
||||
|
||||
/* Fill cfun->machine with info about frame of current function. */
|
||||
@@ -10864,14 +10931,28 @@ static rtx
|
||||
save_fpr (rtx base, int offset, int regnum)
|
||||
{
|
||||
rtx addr;
|
||||
+ rtx insn;
|
||||
+
|
||||
addr = gen_rtx_MEM (DFmode, plus_constant (Pmode, base, offset));
|
||||
|
||||
- if (regnum >= 16 && regnum <= (16 + FP_ARG_NUM_REG))
|
||||
+ if (regnum >= FPR0_REGNUM && regnum <= (FPR0_REGNUM + FP_ARG_NUM_REG))
|
||||
set_mem_alias_set (addr, get_varargs_alias_set ());
|
||||
else
|
||||
set_mem_alias_set (addr, get_frame_alias_set ());
|
||||
|
||||
- return emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
|
||||
+ insn = emit_move_insn (addr, gen_rtx_REG (DFmode, regnum));
|
||||
+
|
||||
+ if (!call_used_regs[regnum] || s390_preserve_fpr_arg_p (regnum))
|
||||
+ RTX_FRAME_RELATED_P (insn) = 1;
|
||||
+
|
||||
+ if (s390_preserve_fpr_arg_p (regnum) && !cfun_fpr_save_p (regnum))
|
||||
+ {
|
||||
+ rtx reg = gen_rtx_REG (DFmode, regnum);
|
||||
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
|
||||
+ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg));
|
||||
+ }
|
||||
+
|
||||
+ return insn;
|
||||
}
|
||||
|
||||
/* Emit insn to restore fpr REGNUM from offset OFFSET relative
|
||||
@@ -10891,10 +10972,11 @@ restore_fpr (rtx base, int offset, int regnum)
|
||||
the register save area located at offset OFFSET
|
||||
relative to register BASE. */
|
||||
|
||||
-static rtx
|
||||
-save_gprs (rtx base, int offset, int first, int last)
|
||||
+static void
|
||||
+save_gprs (rtx base, int offset, int first, int last, rtx_insn *before = NULL)
|
||||
{
|
||||
rtx addr, insn, note;
|
||||
+ rtx_insn *out_insn;
|
||||
int i;
|
||||
|
||||
addr = plus_constant (Pmode, base, offset);
|
||||
@@ -10910,7 +10992,15 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
|
||||
if (!global_not_special_regno_p (first))
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
- return insn;
|
||||
+
|
||||
+ if (s390_preserve_gpr_arg_p (first) && !s390_restore_gpr_p (first))
|
||||
+ {
|
||||
+ rtx reg = gen_rtx_REG (Pmode, first);
|
||||
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
|
||||
+ add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (addr, reg));
|
||||
+ }
|
||||
+
|
||||
+ goto emit;
|
||||
}
|
||||
|
||||
|
||||
@@ -10939,7 +11029,12 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
set, even if it does not. Therefore we emit a new pattern
|
||||
without those registers as REG_FRAME_RELATED_EXPR note. */
|
||||
|
||||
- if (first >= 6 && !global_not_special_regno_p (first))
|
||||
+ /* In these cases all of the sets are marked as frame related:
|
||||
+ 1. call-save GPR saved and restored
|
||||
+ 2. argument GPR saved because of -mpreserve-args */
|
||||
+ if ((first >= GPR6_REGNUM && !global_not_special_regno_p (first))
|
||||
+ || s390_preserve_gpr_arg_in_range_p (first, last))
|
||||
+
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
|
||||
@@ -10950,6 +11045,24 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
|
||||
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
+
|
||||
+ /* For the -mpreserve-args register saves no restore operations
|
||||
+ will be emitted. CFI checking would complain about this. We
|
||||
+ manually generate the REG_CFA notes here to be able to mark
|
||||
+ those operations with REG_CFA_NO_RESTORE. */
|
||||
+ if (s390_preserve_gpr_arg_in_range_p (first, last))
|
||||
+ {
|
||||
+ for (int regno = first; regno <= last; regno++)
|
||||
+ {
|
||||
+ rtx reg = gen_rtx_REG (Pmode, regno);
|
||||
+ rtx reg_addr = plus_constant (Pmode, base,
|
||||
+ offset + (regno - first) * UNITS_PER_LONG);
|
||||
+ if (!s390_restore_gpr_p (regno))
|
||||
+ add_reg_note (insn, REG_CFA_NO_RESTORE, reg);
|
||||
+ add_reg_note (insn, REG_CFA_OFFSET,
|
||||
+ gen_rtx_SET (gen_frame_mem (Pmode, reg_addr), reg));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
else if (last >= 6)
|
||||
{
|
||||
@@ -10960,7 +11073,7 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
break;
|
||||
|
||||
if (start > last)
|
||||
- return insn;
|
||||
+ goto emit;
|
||||
|
||||
addr = plus_constant (Pmode, base,
|
||||
offset + (start - first) * UNITS_PER_LONG);
|
||||
@@ -10978,7 +11091,7 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
|
||||
- return insn;
|
||||
+ goto emit;
|
||||
}
|
||||
|
||||
note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
|
||||
@@ -10997,9 +11110,15 @@ save_gprs (rtx base, int offset, int first, int last)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
|
||||
- return insn;
|
||||
+ emit:
|
||||
+ if (before != NULL_RTX)
|
||||
+ out_insn = emit_insn_before (insn, before);
|
||||
+ else
|
||||
+ out_insn = emit_insn (insn);
|
||||
+ INSN_ADDRESSES_NEW (out_insn, -1);
|
||||
}
|
||||
|
||||
+
|
||||
/* Generate insn to restore registers FIRST to LAST from
|
||||
the register save area located at offset OFFSET
|
||||
relative to register BASE. */
|
||||
@@ -11423,12 +11542,12 @@ s390_emit_prologue (void)
|
||||
/* Save call saved gprs. */
|
||||
if (cfun_frame_layout.first_save_gpr != -1)
|
||||
{
|
||||
- insn = save_gprs (stack_pointer_rtx,
|
||||
- cfun_frame_layout.gprs_offset +
|
||||
- UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
|
||||
- - cfun_frame_layout.first_save_gpr_slot),
|
||||
- cfun_frame_layout.first_save_gpr,
|
||||
- cfun_frame_layout.last_save_gpr);
|
||||
+ save_gprs (stack_pointer_rtx,
|
||||
+ cfun_frame_layout.gprs_offset +
|
||||
+ UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
|
||||
+ - cfun_frame_layout.first_save_gpr_slot),
|
||||
+ cfun_frame_layout.first_save_gpr,
|
||||
+ cfun_frame_layout.last_save_gpr);
|
||||
|
||||
/* This is not 100% correct. If we have more than one register saved,
|
||||
then LAST_PROBE_OFFSET can move even closer to sp. */
|
||||
@@ -11436,8 +11555,6 @@ s390_emit_prologue (void)
|
||||
= (cfun_frame_layout.gprs_offset +
|
||||
UNITS_PER_LONG * (cfun_frame_layout.first_save_gpr
|
||||
- cfun_frame_layout.first_save_gpr_slot));
|
||||
-
|
||||
- emit_insn (insn);
|
||||
}
|
||||
|
||||
/* Dummy insn to mark literal pool slot. */
|
||||
@@ -11467,15 +11584,10 @@ s390_emit_prologue (void)
|
||||
{
|
||||
if (cfun_fpr_save_p (i))
|
||||
{
|
||||
- insn = save_fpr (stack_pointer_rtx, offset, i);
|
||||
+ save_fpr (stack_pointer_rtx, offset, i);
|
||||
if (offset < last_probe_offset)
|
||||
last_probe_offset = offset;
|
||||
offset += 8;
|
||||
-
|
||||
- /* 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])
|
||||
- RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
else if (!TARGET_PACKED_STACK || call_really_used_regs[i])
|
||||
offset += 8;
|
||||
@@ -11491,11 +11603,10 @@ s390_emit_prologue (void)
|
||||
for (i = FPR15_REGNUM; i >= FPR8_REGNUM && offset >= 0; i--)
|
||||
if (cfun_fpr_save_p (i))
|
||||
{
|
||||
- insn = save_fpr (stack_pointer_rtx, offset, i);
|
||||
+ save_fpr (stack_pointer_rtx, offset, i);
|
||||
if (offset < last_probe_offset)
|
||||
last_probe_offset = offset;
|
||||
|
||||
- RTX_FRAME_RELATED_P (insn) = 1;
|
||||
offset -= 8;
|
||||
}
|
||||
if (offset >= cfun_frame_layout.f8_offset)
|
||||
@@ -11663,7 +11774,6 @@ s390_emit_prologue (void)
|
||||
|
||||
insn = save_fpr (temp_reg, offset, i);
|
||||
offset += 8;
|
||||
- RTX_FRAME_RELATED_P (insn) = 1;
|
||||
add_reg_note (insn, REG_FRAME_RELATED_EXPR,
|
||||
gen_rtx_SET (gen_rtx_MEM (DFmode, addr),
|
||||
gen_rtx_REG (DFmode, i)));
|
||||
@@ -14158,15 +14268,11 @@ s390_optimize_prologue (void)
|
||||
continue;
|
||||
|
||||
if (cfun_frame_layout.first_save_gpr != -1)
|
||||
- {
|
||||
- rtx s_pat = save_gprs (base,
|
||||
- off + (cfun_frame_layout.first_save_gpr
|
||||
- - first) * UNITS_PER_LONG,
|
||||
- cfun_frame_layout.first_save_gpr,
|
||||
- cfun_frame_layout.last_save_gpr);
|
||||
- new_insn = emit_insn_before (s_pat, insn);
|
||||
- INSN_ADDRESSES_NEW (new_insn, -1);
|
||||
- }
|
||||
+ save_gprs (base,
|
||||
+ off + (cfun_frame_layout.first_save_gpr
|
||||
+ - first) * UNITS_PER_LONG,
|
||||
+ cfun_frame_layout.first_save_gpr,
|
||||
+ cfun_frame_layout.last_save_gpr, insn);
|
||||
|
||||
remove_insn (insn);
|
||||
continue;
|
||||
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
|
||||
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.
|
||||
+
|
||||
+mpreserve-args
|
||||
+Target Var(s390_preserve_args_p) Init(0)
|
||||
+Store all argument registers on the stack.
|
||||
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-1.c b/gcc/testsuite/gcc.target/s390/preserve-args-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..24dcf547432
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-1.c
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* Functional tests for the -mpreserve-args cmdline option. */
|
||||
+
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O3 -march=z900 -mpreserve-args" } */
|
||||
+
|
||||
+
|
||||
+int
|
||||
+foo (int a, int b, int c, double d, double e)
|
||||
+{
|
||||
+ return a + c + (int)d + (int)e;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "stmg\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target lp64 } } } */
|
||||
+/* { dg-final { scan-assembler "stm\t%r2,%r4,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */
|
||||
+
|
||||
+/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */
|
||||
+/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-2.c b/gcc/testsuite/gcc.target/s390/preserve-args-2.c
|
||||
new file mode 100644
|
||||
index 00000000000..006aad9c371
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-2.c
|
||||
@@ -0,0 +1,19 @@
|
||||
+/* This test requires special handling of a GPR which is saved because
|
||||
+ of -mpreserve-args but not restored. dwarf2cfi used to ICE for
|
||||
+ this in maybe_record_trace_start. The solution was to introduce a
|
||||
+ REG_CFA_NORESTORE reg note. */
|
||||
+
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -march=z900 -mpreserve-args" } */
|
||||
+
|
||||
+void *foo (void *);
|
||||
+void bar ();
|
||||
+int x;
|
||||
+void *
|
||||
+baz (void *y)
|
||||
+{
|
||||
+ if (__builtin_expect (x, 0))
|
||||
+ return foo (y);
|
||||
+ bar ();
|
||||
+ return foo (y);
|
||||
+}
|
||||
diff --git a/gcc/testsuite/gcc.target/s390/preserve-args-3.c b/gcc/testsuite/gcc.target/s390/preserve-args-3.c
|
||||
new file mode 100644
|
||||
index 00000000000..f4b135ab8e6
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/s390/preserve-args-3.c
|
||||
@@ -0,0 +1,19 @@
|
||||
+/* Functional tests for the -mpreserve-args cmdline option. */
|
||||
+
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O3 -march=z900 -mpreserve-args" } */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+int
|
||||
+foo (int a, int, int c, double d, ...)
|
||||
+{
|
||||
+ va_list argp;
|
||||
+ va_start(argp, d);
|
||||
+ return a + c + va_arg(argp, int) + va_arg(argp, int) + (int)va_arg(argp, double);
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "stmg\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target lp64 } } } */
|
||||
+/* { dg-final { scan-assembler "stm\t%r2,%r15,\[0-9\]*\\(%r15\\)" { target { ! lp64 } } } } */
|
||||
+
|
||||
+/* { dg-final { scan-assembler "std\t%f0,\[0-9\]*\\(%r15\\)" } } */
|
||||
+/* { dg-final { scan-assembler "std\t%f2,\[0-9\]*\\(%r15\\)" } } */
|
209
SPECS/gcc.spec
209
SPECS/gcc.spec
@ -4,7 +4,7 @@
|
||||
%global gcc_major 8
|
||||
# Note, gcc_release must be integer, if you want to add suffixes to
|
||||
# %%{release}, append them after %%{gcc_release} on Release: line.
|
||||
%global gcc_release 8
|
||||
%global gcc_release 22
|
||||
%global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f
|
||||
%global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24
|
||||
%global _unpackaged_files_terminate_build 0
|
||||
@ -199,7 +199,7 @@ Requires: libisl.so.15
|
||||
%endif
|
||||
%if %{build_libstdcxx_docs}
|
||||
BuildRequires: doxygen >= 1.7.1
|
||||
BuildRequires: graphviz, dblatex, texlive-collection-latex, docbook5-style-xsl
|
||||
BuildRequires: graphviz, dblatex, texlive-collection-latex, docbook-style-xsl
|
||||
%endif
|
||||
Requires: cpp = %{version}-%{release}
|
||||
# Need .eh_frame ld optimizations
|
||||
@ -283,10 +283,30 @@ Patch22: gcc8-Wbidi-chars.patch
|
||||
Patch23: gcc8-pr96796.patch
|
||||
Patch24: gcc8-pch-tweaks.patch
|
||||
Patch25: gcc8-aarch64-mtune-neoverse-512tvb.patch
|
||||
|
||||
Patch26: gcc8-rh2028609.patch
|
||||
Patch27: gcc8-libgfortran-default-values.patch
|
||||
Patch28: gcc8-rh2001788.patch
|
||||
Patch29: gcc8-rh2117838.patch
|
||||
Patch30: gcc8-rh1668903-1.patch
|
||||
Patch31: gcc8-rh1668903-2.patch
|
||||
Patch32: gcc8-rh1668903-3.patch
|
||||
Patch33: gcc8-harden-1.patch
|
||||
Patch34: gcc8-harden-2.patch
|
||||
Patch35: gcc8-harden-3.patch
|
||||
Patch36: gcc8-harden-4.patch
|
||||
Patch37: gcc8-pr105502.patch
|
||||
Patch38: gcc8-pr99536.patch
|
||||
Patch39: gcc8-libstdc++-make_shared.patch
|
||||
Patch40: gcc8-rh2137448.patch
|
||||
Patch41: gcc8-s390x-regarg-1.patch
|
||||
Patch42: gcc8-s390x-regarg-2.patch
|
||||
Patch43: gcc8-s390x-regarg-3.patch
|
||||
Patch44: gcc8-rh2213753.patch
|
||||
Patch45: gcc8-pr99074.patch
|
||||
Patch46: gcc8-pr87723.patch
|
||||
Patch47: gcc8-pr111039.patch
|
||||
Patch48: gcc8-pr111070.patch
|
||||
Patch49: gcc8-RHEL-32886.patch
|
||||
|
||||
Patch1000: nvptx-tools-no-ptxas.patch
|
||||
Patch1001: nvptx-tools-build.patch
|
||||
@ -832,6 +852,25 @@ NVidia PTX. OpenMP and OpenACC programs linked with -fopenmp will
|
||||
by default add PTX code into the binaries, which can be offloaded
|
||||
to NVidia PTX capable devices if available.
|
||||
|
||||
%package plugin-annobin
|
||||
Summary: The annobin plugin for gcc, built by the installed version of gcc
|
||||
Requires: gcc = %{version}-%{release}
|
||||
# Starting with release 10.01 annobin fixed a bug in its configure scripts
|
||||
# which prevented them from working with a built but not installed compiler
|
||||
BuildRequires: annobin >= 10.01
|
||||
# Starting with release 9.93 annobin-plugin-gcc puts a copy of the sources
|
||||
# in /usr/src/annobin
|
||||
# FIXME: Currently the annobin-plugin-gcc subpackage only exists in Fedora.
|
||||
# For RHEL-9 the annobin package does everything.
|
||||
# BuildRequires: annobin-plugin-gcc
|
||||
# Needed in order to be able to decompress the annobin source tarball.
|
||||
BuildRequires: xz
|
||||
|
||||
%description plugin-annobin
|
||||
This package adds a version of the annobin plugin for gcc. This version
|
||||
of the plugin is explicitly built by the same version of gcc that is installed
|
||||
so that there cannot be any synchronization problems.
|
||||
|
||||
%prep
|
||||
%setup -q -n gcc-%{version}-%{DATE} -a 1 -a 2
|
||||
%patch0 -p0 -b .hack~
|
||||
@ -867,10 +906,31 @@ to NVidia PTX capable devices if available.
|
||||
%patch23 -p1 -b .pr96796~
|
||||
%patch24 -p1 -b .pch-tweaks~
|
||||
%patch25 -p1 -b .neoverse~
|
||||
%patch26 -p1 -b .rh2028609~
|
||||
%patch27 -p1 -b .libgfortran-default~
|
||||
%patch28 -p1 -b .rh2001788~
|
||||
%patch29 -p1 -b .rh2117838~
|
||||
|
||||
%patch30 -p0 -b .rh1668903-1~
|
||||
%patch31 -p0 -b .rh1668903-2~
|
||||
%patch32 -p0 -b .rh1668903-3~
|
||||
%patch33 -p1 -b .harden-1~
|
||||
%patch34 -p1 -b .harden-2~
|
||||
%patch35 -p1 -b .harden-3~
|
||||
%patch36 -p1 -b .harden-4~
|
||||
%patch37 -p1 -b .pr105502~
|
||||
%patch38 -p1 -b .pr99536~
|
||||
%patch39 -p1 -b .make_shared~
|
||||
%patch40 -p1 -b .rh2137448~
|
||||
%patch41 -p1 -b .s390x-regarg-1~
|
||||
%patch42 -p1 -b .s390x-regarg-2~
|
||||
%patch43 -p1 -b .s390x-regarg-3~
|
||||
%patch44 -p1 -b .rh2213753~
|
||||
%patch45 -p1 -b .pr99074~
|
||||
%patch46 -p1 -b .pr87723~
|
||||
%patch47 -p1 -b .pr111039~
|
||||
%patch48 -p1 -b .pr111070~
|
||||
%patch49 -p0 -b .32886~
|
||||
|
||||
cd nvptx-tools-%{nvptx_tools_gitrev}
|
||||
%patch1000 -p1 -b .nvptx-tools-no-ptxas~
|
||||
@ -1208,6 +1268,82 @@ done)
|
||||
rm -f rpm.doc/changelogs/gcc/ChangeLog.[1-9]
|
||||
find rpm.doc -name \*ChangeLog\* | xargs bzip2 -9
|
||||
|
||||
# Get the annobin sources. Note these are not added to the rpm as SOURCE4
|
||||
# because if they were the build phase would try to include them as part of
|
||||
# gcc itself, and this causes problems. Instead we locate the sources in
|
||||
# the buildroot. They should have been put there when annobin was installed.
|
||||
|
||||
pushd %{_builddir}
|
||||
|
||||
%global annobin_source_dir %{_usrsrc}/annobin
|
||||
|
||||
if [ -d %{annobin_source_dir} ]
|
||||
then
|
||||
# Unpack the sources.
|
||||
echo "Unpacking annobin sources"
|
||||
rm -fr annobin-*
|
||||
tar xvf %{annobin_source_dir}/latest-annobin.tar.xz
|
||||
|
||||
# Setting this as a local symbol because using %%global does not appear to work.
|
||||
annobin_dir=$(find . -maxdepth 1 -type d -name "annobin*")
|
||||
|
||||
# Now build the annobin plugin using the just built compiler.
|
||||
echo "annobin directory = ${annobin_dir}"
|
||||
cd ${annobin_dir}
|
||||
|
||||
# Change the plugin so that it generates "nop" instead of ".nop" instructions.
|
||||
sed -e "s/\.nop/nop/" -i gcc-plugin/annobin.cc
|
||||
|
||||
# Work out where this version of gcc stores its plugins.
|
||||
%global ANNOBIN_GCC_PLUGIN_DIR %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin
|
||||
|
||||
CONFIG_ARGS="--quiet"
|
||||
CONFIG_ARGS="$CONFIG_ARGS --with-gcc-plugin-dir=%{ANNOBIN_GCC_PLUGIN_DIR}"
|
||||
CONFIG_ARGS="$CONFIG_ARGS --without-annocheck"
|
||||
CONFIG_ARGS="$CONFIG_ARGS --without-tests"
|
||||
CONFIG_ARGS="$CONFIG_ARGS --disable-rpath"
|
||||
|
||||
comp_dir="%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/gcc/"
|
||||
ccompiler="%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/gcc/xgcc -B $comp_dir"
|
||||
cxxcompiler="%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/gcc/xg++ -B $comp_dir"
|
||||
|
||||
comp_flags="%build_cflags"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/gcc"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/gcc/"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libstdc++-v3/include"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libstdc++-v3/include/%{gcc_target_platform}"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/libstdc++-v3/libsupc++"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/include"
|
||||
comp_flags="$comp_flags -I %{_builddir}/gcc-%{version}-%{DATE}/libcpp/include"
|
||||
|
||||
ld_flags="%build_ldflags"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/libstdc++-v3/.libs"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libstdc++-v3/.libs"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libstdc++-v3/src/.libs"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/libstdc++-v3/libsupc++/.libs"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libstdc++-v3/libsupc++/.libs"
|
||||
ld_flags="$ld_flags -L%{_builddir}/gcc-%{version}-%{DATE}/obj-%{gcc_target_platform}/%{gcc_target_platform}/libgcc/.libs"
|
||||
|
||||
# libtool works with CFLAGS but ignores LDFLAGS, so we have to combine them.
|
||||
comp_flags="$comp_flags $ld_flags"
|
||||
|
||||
echo "Configuring the annobin plugin"
|
||||
CC="${ccompiler}" CFLAGS="${comp_flags}" \
|
||||
CXX="${cxxcompiler}" CXXFLAGS="${comp_flags}" \
|
||||
LDFLAGS="${ld_flags}" \
|
||||
./configure ${CONFIG_ARGS} || cat config.log
|
||||
|
||||
echo "Building the annobin plugin"
|
||||
make
|
||||
|
||||
echo "Annobin plugin build complete"
|
||||
else
|
||||
echo "Unable to locate annobin sources (expected to find: %{annobin_source_dir}/latest-annobin.tar.xz)"
|
||||
echo "These should be provided by installing the annobin package"
|
||||
exit 1
|
||||
fi
|
||||
popd
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
|
||||
@ -1987,6 +2123,20 @@ rm -f %{buildroot}%{mandir}/man3/ffi*
|
||||
# Help plugins find out nvra.
|
||||
echo gcc-%{version}-%{release}.%{_arch} > $FULLPATH/rpmver
|
||||
|
||||
# Rename the annobin plugin to gcc-annobin.
|
||||
mkdir -p %{buildroot}%{ANNOBIN_GCC_PLUGIN_DIR}
|
||||
pushd %{buildroot}%{ANNOBIN_GCC_PLUGIN_DIR}
|
||||
|
||||
annobin_dir=$(find %{_builddir} -maxdepth 1 -type d -name "annobin*")
|
||||
echo "annobin directory = ${annobin_dir}"
|
||||
|
||||
cp ${annobin_dir}/gcc-plugin/.libs/annobin.so.0.0.0 gcc-annobin.so.0.0.0
|
||||
|
||||
rm -f gcc-annobin.so.0 gcc-annobin.so
|
||||
ln -s gcc-annobin.so.0.0.0 gcc-annobin.so.0
|
||||
ln -s gcc-annobin.so.0.0.0 gcc-annobin.so
|
||||
popd
|
||||
|
||||
%check
|
||||
cd obj-%{gcc_target_platform}
|
||||
|
||||
@ -3182,7 +3332,60 @@ fi
|
||||
%{_prefix}/%{_lib}/libgomp-plugin-nvptx.so.*
|
||||
%endif
|
||||
|
||||
%files plugin-annobin
|
||||
%{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so
|
||||
%{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0
|
||||
%{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0
|
||||
|
||||
%changelog
|
||||
* Thu Apr 18 2024 Marek Polacek <polacek@redhat.com> 8.5.0-22
|
||||
- fix ICE in the vectorizer (RHEL-32886)
|
||||
|
||||
* Wed Oct 4 2023 Marek Polacek <polacek@redhat.com> 8.5.0-21
|
||||
- guard the bit test merging code in if-combine (RHEL-11483)
|
||||
|
||||
* Wed Jun 14 2023 Marek Polacek <polacek@redhat.com> 8.5.0-20
|
||||
- fix for TLSLD references (#2213753)
|
||||
- fix crash in dynamic_cast<>() on null pointer (PR c++/99074, #2211506)
|
||||
- adjust a pattern in s390.md (PR target/87723, #2214847)
|
||||
|
||||
* Tue Apr 4 2023 Marek Polacek <polacek@redhat.com> 8.5.0-19
|
||||
- s390x: add support for register arguments preserving (#2168205)
|
||||
|
||||
* Tue Dec 6 2022 Marek Polacek <polacek@redhat.com> 8.5.0-18
|
||||
- fix strlen range with a flexible member array (#2137448)
|
||||
|
||||
* Mon Oct 3 2022 Marek Polacek <polacek@redhat.com> 8.5.0-17
|
||||
- fix deserialization for std::normal_distribution (#2130392,
|
||||
PR libstdc++/105502)
|
||||
- initialize std::normal_distribution::_M_saved (PR libstdc++/99536)
|
||||
- reject std::make_shared<T[]> (PR libstdc++/99006)
|
||||
|
||||
* Thu Sep 29 2022 Marek Polacek <polacek@redhat.com> 8.5.0-16
|
||||
- avoid changing PHIs in GIMPLE split_edge (#2117838)
|
||||
|
||||
* Wed Jul 20 2022 Marek Polacek <polacek@redhat.com> 8.5.0-15
|
||||
- backport straight-line-speculation mitigation (#2108721)
|
||||
|
||||
* Fri Jul 8 2022 Jonathan Wakely <jwakely@redhat.com> 8.5.0-14
|
||||
- backport std::regex check for invalid range (#2001788)
|
||||
|
||||
* Wed Apr 20 2022 Marek Polacek <polacek@redhat.com> 8.5.0-13
|
||||
- require docbook-style-xsl instead of docbook5-style-xsl (#2073888)
|
||||
- backport Default widths with -fdec-format-defaults patch (#2074614)
|
||||
|
||||
* Fri Apr 01 2022 Marek Polacek <polacek@redhat.com> 8.5.0-12
|
||||
- Fix nop generation in annobin plugin. (#2067150)
|
||||
|
||||
* Wed Mar 30 2022 Marek Polacek <polacek@redhat.com> 8.5.0-11
|
||||
- Add a plugin-annobin subpackage. (#2067150)
|
||||
|
||||
* Thu Jan 27 2022 Marek Polacek <polacek@redhat.com> 8.5.0-10
|
||||
- fix typo in the cprop_hardreg patch (#2028609)
|
||||
|
||||
* Mon Jan 24 2022 Marek Polacek <polacek@redhat.com> 8.5.0-9
|
||||
- apply cprop_hardreg fix for narrow mode != lowpart targets (#2028609)
|
||||
|
||||
* Mon Jan 24 2022 Marek Polacek <polacek@redhat.com> 8.5.0-8
|
||||
- aarch64: Add -mtune=neoverse-512tvb (#1845932)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user