Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
2c65cdf052 |
@ -1,3 +0,0 @@
|
||||
b7245af5eab1d4055b6590b6e4f5fb3b7f6c24bf SOURCES/gcc-8.5.0-20210514.tar.xz
|
||||
3bdb3cc01fa7690a0e20ea5cfffcbe690f7665eb SOURCES/nvptx-newlib-aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24.tar.xz
|
||||
ce8eb83be0ac37fb5d5388df455a980fe37b4f13 SOURCES/nvptx-tools-c28050f60193b3b95a18866a96f03334e874e78f.tar.xz
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
SOURCES/gcc-8.5.0-20210514.tar.xz
|
||||
SOURCES/nvptx-newlib-aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24.tar.xz
|
||||
SOURCES/nvptx-tools-c28050f60193b3b95a18866a96f03334e874e78f.tar.xz
|
||||
gcc-14.2.1-20240801.tar.xz
|
||||
isl-0.24.tar.bz2
|
||||
newlib-cygwin-d45261f62a15f8abd94a1031020b9a9f455e4eed.tar.xz
|
||||
nvptx-tools-87ce9dc5999e5fca2e1d3478a30888d9864c9804.tar.xz
|
||||
|
@ -1,59 +0,0 @@
|
||||
2024-04-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-vect-stmts.c (vectorizable_call): For j == 0 use
|
||||
vargs.safe_grow (nargs) rather than vargs.create (nargs), for j != 0
|
||||
remove vargs.truncate (0). Instead of vargs.quick_push store into
|
||||
vargs[i]. Use vargs[i] instead of gimple_call_arg (new_stmt, i)
|
||||
if j != 0.
|
||||
|
||||
* gcc.c-torture/compile/20240418.c: New test.
|
||||
|
||||
--- gcc/tree-vect-stmts.c.jj 2021-04-22 15:48:48.228178359 +0200
|
||||
+++ gcc/tree-vect-stmts.c 2024-04-18 13:21:46.104061529 +0200
|
||||
@@ -3242,9 +3242,7 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
{
|
||||
/* Build argument list for the vectorized call. */
|
||||
if (j == 0)
|
||||
- vargs.create (nargs);
|
||||
- else
|
||||
- vargs.truncate (0);
|
||||
+ vargs.safe_grow (nargs);
|
||||
|
||||
if (slp_node)
|
||||
{
|
||||
@@ -3252,7 +3250,7 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
vec<tree> vec_oprnds0;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
- vargs.quick_push (gimple_call_arg (stmt, i));
|
||||
+ vargs[i] = gimple_call_arg (stmt, i);
|
||||
vect_get_slp_defs (vargs, slp_node, &vec_defs);
|
||||
vec_oprnds0 = vec_defs[0];
|
||||
|
||||
@@ -3314,13 +3312,10 @@ vectorizable_call (gimple *gs, gimple_st
|
||||
vec_oprnd0
|
||||
= vect_get_vec_def_for_operand (op, stmt);
|
||||
else
|
||||
- {
|
||||
- vec_oprnd0 = gimple_call_arg (new_stmt, i);
|
||||
- vec_oprnd0
|
||||
- = vect_get_vec_def_for_stmt_copy (dt[i], vec_oprnd0);
|
||||
- }
|
||||
+ vec_oprnd0
|
||||
+ = vect_get_vec_def_for_stmt_copy (dt[i], vargs[i]);
|
||||
|
||||
- vargs.quick_push (vec_oprnd0);
|
||||
+ vargs[i] = vec_oprnd0;
|
||||
}
|
||||
|
||||
if (gimple_call_internal_p (stmt)
|
||||
--- gcc/testsuite/gcc.c-torture/compile/20240418.c.jj 2024-04-18 13:24:10.180065661 +0200
|
||||
+++ gcc/testsuite/gcc.c-torture/compile/20240418.c 2024-04-18 13:19:12.166194018 +0200
|
||||
@@ -0,0 +1,7 @@
|
||||
+void
|
||||
+foo (signed char *p, unsigned long long *q)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i <= 64; i++)
|
||||
+ *p++ = __builtin_popcountll (*q++);
|
||||
+}
|
File diff suppressed because it is too large
Load Diff
@ -1,27 +0,0 @@
|
||||
2017-02-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.ac: When adding -Wno-format, also add -Wno-format-security.
|
||||
* configure: Regenerated.
|
||||
|
||||
--- gcc/configure.ac.jj 2017-02-13 12:20:53.000000000 +0100
|
||||
+++ gcc/configure.ac 2017-02-25 12:42:32.859175403 +0100
|
||||
@@ -481,7 +481,7 @@ AC_ARG_ENABLE(build-format-warnings,
|
||||
AS_HELP_STRING([--disable-build-format-warnings],[don't use -Wformat while building GCC]),
|
||||
[],[enable_build_format_warnings=yes])
|
||||
AS_IF([test $enable_build_format_warnings = no],
|
||||
- [wf_opt=-Wno-format],[wf_opt=])
|
||||
+ [wf_opt="-Wno-format -Wno-format-security"],[wf_opt=])
|
||||
ACX_PROG_CXX_WARNING_OPTS(
|
||||
m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings ],
|
||||
[-Wcast-qual $wf_opt])), [loose_warn])
|
||||
--- gcc/configure.jj 2017-02-13 12:20:52.000000000 +0100
|
||||
+++ gcc/configure 2017-02-25 12:42:50.041946391 +0100
|
||||
@@ -6647,7 +6647,7 @@ else
|
||||
fi
|
||||
|
||||
if test $enable_build_format_warnings = no; then :
|
||||
- wf_opt=-Wno-format
|
||||
+ wf_opt="-Wno-format -Wno-format-security"
|
||||
else
|
||||
wf_opt=
|
||||
fi
|
@ -1,105 +0,0 @@
|
||||
From 9c108bb84d3a2447dac730c455df658be0a2c751 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Sandiford <richard.sandiford@arm.com>
|
||||
Date: Tue, 17 Aug 2021 15:15:27 +0100
|
||||
Subject: [PATCH] aarch64: Add -mtune=neoverse-512tvb
|
||||
To: gcc-patches@gcc.gnu.org
|
||||
|
||||
This patch adds an option to tune for Neoverse cores that have
|
||||
a total vector bandwidth of 512 bits (4x128 for Advanced SIMD
|
||||
and a vector-length-dependent equivalent for SVE). This is intended
|
||||
to be a compromise between tuning aggressively for a single core like
|
||||
Neoverse V1 (which can be too narrow) and tuning for AArch64 cores
|
||||
in general (which can be too wide).
|
||||
|
||||
-mcpu=neoverse-512tvb is equivalent to -mcpu=neoverse-v1
|
||||
-mtune=neoverse-512tvb.
|
||||
|
||||
gcc/
|
||||
* doc/invoke.texi: Document -mtune=neoverse-512tvb and
|
||||
-mcpu=neoverse-512tvb.
|
||||
* config/aarch64/aarch64-cores.def (neoverse-512tvb): New entry.
|
||||
* config/aarch64/aarch64-tune.md: Regenerate.
|
||||
|
||||
(cherry picked from commit 048039c49b96875144f67e7789fdea54abf7710b)
|
||||
---
|
||||
gcc/config/aarch64/aarch64-cores.def | 1 +
|
||||
gcc/config/aarch64/aarch64-tune.md | 2 +-
|
||||
gcc/doc/invoke.texi | 25 ++++++++++++++++++++++---
|
||||
3 files changed, 24 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
|
||||
index dfb839c01cc..f348d31e22e 100644
|
||||
--- a/gcc/config/aarch64/aarch64-cores.def
|
||||
+++ b/gcc/config/aarch64/aarch64-cores.def
|
||||
@@ -99,6 +99,7 @@ AARCH64_CORE("saphira", saphira, falkor, 8_3A, AARCH64_FL_FOR_ARCH8_3
|
||||
/* ARM ('A') cores. */
|
||||
AARCH64_CORE("zeus", zeus, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1)
|
||||
AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1)
|
||||
+AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversev1, INVALID_IMP, INVALID_CORE, -1)
|
||||
|
||||
/* Armv8.5-A Architecture Processors. */
|
||||
AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_F16 | AARCH64_FL_SVE | AARCH64_FL_RNG, neoversen2, 0x41, 0xd49, -1)
|
||||
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
|
||||
index 2d7c9aa4740..09b76480f0b 100644
|
||||
--- a/gcc/config/aarch64/aarch64-tune.md
|
||||
+++ b/gcc/config/aarch64/aarch64-tune.md
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- buffer-read-only: t -*-
|
||||
;; Generated automatically by gentune.sh from aarch64-cores.def
|
||||
(define_attr "tune"
|
||||
- "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,xgene1,falkor,qdf24xx,exynosm1,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,ares,neoversen1,saphira,zeus,neoversev1,neoversen2,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55"
|
||||
+ "cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,thunderxt81,thunderxt83,xgene1,falkor,qdf24xx,exynosm1,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,ares,neoversen1,saphira,zeus,neoversev1,neoverse512tvb,neoversen2,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55"
|
||||
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 78ca7738df2..68fda03281a 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -14772,9 +14772,9 @@ performance of the code. Permissible values for this option are:
|
||||
@samp{generic}, @samp{cortex-a35}, @samp{cortex-a53}, @samp{cortex-a55},
|
||||
@samp{cortex-a57}, @samp{cortex-a72}, @samp{cortex-a73}, @samp{cortex-a75},
|
||||
@samp{cortex-a76}, @samp{ares}, @samp{neoverse-n1}, @samp{neoverse-n2},
|
||||
-@samp{neoverse-v1}, @samp{zeus}, @samp{exynos-m1}, @samp{falkor},
|
||||
-@samp{qdf24xx}, @samp{saphira}, @samp{xgene1}, @samp{vulcan}, @samp{thunderx},
|
||||
-@samp{thunderxt88}, @samp{thunderxt88p1}, @samp{thunderxt81},
|
||||
+@samp{neoverse-v1}, @samp{zeus}, @samp{neoverse-512tvb}, @samp{exynos-m1},
|
||||
+@samp{falkor}, @samp{qdf24xx}, @samp{saphira}, @samp{xgene1}, @samp{vulcan},
|
||||
+@samp{thunderx}, @samp{thunderxt88}, @samp{thunderxt88p1}, @samp{thunderxt81},
|
||||
@samp{thunderxt83}, @samp{thunderx2t99}, @samp{cortex-a57.cortex-a53},
|
||||
@samp{cortex-a72.cortex-a53}, @samp{cortex-a73.cortex-a35},
|
||||
@samp{cortex-a73.cortex-a53}, @samp{cortex-a75.cortex-a55},
|
||||
@@ -14785,6 +14785,15 @@ The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
|
||||
@samp{cortex-a75.cortex-a55} specify that GCC should tune for a
|
||||
big.LITTLE system.
|
||||
|
||||
+The value @samp{neoverse-512tvb} specifies that GCC should tune
|
||||
+for Neoverse cores that (a) implement SVE and (b) have a total vector
|
||||
+bandwidth of 512 bits per cycle. In other words, the option tells GCC to
|
||||
+tune for Neoverse cores that can execute 4 128-bit Advanced SIMD arithmetic
|
||||
+instructions a cycle and that can execute an equivalent number of SVE
|
||||
+arithmetic instructions per cycle (2 for 256-bit SVE, 4 for 128-bit SVE).
|
||||
+This is more general than tuning for a specific core like Neoverse V1
|
||||
+but is more specific than the default tuning described below.
|
||||
+
|
||||
Additionally on native AArch64 GNU/Linux systems the value
|
||||
@samp{native} tunes performance to the host system. This option has no effect
|
||||
if the compiler is unable to recognize the processor of the host system.
|
||||
@@ -14814,6 +14823,16 @@ by @option{-mtune}). Where this option is used in conjunction
|
||||
with @option{-march} or @option{-mtune}, those options take precedence
|
||||
over the appropriate part of this option.
|
||||
|
||||
+@option{-mcpu=neoverse-512tvb} is special in that it does not refer
|
||||
+to a specific core, but instead refers to all Neoverse cores that
|
||||
+(a) implement SVE and (b) have a total vector bandwidth of 512 bits
|
||||
+a cycle. Unless overridden by @option{-march},
|
||||
+@option{-mcpu=neoverse-512tvb} generates code that can run on a
|
||||
+Neoverse V1 core, since Neoverse V1 is the first Neoverse core with
|
||||
+these properties. Unless overridden by @option{-mtune},
|
||||
+@option{-mcpu=neoverse-512tvb} tunes code in the same way as for
|
||||
+@option{-mtune=neoverse-512tvb}.
|
||||
+
|
||||
@item -moverride=@var{string}
|
||||
@opindex moverride
|
||||
Override tuning decisions made by the back-end in response to a
|
||||
--
|
||||
2.25.1
|
||||
|
@ -1,117 +0,0 @@
|
||||
2017-01-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.c (offload_targets_default): New variable.
|
||||
(process_command): Set it if -foffload is defaulted.
|
||||
(driver::maybe_putenv_OFFLOAD_TARGETS): Add OFFLOAD_TARGET_DEFAULT=1
|
||||
into environment if -foffload has been defaulted.
|
||||
* lto-wrapper.c (OFFLOAD_TARGET_DEFAULT_ENV): Define.
|
||||
(compile_images_for_offload_targets): If OFFLOAD_TARGET_DEFAULT
|
||||
is in the environment, don't fail if corresponding mkoffload
|
||||
can't be found. Free and clear offload_names if no valid offload
|
||||
is found.
|
||||
libgomp/
|
||||
* target.c (gomp_load_plugin_for_device): If a plugin can't be
|
||||
dlopened, assume it has no devices silently.
|
||||
|
||||
--- gcc/gcc.c.jj 2017-01-17 10:28:40.000000000 +0100
|
||||
+++ gcc/gcc.c 2017-01-20 16:26:29.649962902 +0100
|
||||
@@ -290,6 +290,10 @@ static const char *spec_host_machine = D
|
||||
|
||||
static char *offload_targets = NULL;
|
||||
|
||||
+/* Set to true if -foffload has not been used and offload_targets
|
||||
+ is set to the configured in default. */
|
||||
+static bool offload_targets_default;
|
||||
+
|
||||
/* Nonzero if cross-compiling.
|
||||
When -b is used, the value comes from the `specs' file. */
|
||||
|
||||
@@ -4457,7 +4461,10 @@ process_command (unsigned int decoded_op
|
||||
/* If the user didn't specify any, default to all configured offload
|
||||
targets. */
|
||||
if (ENABLE_OFFLOADING && offload_targets == NULL)
|
||||
- handle_foffload_option (OFFLOAD_TARGETS);
|
||||
+ {
|
||||
+ handle_foffload_option (OFFLOAD_TARGETS);
|
||||
+ offload_targets_default = true;
|
||||
+ }
|
||||
|
||||
if (output_file
|
||||
&& strcmp (output_file, "-") != 0
|
||||
@@ -7693,6 +7700,8 @@ driver::maybe_putenv_OFFLOAD_TARGETS ()
|
||||
obstack_grow (&collect_obstack, offload_targets,
|
||||
strlen (offload_targets) + 1);
|
||||
xputenv (XOBFINISH (&collect_obstack, char *));
|
||||
+ if (offload_targets_default)
|
||||
+ xputenv ("OFFLOAD_TARGET_DEFAULT=1");
|
||||
}
|
||||
|
||||
free (offload_targets);
|
||||
--- gcc/lto-wrapper.c.jj 2017-01-01 12:45:34.000000000 +0100
|
||||
+++ gcc/lto-wrapper.c 2017-01-20 16:34:18.294016997 +0100
|
||||
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
|
||||
/* Environment variable, used for passing the names of offload targets from GCC
|
||||
driver to lto-wrapper. */
|
||||
#define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES"
|
||||
+#define OFFLOAD_TARGET_DEFAULT_ENV "OFFLOAD_TARGET_DEFAULT"
|
||||
|
||||
enum lto_mode_d {
|
||||
LTO_MODE_NONE, /* Not doing LTO. */
|
||||
@@ -790,8 +791,10 @@ compile_images_for_offload_targets (unsi
|
||||
if (!target_names)
|
||||
return;
|
||||
unsigned num_targets = parse_env_var (target_names, &names, NULL);
|
||||
+ const char *target_names_default = getenv (OFFLOAD_TARGET_DEFAULT_ENV);
|
||||
|
||||
int next_name_entry = 0;
|
||||
+ bool hsa_seen = false;
|
||||
const char *compiler_path = getenv ("COMPILER_PATH");
|
||||
if (!compiler_path)
|
||||
goto out;
|
||||
@@ -804,18 +807,32 @@ compile_images_for_offload_targets (unsi
|
||||
/* HSA does not use LTO-like streaming and a different compiler, skip
|
||||
it. */
|
||||
if (strcmp (names[i], "hsa") == 0)
|
||||
- continue;
|
||||
+ {
|
||||
+ hsa_seen = true;
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
offload_names[next_name_entry]
|
||||
= compile_offload_image (names[i], compiler_path, in_argc, in_argv,
|
||||
compiler_opts, compiler_opt_count,
|
||||
linker_opts, linker_opt_count);
|
||||
if (!offload_names[next_name_entry])
|
||||
- fatal_error (input_location,
|
||||
- "problem with building target image for %s\n", names[i]);
|
||||
+ {
|
||||
+ if (target_names_default != NULL)
|
||||
+ continue;
|
||||
+ fatal_error (input_location,
|
||||
+ "problem with building target image for %s\n",
|
||||
+ names[i]);
|
||||
+ }
|
||||
next_name_entry++;
|
||||
}
|
||||
|
||||
+ if (next_name_entry == 0 && !hsa_seen)
|
||||
+ {
|
||||
+ free (offload_names);
|
||||
+ offload_names = NULL;
|
||||
+ }
|
||||
+
|
||||
out:
|
||||
free_array_of_ptrs ((void **) names, num_targets);
|
||||
}
|
||||
--- libgomp/target.c.jj 2017-01-01 12:45:52.000000000 +0100
|
||||
+++ libgomp/target.c 2017-01-20 20:12:13.756710875 +0100
|
||||
@@ -2356,7 +2356,7 @@ gomp_load_plugin_for_device (struct gomp
|
||||
|
||||
void *plugin_handle = dlopen (plugin_name, RTLD_LAZY);
|
||||
if (!plugin_handle)
|
||||
- goto dl_fail;
|
||||
+ return 0;
|
||||
|
||||
/* Check if all required functions are available in the plugin and store
|
||||
their handlers. None of the symbols can legitimately be NULL,
|
@ -1,294 +0,0 @@
|
||||
From 88bf1c3910e4cf97dcb85c6d32291c23e572a516 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 27 Oct 2021 07:48:54 -0700
|
||||
Subject: [PATCH 1/4] x86: Add -mharden-sls=[none|all|return|indirect-branch]
|
||||
|
||||
Add -mharden-sls= to mitigate against straight line speculation (SLS)
|
||||
for function return and indirect branch by adding an INT3 instruction
|
||||
after function return and indirect branch.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386-opts.h (harden_sls): New enum.
|
||||
* config/i386/i386.c (output_indirect_thunk): Mitigate against
|
||||
SLS for function return.
|
||||
(ix86_output_function_return): Likewise.
|
||||
(ix86_output_jmp_thunk_or_indirect): Mitigate against indirect
|
||||
branch.
|
||||
(ix86_output_indirect_jmp): Likewise.
|
||||
(ix86_output_call_insn): Likewise.
|
||||
* config/i386/i386.opt: Add -mharden-sls=.
|
||||
* doc/invoke.texi: Document -mharden-sls=.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/102952
|
||||
* gcc.target/i386/harden-sls-1.c: New test.
|
||||
* gcc.target/i386/harden-sls-2.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-3.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-4.c: Likewise.
|
||||
* gcc.target/i386/harden-sls-5.c: Likewise.
|
||||
|
||||
(cherry picked from commit 53a643f8568067d7700a9f2facc8ba39974973d3)
|
||||
---
|
||||
gcc/config/i386/i386-opts.h | 7 +++++++
|
||||
gcc/config/i386/i386.c | 22 +++++++++++++++-----
|
||||
gcc/config/i386/i386.opt | 20 ++++++++++++++++++
|
||||
gcc/doc/invoke.texi | 10 ++++++++-
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-1.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-2.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-3.c | 14 +++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-4.c | 16 ++++++++++++++
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-5.c | 17 +++++++++++++++
|
||||
9 files changed, 128 insertions(+), 6 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
|
||||
index 46366cbfa72..34718b6d52c 100644
|
||||
--- a/gcc/config/i386/i386-opts.h
|
||||
+++ b/gcc/config/i386/i386-opts.h
|
||||
@@ -119,4 +119,11 @@ enum indirect_branch {
|
||||
indirect_branch_thunk_extern
|
||||
};
|
||||
|
||||
+enum harden_sls {
|
||||
+ harden_sls_none = 0,
|
||||
+ harden_sls_return = 1 << 0,
|
||||
+ harden_sls_indirect_branch = 1 << 1,
|
||||
+ harden_sls_all = harden_sls_return | harden_sls_indirect_branch
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 31502774ef3..eb9303f8742 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -10977,6 +10977,9 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
|
||||
fputs ("\tbnd ret\n", asm_out_file);
|
||||
else
|
||||
fputs ("\tret\n", asm_out_file);
|
||||
+
|
||||
+ if ((ix86_harden_sls & harden_sls_return))
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
|
||||
/* Output a funtion with a call and return thunk for indirect branch.
|
||||
@@ -28728,6 +28731,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
fprintf (asm_out_file, "\tjmp\t");
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
+ if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
@@ -28973,10 +28978,10 @@ ix86_output_indirect_jmp (rtx call_op)
|
||||
gcc_unreachable ();
|
||||
|
||||
ix86_output_indirect_branch (call_op, "%0", true);
|
||||
- return "";
|
||||
}
|
||||
else
|
||||
- return "%!jmp\t%A0";
|
||||
+ output_asm_insn ("%!jmp\t%A0", &call_op);
|
||||
+ return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output function return. CALL_OP is the jump target. Add a REP
|
||||
@@ -29018,9 +29023,11 @@ ix86_output_function_return (bool long_p)
|
||||
}
|
||||
|
||||
if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))
|
||||
- return "%!ret";
|
||||
+ output_asm_insn ("%!ret", NULL);
|
||||
+ else
|
||||
+ output_asm_insn ("rep%; ret", NULL);
|
||||
|
||||
- return "rep%; ret";
|
||||
+ return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output indirect function return. RET_OP is the function return
|
||||
@@ -29158,7 +29165,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
|
||||
if (output_indirect_p && !direct_p)
|
||||
ix86_output_indirect_branch (call_op, xasm, true);
|
||||
else
|
||||
- output_asm_insn (xasm, &call_op);
|
||||
+ {
|
||||
+ output_asm_insn (xasm, &call_op);
|
||||
+ if (!direct_p
|
||||
+ && (ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ return "int3";
|
||||
+ }
|
||||
return "";
|
||||
}
|
||||
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index d9bd909a885..3ae48609e25 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1055,3 +1055,23 @@ Support MOVDIRI built-in functions and code generation.
|
||||
mmovdir64b
|
||||
Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save
|
||||
Support MOVDIR64B built-in functions and code generation.
|
||||
+
|
||||
+mharden-sls=
|
||||
+Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none)
|
||||
+Generate code to mitigate against straight line speculation.
|
||||
+
|
||||
+Enum
|
||||
+Name(harden_sls) Type(enum harden_sls)
|
||||
+Known choices for mitigation against straight line speculation with -mharden-sls=:
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(none) Value(harden_sls_none)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(return) Value(harden_sls_return)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(harden_sls) String(all) Value(harden_sls_all)
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 78ca7738df2..1e20efd6969 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -1284,7 +1284,7 @@ See RS/6000 and PowerPC Options.
|
||||
-mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
|
||||
-mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
|
||||
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
|
||||
--mindirect-branch-register}
|
||||
+-mindirect-branch-register -mharden-sls=@var{choice}}
|
||||
|
||||
@emph{x86 Windows Options}
|
||||
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
|
||||
@@ -28036,6 +28036,14 @@ not be reachable in the large code model.
|
||||
@opindex -mindirect-branch-register
|
||||
Force indirect call and jump via register.
|
||||
|
||||
+@item -mharden-sls=@var{choice}
|
||||
+@opindex mharden-sls
|
||||
+Generate code to mitigate against straight line speculation (SLS) with
|
||||
+@var{choice}. The default is @samp{none} which disables all SLS
|
||||
+hardening. @samp{return} enables SLS hardening for function return.
|
||||
+@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
+@samp{all} enables all SLS hardening.
|
||||
+
|
||||
@end table
|
||||
|
||||
These @samp{-m} switches are supported in addition to the above
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..6f70dc94a23
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void foo (void);
|
||||
+
|
||||
+void
|
||||
+bar (void)
|
||||
+{
|
||||
+ foo ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */
|
||||
+/* { dg-final { scan-assembler-not {int3} } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
new file mode 100644
|
||||
index 00000000000..a7c59078d03
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
new file mode 100644
|
||||
index 00000000000..1a6056b6d7b
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 2 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
new file mode 100644
|
||||
index 00000000000..f70dd1379d3
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
|
||||
@@ -0,0 +1,16 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" { target { ! x32 } } } } */
|
||||
+/* { dg-final { scan-assembler "movl\[ \t\]+fptr\\(%rip\\), %eax" { target x32 } } } */
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rax" { target x32 } } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-5.c b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
new file mode 100644
|
||||
index 00000000000..613c44c6f82
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
|
||||
@@ -0,0 +1,17 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -mharden-sls=return" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+typedef void (*dispatch_t)(long offset);
|
||||
+
|
||||
+dispatch_t dispatch;
|
||||
+
|
||||
+int
|
||||
+male_indirect_jump (long offset)
|
||||
+{
|
||||
+ dispatch(offset);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "ret" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
@ -1,155 +0,0 @@
|
||||
From 0df8313a0a5d8533f2487e21d7b42e9adee28f18 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 27 Oct 2021 06:27:15 -0700
|
||||
Subject: [PATCH 2/4] x86: Add -mindirect-branch-cs-prefix
|
||||
|
||||
Add -mindirect-branch-cs-prefix to add CS prefix to call and jmp to
|
||||
indirect thunk with branch target in r8-r15 registers so that the call
|
||||
and jmp instruction length is 6 bytes to allow them to be replaced with
|
||||
"lfence; call *%r8-r15" or "lfence; jmp *%r8-r15" at run-time.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386.c (ix86_output_jmp_thunk_or_indirect): Emit
|
||||
CS prefix for -mindirect-branch-cs-prefix.
|
||||
(ix86_output_indirect_branch_via_reg): Likewise.
|
||||
* config/i386/i386.opt: Add -mindirect-branch-cs-prefix.
|
||||
* doc/invoke.texi: Document -mindirect-branch-cs-prefix.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/102952
|
||||
* gcc.target/i386/indirect-thunk-cs-prefix-1.c: New test.
|
||||
* gcc.target/i386/indirect-thunk-cs-prefix-2.c: Likewise.
|
||||
|
||||
(cherry picked from commit 2196a681d7810ad8b227bf983f38ba716620545e)
|
||||
---
|
||||
gcc/config/i386/i386.c | 14 ++++++++++++--
|
||||
gcc/config/i386/i386.opt | 4 ++++
|
||||
gcc/doc/invoke.texi | 10 +++++++++-
|
||||
.../gcc.target/i386/indirect-thunk-cs-prefix-1.c | 14 ++++++++++++++
|
||||
.../gcc.target/i386/indirect-thunk-cs-prefix-2.c | 15 +++++++++++++++
|
||||
5 files changed, 54 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index eb9303f8742..8442dd0daea 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -28728,7 +28728,12 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd jmp\t");
|
||||
else
|
||||
- fprintf (asm_out_file, "\tjmp\t");
|
||||
+ {
|
||||
+ if (REX_INT_REGNO_P (regno)
|
||||
+ && ix86_indirect_branch_cs_prefix)
|
||||
+ fprintf (asm_out_file, "\tcs\n");
|
||||
+ fprintf (asm_out_file, "\tjmp\t");
|
||||
+ }
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
@@ -28787,7 +28792,12 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
|
||||
if (need_prefix == indirect_thunk_prefix_bnd)
|
||||
fprintf (asm_out_file, "\tbnd call\t");
|
||||
else
|
||||
- fprintf (asm_out_file, "\tcall\t");
|
||||
+ {
|
||||
+ if (REX_INT_REGNO_P (regno)
|
||||
+ && ix86_indirect_branch_cs_prefix)
|
||||
+ fprintf (asm_out_file, "\tcs\n");
|
||||
+ fprintf (asm_out_file, "\tcall\t");
|
||||
+ }
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
return;
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index 3ae48609e25..9f67ef558dc 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1044,6 +1044,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline)
|
||||
EnumValue
|
||||
Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
|
||||
|
||||
+mindirect-branch-cs-prefix
|
||||
+Target Var(ix86_indirect_branch_cs_prefix) Init(0)
|
||||
+Add CS prefix to call and jmp to indirect thunk with branch target in r8-r15 registers.
|
||||
+
|
||||
mindirect-branch-register
|
||||
Target Report Var(ix86_indirect_branch_register) Init(0)
|
||||
Force indirect call and jump via register.
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 1e20efd6969..605cd4b93f1 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -1284,7 +1284,8 @@ See RS/6000 and PowerPC Options.
|
||||
-mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
|
||||
-mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
|
||||
-mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
|
||||
--mindirect-branch-register -mharden-sls=@var{choice}}
|
||||
+-mindirect-branch-register -mharden-sls=@var{choice} @gol
|
||||
+-mindirect-branch-cs-prefix}
|
||||
|
||||
@emph{x86 Windows Options}
|
||||
@gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
|
||||
@@ -28044,6 +28045,13 @@ hardening. @samp{return} enables SLS hardening for function return.
|
||||
@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
@samp{all} enables all SLS hardening.
|
||||
|
||||
+@item -mindirect-branch-cs-prefix
|
||||
+@opindex mindirect-branch-cs-prefix
|
||||
+Add CS prefix to call and jmp to indirect thunk with branch target in
|
||||
+r8-r15 registers so that the call and jmp instruction length is 6 bytes
|
||||
+to allow them to be replaced with @samp{lfence; call *%r8-r15} or
|
||||
+@samp{lfence; jmp *%r8-r15} at run-time.
|
||||
+
|
||||
@end table
|
||||
|
||||
These @samp{-m} switches are supported in addition to the above
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
new file mode 100644
|
||||
index 00000000000..db2f3416823
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*fptr) (void);
|
||||
+
|
||||
+void
|
||||
+foo (void)
|
||||
+{
|
||||
+ fptr ();
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "jmp\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "\tcs" 1 } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
new file mode 100644
|
||||
index 00000000000..adfc39a49d4
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */
|
||||
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
|
||||
+
|
||||
+extern void (*bar) (void);
|
||||
+
|
||||
+int
|
||||
+foo (void)
|
||||
+{
|
||||
+ bar ();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-times "call\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */
|
||||
+/* { dg-final { scan-assembler-times "\tcs" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
@ -1,108 +0,0 @@
|
||||
From 621de498ee19e1f2642eebde707430254c0459c0 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 5 Jan 2022 16:33:16 -0800
|
||||
Subject: [PATCH 3/4] x86: Rename -harden-sls=indirect-branch to
|
||||
-harden-sls=indirect-jmp
|
||||
|
||||
Indirect branch also includes indirect call instructions. Rename
|
||||
-harden-sls=indirect-branch to -harden-sls=indirect-jmp to match its
|
||||
intended behavior.
|
||||
|
||||
PR target/102952
|
||||
* config/i386/i386-opts.h (harden_sls): Replace
|
||||
harden_sls_indirect_branch with harden_sls_indirect_jmp.
|
||||
* config/i386/i386.c (ix86_output_jmp_thunk_or_indirect):
|
||||
Likewise.
|
||||
(ix86_output_indirect_jmp): Likewise.
|
||||
(ix86_output_call_insn): Likewise.
|
||||
* config/i386/i386.opt: Replace indirect-branch with
|
||||
indirect-jmp. Replace harden_sls_indirect_branch with
|
||||
harden_sls_indirect_jmp.
|
||||
* doc/invoke.texi (-harden-sls=): Replace indirect-branch with
|
||||
indirect-jmp.
|
||||
|
||||
(cherry picked from commit ed8060950c64f2e449aaf90e438aa26d0d9d0b31)
|
||||
---
|
||||
gcc/config/i386/i386-opts.h | 4 ++--
|
||||
gcc/config/i386/i386.c | 6 +++---
|
||||
gcc/config/i386/i386.opt | 2 +-
|
||||
gcc/doc/invoke.texi | 4 ++--
|
||||
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
|
||||
index 34718b6d52c..47facc254cd 100644
|
||||
--- a/gcc/config/i386/i386-opts.h
|
||||
+++ b/gcc/config/i386/i386-opts.h
|
||||
@@ -122,8 +122,8 @@ enum indirect_branch {
|
||||
enum harden_sls {
|
||||
harden_sls_none = 0,
|
||||
harden_sls_return = 1 << 0,
|
||||
- harden_sls_indirect_branch = 1 << 1,
|
||||
- harden_sls_all = harden_sls_return | harden_sls_indirect_branch
|
||||
+ harden_sls_indirect_jmp = 1 << 1,
|
||||
+ harden_sls_all = harden_sls_return | harden_sls_indirect_jmp
|
||||
};
|
||||
|
||||
#endif
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 8442dd0daea..3bc14e20105 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -28736,7 +28736,7 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
|
||||
}
|
||||
assemble_name (asm_out_file, thunk_name);
|
||||
putc ('\n', asm_out_file);
|
||||
- if ((ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ if ((ix86_harden_sls & harden_sls_indirect_jmp))
|
||||
fputs ("\tint3\n", asm_out_file);
|
||||
}
|
||||
else
|
||||
@@ -28991,7 +28991,7 @@ ix86_output_indirect_jmp (rtx call_op)
|
||||
}
|
||||
else
|
||||
output_asm_insn ("%!jmp\t%A0", &call_op);
|
||||
- return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : "";
|
||||
+ return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
|
||||
}
|
||||
|
||||
/* Output function return. CALL_OP is the jump target. Add a REP
|
||||
@@ -29178,7 +29178,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
|
||||
{
|
||||
output_asm_insn (xasm, &call_op);
|
||||
if (!direct_p
|
||||
- && (ix86_harden_sls & harden_sls_indirect_branch))
|
||||
+ && (ix86_harden_sls & harden_sls_indirect_jmp))
|
||||
return "int3";
|
||||
}
|
||||
return "";
|
||||
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
|
||||
index 9f67ef558dc..7a5c7b9369a 100644
|
||||
--- a/gcc/config/i386/i386.opt
|
||||
+++ b/gcc/config/i386/i386.opt
|
||||
@@ -1075,7 +1075,7 @@ EnumValue
|
||||
Enum(harden_sls) String(return) Value(harden_sls_return)
|
||||
|
||||
EnumValue
|
||||
-Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch)
|
||||
+Enum(harden_sls) String(indirect-jmp) Value(harden_sls_indirect_jmp)
|
||||
|
||||
EnumValue
|
||||
Enum(harden_sls) String(all) Value(harden_sls_all)
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 605cd4b93f1..20d8e3fd782 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -28041,8 +28041,8 @@ Force indirect call and jump via register.
|
||||
@opindex mharden-sls
|
||||
Generate code to mitigate against straight line speculation (SLS) with
|
||||
@var{choice}. The default is @samp{none} which disables all SLS
|
||||
-hardening. @samp{return} enables SLS hardening for function return.
|
||||
-@samp{indirect-branch} enables SLS hardening for indirect branch.
|
||||
+hardening. @samp{return} enables SLS hardening for function returns.
|
||||
+@samp{indirect-jmp} enables SLS hardening for indirect jumps.
|
||||
@samp{all} enables all SLS hardening.
|
||||
|
||||
@item -mindirect-branch-cs-prefix
|
||||
--
|
||||
2.36.1
|
||||
|
@ -1,75 +0,0 @@
|
||||
From 5a5e7890cefa112e95e1de9800d8081c2a38a1da Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Wed, 5 Jan 2022 18:04:21 -0800
|
||||
Subject: [PATCH 4/4] x86: Generate INT3 for __builtin_eh_return
|
||||
|
||||
Generate INT3 after indirect jmp in exception return for -fcf-protection
|
||||
with -mharden-sls=indirect-jmp.
|
||||
|
||||
gcc/
|
||||
|
||||
PR target/103925
|
||||
* config/i386/i386.c (ix86_output_indirect_function_return):
|
||||
Generate INT3 after indirect jmp for -mharden-sls=indirect-jmp.
|
||||
|
||||
gcc/testsuite/
|
||||
|
||||
PR target/103925
|
||||
* gcc.target/i386/harden-sls-6.c: New test.
|
||||
|
||||
(cherry picked from commit c2e5c4feed32c808591b5278f680bbabe63eb225)
|
||||
---
|
||||
gcc/config/i386/i386.c | 9 ++++++---
|
||||
gcc/testsuite/gcc.target/i386/harden-sls-6.c | 18 ++++++++++++++++++
|
||||
2 files changed, 24 insertions(+), 3 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
|
||||
index 3bc14e20105..dbc3d462fda 100644
|
||||
--- a/gcc/config/i386/i386.c
|
||||
+++ b/gcc/config/i386/i386.c
|
||||
@@ -29083,11 +29083,14 @@ ix86_output_indirect_function_return (rtx ret_op)
|
||||
}
|
||||
else
|
||||
output_indirect_thunk (need_prefix, regno);
|
||||
-
|
||||
- return "";
|
||||
}
|
||||
else
|
||||
- return "%!jmp\t%A0";
|
||||
+ {
|
||||
+ output_asm_insn ("%!jmp\t%A0", &ret_op);
|
||||
+ if (ix86_harden_sls & harden_sls_indirect_jmp)
|
||||
+ fputs ("\tint3\n", asm_out_file);
|
||||
+ }
|
||||
+ return "";
|
||||
}
|
||||
|
||||
/* Split simple return with popping POPC bytes from stack to indirect
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-6.c b/gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
new file mode 100644
|
||||
index 00000000000..9068eb64008
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-6.c
|
||||
@@ -0,0 +1,18 @@
|
||||
+/* { dg-do compile { target { ! ia32 } } } */
|
||||
+/* { dg-options "-O2 -fcf-protection -mharden-sls=indirect-jmp" } */
|
||||
+
|
||||
+struct _Unwind_Context _Unwind_Resume_or_Rethrow_this_context;
|
||||
+
|
||||
+void offset (int);
|
||||
+
|
||||
+struct _Unwind_Context {
|
||||
+ void *reg[7];
|
||||
+} _Unwind_Resume_or_Rethrow() {
|
||||
+ struct _Unwind_Context cur_contextcur_context =
|
||||
+ _Unwind_Resume_or_Rethrow_this_context;
|
||||
+ offset(0);
|
||||
+ __builtin_eh_return ((long) offset, 0);
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rcx" } } */
|
||||
+/* { dg-final { scan-assembler-times "int3" 1 } } */
|
||||
--
|
||||
2.36.1
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- libgomp/configure.tgt.jj 2008-01-10 20:53:48.000000000 +0100
|
||||
+++ libgomp/configure.tgt 2008-03-27 12:44:51.000000000 +0100
|
||||
@@ -67,7 +67,7 @@ if test $enable_linux_futex = yes; then
|
||||
;;
|
||||
*)
|
||||
if test -z "$with_arch"; then
|
||||
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
|
||||
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=generic"
|
||||
fi
|
||||
esac
|
||||
;;
|
@ -1,14 +0,0 @@
|
||||
--- libgcc/config/t-slibgcc.mp 2018-10-03 16:07:00.336990246 -0400
|
||||
+++ libgcc/config/t-slibgcc 2018-10-03 16:06:26.719946740 -0400
|
||||
@@ -30,9 +30,10 @@ SHLIB_LC = -lc
|
||||
SHLIB_MAKE_SOLINK = $(LN_S) $(SHLIB_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
|
||||
SHLIB_INSTALL_SOLINK = $(LN_S) $(SHLIB_SONAME) \
|
||||
$(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
|
||||
+SHLIB_EXTRA_LDFLAGS = -Wl,-z,relro -Wl,-z,now
|
||||
|
||||
SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
- $(SHLIB_LDFLAGS) \
|
||||
+ $(SHLIB_LDFLAGS) $(SHLIB_EXTRA_LDFLAGS) \
|
||||
-o $(SHLIB_DIR)/$(SHLIB_SONAME).tmp @multilib_flags@ \
|
||||
$(SHLIB_OBJS) $(SHLIB_LC) && \
|
||||
rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \
|
@ -1,516 +0,0 @@
|
||||
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
|
||||
index d93dcfa..f47565c 100644
|
||||
--- a/gcc/fortran/io.c
|
||||
+++ b/gcc/fortran/io.c
|
||||
@@ -909,6 +909,13 @@ data_desc:
|
||||
|
||||
if (u != FMT_POSINT)
|
||||
{
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume a default width based on the variable size. */
|
||||
+ saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
format_locus.nextc += format_string_pos;
|
||||
gfc_error ("Positive width required in format "
|
||||
"specifier %s at %L", token_to_string (t),
|
||||
@@ -1030,6 +1037,13 @@ data_desc:
|
||||
goto fail;
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume the default width is expected here and continue lexing. */
|
||||
+ value = 0; /* It doesn't matter what we set the value to here. */
|
||||
+ saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
error = nonneg_required;
|
||||
goto syntax;
|
||||
}
|
||||
@@ -1099,8 +1113,17 @@ data_desc:
|
||||
goto fail;
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
- error = nonneg_required;
|
||||
- goto syntax;
|
||||
+ if (flag_dec)
|
||||
+ {
|
||||
+ /* Assume the default width is expected here and continue lexing. */
|
||||
+ value = 0; /* It doesn't matter what we set the value to here. */
|
||||
+ saved_token = t;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ error = nonneg_required;
|
||||
+ goto syntax;
|
||||
+ }
|
||||
}
|
||||
else if (is_input && t == FMT_ZERO)
|
||||
{
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..b087b8f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
|
||||
@@ -0,0 +1,43 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+!
|
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float
|
||||
+! values to a higher precision than the type can actually store, the results
|
||||
+! are implementation dependent: some platforms print zeros, others print random
|
||||
+! numbers. Don't depend on this behaviour in tests because they will not be
|
||||
+! portable.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+
|
||||
+ real*4 :: real_4
|
||||
+ real*8 :: real_8
|
||||
+ real*16 :: real_16
|
||||
+ integer :: len
|
||||
+
|
||||
+ real_4 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 4.1799998:") call abort
|
||||
+
|
||||
+ real_4 = 0.00000018
|
||||
+ write(buffer, '(A, F, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.0000002:") call abort
|
||||
+
|
||||
+ real_8 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_8,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 27) call abort
|
||||
+
|
||||
+ real_16 = 4.18
|
||||
+ write(buffer, '(A, F, A)') ':',real_16,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 44) call abort
|
||||
+end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..3d3a476
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
|
||||
@@ -0,0 +1,48 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+!
|
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float
|
||||
+! values to a higher precision than the type can actually store, the results
|
||||
+! are implementation dependent: some platforms print zeros, others print random
|
||||
+! numbers. Don't depend on this behaviour in tests because they will not be
|
||||
+! portable.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+
|
||||
+ real*4 :: real_4
|
||||
+ real*8 :: real_8
|
||||
+ real*16 :: real_16
|
||||
+ integer :: len
|
||||
+
|
||||
+ real_4 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 4.180000 :") call abort
|
||||
+
|
||||
+ real_4 = 0.00000018
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.1800000E-06:") call abort
|
||||
+
|
||||
+ real_4 = 18000000.4
|
||||
+ write(buffer, '(A, G, A)') ':',real_4,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 0.1800000E+08:") call abort
|
||||
+
|
||||
+ real_8 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_8,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 27) call abort
|
||||
+
|
||||
+ real_16 = 4.18
|
||||
+ write(buffer, '(A, G, A)') ':',real_16,':'
|
||||
+ print *,buffer
|
||||
+ len = len_trim(buffer)
|
||||
+ if (len /= 44) call abort
|
||||
+end
|
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
|
||||
new file mode 100644
|
||||
index 0000000..ac4e165
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
|
||||
@@ -0,0 +1,38 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options -fdec }
|
||||
+!
|
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
|
||||
+!
|
||||
+! This feature is not part of any Fortran standard, but it is supported by the
|
||||
+! Oracle Fortran compiler and others.
|
||||
+
|
||||
+ character(50) :: buffer
|
||||
+ character(1) :: colon
|
||||
+
|
||||
+ integer*2 :: integer_2
|
||||
+ integer*4 :: integer_4
|
||||
+ integer*8 :: integer_8
|
||||
+
|
||||
+ write(buffer, '(A, I, A)') ':',12340,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": 12340:") call abort
|
||||
+
|
||||
+ read(buffer, '(A1, I, A1)') colon, integer_4, colon
|
||||
+ if (integer_4.ne.12340) call abort
|
||||
+
|
||||
+ integer_2 = -99
|
||||
+ write(buffer, '(A, I, A)') ':',integer_2,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": -99:") call abort
|
||||
+
|
||||
+ integer_8 = -11112222
|
||||
+ write(buffer, '(A, I, A)') ':',integer_8,':'
|
||||
+ print *,buffer
|
||||
+ if (buffer.ne.": -11112222:") call abort
|
||||
+
|
||||
+! If the width is 7 and there are 7 leading zeroes, the result should be zero.
|
||||
+ integer_2 = 789
|
||||
+ buffer = '0000000789'
|
||||
+ read(buffer, '(I)') integer_2
|
||||
+ if (integer_2.ne.0) call abort
|
||||
+end
|
||||
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
|
||||
index c2abdd7..692b1ff 100644
|
||||
--- a/libgfortran/io/format.c
|
||||
+++ b/libgfortran/io/format.c
|
||||
@@ -956,12 +956,33 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
*seen_dd = true;
|
||||
if (u != FMT_POSINT && u != FMT_ZERO)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.real.w = DEFAULT_WIDTH;
|
||||
+ tail->u.real.d = 0;
|
||||
+ tail->u.real.e = -1;
|
||||
+ fmt->saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = nonneg_required;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
+ else if (u == FMT_ZERO)
|
||||
+ {
|
||||
+ fmt->error = posint_required;
|
||||
+ goto finished;
|
||||
+ }
|
||||
else if (u != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.real.w = DEFAULT_WIDTH;
|
||||
+ tail->u.real.d = 0;
|
||||
+ tail->u.real.e = -1;
|
||||
+ fmt->saved_token = u;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = posint_required;
|
||||
goto finished;
|
||||
}
|
||||
@@ -1099,6 +1120,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
{
|
||||
if (t != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.integer.w = DEFAULT_WIDTH;
|
||||
+ tail->u.integer.m = -1;
|
||||
+ fmt->saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = posint_required;
|
||||
goto finished;
|
||||
}
|
||||
@@ -1107,6 +1135,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
|
||||
{
|
||||
if (t != FMT_ZERO && t != FMT_POSINT)
|
||||
{
|
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT)
|
||||
+ {
|
||||
+ tail->u.integer.w = DEFAULT_WIDTH;
|
||||
+ tail->u.integer.m = -1;
|
||||
+ fmt->saved_token = t;
|
||||
+ break;
|
||||
+ }
|
||||
fmt->error = nonneg_required;
|
||||
goto finished;
|
||||
}
|
||||
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
|
||||
index 5583183..d1d08e8 100644
|
||||
--- a/libgfortran/io/io.h
|
||||
+++ b/libgfortran/io/io.h
|
||||
@@ -981,5 +981,55 @@ memset4 (gfc_char4_t *p, gfc_char4_t c, int k)
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
+/* Used in width fields to indicate that the default should be used */
|
||||
+#define DEFAULT_WIDTH -1
|
||||
+
|
||||
+/* Defaults for certain format field descriptors. These are decided based on
|
||||
+ * the type of the value being formatted.
|
||||
+ *
|
||||
+ * The behaviour here is modelled on the Oracle Fortran compiler. At the time
|
||||
+ * of writing, the details were available at this URL:
|
||||
+ *
|
||||
+ * https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnc3/index.html#z4000743746d
|
||||
+ */
|
||||
+
|
||||
+static inline int
|
||||
+default_width_for_integer (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ case 2: return 7;
|
||||
+ case 4: return 12;
|
||||
+ case 8: return 23;
|
||||
+ case 16: return 44;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+default_width_for_float (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 4: return 15;
|
||||
+ case 8: return 25;
|
||||
+ case 16: return 42;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+default_precision_for_float (int kind)
|
||||
+{
|
||||
+ switch (kind)
|
||||
+ {
|
||||
+ case 4: return 7;
|
||||
+ case 8: return 16;
|
||||
+ case 16: return 33;
|
||||
+ default: return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
|
||||
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
|
||||
index 2c9de48..e911e35 100644
|
||||
--- a/libgfortran/io/read.c
|
||||
+++ b/libgfortran/io/read.c
|
||||
@@ -629,6 +629,12 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
|
||||
|
||||
w = f->u.w;
|
||||
|
||||
+ /* This is a legacy extension, and the frontend will only allow such cases
|
||||
+ * through when -fdec-format-defaults is passed.
|
||||
+ */
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (length);
|
||||
+
|
||||
p = read_block_form (dtp, &w);
|
||||
|
||||
if (p == NULL)
|
||||
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
|
||||
index a7307a8..c8e52fb 100644
|
||||
--- a/libgfortran/io/write.c
|
||||
+++ b/libgfortran/io/write.c
|
||||
@@ -684,9 +684,8 @@ write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
|
||||
p[wlen - 1] = (n) ? 'T' : 'F';
|
||||
}
|
||||
|
||||
-
|
||||
static void
|
||||
-write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
|
||||
+write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
|
||||
{
|
||||
int w, m, digits, nzero, nblank;
|
||||
char *p;
|
||||
@@ -719,6 +718,9 @@ write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
|
||||
/* Select a width if none was specified. The idea here is to always
|
||||
print something. */
|
||||
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (len);
|
||||
+
|
||||
if (w == 0)
|
||||
w = ((digits < m) ? m : digits);
|
||||
|
||||
@@ -845,6 +847,8 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
|
||||
|
||||
/* Select a width if none was specified. The idea here is to always
|
||||
print something. */
|
||||
+ if (w == DEFAULT_WIDTH)
|
||||
+ w = default_width_for_integer (len);
|
||||
|
||||
if (w == 0)
|
||||
w = ((digits < m) ? m : digits) + nsign;
|
||||
@@ -1187,13 +1191,13 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = btoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = btoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,13 +1212,13 @@ write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = otoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = otoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,13 +1232,13 @@ write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
|
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
|
||||
{
|
||||
p = ztoa_big (source, itoa_buf, len, &n);
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = extract_uint (source, len);
|
||||
p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
|
||||
- write_boz (dtp, f, p, n);
|
||||
+ write_boz (dtp, f, p, n, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1504,7 +1508,7 @@ size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
|
||||
{
|
||||
int size;
|
||||
|
||||
- if (f->format == FMT_F && f->u.real.w == 0)
|
||||
+ if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
|
||||
index 7f0aa1d..73dc910 100644
|
||||
--- a/libgfortran/io/write_float.def
|
||||
+++ b/libgfortran/io/write_float.def
|
||||
@@ -113,7 +113,8 @@ determine_precision (st_parameter_dt * d
|
||||
static void
|
||||
build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer,
|
||||
size_t size, int nprinted, int precision, int sign_bit,
|
||||
- bool zero_flag, int npad, char *result, size_t *len)
|
||||
+ bool zero_flag, int npad, int default_width, char *result,
|
||||
+ size_t *len)
|
||||
{
|
||||
char *put;
|
||||
char *digits;
|
||||
@@ -132,8 +133,17 @@ build_float_string (st_parameter_dt *dtp
|
||||
sign_t sign;
|
||||
|
||||
ft = f->format;
|
||||
- w = f->u.real.w;
|
||||
- d = f->u.real.d;
|
||||
+ if (f->u.real.w == DEFAULT_WIDTH)
|
||||
+ /* This codepath can only be reached with -fdec-format-defaults. */
|
||||
+ {
|
||||
+ w = default_width;
|
||||
+ d = precision;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ w = f->u.real.w;
|
||||
+ d = f->u.real.d;
|
||||
+ }
|
||||
p = dtp->u.p.scale_factor;
|
||||
*len = 0;
|
||||
|
||||
@@ -959,6 +969,11 @@ determine_en_precision (st_parameter_dt
|
||||
int save_scale_factor;\
|
||||
volatile GFC_REAL_ ## x temp;\
|
||||
save_scale_factor = dtp->u.p.scale_factor;\
|
||||
+ if (w == DEFAULT_WIDTH)\
|
||||
+ {\
|
||||
+ w = default_width;\
|
||||
+ d = precision;\
|
||||
+ }\
|
||||
switch (dtp->u.p.current_unit->round_status)\
|
||||
{\
|
||||
case ROUND_ZERO:\
|
||||
@@ -1034,7 +1049,8 @@ determine_en_precision (st_parameter_dt
|
||||
nprinted = FDTOA(y,precision,m);\
|
||||
}\
|
||||
build_float_string (dtp, &newf, buffer, size, nprinted, precision,\
|
||||
- sign_bit, zero_flag, npad, result, res_len);\
|
||||
+ sign_bit, zero_flag, npad, default_width,\
|
||||
+ result, res_len);\
|
||||
dtp->u.p.scale_factor = save_scale_factor;\
|
||||
}\
|
||||
else\
|
||||
@@ -1044,7 +1060,8 @@ determine_en_precision (st_parameter_dt
|
||||
else\
|
||||
nprinted = DTOA(y,precision,m);\
|
||||
build_float_string (dtp, f, buffer, size, nprinted, precision,\
|
||||
- sign_bit, zero_flag, npad, result, res_len);\
|
||||
+ sign_bit, zero_flag, npad, default_width,\
|
||||
+ result, res_len);\
|
||||
}\
|
||||
}\
|
||||
|
||||
@@ -1058,6 +1075,16 @@ get_float_string (st_parameter_dt *dtp,
|
||||
{
|
||||
int sign_bit, nprinted;
|
||||
bool zero_flag;
|
||||
+ int default_width = 0;
|
||||
+
|
||||
+ if (f->u.real.w == DEFAULT_WIDTH)
|
||||
+ /* This codepath can only be reached with -fdec-format-defaults. The default
|
||||
+ * values are based on those used in the Oracle Fortran compiler.
|
||||
+ */
|
||||
+ {
|
||||
+ default_width = default_width_for_float (kind);
|
||||
+ precision = default_precision_for_float (kind);
|
||||
+ }
|
||||
|
||||
switch (kind)
|
||||
{
|
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
--- libgomp/testsuite/libgomp-test-support.exp.in.jj 2018-04-25 09:40:31.323655308 +0200
|
||||
+++ libgomp/testsuite/libgomp-test-support.exp.in 2019-04-25 20:01:50.028243827 +0200
|
||||
@@ -2,4 +2,5 @@ set cuda_driver_include "@CUDA_DRIVER_IN
|
||||
set cuda_driver_lib "@CUDA_DRIVER_LIB@"
|
||||
set hsa_runtime_lib "@HSA_RUNTIME_LIB@"
|
||||
|
||||
+set offload_plugins "@offload_plugins@"
|
||||
set offload_targets "@offload_targets@"
|
||||
--- libgomp/testsuite/lib/libgomp.exp.jj 2018-04-25 09:40:31.584655429 +0200
|
||||
+++ libgomp/testsuite/lib/libgomp.exp 2019-05-24 11:41:51.015822702 +0200
|
||||
@@ -40,7 +40,7 @@ load_file libgomp-test-support.exp
|
||||
# Populate offload_targets_s (offloading targets separated by a space), and
|
||||
# offload_targets_s_openacc (the same, but with OpenACC names; OpenACC spells
|
||||
# some of them a little differently).
|
||||
-set offload_targets_s [split $offload_targets ","]
|
||||
+set offload_targets_s [split $offload_plugins ","]
|
||||
set offload_targets_s_openacc {}
|
||||
foreach offload_target_openacc $offload_targets_s {
|
||||
# Translate to OpenACC names, or skip if not yet supported.
|
||||
@@ -137,8 +137,8 @@ proc libgomp_init { args } {
|
||||
|
||||
# Add liboffloadmic build directory in LD_LIBRARY_PATH to support
|
||||
# non-fallback testing for Intel MIC targets
|
||||
- global offload_targets
|
||||
- if { [string match "*,intelmic,*" ",$offload_targets,"] } {
|
||||
+ global offload_plugins
|
||||
+ if { [string match "*,intelmic,*" ",$offload_plugins,"] } {
|
||||
append always_ld_library_path ":${blddir}/../liboffloadmic/.libs"
|
||||
append always_ld_library_path ":${blddir}/../liboffloadmic/plugin/.libs"
|
||||
# libstdc++ is required by liboffloadmic
|
||||
@@ -362,8 +362,8 @@ proc check_effective_target_offload_devi
|
||||
# Return 1 if configured for nvptx offloading.
|
||||
|
||||
proc check_effective_target_openacc_nvidia_accel_configured { } {
|
||||
- global offload_targets
|
||||
- if { ![string match "*,nvptx,*" ",$offload_targets,"] } {
|
||||
+ global offload_plugins
|
||||
+ if { ![string match "*,nvptx,*" ",$offload_plugins,"] } {
|
||||
return 0
|
||||
}
|
||||
# PR libgomp/65099: Currently, we only support offloading in 64-bit
|
@ -1,61 +0,0 @@
|
||||
commit 79fa567e234585dc6a71f9bd069101c993513f3e
|
||||
Author: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Thu Apr 22 15:46:51 2021 +0100
|
||||
|
||||
libstdc++: Reject std::make_shared<T[]> [PR 99006]
|
||||
|
||||
Prior to C++20 it should be ill-formed to use std::make_shared with an
|
||||
array type (and we don't support the C++20 feature to make it valid yet
|
||||
anyway).
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/99006
|
||||
* include/bits/shared_ptr.h (allocate_shared): Assert that _Tp
|
||||
is not an array type.
|
||||
* include/bits/shared_ptr_base.h (__allocate_shared): Likewise.
|
||||
* testsuite/20_util/shared_ptr/creation/99006.cc: New test.
|
||||
|
||||
(cherry picked from commit 55650236cd97d81f42f9fdb4f6bcb12babafe51f)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h
|
||||
index 281600b2901..4ddc52ae723 100644
|
||||
--- a/libstdc++-v3/include/bits/shared_ptr.h
|
||||
+++ b/libstdc++-v3/include/bits/shared_ptr.h
|
||||
@@ -698,6 +698,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline shared_ptr<_Tp>
|
||||
allocate_shared(const _Alloc& __a, _Args&&... __args)
|
||||
{
|
||||
+ static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
|
||||
+
|
||||
return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
index 0367c2d51a5..8af6e9fb11c 100644
|
||||
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
|
||||
@@ -1822,6 +1822,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
inline __shared_ptr<_Tp, _Lp>
|
||||
__allocate_shared(const _Alloc& __a, _Args&&... __args)
|
||||
{
|
||||
+ static_assert(!is_array<_Tp>::value, "make_shared<T[]> not supported");
|
||||
+
|
||||
return __shared_ptr<_Tp, _Lp>(_Sp_alloc_shared_tag<_Alloc>{__a},
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc
|
||||
new file mode 100644
|
||||
index 00000000000..d5f7a5da5e9
|
||||
--- /dev/null
|
||||
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/creation/99006.cc
|
||||
@@ -0,0 +1,9 @@
|
||||
+// FIXME: This should use { target { ! c++20 } }
|
||||
+// { dg-do compile }
|
||||
+
|
||||
+#include <memory>
|
||||
+
|
||||
+auto p = std::make_shared<int[]>(2); // { dg-error "here" }
|
||||
+auto q = std::make_shared<int[2]>(1, 2); // { dg-error "here" }
|
||||
+
|
||||
+// { dg-prune-output "static assertion failed" }
|
@ -1,17 +0,0 @@
|
||||
2018-04-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* config/i386/i386.opt (mcet): Remporarily re-add as alias to -mshstk.
|
||||
|
||||
--- gcc/config/i386/i386.opt (revision 259613)
|
||||
+++ gcc/config/i386/i386.opt (revision 259612)
|
||||
@@ -1006,6 +1006,10 @@ mgeneral-regs-only
|
||||
Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
|
||||
Generate code which uses only the general registers.
|
||||
|
||||
+mcet
|
||||
+Target Undocumented Alias(mshstk)
|
||||
+;; Deprecated
|
||||
+
|
||||
mshstk
|
||||
Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
|
||||
Enable shadow stack built-in functions from Control-flow Enforcement
|
@ -1,844 +0,0 @@
|
||||
commit fe7c3ecff1f9c0520090a77fa824d8c5d9dbec12
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Fri Dec 3 11:03:30 2021 +0100
|
||||
|
||||
pch: Add support for PCH for relocatable executables [PR71934]
|
||||
|
||||
So, if we want to make PCH work for PIEs, I'd say we can:
|
||||
1) add a new GTY option, say callback, which would act like
|
||||
skip for non-PCH and for PCH would make us skip it but
|
||||
remember for address bias translation
|
||||
2) drop the skip for tree_translation_unit_decl::language
|
||||
3) change get_unnamed_section to have const char * as
|
||||
last argument instead of const void *, change
|
||||
unnamed_section::data also to const char * and update
|
||||
everything related to that
|
||||
4) maybe add a host hook whether it is ok to support binaries
|
||||
changing addresses (the only thing I'm worried is if
|
||||
some host that uses function descriptors allocates them
|
||||
dynamically instead of having them somewhere in the
|
||||
executable)
|
||||
5) maybe add a gengtype warning if it sees in GTY tracked
|
||||
structure a function pointer without that new callback
|
||||
option
|
||||
|
||||
Here is 1), 2), 3) implemented.
|
||||
|
||||
Note, on stdc++.h.gch/O2g.gch there are just those 10 relocations without
|
||||
the second patch, with it a few more, but nothing huge. And for non-PIEs
|
||||
there isn't really any extra work on the load side except freading two scalar
|
||||
values and fseek.
|
||||
|
||||
2021-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR pch/71934
|
||||
gcc/
|
||||
* ggc.h (gt_pch_note_callback): Declare.
|
||||
* gengtype.h (enum typekind): Add TYPE_CALLBACK.
|
||||
(callback_type): Declare.
|
||||
* gengtype.c (dbgprint_count_type_at): Handle TYPE_CALLBACK.
|
||||
(callback_type): New variable.
|
||||
(process_gc_options): Add CALLBACK argument, handle callback
|
||||
option.
|
||||
(set_gc_used_type): Adjust process_gc_options caller, if callback,
|
||||
set type to &callback_type.
|
||||
(output_mangled_typename): Handle TYPE_CALLBACK.
|
||||
(walk_type): Likewise. Handle callback option.
|
||||
(write_types_process_field): Handle TYPE_CALLBACK.
|
||||
(write_types_local_user_process_field): Likewise.
|
||||
(write_types_local_process_field): Likewise.
|
||||
(write_root): Likewise.
|
||||
(dump_typekind): Likewise.
|
||||
(dump_type): Likewise.
|
||||
* gengtype-state.c (type_lineloc): Handle TYPE_CALLBACK.
|
||||
(state_writer::write_state_callback_type): New method.
|
||||
(state_writer::write_state_type): Handle TYPE_CALLBACK.
|
||||
(read_state_callback_type): New function.
|
||||
(read_state_type): Handle TYPE_CALLBACK.
|
||||
* ggc-common.c (callback_vec): New variable.
|
||||
(gt_pch_note_callback): New function.
|
||||
(gt_pch_save): Stream out gt_pch_save function address and relocation
|
||||
table.
|
||||
(gt_pch_restore): Stream in saved gt_pch_save function address and
|
||||
relocation table and apply relocations if needed.
|
||||
* doc/gty.texi (callback): Document new GTY option.
|
||||
* varasm.c (get_unnamed_section): Change callback argument's type and
|
||||
last argument's type from const void * to const char *.
|
||||
(output_section_asm_op): Change argument's type from const void *
|
||||
to const char *, remove unnecessary cast.
|
||||
* tree-core.h (struct tree_translation_unit_decl): Drop GTY((skip))
|
||||
from language member.
|
||||
* output.h (unnamed_section_callback): Change argument type from
|
||||
const void * to const char *.
|
||||
(struct unnamed_section): Use GTY((callback)) instead of GTY((skip))
|
||||
for callback member. Change data member type from const void *
|
||||
to const char *.
|
||||
(struct noswitch_section): Use GTY((callback)) instead of GTY((skip))
|
||||
for callback member.
|
||||
(get_unnamed_section): Change callback argument's type and
|
||||
last argument's type from const void * to const char *.
|
||||
(output_section_asm_op): Change argument's type from const void *
|
||||
to const char *.
|
||||
* config/avr/avr.c (avr_output_progmem_section_asm_op): Likewise.
|
||||
Remove unneeded cast.
|
||||
* config/darwin.c (output_objc_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
* config/pa/pa.c (som_output_text_section_asm_op): Likewise.
|
||||
(som_output_comdat_data_section_asm_op): Likewise.
|
||||
* config/rs6000/rs6000.c (rs6000_elf_output_toc_section_asm_op):
|
||||
Likewise.
|
||||
(rs6000_xcoff_output_readonly_section_asm_op): Likewise. Instead
|
||||
of dereferencing directive hardcode variable names and decide based on
|
||||
whether directive is NULL or not.
|
||||
(rs6000_xcoff_output_readwrite_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
(rs6000_xcoff_output_tls_section_asm_op): Likewise. Instead
|
||||
of dereferencing directive hardcode variable names and decide based on
|
||||
whether directive is NULL or not.
|
||||
(rs6000_xcoff_output_toc_section_asm_op): Change argument's type
|
||||
from const void * to const char *.
|
||||
(rs6000_xcoff_asm_init_sections): Adjust get_unnamed_section callers.
|
||||
gcc/c-family/
|
||||
* c-pch.c (struct c_pch_validity): Remove pch_init member.
|
||||
(pch_init): Don't initialize v.pch_init.
|
||||
(c_common_valid_pch): Don't warn and punt if .text addresses change.
|
||||
libcpp/
|
||||
* include/line-map.h (class line_maps): Add GTY((callback)) to
|
||||
reallocator and round_alloc_size members.
|
||||
|
||||
commit 4dc6d19222581c77a174d44d97507d234fb7e39b
|
||||
Author: Jakub Jelinek <jakub@redhat.com>
|
||||
Date: Mon Dec 6 11:18:58 2021 +0100
|
||||
|
||||
avr: Fix AVR build [PR71934]
|
||||
|
||||
On Mon, Dec 06, 2021 at 11:00:30AM +0100, Martin Liška wrote:
|
||||
> Jakub, I think the patch broke avr-linux target:
|
||||
>
|
||||
> g++ -fno-PIE -c -g -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-erro
|
||||
> /home/marxin/Programming/gcc/gcc/config/avr/avr.c: In function ‘void avr_output_data_section_asm_op(const void*)’:
|
||||
> /home/marxin/Programming/gcc/gcc/config/avr/avr.c:10097:26: error: invalid conversion from ‘const void*’ to ‘const char*’ [-fpermissive]
|
||||
|
||||
This patch fixes that.
|
||||
|
||||
2021-12-06 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR pch/71934
|
||||
* config/avr/avr.c (avr_output_data_section_asm_op,
|
||||
avr_output_bss_section_asm_op): Change argument type from const void *
|
||||
to const char *.
|
||||
|
||||
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
|
||||
index 5da60423354..2cafa1387bb 100644
|
||||
--- a/gcc/c-family/c-pch.c
|
||||
+++ b/gcc/c-family/c-pch.c
|
||||
@@ -58,7 +58,6 @@ struct c_pch_validity
|
||||
{
|
||||
unsigned char debug_info_type;
|
||||
signed char match[MATCH_SIZE];
|
||||
- void (*pch_init) (void);
|
||||
size_t target_data_length;
|
||||
};
|
||||
|
||||
@@ -123,7 +122,6 @@ pch_init (void)
|
||||
gcc_assert (v.match[i] == *pch_matching[i].flag_var);
|
||||
}
|
||||
}
|
||||
- v.pch_init = &pch_init;
|
||||
target_validity = targetm.get_pch_validity (&v.target_data_length);
|
||||
|
||||
if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
|
||||
@@ -287,20 +285,6 @@ c_common_valid_pch (cpp_reader *pfile, c
|
||||
}
|
||||
}
|
||||
|
||||
- /* If the text segment was not loaded at the same address as it was
|
||||
- when the PCH file was created, function pointers loaded from the
|
||||
- PCH will not be valid. We could in theory remap all the function
|
||||
- pointers, but no support for that exists at present.
|
||||
- Since we have the same executable, it should only be necessary to
|
||||
- check one function. */
|
||||
- if (v.pch_init != &pch_init)
|
||||
- {
|
||||
- if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
- cpp_error (pfile, CPP_DL_WARNING,
|
||||
- "%s: had text segment at different address", name);
|
||||
- return 2;
|
||||
- }
|
||||
-
|
||||
/* Check the target-specific validity data. */
|
||||
{
|
||||
void *this_file_data = xmalloc (v.target_data_length);
|
||||
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
|
||||
index 200701a583c..6ba038881d6 100644
|
||||
--- a/gcc/config/avr/avr.c
|
||||
+++ b/gcc/config/avr/avr.c
|
||||
@@ -10114,10 +10114,9 @@ avr_output_bss_section_asm_op (const void *data)
|
||||
/* Unnamed section callback for progmem*.data sections. */
|
||||
|
||||
static void
|
||||
-avr_output_progmem_section_asm_op (const void *data)
|
||||
+avr_output_progmem_section_asm_op (const char *data)
|
||||
{
|
||||
- fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
|
||||
- (const char*) data);
|
||||
+ fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n", data);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
|
||||
index c5ba7927ce1..8ad5b26c980 100644
|
||||
--- a/gcc/config/darwin.c
|
||||
+++ b/gcc/config/darwin.c
|
||||
@@ -134,7 +134,7 @@ int emit_aligned_common = false;
|
||||
DIRECTIVE is as for output_section_asm_op. */
|
||||
|
||||
static void
|
||||
-output_objc_section_asm_op (const void *directive)
|
||||
+output_objc_section_asm_op (const char *directive)
|
||||
{
|
||||
static bool been_here = false;
|
||||
|
||||
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
|
||||
index f22d25a4066..2b10ef34061 100644
|
||||
--- a/gcc/config/pa/pa.c
|
||||
+++ b/gcc/config/pa/pa.c
|
||||
@@ -10009,7 +10009,7 @@ pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
|
||||
to the default text subspace. */
|
||||
|
||||
static void
|
||||
-som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
+som_output_text_section_asm_op (const char *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
gcc_assert (TARGET_SOM);
|
||||
if (TARGET_GAS)
|
||||
@@ -10053,7 +10053,7 @@ som_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
sections. This function is only used with SOM. */
|
||||
|
||||
static void
|
||||
-som_output_comdat_data_section_asm_op (const void *data)
|
||||
+som_output_comdat_data_section_asm_op (const char *data)
|
||||
{
|
||||
in_section = NULL;
|
||||
output_section_asm_op (data);
|
||||
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
|
||||
index 945157b1c1a..34089743759 100644
|
||||
--- a/gcc/config/rs6000/rs6000.c
|
||||
+++ b/gcc/config/rs6000/rs6000.c
|
||||
@@ -20599,7 +20599,7 @@ rs6000_ms_bitfield_layout_p (const_tree record_type)
|
||||
/* A get_unnamed_section callback, used for switching to toc_section. */
|
||||
|
||||
static void
|
||||
-rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
+rs6000_elf_output_toc_section_asm_op (const char *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
|
||||
&& TARGET_MINIMAL_TOC)
|
||||
@@ -21303,35 +21303,39 @@ rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
|
||||
points to the section string variable. */
|
||||
|
||||
static void
|
||||
-rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
|
||||
+rs6000_xcoff_output_readonly_section_asm_op (const char *directive)
|
||||
{
|
||||
fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
|
||||
- *(const char *const *) directive,
|
||||
+ directive
|
||||
+ ? xcoff_private_rodata_section_name
|
||||
+ : xcoff_read_only_section_name,
|
||||
XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
|
||||
}
|
||||
|
||||
/* Likewise for read-write sections. */
|
||||
|
||||
static void
|
||||
-rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
|
||||
+rs6000_xcoff_output_readwrite_section_asm_op (const char *)
|
||||
{
|
||||
fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
|
||||
- *(const char *const *) directive,
|
||||
+ xcoff_private_data_section_name,
|
||||
XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
|
||||
}
|
||||
|
||||
static void
|
||||
-rs6000_xcoff_output_tls_section_asm_op (const void *directive)
|
||||
+rs6000_xcoff_output_tls_section_asm_op (const char *directive)
|
||||
{
|
||||
fprintf (asm_out_file, "\t.csect %s[TL],%s\n",
|
||||
- *(const char *const *) directive,
|
||||
+ directive
|
||||
+ ? xcoff_private_data_section_name
|
||||
+ : xcoff_tls_data_section_name,
|
||||
XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
|
||||
}
|
||||
|
||||
/* A get_unnamed_section callback, used for switching to toc_section. */
|
||||
|
||||
static void
|
||||
-rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
|
||||
+rs6000_xcoff_output_toc_section_asm_op (const char *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
{
|
||||
@@ -21358,26 +21362,26 @@ rs6000_xcoff_asm_init_sections (void)
|
||||
{
|
||||
read_only_data_section
|
||||
= get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
|
||||
- &xcoff_read_only_section_name);
|
||||
+ NULL);
|
||||
|
||||
private_data_section
|
||||
= get_unnamed_section (SECTION_WRITE,
|
||||
rs6000_xcoff_output_readwrite_section_asm_op,
|
||||
- &xcoff_private_data_section_name);
|
||||
+ NULL);
|
||||
|
||||
read_only_private_data_section
|
||||
= get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
|
||||
- &xcoff_private_rodata_section_name);
|
||||
+ "");
|
||||
|
||||
tls_data_section
|
||||
= get_unnamed_section (SECTION_TLS,
|
||||
rs6000_xcoff_output_tls_section_asm_op,
|
||||
- &xcoff_tls_data_section_name);
|
||||
+ NULL);
|
||||
|
||||
tls_private_data_section
|
||||
= get_unnamed_section (SECTION_TLS,
|
||||
rs6000_xcoff_output_tls_section_asm_op,
|
||||
- &xcoff_private_data_section_name);
|
||||
+ "");
|
||||
|
||||
toc_section
|
||||
= get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
|
||||
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
|
||||
index b996ff2c44e..ca2c8404894 100644
|
||||
--- a/gcc/doc/gty.texi
|
||||
+++ b/gcc/doc/gty.texi
|
||||
@@ -205,6 +205,15 @@ If @code{skip} is applied to a field, the type machinery will ignore it.
|
||||
This is somewhat dangerous; the only safe use is in a union when one
|
||||
field really isn't ever used.
|
||||
|
||||
+@findex callback
|
||||
+@item callback
|
||||
+
|
||||
+@code{callback} should be applied to fields with pointer to function type
|
||||
+and causes the field to be ignored similarly to @code{skip}, except when
|
||||
+writing PCH and the field is non-NULL it will remember the field's address
|
||||
+for relocation purposes if the process writing PCH has different load base
|
||||
+from a process reading PCH.
|
||||
+
|
||||
@findex for_user
|
||||
@item for_user
|
||||
|
||||
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
|
||||
index ac9d536963f..36a96e84574 100644
|
||||
--- a/gcc/gengtype-state.c
|
||||
+++ b/gcc/gengtype-state.c
|
||||
@@ -57,6 +57,7 @@ type_lineloc (const_type_p ty)
|
||||
case TYPE_STRING:
|
||||
case TYPE_POINTER:
|
||||
case TYPE_ARRAY:
|
||||
+ case TYPE_CALLBACK:
|
||||
return NULL;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
@@ -171,6 +172,7 @@ private:
|
||||
void write_state_version (const char *version);
|
||||
void write_state_scalar_type (type_p current);
|
||||
void write_state_string_type (type_p current);
|
||||
+ void write_state_callback_type (type_p current);
|
||||
void write_state_undefined_type (type_p current);
|
||||
void write_state_struct_union_type (type_p current, const char *kindstr);
|
||||
void write_state_struct_type (type_p current);
|
||||
@@ -898,6 +900,20 @@ state_writer::write_state_string_type (type_p current)
|
||||
fatal ("Unexpected type in write_state_string_type");
|
||||
}
|
||||
|
||||
+/* Write the callback type. There is only one such thing! */
|
||||
+void
|
||||
+state_writer::write_state_callback_type (type_p current)
|
||||
+{
|
||||
+ if (current == &callback_type)
|
||||
+ {
|
||||
+ write_any_indent (0);
|
||||
+ fprintf (state_file, "callback ");
|
||||
+ write_state_common_type_content (current);
|
||||
+ }
|
||||
+ else
|
||||
+ fatal ("Unexpected type in write_state_callback_type");
|
||||
+}
|
||||
+
|
||||
/* Write an undefined type. */
|
||||
void
|
||||
state_writer::write_state_undefined_type (type_p current)
|
||||
@@ -1143,6 +1159,9 @@ state_writer::write_state_type (type_p current)
|
||||
case TYPE_STRING:
|
||||
write_state_string_type (current);
|
||||
break;
|
||||
+ case TYPE_CALLBACK:
|
||||
+ write_state_callback_type (current);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1477,6 +1496,14 @@ read_state_string_type (type_p *type)
|
||||
read_state_common_type_content (*type);
|
||||
}
|
||||
|
||||
+/* Read the callback_type. */
|
||||
+static void
|
||||
+read_state_callback_type (type_p *type)
|
||||
+{
|
||||
+ *type = &callback_type;
|
||||
+ read_state_common_type_content (*type);
|
||||
+}
|
||||
+
|
||||
|
||||
/* Read a lang_bitmap representing a set of GCC front-end languages. */
|
||||
static void
|
||||
@@ -1834,6 +1861,11 @@ read_state_type (type_p *current)
|
||||
next_state_tokens (1);
|
||||
read_state_string_type (current);
|
||||
}
|
||||
+ else if (state_token_is_name (t0, "callback"))
|
||||
+ {
|
||||
+ next_state_tokens (1);
|
||||
+ read_state_callback_type (current);
|
||||
+ }
|
||||
else if (state_token_is_name (t0, "undefined"))
|
||||
{
|
||||
*current = XCNEW (struct type);
|
||||
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
|
||||
index a77cfd92bfa..b9daaa43689 100644
|
||||
--- a/gcc/gengtype.c
|
||||
+++ b/gcc/gengtype.c
|
||||
@@ -172,6 +172,7 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
int nb_struct = 0, nb_union = 0, nb_array = 0, nb_pointer = 0;
|
||||
int nb_lang_struct = 0;
|
||||
int nb_user_struct = 0, nb_undefined = 0;
|
||||
+ int nb_callback = 0;
|
||||
type_p p = NULL;
|
||||
for (p = t; p; p = p->next)
|
||||
{
|
||||
@@ -202,6 +203,9 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
case TYPE_ARRAY:
|
||||
nb_array++;
|
||||
break;
|
||||
+ case TYPE_CALLBACK:
|
||||
+ nb_callback++;
|
||||
+ break;
|
||||
case TYPE_LANG_STRUCT:
|
||||
nb_lang_struct++;
|
||||
break;
|
||||
@@ -217,6 +221,8 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
|
||||
fprintf (stderr, "@@%%@@ %d structs, %d unions\n", nb_struct, nb_union);
|
||||
if (nb_pointer > 0 || nb_array > 0)
|
||||
fprintf (stderr, "@@%%@@ %d pointers, %d arrays\n", nb_pointer, nb_array);
|
||||
+ if (nb_callback > 0)
|
||||
+ fprintf (stderr, "@@%%@@ %d callbacks\n", nb_callback);
|
||||
if (nb_lang_struct > 0)
|
||||
fprintf (stderr, "@@%%@@ %d lang_structs\n", nb_lang_struct);
|
||||
if (nb_user_struct > 0)
|
||||
@@ -495,6 +501,10 @@ struct type scalar_char = {
|
||||
TYPE_SCALAR, 0, 0, 0, GC_USED, {0}
|
||||
};
|
||||
|
||||
+struct type callback_type = {
|
||||
+ TYPE_CALLBACK, 0, 0, 0, GC_USED, {0}
|
||||
+};
|
||||
+
|
||||
/* Lists of various things. */
|
||||
|
||||
pair_p typedefs = NULL;
|
||||
@@ -1464,7 +1474,7 @@ static void set_gc_used (pair_p);
|
||||
|
||||
static void
|
||||
process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
|
||||
- int *length, int *skip, type_p *nested_ptr)
|
||||
+ int *length, int *skip, int *callback, type_p *nested_ptr)
|
||||
{
|
||||
options_p o;
|
||||
for (o = opt; o; o = o->next)
|
||||
@@ -1478,6 +1488,8 @@ process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
|
||||
*length = 1;
|
||||
else if (strcmp (o->name, "skip") == 0)
|
||||
*skip = 1;
|
||||
+ else if (strcmp (o->name, "callback") == 0)
|
||||
+ *callback = 1;
|
||||
else if (strcmp (o->name, "nested_ptr") == 0
|
||||
&& o->kind == OPTION_NESTED)
|
||||
*nested_ptr = ((const struct nested_ptr_data *) o->info.nested)->type;
|
||||
@@ -1526,7 +1538,7 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
type_p dummy2;
|
||||
bool allow_undefined_field_types = (t->kind == TYPE_USER_STRUCT);
|
||||
|
||||
- process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
|
||||
+ process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy, &dummy,
|
||||
&dummy2);
|
||||
|
||||
if (t->u.s.base_class)
|
||||
@@ -1542,9 +1554,10 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
int maybe_undef = 0;
|
||||
int length = 0;
|
||||
int skip = 0;
|
||||
+ int callback = 0;
|
||||
type_p nested_ptr = NULL;
|
||||
process_gc_options (f->opt, level, &maybe_undef, &length, &skip,
|
||||
- &nested_ptr);
|
||||
+ &callback, &nested_ptr);
|
||||
|
||||
if (nested_ptr && f->type->kind == TYPE_POINTER)
|
||||
set_gc_used_type (nested_ptr, GC_POINTED_TO);
|
||||
@@ -1554,6 +1567,8 @@ set_gc_used_type (type_p t, enum gc_used_enum level,
|
||||
set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
|
||||
else if (skip)
|
||||
; /* target type is not used through this field */
|
||||
+ else if (callback)
|
||||
+ f->type = &callback_type;
|
||||
else
|
||||
set_gc_used_type (f->type, GC_USED, allow_undefined_field_types);
|
||||
}
|
||||
@@ -2519,6 +2534,7 @@ output_mangled_typename (outf_p of, const_type_p t)
|
||||
{
|
||||
case TYPE_NONE:
|
||||
case TYPE_UNDEFINED:
|
||||
+ case TYPE_CALLBACK:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
case TYPE_POINTER:
|
||||
@@ -2719,6 +2735,8 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
;
|
||||
else if (strcmp (oo->name, "for_user") == 0)
|
||||
;
|
||||
+ else if (strcmp (oo->name, "callback") == 0)
|
||||
+ ;
|
||||
else
|
||||
error_at_line (d->line, "unknown option `%s'\n", oo->name);
|
||||
|
||||
@@ -2744,6 +2762,7 @@ walk_type (type_p t, struct walk_type_data *d)
|
||||
{
|
||||
case TYPE_SCALAR:
|
||||
case TYPE_STRING:
|
||||
+ case TYPE_CALLBACK:
|
||||
d->process_field (t, d);
|
||||
break;
|
||||
|
||||
@@ -3275,6 +3294,7 @@ write_types_process_field (type_p f, const struct walk_type_data *d)
|
||||
break;
|
||||
|
||||
case TYPE_SCALAR:
|
||||
+ case TYPE_CALLBACK:
|
||||
break;
|
||||
|
||||
case TYPE_ARRAY:
|
||||
@@ -3820,6 +3840,7 @@ write_types_local_user_process_field (type_p f, const struct walk_type_data *d)
|
||||
break;
|
||||
|
||||
case TYPE_SCALAR:
|
||||
+ case TYPE_CALLBACK:
|
||||
break;
|
||||
|
||||
case TYPE_ARRAY:
|
||||
@@ -3906,6 +3927,13 @@ write_types_local_process_field (type_p f, const struct walk_type_data *d)
|
||||
case TYPE_SCALAR:
|
||||
break;
|
||||
|
||||
+ case TYPE_CALLBACK:
|
||||
+ oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
|
||||
+ d->prev_val[3]);
|
||||
+ oprintf (d->of, "%*s gt_pch_note_callback (&(%s), this_obj);\n",
|
||||
+ d->indent, "", d->val);
|
||||
+ break;
|
||||
+
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_NONE:
|
||||
case TYPE_UNDEFINED:
|
||||
@@ -4434,6 +4462,7 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
|
||||
case TYPE_UNDEFINED:
|
||||
case TYPE_UNION:
|
||||
case TYPE_LANG_STRUCT:
|
||||
+ case TYPE_CALLBACK:
|
||||
error_at_line (line, "global `%s' is unimplemented type", name);
|
||||
}
|
||||
}
|
||||
@@ -4728,6 +4757,9 @@ dump_typekind (int indent, enum typekind kind)
|
||||
case TYPE_ARRAY:
|
||||
printf ("TYPE_ARRAY");
|
||||
break;
|
||||
+ case TYPE_CALLBACK:
|
||||
+ printf ("TYPE_CALLBACK");
|
||||
+ break;
|
||||
case TYPE_LANG_STRUCT:
|
||||
printf ("TYPE_LANG_STRUCT");
|
||||
break;
|
||||
@@ -4894,6 +4926,7 @@ dump_type (int indent, type_p t)
|
||||
t->u.scalar_is_char ? "true" : "false");
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
+ case TYPE_CALLBACK:
|
||||
break;
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_UNION:
|
||||
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
|
||||
index 8a7a54957ea..8fa7064ca85 100644
|
||||
--- a/gcc/gengtype.h
|
||||
+++ b/gcc/gengtype.h
|
||||
@@ -154,6 +154,9 @@ enum typekind {
|
||||
TYPE_UNION, /* Type for GTY-ed discriminated unions. */
|
||||
TYPE_POINTER, /* Pointer type to GTY-ed type. */
|
||||
TYPE_ARRAY, /* Array of GTY-ed types. */
|
||||
+ TYPE_CALLBACK, /* A function pointer that needs relocation if
|
||||
+ the executable has been loaded at a different
|
||||
+ address. */
|
||||
TYPE_LANG_STRUCT, /* GCC front-end language specific structs.
|
||||
Various languages may have homonymous but
|
||||
different structs. */
|
||||
@@ -331,6 +334,9 @@ extern struct type string_type;
|
||||
extern struct type scalar_nonchar;
|
||||
extern struct type scalar_char;
|
||||
|
||||
+/* The one and only TYPE_CALLBACK. */
|
||||
+extern struct type callback_type;
|
||||
+
|
||||
/* Test if a type is a union, either a plain one or a language
|
||||
specific one. */
|
||||
#define UNION_P(x) \
|
||||
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
|
||||
index b6abed1d9a2..7c998e95473 100644
|
||||
--- a/gcc/ggc-common.c
|
||||
+++ b/gcc/ggc-common.c
|
||||
@@ -256,6 +256,7 @@ saving_hasher::equal (const ptr_data *p1
|
||||
}
|
||||
|
||||
static hash_table<saving_hasher> *saving_htab;
|
||||
+static vec<void *> callback_vec;
|
||||
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
@@ -288,6 +289,23 @@ gt_pch_note_object (void *obj, void *not
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* Register address of a callback pointer. */
|
||||
+void
|
||||
+gt_pch_note_callback (void *obj, void *base)
|
||||
+{
|
||||
+ void *ptr;
|
||||
+ memcpy (&ptr, obj, sizeof (void *));
|
||||
+ if (ptr != NULL)
|
||||
+ {
|
||||
+ struct ptr_data *data
|
||||
+ = (struct ptr_data *)
|
||||
+ saving_htab->find_with_hash (base, POINTER_HASH (base));
|
||||
+ gcc_assert (data);
|
||||
+ callback_vec.safe_push ((char *) data->new_addr
|
||||
+ + ((char *) obj - (char *) base));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
void
|
||||
@@ -582,10 +600,20 @@ gt_pch_save (FILE *f)
|
||||
ggc_pch_finish (state.d, state.f);
|
||||
gt_pch_fixup_stringpool ();
|
||||
|
||||
+ unsigned num_callbacks = callback_vec.length ();
|
||||
+ void (*pch_save) (FILE *) = >_pch_save;
|
||||
+ if (fwrite (&pch_save, sizeof (pch_save), 1, f) != 1
|
||||
+ || fwrite (&num_callbacks, sizeof (num_callbacks), 1, f) != 1
|
||||
+ || (num_callbacks
|
||||
+ && fwrite (callback_vec.address (), sizeof (void *), num_callbacks,
|
||||
+ f) != num_callbacks))
|
||||
+ fatal_error (input_location, "cannot write PCH file: %m");
|
||||
+
|
||||
XDELETE (state.ptrs);
|
||||
XDELETE (this_object);
|
||||
delete saving_htab;
|
||||
saving_htab = NULL;
|
||||
+ callback_vec.release ();
|
||||
}
|
||||
|
||||
/* Read the state of the compiler back in from F. */
|
||||
@@ -639,6 +667,30 @@ gt_pch_restore (FILE *f)
|
||||
ggc_pch_read (f, mmi.preferred_base);
|
||||
|
||||
gt_pch_restore_stringpool ();
|
||||
+
|
||||
+ void (*pch_save) (FILE *);
|
||||
+ unsigned num_callbacks;
|
||||
+ if (fread (&pch_save, sizeof (pch_save), 1, f) != 1
|
||||
+ || fread (&num_callbacks, sizeof (num_callbacks), 1, f) != 1)
|
||||
+ fatal_error (input_location, "cannot read PCH file: %m");
|
||||
+ if (pch_save != >_pch_save)
|
||||
+ {
|
||||
+ uintptr_t bias = (uintptr_t) >_pch_save - (uintptr_t) pch_save;
|
||||
+ void **ptrs = XNEWVEC (void *, num_callbacks);
|
||||
+ unsigned i;
|
||||
+
|
||||
+ if (fread (ptrs, sizeof (void *), num_callbacks, f) != num_callbacks)
|
||||
+ fatal_error (input_location, "cannot read PCH file: %m");
|
||||
+ for (i = 0; i < num_callbacks; ++i)
|
||||
+ {
|
||||
+ memcpy (&pch_save, ptrs[i], sizeof (pch_save));
|
||||
+ pch_save = (void (*) (FILE *)) ((uintptr_t) pch_save + bias);
|
||||
+ memcpy (ptrs[i], &pch_save, sizeof (pch_save));
|
||||
+ }
|
||||
+ XDELETE (ptrs);
|
||||
+ }
|
||||
+ else if (fseek (f, num_callbacks * sizeof (void *), SEEK_CUR) != 0)
|
||||
+ fatal_error (input_location, "cannot read PCH file: %m");
|
||||
}
|
||||
|
||||
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
|
||||
diff --git a/gcc/ggc.h b/gcc/ggc.h
|
||||
index 5e921d957fd..c005f7e0412 100644
|
||||
--- a/gcc/ggc.h
|
||||
+++ b/gcc/ggc.h
|
||||
@@ -46,6 +46,10 @@ typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
|
||||
/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
|
||||
extern int gt_pch_note_object (void *, void *, gt_note_pointers);
|
||||
|
||||
+/* Used by the gt_pch_p_* routines. Register address of a callback
|
||||
+ pointer. */
|
||||
+extern void gt_pch_note_callback (void *, void *);
|
||||
+
|
||||
/* Used by the gt_pch_n_* routines. Register that an object has a reorder
|
||||
function. */
|
||||
extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
|
||||
diff --git a/gcc/output.h b/gcc/output.h
|
||||
index 8f6f15308f4..4a23795bf7e 100644
|
||||
--- a/gcc/output.h
|
||||
+++ b/gcc/output.h
|
||||
@@ -456,7 +456,7 @@ struct GTY(()) named_section {
|
||||
|
||||
/* A callback that writes the assembly code for switching to an unnamed
|
||||
section. The argument provides callback-specific data. */
|
||||
-typedef void (*unnamed_section_callback) (const void *);
|
||||
+typedef void (*unnamed_section_callback) (const char *);
|
||||
|
||||
/* Information about a SECTION_UNNAMED section. */
|
||||
struct GTY(()) unnamed_section {
|
||||
@@ -464,8 +464,8 @@ struct GTY(()) unnamed_section {
|
||||
|
||||
/* The callback used to switch to the section, and the data that
|
||||
should be passed to the callback. */
|
||||
- unnamed_section_callback GTY ((skip)) callback;
|
||||
- const void *GTY ((skip)) data;
|
||||
+ unnamed_section_callback GTY ((callback)) callback;
|
||||
+ const char *data;
|
||||
|
||||
/* The next entry in the chain of unnamed sections. */
|
||||
section *next;
|
||||
@@ -489,7 +489,7 @@ struct GTY(()) noswitch_section {
|
||||
struct section_common common;
|
||||
|
||||
/* The callback used to assemble decls in this section. */
|
||||
- noswitch_section_callback GTY ((skip)) callback;
|
||||
+ noswitch_section_callback GTY ((callback)) callback;
|
||||
};
|
||||
|
||||
/* Information about a section, which may be named or unnamed. */
|
||||
@@ -524,8 +524,8 @@ extern GTY(()) section *bss_noswitch_sec
|
||||
extern GTY(()) section *in_section;
|
||||
extern GTY(()) bool in_cold_section_p;
|
||||
|
||||
-extern section *get_unnamed_section (unsigned int, void (*) (const void *),
|
||||
- const void *);
|
||||
+extern section *get_unnamed_section (unsigned int, void (*) (const char *),
|
||||
+ const char *);
|
||||
extern section *get_section (const char *, unsigned int, tree);
|
||||
extern section *get_named_section (tree, const char *, int);
|
||||
extern section *get_variable_section (tree, bool);
|
||||
@@ -546,7 +546,7 @@ extern section *get_cdtor_priority_secti
|
||||
|
||||
extern bool unlikely_text_section_p (section *);
|
||||
extern void switch_to_section (section *);
|
||||
-extern void output_section_asm_op (const void *);
|
||||
+extern void output_section_asm_op (const char *);
|
||||
|
||||
extern void record_tm_clone_pair (tree, tree);
|
||||
extern void finish_tm_clone_pairs (void);
|
||||
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
|
||||
index 8ab119dc9a2..91ae5237d7e 100644
|
||||
--- a/gcc/tree-core.h
|
||||
+++ b/gcc/tree-core.h
|
||||
@@ -1961,7 +1961,7 @@ struct GTY(()) tree_function_decl {
|
||||
struct GTY(()) tree_translation_unit_decl {
|
||||
struct tree_decl_common common;
|
||||
/* Source language of this translation unit. Used for DWARF output. */
|
||||
- const char * GTY((skip(""))) language;
|
||||
+ const char *language;
|
||||
/* TODO: Non-optimization used to build this translation unit. */
|
||||
/* TODO: Root of a partial DWARF tree for global types and decls. */
|
||||
};
|
||||
diff --git a/gcc/varasm.c b/gcc/varasm.c
|
||||
index 9315e2c6936..aff93ca5de9 100644
|
||||
--- a/gcc/varasm.c
|
||||
+++ b/gcc/varasm.c
|
||||
@@ -250,8 +250,8 @@ object_block_hasher::hash (object_block *old)
|
||||
/* Return a new unnamed section with the given fields. */
|
||||
|
||||
section *
|
||||
-get_unnamed_section (unsigned int flags, void (*callback) (const void *),
|
||||
- const void *data)
|
||||
+get_unnamed_section (unsigned int flags, void (*callback) (const char *),
|
||||
+ const char *data)
|
||||
{
|
||||
section *sect;
|
||||
|
||||
@@ -7778,9 +7778,9 @@ file_end_indicate_split_stack (void)
|
||||
a get_unnamed_section callback. */
|
||||
|
||||
void
|
||||
-output_section_asm_op (const void *directive)
|
||||
+output_section_asm_op (const char *directive)
|
||||
{
|
||||
- fprintf (asm_out_file, "%s\n", (const char *) directive);
|
||||
+ fprintf (asm_out_file, "%s\n", directive);
|
||||
}
|
||||
|
||||
/* Emit assembly code to switch to section NEW_SECTION. Do nothing if
|
||||
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
|
||||
index 8b5e2f82982..bc40e333579 100644
|
||||
--- a/libcpp/include/line-map.h
|
||||
+++ b/libcpp/include/line-map.h
|
||||
@@ -758,11 +758,11 @@ struct GTY(()) line_maps {
|
||||
|
||||
/* If non-null, the allocator to use when resizing 'maps'. If null,
|
||||
xrealloc is used. */
|
||||
- line_map_realloc reallocator;
|
||||
+ line_map_realloc GTY((callback)) reallocator;
|
||||
|
||||
/* The allocators' function used to know the actual size it
|
||||
allocated, for a certain allocation size requested. */
|
||||
- line_map_round_alloc_size_func round_alloc_size;
|
||||
+ line_map_round_alloc_size_func GTY((callback)) round_alloc_size;
|
||||
|
||||
struct location_adhoc_data_map location_adhoc_data_map;
|
||||
|
||||
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
|
||||
index 6ba038881d6..1c2f7d564e7 100644
|
||||
--- a/gcc/config/avr/avr.c
|
||||
+++ b/gcc/config/avr/avr.c
|
||||
@@ -10089,7 +10089,7 @@ avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
|
||||
to track need of __do_copy_data. */
|
||||
|
||||
static void
|
||||
-avr_output_data_section_asm_op (const void *data)
|
||||
+avr_output_data_section_asm_op (const char *data)
|
||||
{
|
||||
avr_need_copy_data_p = true;
|
||||
|
||||
@@ -10102,7 +10102,7 @@ avr_output_data_section_asm_op (const void *data)
|
||||
to track need of __do_clear_bss. */
|
||||
|
||||
static void
|
||||
-avr_output_bss_section_asm_op (const void *data)
|
||||
+avr_output_bss_section_asm_op (const char *data)
|
||||
{
|
||||
avr_need_clear_bss_p = true;
|
||||
|
@ -1,137 +0,0 @@
|
||||
commit ebfe8b28d40746ff33724bd5b9ade2552e619213
|
||||
Author: Jason Merrill <jason@redhat.com>
|
||||
Date: Thu May 27 23:54:52 2021 -0400
|
||||
|
||||
c++: 'this' adjustment for devirtualized call
|
||||
|
||||
My patch for 95719 made us do a better job of finding the actual virtual
|
||||
function we want to call, but didn't update the 'this' pointer adjustment to
|
||||
match.
|
||||
|
||||
This backport also incorporates a bit of the r11-1638 reorganization.
|
||||
|
||||
PR c++/100797
|
||||
PR c++/95719
|
||||
|
||||
gcc/cp/ChangeLog:
|
||||
|
||||
* call.c (build_over_call): Adjust base_binfo in
|
||||
resolves_to_fixed_type_p case.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* g++.dg/inherit/virtual15.C: New test.
|
||||
* g++.dg/inherit/virtual15a.C: New test.
|
||||
|
||||
--- gcc/cp/call.c
|
||||
+++ gcc/cp/call.c
|
||||
@@ -8309,19 +8309,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
|| CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
|
||||
flags |= LOOKUP_NONVIRTUAL;
|
||||
|
||||
- /* If we know the dynamic type of the object, look up the final overrider
|
||||
- in the BINFO. */
|
||||
- if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
|
||||
- && resolves_to_fixed_type_p (arg))
|
||||
- {
|
||||
- tree binfo = cand->conversion_path;
|
||||
- if (BINFO_TYPE (binfo) != DECL_CONTEXT (fn))
|
||||
- binfo = lookup_base (binfo, DECL_CONTEXT (fn), ba_unique,
|
||||
- NULL, complain);
|
||||
- fn = lookup_vfn_in_binfo (DECL_VINDEX (fn), binfo);
|
||||
- flags |= LOOKUP_NONVIRTUAL;
|
||||
- }
|
||||
-
|
||||
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
|
||||
X is called for an object that is not of type X, or of a type
|
||||
derived from X, the behavior is undefined.
|
||||
@@ -8331,10 +8318,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
gcc_assert (TYPE_PTR_P (parmtype));
|
||||
/* Convert to the base in which the function was declared. */
|
||||
gcc_assert (cand->conversion_path != NULL_TREE);
|
||||
- converted_arg = build_base_path (PLUS_EXPR,
|
||||
- arg,
|
||||
- cand->conversion_path,
|
||||
- 1, complain);
|
||||
/* Check that the base class is accessible. */
|
||||
if (!accessible_base_p (TREE_TYPE (argtype),
|
||||
BINFO_TYPE (cand->conversion_path), true))
|
||||
@@ -8349,10 +8332,33 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
/* If fn was found by a using declaration, the conversion path
|
||||
will be to the derived class, not the base declaring fn. We
|
||||
must convert from derived to base. */
|
||||
- base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
|
||||
+ base_binfo = lookup_base (cand->conversion_path,
|
||||
TREE_TYPE (parmtype), ba_unique,
|
||||
NULL, complain);
|
||||
- converted_arg = build_base_path (PLUS_EXPR, converted_arg,
|
||||
+
|
||||
+ /* If we know the dynamic type of the object, look up the final overrider
|
||||
+ in the BINFO. */
|
||||
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
|
||||
+ && resolves_to_fixed_type_p (arg))
|
||||
+ {
|
||||
+ tree ov = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
|
||||
+
|
||||
+ /* And unwind base_binfo to match. If we don't find the type we're
|
||||
+ looking for in BINFO_INHERITANCE_CHAIN, we're looking at diamond
|
||||
+ inheritance; for now do a normal virtual call in that case. */
|
||||
+ tree octx = DECL_CONTEXT (ov);
|
||||
+ tree obinfo = base_binfo;
|
||||
+ while (obinfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (obinfo), octx))
|
||||
+ obinfo = BINFO_INHERITANCE_CHAIN (obinfo);
|
||||
+ if (obinfo)
|
||||
+ {
|
||||
+ fn = ov;
|
||||
+ base_binfo = obinfo;
|
||||
+ flags |= LOOKUP_NONVIRTUAL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ converted_arg = build_base_path (PLUS_EXPR, arg,
|
||||
base_binfo, 1, complain);
|
||||
|
||||
argarray[j++] = converted_arg;
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/inherit/virtual15.C
|
||||
@@ -0,0 +1,18 @@
|
||||
+// PR c++/100797
|
||||
+// { dg-do run }
|
||||
+
|
||||
+bool ok = false;
|
||||
+struct S1 { virtual ~S1() {} };
|
||||
+struct S2 { virtual void f1() = 0; };
|
||||
+struct S3: S1, S2 {
|
||||
+ void f1() { f2(); }
|
||||
+ virtual void f2() = 0;
|
||||
+};
|
||||
+struct S4: S3 {
|
||||
+ void f2() { ok = true; }
|
||||
+ using S2::f1;
|
||||
+};
|
||||
+int main() {
|
||||
+ S4().f1();
|
||||
+ if (!ok) __builtin_abort ();
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/inherit/virtual15a.C
|
||||
@@ -0,0 +1,19 @@
|
||||
+// PR c++/100797 plus diamond inheritance
|
||||
+// { dg-do run }
|
||||
+
|
||||
+bool ok = false;
|
||||
+struct S1 { virtual ~S1() {} };
|
||||
+struct S2 { virtual void f1() = 0; };
|
||||
+struct S3: S1, virtual S2 {
|
||||
+ void f1() { f2(); }
|
||||
+ virtual void f2() = 0;
|
||||
+};
|
||||
+struct SX: virtual S2 { };
|
||||
+struct S4: SX, S3 {
|
||||
+ void f2() { ok = true; }
|
||||
+ using S2::f1;
|
||||
+};
|
||||
+int main() {
|
||||
+ S4().f1();
|
||||
+ if (!ok) __builtin_abort ();
|
||||
+}
|
@ -1,98 +0,0 @@
|
||||
From b005000525ab0a5116d21217c41fb1da5bd03796 Mon Sep 17 00:00:00 2001
|
||||
From: Jonathan Wakely <jwakely@redhat.com>
|
||||
Date: Fri, 6 May 2022 21:19:17 +0100
|
||||
Subject: [PATCH] libstdc++: Fix deserialization for std::normal_distribution
|
||||
[PR105502]
|
||||
|
||||
This fixes a regression in std::normal_distribution deserialization that
|
||||
caused the object to be left unchanged if the __state_avail value read
|
||||
from the stream was false.
|
||||
|
||||
libstdc++-v3/ChangeLog:
|
||||
|
||||
PR libstdc++/105502
|
||||
* include/bits/random.tcc
|
||||
(operator>>(basic_istream<C,T>&, normal_distribution<R>&)):
|
||||
Update state when __state_avail is false.
|
||||
* testsuite/26_numerics/random/normal_distribution/operators/serialize.cc:
|
||||
Check that deserialized object equals serialized one.
|
||||
|
||||
(cherry picked from commit 909ef4e2727ddc50a32d6ad379a1f1ccc1043c6a)
|
||||
---
|
||||
libstdc++-v3/include/bits/random.tcc | 2 +-
|
||||
.../operators/serialize.cc | 36 ++++++++++++++++++-
|
||||
2 files changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
|
||||
index 0a299baedc5..0f758671f69 100644
|
||||
--- a/libstdc++-v3/include/bits/random.tcc
|
||||
+++ b/libstdc++-v3/include/bits/random.tcc
|
||||
@@ -1941,7 +1941,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
bool __saved_avail;
|
||||
if (__is >> __mean >> __stddev >> __saved_avail)
|
||||
{
|
||||
- if (__saved_avail && (__is >> __x._M_saved))
|
||||
+ if (!__saved_avail || (__is >> __x._M_saved))
|
||||
{
|
||||
__x._M_saved_available = __saved_avail;
|
||||
__x.param(typename normal_distribution<_RealType>::
|
||||
diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
index a65d4004161..8cc70886bc7 100644
|
||||
--- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
+++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/operators/serialize.cc
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
+#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
@@ -37,10 +38,43 @@ test01()
|
||||
str << u;
|
||||
|
||||
str >> v;
|
||||
+ VERIFY( u == v );
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+test_pr105502()
|
||||
+{
|
||||
+ // PR libstdc++/105502 std::normal_distribution deserialization issue
|
||||
+ std::stringstream str;
|
||||
+ std::normal_distribution<> d{1, 2}, d2;
|
||||
+ std::minstd_rand0 g;
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
+
|
||||
+ (void) d(g); // sets d._M_saved_available = true
|
||||
+ str.str("");
|
||||
+ str.clear();
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
+
|
||||
+ (void) d(g); // sets d._M_saved_available = false
|
||||
+ str.str("");
|
||||
+ str.clear();
|
||||
+ str << d;
|
||||
+ VERIFY( str );
|
||||
+ str >> d2;
|
||||
+ VERIFY( str );
|
||||
+ VERIFY( d == d2 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
- return 0;
|
||||
+ test_pr105502();
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,61 +0,0 @@
|
||||
commit e150cbf591759af10f3d57acbe0eb381aafa00de
|
||||
Author: Richard Biener <rguenther@suse.de>
|
||||
Date: Thu Aug 17 13:10:14 2023 +0200
|
||||
|
||||
tree-optimization/111039 - abnormals and bit test merging
|
||||
|
||||
The following guards the bit test merging code in if-combine against
|
||||
the appearance of SSA names used in abnormal PHIs.
|
||||
|
||||
PR tree-optimization/111039
|
||||
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Check for
|
||||
SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
|
||||
|
||||
* gcc.dg/pr111039.c: New testcase.
|
||||
|
||||
(cherry picked from commit 482551a79a3d3f107f6239679ee74655cfe8707e)
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/pr111039.c b/gcc/testsuite/gcc.dg/pr111039.c
|
||||
new file mode 100644
|
||||
index 00000000000..bec9983b35f
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/pr111039.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O" } */
|
||||
+
|
||||
+int _setjmp ();
|
||||
+void abcd ();
|
||||
+void abcde ();
|
||||
+void compiler_corruption_function(int flags)
|
||||
+{
|
||||
+ int nowait = flags & 1048576, isexpand = flags & 8388608;
|
||||
+ abcd();
|
||||
+ _setjmp(flags);
|
||||
+ if (nowait && isexpand)
|
||||
+ flags &= 0;
|
||||
+ abcde();
|
||||
+}
|
||||
--- a/gcc/tree-ssa-ifcombine.c
|
||||
+++ b/gcc/tree-ssa-ifcombine.c
|
||||
@@ -407,6 +407,9 @@ ifcombine_ifandif (basic_block inner_con
|
||||
{
|
||||
tree t, t2;
|
||||
|
||||
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1))
|
||||
+ return false;
|
||||
+
|
||||
/* Do it. */
|
||||
gsi = gsi_for_stmt (inner_cond);
|
||||
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
|
||||
@@ -457,6 +460,10 @@ ifcombine_ifandif (basic_block inner_con
|
||||
gimple_stmt_iterator gsi;
|
||||
tree t;
|
||||
|
||||
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name1)
|
||||
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name2))
|
||||
+ return false;
|
||||
+
|
||||
/* Find the common name which is bit-tested. */
|
||||
if (name1 == name2)
|
||||
;
|
@ -1,68 +0,0 @@
|
||||
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. */
|
@ -1,71 +0,0 @@
|
||||
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;
|
||||
+ }
|
||||
+}
|
@ -1,254 +0,0 @@
|
||||
commit 6001db79c477b03eacc7e7049560921fb54b7845
|
||||
Author: Richard Sandiford <richard.sandiford@arm.com>
|
||||
Date: Mon Sep 7 20:15:36 2020 +0100
|
||||
|
||||
lra: Avoid cycling on certain subreg reloads [PR96796]
|
||||
|
||||
This PR is about LRA cycling for a reload of the form:
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Changing pseudo 196 in operand 1 of insn 103 on equiv [r105:DI*0x8+r140:DI]
|
||||
Creating newreg=287, assigning class ALL_REGS to slow/invalid mem r287
|
||||
Creating newreg=288, assigning class ALL_REGS to slow/invalid mem r288
|
||||
103: r203:SI=r288:SI<<0x1+r196:DI#0
|
||||
REG_DEAD r196:DI
|
||||
Inserting slow/invalid mem reload before:
|
||||
316: r287:DI=[r105:DI*0x8+r140:DI]
|
||||
317: r288:SI=r287:DI#0
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
The problem is with r287. We rightly give it a broad starting class of
|
||||
POINTER_AND_FP_REGS (reduced from ALL_REGS by preferred_reload_class).
|
||||
However, we never make forward progress towards narrowing it down to
|
||||
a specific choice of class (POINTER_REGS or FP_REGS).
|
||||
|
||||
I think in practice we rely on two things to narrow a reload pseudo's
|
||||
class down to a specific choice:
|
||||
|
||||
(1) a restricted class is specified when the pseudo is created
|
||||
|
||||
This happens for input address reloads, where the class is taken
|
||||
from the target's chosen base register class. It also happens
|
||||
for simple REG reloads, where the class is taken from the chosen
|
||||
alternative's constraints.
|
||||
|
||||
(2) uses of the reload pseudo as a direct input operand
|
||||
|
||||
In this case get_reload_reg tries to reuse the existing register
|
||||
and narrow its class, instead of creating a new reload pseudo.
|
||||
|
||||
However, neither occurs here. As described above, r287 rightly
|
||||
starts out with a wide choice of class, ultimately derived from
|
||||
ALL_REGS, so we don't get (1). And as the comments in the PR
|
||||
explain, r287 is never used as an input reload, only the subreg is,
|
||||
so we don't get (2):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Choosing alt 13 in insn 317: (0) r (1) w {*movsi_aarch64}
|
||||
Creating newreg=291, assigning class FP_REGS to r291
|
||||
317: r288:SI=r291:SI
|
||||
Inserting insn reload before:
|
||||
320: r291:SI=r287:DI#0
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
IMO, in this case we should rely on the reload of r316 to narrow
|
||||
down the class of r278. Currently we do:
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Choosing alt 7 in insn 316: (0) r (1) m {*movdi_aarch64}
|
||||
Creating newreg=289 from oldreg=287, assigning class GENERAL_REGS to r289
|
||||
316: r289:DI=[r105:DI*0x8+r140:DI]
|
||||
Inserting insn reload after:
|
||||
318: r287:DI=r289:DI
|
||||
---------------------------------------------------
|
||||
|
||||
i.e. we create a new pseudo register r289 and give *that* pseudo
|
||||
GENERAL_REGS instead. This is because get_reload_reg only narrows
|
||||
down the existing class for OP_IN and OP_INOUT, not OP_OUT.
|
||||
|
||||
But if we have a reload pseudo in a reload instruction and have chosen
|
||||
a specific class for the reload pseudo, I think we should simply install
|
||||
it for OP_OUT reloads too, if the class is a subset of the existing class.
|
||||
We will need to pick such a register whatever happens (for r289 in the
|
||||
example above). And as explained in the PR, doing this actually avoids
|
||||
an unnecessary move via the FP registers too.
|
||||
|
||||
The patch is quite aggressive in that it does this for all reload
|
||||
pseudos in all reload instructions. I wondered about reusing the
|
||||
condition for a reload move in in_class_p:
|
||||
|
||||
INSN_UID (curr_insn) >= new_insn_uid_start
|
||||
&& curr_insn_set != NULL
|
||||
&& ((OBJECT_P (SET_SRC (curr_insn_set))
|
||||
&& ! CONSTANT_P (SET_SRC (curr_insn_set)))
|
||||
|| (GET_CODE (SET_SRC (curr_insn_set)) == SUBREG
|
||||
&& OBJECT_P (SUBREG_REG (SET_SRC (curr_insn_set)))
|
||||
&& ! CONSTANT_P (SUBREG_REG (SET_SRC (curr_insn_set)))))))
|
||||
|
||||
but I can't really justify that on first principles. I think we
|
||||
should apply the rule consistently until we have a specific reason
|
||||
for doing otherwise.
|
||||
|
||||
gcc/
|
||||
PR rtl-optimization/96796
|
||||
* lra-constraints.c (in_class_p): Add a default-false
|
||||
allow_all_reload_class_changes_p parameter. Do not treat
|
||||
reload moves specially when the parameter is true.
|
||||
(get_reload_reg): Try to narrow the class of an existing OP_OUT
|
||||
reload if we're reloading a reload pseudo in a reload instruction.
|
||||
|
||||
gcc/testsuite/
|
||||
PR rtl-optimization/96796
|
||||
* gcc.c-torture/compile/pr96796.c: New test.
|
||||
|
||||
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
|
||||
index 580da9c3ed6..161b721efb1 100644
|
||||
--- a/gcc/lra-constraints.c
|
||||
+++ b/gcc/lra-constraints.c
|
||||
@@ -236,12 +236,17 @@ get_reg_class (int regno)
|
||||
CL. Use elimination first if REG is a hard register. If REG is a
|
||||
reload pseudo created by this constraints pass, assume that it will
|
||||
be allocated a hard register from its allocno class, but allow that
|
||||
- class to be narrowed to CL if it is currently a superset of CL.
|
||||
+ class to be narrowed to CL if it is currently a superset of CL and
|
||||
+ if either:
|
||||
+
|
||||
+ - ALLOW_ALL_RELOAD_CLASS_CHANGES_P is true or
|
||||
+ - the instruction we're processing is not a reload move.
|
||||
|
||||
If NEW_CLASS is nonnull, set *NEW_CLASS to the new allocno class of
|
||||
REGNO (reg), or NO_REGS if no change in its class was needed. */
|
||||
static bool
|
||||
-in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
|
||||
+in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
|
||||
+ bool allow_all_reload_class_changes_p = false)
|
||||
{
|
||||
enum reg_class rclass, common_class;
|
||||
machine_mode reg_mode;
|
||||
@@ -266,7 +271,8 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
|
||||
typically moves that have many alternatives, and restricting
|
||||
reload pseudos for one alternative may lead to situations
|
||||
where other reload pseudos are no longer allocatable. */
|
||||
- || (INSN_UID (curr_insn) >= new_insn_uid_start
|
||||
+ || (!allow_all_reload_class_changes_p
|
||||
+ && INSN_UID (curr_insn) >= new_insn_uid_start
|
||||
&& curr_insn_set != NULL
|
||||
&& ((OBJECT_P (SET_SRC (curr_insn_set))
|
||||
&& ! CONSTANT_P (SET_SRC (curr_insn_set)))
|
||||
@@ -551,13 +557,12 @@ init_curr_insn_input_reloads (void)
|
||||
curr_insn_input_reloads_num = 0;
|
||||
}
|
||||
|
||||
-/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
|
||||
- created input reload pseudo (only if TYPE is not OP_OUT). Don't
|
||||
- reuse pseudo if IN_SUBREG_P is true and the reused pseudo should be
|
||||
- wrapped up in SUBREG. The result pseudo is returned through
|
||||
- RESULT_REG. Return TRUE if we created a new pseudo, FALSE if we
|
||||
- reused the already created input reload pseudo. Use TITLE to
|
||||
- describe new registers for debug purposes. */
|
||||
+/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse an existing
|
||||
+ reload pseudo. Don't reuse an existing reload pseudo if IN_SUBREG_P
|
||||
+ is true and the reused pseudo should be wrapped up in a SUBREG.
|
||||
+ The result pseudo is returned through RESULT_REG. Return TRUE if we
|
||||
+ created a new pseudo, FALSE if we reused an existing reload pseudo.
|
||||
+ Use TITLE to describe new registers for debug purposes. */
|
||||
static bool
|
||||
get_reload_reg (enum op_type type, machine_mode mode, rtx original,
|
||||
enum reg_class rclass, bool in_subreg_p,
|
||||
@@ -616,6 +621,35 @@ get_reload_reg (enum op_type type, machine_mode mode, rtx original,
|
||||
|
||||
if (type == OP_OUT)
|
||||
{
|
||||
+ /* Output reload registers tend to start out with a conservative
|
||||
+ choice of register class. Usually this is ALL_REGS, although
|
||||
+ a target might narrow it (for performance reasons) through
|
||||
+ targetm.preferred_reload_class. It's therefore quite common
|
||||
+ for a reload instruction to require a more restrictive class
|
||||
+ than the class that was originally assigned to the reload register.
|
||||
+
|
||||
+ In these situations, it's more efficient to refine the choice
|
||||
+ of register class rather than create a second reload register.
|
||||
+ This also helps to avoid cycling for registers that are only
|
||||
+ used by reload instructions. */
|
||||
+ if (REG_P (original)
|
||||
+ && (int) REGNO (original) >= new_regno_start
|
||||
+ && INSN_UID (curr_insn) >= new_insn_uid_start
|
||||
+ && in_class_p (original, rclass, &new_class, true))
|
||||
+ {
|
||||
+ unsigned int regno = REGNO (original);
|
||||
+ if (lra_dump_file != NULL)
|
||||
+ {
|
||||
+ fprintf (lra_dump_file, " Reuse r%d for output ", regno);
|
||||
+ dump_value_slim (lra_dump_file, original, 1);
|
||||
+ }
|
||||
+ if (new_class != lra_get_allocno_class (regno))
|
||||
+ lra_change_class (regno, new_class, ", change to", false);
|
||||
+ if (lra_dump_file != NULL)
|
||||
+ fprintf (lra_dump_file, "\n");
|
||||
+ *result_reg = original;
|
||||
+ return false;
|
||||
+ }
|
||||
*result_reg
|
||||
= lra_create_new_reg_with_unique_value (mode, original, rclass, title);
|
||||
return true;
|
||||
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr96796.c b/gcc/testsuite/gcc.c-torture/compile/pr96796.c
|
||||
new file mode 100644
|
||||
index 00000000000..8808e62fe77
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.c-torture/compile/pr96796.c
|
||||
@@ -0,0 +1,55 @@
|
||||
+/* { dg-additional-options "-fcommon" } */
|
||||
+
|
||||
+struct S0 {
|
||||
+ signed f0 : 8;
|
||||
+ unsigned f1;
|
||||
+ unsigned f4;
|
||||
+};
|
||||
+struct S1 {
|
||||
+ long f3;
|
||||
+ char f4;
|
||||
+} g_3_4;
|
||||
+
|
||||
+int g_5, func_1_l_32, func_50___trans_tmp_31;
|
||||
+static struct S0 g_144, g_834, g_1255, g_1261;
|
||||
+
|
||||
+int g_273[120] = {};
|
||||
+int *g_555;
|
||||
+char **g_979;
|
||||
+static int g_1092_0;
|
||||
+static int g_1193;
|
||||
+int safe_mul_func_int16_t_s_s(int si1, int si2) { return si1 * si2; }
|
||||
+static struct S0 *func_50();
|
||||
+int func_1() { func_50(g_3_4, g_5, func_1_l_32, 8, 3); }
|
||||
+void safe_div_func_int64_t_s_s(int *);
|
||||
+void safe_mod_func_uint32_t_u_u(struct S0);
|
||||
+struct S0 *func_50(int p_51, struct S0 p_52, struct S1 p_53, int p_54,
|
||||
+ int p_55) {
|
||||
+ int __trans_tmp_30;
|
||||
+ char __trans_tmp_22;
|
||||
+ short __trans_tmp_19;
|
||||
+ long l_985_1;
|
||||
+ long l_1191[8];
|
||||
+ safe_div_func_int64_t_s_s(g_273);
|
||||
+ __builtin_printf((char*)g_1261.f4);
|
||||
+ safe_mod_func_uint32_t_u_u(g_834);
|
||||
+ g_144.f0 += 1;
|
||||
+ for (;;) {
|
||||
+ struct S1 l_1350 = {&l_1350};
|
||||
+ for (; p_53.f3; p_53.f3 -= 1)
|
||||
+ for (; g_1193 <= 2; g_1193 += 1) {
|
||||
+ __trans_tmp_19 = safe_mul_func_int16_t_s_s(l_1191[l_985_1 + p_53.f3],
|
||||
+ p_55 % (**g_979 = 10));
|
||||
+ __trans_tmp_22 = g_1255.f1 * p_53.f4;
|
||||
+ __trans_tmp_30 = __trans_tmp_19 + __trans_tmp_22;
|
||||
+ if (__trans_tmp_30)
|
||||
+ g_1261.f0 = p_51;
|
||||
+ else {
|
||||
+ g_1255.f0 = p_53.f3;
|
||||
+ int *l_1422 = g_834.f0 = g_144.f4 != (*l_1422)++ > 0 < 0 ^ 51;
|
||||
+ g_555 = ~0;
|
||||
+ g_1092_0 |= func_50___trans_tmp_31;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
@ -1,77 +0,0 @@
|
||||
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,
|
@ -1,47 +0,0 @@
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
File diff suppressed because it is too large
Load Diff
@ -1,445 +0,0 @@
|
||||
--- gcc/config/aarch64/aarch64.c
|
||||
+++ gcc/config/aarch64/aarch64.c
|
||||
@@ -3799,7 +3799,14 @@ aarch64_output_probe_stack_range (rtx reg1, rtx reg2)
|
||||
output_asm_insn ("sub\t%0, %0, %1", xops);
|
||||
|
||||
/* Probe at TEST_ADDR. */
|
||||
- output_asm_insn ("str\txzr, [%0]", xops);
|
||||
+ if (flag_stack_clash_protection)
|
||||
+ {
|
||||
+ gcc_assert (xops[0] == stack_pointer_rtx);
|
||||
+ xops[1] = GEN_INT (PROBE_INTERVAL - 8);
|
||||
+ output_asm_insn ("str\txzr, [%0, %1]", xops);
|
||||
+ }
|
||||
+ else
|
||||
+ output_asm_insn ("str\txzr, [%0]", xops);
|
||||
|
||||
/* Test if TEST_ADDR == LAST_ADDR. */
|
||||
xops[1] = reg2;
|
||||
@@ -4589,6 +4596,133 @@ aarch64_set_handled_components (sbitmap components)
|
||||
cfun->machine->reg_is_wrapped_separately[regno] = true;
|
||||
}
|
||||
|
||||
+/* Allocate POLY_SIZE bytes of stack space using TEMP1 and TEMP2 as scratch
|
||||
+ registers. */
|
||||
+
|
||||
+static void
|
||||
+aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2,
|
||||
+ poly_int64 poly_size)
|
||||
+{
|
||||
+ HOST_WIDE_INT size;
|
||||
+ if (!poly_size.is_constant (&size))
|
||||
+ {
|
||||
+ sorry ("stack probes for SVE frames");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ HOST_WIDE_INT probe_interval
|
||||
+ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL);
|
||||
+ HOST_WIDE_INT guard_size
|
||||
+ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE);
|
||||
+ HOST_WIDE_INT guard_used_by_caller = 1024;
|
||||
+
|
||||
+ /* SIZE should be large enough to require probing here. ie, it
|
||||
+ must be larger than GUARD_SIZE - GUARD_USED_BY_CALLER.
|
||||
+
|
||||
+ We can allocate GUARD_SIZE - GUARD_USED_BY_CALLER as a single chunk
|
||||
+ without any probing. */
|
||||
+ gcc_assert (size >= guard_size - guard_used_by_caller);
|
||||
+ aarch64_sub_sp (temp1, temp2, guard_size - guard_used_by_caller, true);
|
||||
+ HOST_WIDE_INT orig_size = size;
|
||||
+ size -= (guard_size - guard_used_by_caller);
|
||||
+
|
||||
+ HOST_WIDE_INT rounded_size = size & -probe_interval;
|
||||
+ HOST_WIDE_INT residual = size - rounded_size;
|
||||
+
|
||||
+ /* We can handle a small number of allocations/probes inline. Otherwise
|
||||
+ punt to a loop. */
|
||||
+ if (rounded_size && rounded_size <= 4 * probe_interval)
|
||||
+ {
|
||||
+ /* We don't use aarch64_sub_sp here because we don't want to
|
||||
+ repeatedly load TEMP1. */
|
||||
+ rtx step = GEN_INT (-probe_interval);
|
||||
+ if (probe_interval > ARITH_FACTOR)
|
||||
+ {
|
||||
+ emit_move_insn (temp1, step);
|
||||
+ step = temp1;
|
||||
+ }
|
||||
+
|
||||
+ for (HOST_WIDE_INT i = 0; i < rounded_size; i += probe_interval)
|
||||
+ {
|
||||
+ rtx_insn *insn = emit_insn (gen_add2_insn (stack_pointer_rtx, step));
|
||||
+ add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
|
||||
+
|
||||
+ if (probe_interval > ARITH_FACTOR)
|
||||
+ {
|
||||
+ RTX_FRAME_RELATED_P (insn) = 1;
|
||||
+ rtx adj = plus_constant (Pmode, stack_pointer_rtx, -probe_interval);
|
||||
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
||||
+ gen_rtx_SET (stack_pointer_rtx, adj));
|
||||
+ }
|
||||
+
|
||||
+ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
|
||||
+ (probe_interval
|
||||
+ - GET_MODE_SIZE (word_mode))));
|
||||
+ emit_insn (gen_blockage ());
|
||||
+ }
|
||||
+ dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size);
|
||||
+ }
|
||||
+ else if (rounded_size)
|
||||
+ {
|
||||
+ /* Compute the ending address. */
|
||||
+ unsigned int scratchreg = REGNO (temp1);
|
||||
+ emit_move_insn (temp1, GEN_INT (-rounded_size));
|
||||
+ rtx_insn *insn
|
||||
+ = emit_insn (gen_add3_insn (temp1, stack_pointer_rtx, temp1));
|
||||
+
|
||||
+ /* For the initial allocation, we don't have a frame pointer
|
||||
+ set up, so we always need CFI notes. If we're doing the
|
||||
+ final allocation, then we may have a frame pointer, in which
|
||||
+ case it is the CFA, otherwise we need CFI notes.
|
||||
+
|
||||
+ We can determine which allocation we are doing by looking at
|
||||
+ the temporary register. IP0 is the initial allocation, IP1
|
||||
+ is the final allocation. */
|
||||
+ if (scratchreg == IP0_REGNUM || !frame_pointer_needed)
|
||||
+ {
|
||||
+ /* We want the CFA independent of the stack pointer for the
|
||||
+ duration of the loop. */
|
||||
+ add_reg_note (insn, REG_CFA_DEF_CFA,
|
||||
+ plus_constant (Pmode, temp1,
|
||||
+ (rounded_size + (orig_size - size))));
|
||||
+ RTX_FRAME_RELATED_P (insn) = 1;
|
||||
+ }
|
||||
+
|
||||
+ /* This allocates and probes the stack.
|
||||
+
|
||||
+ It also probes at a 4k interval regardless of the value of
|
||||
+ PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL. */
|
||||
+ insn = emit_insn (gen_probe_stack_range (stack_pointer_rtx,
|
||||
+ stack_pointer_rtx, temp1));
|
||||
+
|
||||
+ /* Now reset the CFA register if needed. */
|
||||
+ if (scratchreg == IP0_REGNUM || !frame_pointer_needed)
|
||||
+ {
|
||||
+ add_reg_note (insn, REG_CFA_DEF_CFA,
|
||||
+ plus_constant (Pmode, stack_pointer_rtx,
|
||||
+ (rounded_size + (orig_size - size))));
|
||||
+ RTX_FRAME_RELATED_P (insn) = 1;
|
||||
+ }
|
||||
+
|
||||
+ emit_insn (gen_blockage ());
|
||||
+ dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
|
||||
+ }
|
||||
+ else
|
||||
+ dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size);
|
||||
+
|
||||
+ /* Handle any residuals.
|
||||
+ Note that any residual must be probed. */
|
||||
+ if (residual)
|
||||
+ {
|
||||
+ aarch64_sub_sp (temp1, temp2, residual, true);
|
||||
+ add_reg_note (get_last_insn (), REG_STACK_CHECK, const0_rtx);
|
||||
+ emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
|
||||
+ (residual - GET_MODE_SIZE (word_mode))));
|
||||
+ emit_insn (gen_blockage ());
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
/* Add a REG_CFA_EXPRESSION note to INSN to say that register REG
|
||||
is saved at BASE + OFFSET. */
|
||||
|
||||
@@ -4686,7 +4820,54 @@ aarch64_expand_prologue (void)
|
||||
rtx ip0_rtx = gen_rtx_REG (Pmode, IP0_REGNUM);
|
||||
rtx ip1_rtx = gen_rtx_REG (Pmode, IP1_REGNUM);
|
||||
|
||||
- aarch64_sub_sp (ip0_rtx, ip1_rtx, initial_adjust, true);
|
||||
+ /* We do not fully protect aarch64 against stack clash style attacks
|
||||
+ as doing so would be prohibitively expensive with less utility over
|
||||
+ time as newer compilers are deployed.
|
||||
+
|
||||
+ We assume the guard is at least 64k. Furthermore, we assume that
|
||||
+ the caller has not pushed the stack pointer more than 1k into
|
||||
+ the guard. A caller that pushes the stack pointer than 1k into
|
||||
+ the guard is considered invalid.
|
||||
+
|
||||
+ Note that the caller's ability to push the stack pointer into the
|
||||
+ guard is a function of the number and size of outgoing arguments and/or
|
||||
+ dynamic stack allocations due to the mandatory save of the link register
|
||||
+ in the caller's frame.
|
||||
+
|
||||
+ With those assumptions the callee can allocate up to 63k of stack
|
||||
+ space without probing.
|
||||
+
|
||||
+ When probing is needed, we emit a probe at the start of the prologue
|
||||
+ and every PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL bytes thereafter.
|
||||
+
|
||||
+ We have to track how much space has been allocated, but we do not
|
||||
+ track stores into the stack as implicit probes except for the
|
||||
+ fp/lr store. */
|
||||
+ HOST_WIDE_INT guard_size
|
||||
+ = 1 << PARAM_VALUE (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE);
|
||||
+ HOST_WIDE_INT guard_used_by_caller = 1024;
|
||||
+ if (flag_stack_clash_protection)
|
||||
+ {
|
||||
+ if (known_eq (frame_size, 0))
|
||||
+ dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
|
||||
+ else if (known_lt (initial_adjust, guard_size - guard_used_by_caller)
|
||||
+ && known_lt (final_adjust, guard_size - guard_used_by_caller))
|
||||
+ dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
|
||||
+ }
|
||||
+
|
||||
+ /* In theory we should never have both an initial adjustment
|
||||
+ and a callee save adjustment. Verify that is the case since the
|
||||
+ code below does not handle it for -fstack-clash-protection. */
|
||||
+ gcc_assert (known_eq (initial_adjust, 0) || callee_adjust == 0);
|
||||
+
|
||||
+ /* Only probe if the initial adjustment is larger than the guard
|
||||
+ less the amount of the guard reserved for use by the caller's
|
||||
+ outgoing args. */
|
||||
+ if (flag_stack_clash_protection
|
||||
+ && maybe_ge (initial_adjust, guard_size - guard_used_by_caller))
|
||||
+ aarch64_allocate_and_probe_stack_space (ip0_rtx, ip1_rtx, initial_adjust);
|
||||
+ else
|
||||
+ aarch64_sub_sp (ip0_rtx, ip1_rtx, initial_adjust, true);
|
||||
|
||||
if (callee_adjust != 0)
|
||||
aarch64_push_regs (reg1, reg2, callee_adjust);
|
||||
@@ -4742,7 +4923,31 @@ aarch64_expand_prologue (void)
|
||||
callee_adjust != 0 || emit_frame_chain);
|
||||
aarch64_save_callee_saves (DFmode, callee_offset, V0_REGNUM, V31_REGNUM,
|
||||
callee_adjust != 0 || emit_frame_chain);
|
||||
- aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed);
|
||||
+
|
||||
+ /* We may need to probe the final adjustment as well. */
|
||||
+ if (flag_stack_clash_protection && maybe_ne (final_adjust, 0))
|
||||
+ {
|
||||
+ /* First probe if the final adjustment is larger than the guard size
|
||||
+ less the amount of the guard reserved for use by the caller's
|
||||
+ outgoing args. */
|
||||
+ if (maybe_ge (final_adjust, guard_size - guard_used_by_caller))
|
||||
+ aarch64_allocate_and_probe_stack_space (ip1_rtx, ip0_rtx,
|
||||
+ final_adjust);
|
||||
+ else
|
||||
+ aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed);
|
||||
+
|
||||
+ /* We must also probe if the final adjustment is larger than the guard
|
||||
+ that is assumed used by the caller. This may be sub-optimal. */
|
||||
+ if (maybe_ge (final_adjust, guard_used_by_caller))
|
||||
+ {
|
||||
+ if (dump_file)
|
||||
+ fprintf (dump_file,
|
||||
+ "Stack clash aarch64 large outgoing arg, probing\n");
|
||||
+ emit_stack_probe (stack_pointer_rtx);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ aarch64_sub_sp (ip1_rtx, ip0_rtx, final_adjust, !frame_pointer_needed);
|
||||
}
|
||||
|
||||
/* Return TRUE if we can use a simple_return insn.
|
||||
@@ -10476,6 +10681,12 @@ aarch64_override_options_internal (struct gcc_options *opts)
|
||||
&& opts->x_optimize >= aarch64_tune_params.prefetch->default_opt_level)
|
||||
opts->x_flag_prefetch_loop_arrays = 1;
|
||||
|
||||
+ /* We assume the guard page is 64k. */
|
||||
+ maybe_set_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
|
||||
+ 16,
|
||||
+ opts->x_param_values,
|
||||
+ global_options_set.x_param_values);
|
||||
+
|
||||
aarch64_override_options_after_change_1 (opts);
|
||||
}
|
||||
|
||||
@@ -17161,6 +17372,28 @@ aarch64_sched_can_speculate_insn (rtx_insn *insn)
|
||||
}
|
||||
}
|
||||
|
||||
+/* It has been decided that to allow up to 1kb of outgoing argument
|
||||
+ space to be allocated w/o probing. If more than 1kb of outgoing
|
||||
+ argment space is allocated, then it must be probed and the last
|
||||
+ probe must occur no more than 1kbyte away from the end of the
|
||||
+ allocated space.
|
||||
+
|
||||
+ This implies that the residual part of an alloca allocation may
|
||||
+ need probing in cases where the generic code might not otherwise
|
||||
+ think a probe is needed.
|
||||
+
|
||||
+ This target hook returns TRUE when allocating RESIDUAL bytes of
|
||||
+ alloca space requires an additional probe, otherwise FALSE is
|
||||
+ returned. */
|
||||
+
|
||||
+static bool
|
||||
+aarch64_stack_clash_protection_final_dynamic_probe (rtx residual)
|
||||
+{
|
||||
+ return (residual == CONST0_RTX (Pmode)
|
||||
+ || GET_CODE (residual) != CONST_INT
|
||||
+ || INTVAL (residual) >= 1024);
|
||||
+}
|
||||
+
|
||||
/* Implement TARGET_COMPUTE_PRESSURE_CLASSES. */
|
||||
|
||||
static int
|
||||
@@ -17669,6 +17902,10 @@ aarch64_libgcc_floating_mode_supported_p
|
||||
#undef TARGET_CONSTANT_ALIGNMENT
|
||||
#define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment
|
||||
|
||||
+#undef TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE
|
||||
+#define TARGET_STACK_CLASH_PROTECTION_FINAL_DYNAMIC_PROBE \
|
||||
+ aarch64_stack_clash_protection_final_dynamic_probe
|
||||
+
|
||||
#undef TARGET_COMPUTE_PRESSURE_CLASSES
|
||||
#define TARGET_COMPUTE_PRESSURE_CLASSES aarch64_compute_pressure_classes
|
||||
|
||||
--- gcc/config/aarch64/aarch64.md
|
||||
+++ gcc/config/aarch64/aarch64.md
|
||||
@@ -5812,7 +5812,7 @@
|
||||
)
|
||||
|
||||
(define_insn "probe_stack_range"
|
||||
- [(set (match_operand:DI 0 "register_operand" "=r")
|
||||
+ [(set (match_operand:DI 0 "register_operand" "=rk")
|
||||
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")
|
||||
(match_operand:DI 2 "register_operand" "r")]
|
||||
UNSPECV_PROBE_STACK_RANGE))]
|
||||
--- gcc/testsuite/gcc.target/aarch64/stack-check-12.c
|
||||
+++ gcc/testsuite/gcc.target/aarch64/stack-check-12.c
|
||||
@@ -0,0 +1,20 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
+
|
||||
+extern void arf (unsigned long int *, unsigned long int *);
|
||||
+void
|
||||
+frob ()
|
||||
+{
|
||||
+ unsigned long int num[1000];
|
||||
+ unsigned long int den[1000];
|
||||
+ arf (den, num);
|
||||
+}
|
||||
+
|
||||
+/* This verifies that the scheduler did not break the dependencies
|
||||
+ by adjusting the offsets within the probe and that the scheduler
|
||||
+ did not reorder around the stack probes. */
|
||||
+/* { dg-final { scan-assembler-times "sub\\tsp, sp, #4096\\n\\tstr\\txzr, .sp, 4088." 3 } } */
|
||||
+
|
||||
+
|
||||
+
|
||||
--- gcc/testsuite/gcc.target/aarch64/stack-check-13.c
|
||||
+++ gcc/testsuite/gcc.target/aarch64/stack-check-13.c
|
||||
@@ -0,0 +1,28 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
+
|
||||
+#define ARG32(X) X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X
|
||||
+#define ARG192(X) ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X),ARG32(X)
|
||||
+void out1(ARG192(__int128));
|
||||
+int t1(int);
|
||||
+
|
||||
+int t3(int x)
|
||||
+{
|
||||
+ if (x < 1000)
|
||||
+ return t1 (x) + 1;
|
||||
+
|
||||
+ out1 (ARG192(1));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
+/* This test creates a large (> 1k) outgoing argument area that needs
|
||||
+ to be probed. We don't test the exact size of the space or the
|
||||
+ exact offset to make the test a little less sensitive to trivial
|
||||
+ output changes. */
|
||||
+/* { dg-final { scan-assembler-times "sub\\tsp, sp, #....\\n\\tstr\\txzr, \\\[sp" 1 } } */
|
||||
+
|
||||
+
|
||||
+
|
||||
--- gcc/testsuite/gcc.target/aarch64/stack-check-14.c
|
||||
+++ gcc/testsuite/gcc.target/aarch64/stack-check-14.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
+
|
||||
+int t1(int);
|
||||
+
|
||||
+int t2(int x)
|
||||
+{
|
||||
+ char *p = __builtin_alloca (4050);
|
||||
+ x = t1 (x);
|
||||
+ return p[x];
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* This test has a constant sized alloca that is smaller than the
|
||||
+ probe interval. But it actually requires two probes instead
|
||||
+ of one because of the optimistic assumptions we made in the
|
||||
+ aarch64 prologue code WRT probing state.
|
||||
+
|
||||
+ The form can change quite a bit so we just check for two
|
||||
+ probes without looking at the actual address. */
|
||||
+/* { dg-final { scan-assembler-times "str\\txzr," 2 } } */
|
||||
+
|
||||
+
|
||||
+
|
||||
--- gcc/testsuite/gcc.target/aarch64/stack-check-15.c
|
||||
+++ gcc/testsuite/gcc.target/aarch64/stack-check-15.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -fstack-clash-protection --param stack-clash-protection-guard-size=12" } */
|
||||
+/* { dg-require-effective-target supports_stack_clash_protection } */
|
||||
+
|
||||
+int t1(int);
|
||||
+
|
||||
+int t2(int x)
|
||||
+{
|
||||
+ char *p = __builtin_alloca (x);
|
||||
+ x = t1 (x);
|
||||
+ return p[x];
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* This test has a variable sized alloca. It requires 3 probes.
|
||||
+ One in the loop, one for the residual and at the end of the
|
||||
+ alloca area.
|
||||
+
|
||||
+ The form can change quite a bit so we just check for two
|
||||
+ probes without looking at the actual address. */
|
||||
+/* { dg-final { scan-assembler-times "str\\txzr," 3 } } */
|
||||
+
|
||||
+
|
||||
+
|
||||
--- gcc/testsuite/lib/target-supports.exp
|
||||
+++ gcc/testsuite/lib/target-supports.exp
|
||||
@@ -9201,14 +9201,9 @@ proc check_effective_target_autoincdec { } {
|
||||
#
|
||||
proc check_effective_target_supports_stack_clash_protection { } {
|
||||
|
||||
- # Temporary until the target bits are fully ACK'd.
|
||||
-# if { [istarget aarch*-*-*] } {
|
||||
-# return 1
|
||||
-# }
|
||||
-
|
||||
if { [istarget x86_64-*-*] || [istarget i?86-*-*]
|
||||
|| [istarget powerpc*-*-*] || [istarget rs6000*-*-*]
|
||||
- || [istarget s390*-*-*] } {
|
||||
+ || [istarget aarch64*-**] || [istarget s390*-*-*] } {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
@@ -9217,9 +9212,9 @@ proc check_effective_target_supports_stack_clash_protection { } {
|
||||
# Return 1 if the target creates a frame pointer for non-leaf functions
|
||||
# Note we ignore cases where we apply tail call optimization here.
|
||||
proc check_effective_target_frame_pointer_for_non_leaf { } {
|
||||
- if { [istarget aarch*-*-*] } {
|
||||
- return 1
|
||||
- }
|
||||
+# if { [istarget aarch*-*-*] } {
|
||||
+# return 1
|
||||
+# }
|
||||
|
||||
# Solaris/x86 defaults to -fno-omit-frame-pointer.
|
||||
if { [istarget i?86-*-solaris*] || [istarget x86_64-*-solaris*] } {
|
@ -1,31 +0,0 @@
|
||||
crt files and statically linked libgcc objects cause false positives
|
||||
in annobin coverage, so we add the assembler flag to generate notes
|
||||
for them.
|
||||
|
||||
The patch also adds notes to libgcc_s.so, but this is harmless because
|
||||
these notes only confer that there is no other annobin markup.
|
||||
|
||||
2018-07-25 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* Makefile.in (LIBGCC2_CFLAGS, CRTSTUFF_CFLAGS): Add
|
||||
-Wa,--generate-missing-build-notes=yes.
|
||||
|
||||
--- libgcc/Makefile.in 2018-01-13 13:05:41.000000000 +0100
|
||||
+++ libgcc/Makefile.in 2018-07-25 13:15:02.036226940 +0200
|
||||
@@ -244,6 +244,7 @@
|
||||
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
|
||||
$(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
|
||||
-fbuilding-libgcc -fno-stack-protector \
|
||||
+ -Wa,--generate-missing-build-notes=yes \
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
|
||||
# Additional options to use when compiling libgcc2.a.
|
||||
@@ -297,6 +298,7 @@
|
||||
$(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
|
||||
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
|
||||
-fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
|
||||
+ -Wa,--generate-missing-build-notes=yes \
|
||||
$(INHIBIT_LIBC_CFLAGS)
|
||||
|
||||
# Extra flags to use when compiling crt{begin,end}.o.
|
||||
|
@ -1,406 +0,0 @@
|
||||
commit 126dab7c9d84294f256b1f7bf91c24a9e7103249
|
||||
Author: qinzhao <qinzhao@138bc75d-0d04-0410-961f-82ee72b054a4>
|
||||
Date: Thu Nov 29 16:06:03 2018 +0000
|
||||
|
||||
Add a new option -flive-patching={inline-only-static|inline-clone}
|
||||
to support live patching in GCC.
|
||||
|
||||
2018-11-29 qing zhao <qing.zhao@oracle.com>
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* cif-code.def (EXTERN_LIVE_ONLY_STATIC): New CIF code.
|
||||
* common.opt: Add -flive-patching flag.
|
||||
* doc/invoke.texi: Document -flive-patching.
|
||||
* flag-types.h (enum live_patching_level): New enum.
|
||||
* ipa-inline.c (can_inline_edge_p): Disable external functions from
|
||||
inlining when flag_live_patching is LIVE_PATCHING_INLINE_ONLY_STATIC.
|
||||
* opts.c (control_options_for_live_patching): New function.
|
||||
(finish_options): Make flag_live_patching incompatible with flag_lto.
|
||||
Control IPA optimizations based on different levels of
|
||||
flag_live_patching.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gcc.dg/live-patching-1.c: New test.
|
||||
* gcc.dg/live-patching-2.c: New test.
|
||||
* gcc.dg/live-patching-3.c: New test.
|
||||
* gcc.dg/tree-ssa/writeonly-3.c: New test.
|
||||
* gcc.target/i386/ipa-stack-alignment-2.c: New test.
|
||||
|
||||
|
||||
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266627 138bc75d-0d04-0410-961f-82ee72b054a4
|
||||
|
||||
--- gcc/cif-code.def
|
||||
+++ gcc/cif-code.def
|
||||
@@ -132,6 +132,12 @@ DEFCIFCODE(USES_COMDAT_LOCAL, CIF_FINAL_ERROR,
|
||||
DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR,
|
||||
N_("function attribute mismatch"))
|
||||
|
||||
+/* We can't inline because the user requests only static functions
|
||||
+ but the function has external linkage for live patching purpose. */
|
||||
+DEFCIFCODE(EXTERN_LIVE_ONLY_STATIC, CIF_FINAL_ERROR,
|
||||
+ N_("function has external linkage when the user requests only"
|
||||
+ " inlining static for live patching"))
|
||||
+
|
||||
/* We proved that the call is unreachable. */
|
||||
DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
|
||||
N_("unreachable"))
|
||||
--- gcc/common.opt
|
||||
+++ gcc/common.opt
|
||||
@@ -2181,6 +2181,24 @@ starts and when the destructor finishes.
|
||||
flifetime-dse=
|
||||
Common Joined RejectNegative UInteger Var(flag_lifetime_dse) Optimization IntegerRange(0, 2)
|
||||
|
||||
+flive-patching
|
||||
+Common RejectNegative Alias(flive-patching=,inline-clone) Optimization
|
||||
+
|
||||
+flive-patching=
|
||||
+Common Report Joined RejectNegative Enum(live_patching_level) Var(flag_live_patching) Init(LIVE_PATCHING_NONE) Optimization
|
||||
+-flive-patching=[inline-only-static|inline-clone] Control IPA
|
||||
+optimizations to provide a safe compilation for live-patching. At the same
|
||||
+time, provides multiple-level control on the enabled IPA optimizations.
|
||||
+
|
||||
+Enum
|
||||
+Name(live_patching_level) Type(enum live_patching_level) UnknownError(unknown Live-Patching Level %qs)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_ONLY_STATIC)
|
||||
+
|
||||
+EnumValue
|
||||
+Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE)
|
||||
+
|
||||
flive-range-shrinkage
|
||||
Common Report Var(flag_live_range_shrinkage) Init(0) Optimization
|
||||
Relief of register pressure through live range shrinkage.
|
||||
--- gcc/doc/invoke.texi
|
||||
+++ gcc/doc/invoke.texi
|
||||
@@ -389,6 +389,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-fipa-bit-cp -fipa-vrp @gol
|
||||
-fipa-pta -fipa-profile -fipa-pure-const -fipa-reference -fipa-icf @gol
|
||||
-fira-algorithm=@var{algorithm} @gol
|
||||
+-flive-patching=@var{level} @gol
|
||||
-fira-region=@var{region} -fira-hoist-pressure @gol
|
||||
-fira-loop-pressure -fno-ira-share-save-slots @gol
|
||||
-fno-ira-share-spill-slots @gol
|
||||
@@ -9291,6 +9292,65 @@ equivalences that are found only by GCC and equivalences found only by Gold.
|
||||
|
||||
This flag is enabled by default at @option{-O2} and @option{-Os}.
|
||||
|
||||
+@item -flive-patching=@var{level}
|
||||
+@opindex flive-patching
|
||||
+Control GCC's optimizations to provide a safe compilation for live-patching.
|
||||
+
|
||||
+If the compiler's optimization uses a function's body or information extracted
|
||||
+from its body to optimize/change another function, the latter is called an
|
||||
+impacted function of the former. If a function is patched, its impacted
|
||||
+functions should be patched too.
|
||||
+
|
||||
+The impacted functions are decided by the compiler's interprocedural
|
||||
+optimizations. For example, inlining a function into its caller, cloning
|
||||
+a function and changing its caller to call this new clone, or extracting
|
||||
+a function's pureness/constness information to optimize its direct or
|
||||
+indirect callers, etc.
|
||||
+
|
||||
+Usually, the more IPA optimizations enabled, the larger the number of
|
||||
+impacted functions for each function. In order to control the number of
|
||||
+impacted functions and computed the list of impacted function easily,
|
||||
+we provide control to partially enable IPA optimizations on two different
|
||||
+levels.
|
||||
+
|
||||
+The @var{level} argument should be one of the following:
|
||||
+
|
||||
+@table @samp
|
||||
+
|
||||
+@item inline-clone
|
||||
+
|
||||
+Only enable inlining and cloning optimizations, which includes inlining,
|
||||
+cloning, interprocedural scalar replacement of aggregates and partial inlining.
|
||||
+As a result, when patching a function, all its callers and its clones'
|
||||
+callers need to be patched as well.
|
||||
+
|
||||
+@option{-flive-patching=inline-clone} disables the following optimization flags:
|
||||
+@gccoptlist{-fwhole-program -fipa-pta -fipa-reference -fipa-ra @gol
|
||||
+-fipa-icf -fipa-icf-functions -fipa-icf-variables @gol
|
||||
+-fipa-bit-cp -fipa-vrp -fipa-pure-const -fipa-reference-addressable @gol
|
||||
+-fipa-stack-alignment}
|
||||
+
|
||||
+@item inline-only-static
|
||||
+
|
||||
+Only enable inlining of static functions.
|
||||
+As a result, when patching a static function, all its callers need to be
|
||||
+patches as well.
|
||||
+
|
||||
+In addition to all the flags that -flive-patching=inline-clone disables,
|
||||
+@option{-flive-patching=inline-only-static} disables the following additional
|
||||
+optimization flags:
|
||||
+@gccoptlist{-fipa-cp-clone -fipa-sra -fpartial-inlining -fipa-cp}
|
||||
+
|
||||
+@end table
|
||||
+
|
||||
+When -flive-patching specified without any value, the default value
|
||||
+is "inline-clone".
|
||||
+
|
||||
+This flag is disabled by default.
|
||||
+
|
||||
+Note that -flive-patching is not supported with link-time optimizer.
|
||||
+(@option{-flto}).
|
||||
+
|
||||
@item -fisolate-erroneous-paths-dereference
|
||||
@opindex fisolate-erroneous-paths-dereference
|
||||
Detect paths that trigger erroneous or undefined behavior due to
|
||||
--- gcc/flag-types.h
|
||||
+++ gcc/flag-types.h
|
||||
@@ -123,6 +123,14 @@ enum stack_reuse_level
|
||||
SR_ALL
|
||||
};
|
||||
|
||||
+/* The live patching level. */
|
||||
+enum live_patching_level
|
||||
+{
|
||||
+ LIVE_PATCHING_NONE = 0,
|
||||
+ LIVE_PATCHING_INLINE_ONLY_STATIC,
|
||||
+ LIVE_PATCHING_INLINE_CLONE
|
||||
+};
|
||||
+
|
||||
/* The algorithm used for basic block reordering. */
|
||||
enum reorder_blocks_algorithm
|
||||
{
|
||||
--- gcc/ipa-inline.c
|
||||
+++ gcc/ipa-inline.c
|
||||
@@ -379,6 +379,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
||||
e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
|
||||
inlinable = false;
|
||||
}
|
||||
+ else if (callee->externally_visible
|
||||
+ && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
|
||||
+ {
|
||||
+ e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
|
||||
+ inlinable = false;
|
||||
+ }
|
||||
if (!inlinable && report)
|
||||
report_inline_failed_reason (e);
|
||||
return inlinable;
|
||||
--- gcc/opts.c
|
||||
+++ gcc/opts.c
|
||||
@@ -699,6 +699,152 @@ default_options_optimization (struct gcc
|
||||
lang_mask, handlers, loc, dc);
|
||||
}
|
||||
|
||||
+/* Control IPA optimizations based on different live patching LEVEL. */
|
||||
+static void
|
||||
+control_options_for_live_patching (struct gcc_options *opts,
|
||||
+ struct gcc_options *opts_set,
|
||||
+ enum live_patching_level level,
|
||||
+ location_t loc)
|
||||
+{
|
||||
+ gcc_assert (level > LIVE_PATCHING_NONE);
|
||||
+
|
||||
+ switch (level)
|
||||
+ {
|
||||
+ case LIVE_PATCHING_INLINE_ONLY_STATIC:
|
||||
+ if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-cp-clone%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_cp_clone = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-sra%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_sra = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
|
||||
+ error_at (loc,
|
||||
+ "%<-fpartial-inlining%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static%>");
|
||||
+ else
|
||||
+ opts->x_flag_partial_inlining = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-cp%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_cp = 0;
|
||||
+
|
||||
+ /* FALLTHROUGH. */
|
||||
+ case LIVE_PATCHING_INLINE_CLONE:
|
||||
+ /* live patching should disable whole-program optimization. */
|
||||
+ if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
|
||||
+ error_at (loc,
|
||||
+ "%<-fwhole-program%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_whole_program = 0;
|
||||
+
|
||||
+ /* visibility change should be excluded by !flag_whole_program
|
||||
+ && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra
|
||||
+ && !flag_partial_inlining. */
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-pta%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_pta = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-reference%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_reference = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-ra%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_ra = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-icf%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_icf = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-icf-functions%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_icf_functions = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-icf-variables%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_icf_variables = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-bit-cp%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_bit_cp = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-vrp%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_vrp = 0;
|
||||
+
|
||||
+ if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-pure-const%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_pure_const = 0;
|
||||
+
|
||||
+ /* FIXME: disable unreachable code removal. */
|
||||
+
|
||||
+ /* discovery of functions/variables with no address taken. */
|
||||
+// GCC 8 doesn't have these options.
|
||||
+#if 0
|
||||
+ if (opts_set->x_flag_ipa_reference_addressable
|
||||
+ && opts->x_flag_ipa_reference_addressable)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-reference-addressable%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_reference_addressable = 0;
|
||||
+
|
||||
+ /* ipa stack alignment propagation. */
|
||||
+ if (opts_set->x_flag_ipa_stack_alignment
|
||||
+ && opts->x_flag_ipa_stack_alignment)
|
||||
+ error_at (loc,
|
||||
+ "%<-fipa-stack-alignment%> is incompatible with "
|
||||
+ "%<-flive-patching=inline-only-static|inline-clone%>");
|
||||
+ else
|
||||
+ opts->x_flag_ipa_stack_alignment = 0;
|
||||
+#endif
|
||||
+
|
||||
+ break;
|
||||
+ default:
|
||||
+ gcc_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* After all options at LOC have been read into OPTS and OPTS_SET,
|
||||
finalize settings of those options and diagnose incompatible
|
||||
combinations. */
|
||||
@@ -1057,6 +1203,18 @@ finish_options (struct gcc_options *opts
|
||||
sorry ("transactional memory is not supported with "
|
||||
"%<-fsanitize=kernel-address%>");
|
||||
|
||||
+ /* Currently live patching is not support for LTO. */
|
||||
+ if (opts->x_flag_live_patching && opts->x_flag_lto)
|
||||
+ sorry ("live patching is not supported with LTO");
|
||||
+
|
||||
+ /* Control IPA optimizations based on different -flive-patching level. */
|
||||
+ if (opts->x_flag_live_patching)
|
||||
+ {
|
||||
+ control_options_for_live_patching (opts, opts_set,
|
||||
+ opts->x_flag_live_patching,
|
||||
+ loc);
|
||||
+ }
|
||||
+
|
||||
/* Comes from final.c -- no real reason to change it. */
|
||||
#define MAX_CODE_ALIGN 16
|
||||
#define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/gcc.dg/live-patching-1.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-ipa-inline" } */
|
||||
+
|
||||
+extern int sum, n, m;
|
||||
+
|
||||
+int foo (int a)
|
||||
+{
|
||||
+ return a + n;
|
||||
+}
|
||||
+
|
||||
+static int bar (int b)
|
||||
+{
|
||||
+ return b * m;
|
||||
+}
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ sum = foo (m) + bar (n);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-ipa-dump "foo/0 function has external linkage when the user requests only inlining static for live patching" "inline" } } */
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/gcc.dg/live-patching-2.c
|
||||
@@ -0,0 +1,9 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -flive-patching -flto" } */
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-message "sorry, unimplemented: live patching is not supported with LTO" "-flive-patching and -flto together" { target *-*-* } 0 } */
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/gcc.dg/live-patching-3.c
|
||||
@@ -0,0 +1,9 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O1 -flive-patching -fwhole-program" } */
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-message "'-fwhole-program' is incompatible with '-flive-patching=inline-only-static|inline-clone’" "" {target "*-*-*"} 0 } */
|
@ -1,73 +0,0 @@
|
||||
commit 9939b2f79bd9b75b99080a17f3d6f1214d543477
|
||||
Author: qinzhao <qinzhao@138bc75d-0d04-0410-961f-82ee72b054a4>
|
||||
Date: Wed Apr 3 19:00:25 2019 +0000
|
||||
|
||||
2019-04-03 qing zhao <qing.zhao@oracle.com>
|
||||
|
||||
PR tree-optimization/89730
|
||||
* ipa-inline.c (can_inline_edge_p): Delete the checking for
|
||||
-flive-patching=inline-only-static.
|
||||
(can_inline_edge_by_limits_p): Add the checking for
|
||||
-flive-patching=inline-only-static and grant always_inline
|
||||
even when -flive-patching=inline-only-static is specified.
|
||||
|
||||
* gcc.dg/live-patching-4.c: New test.
|
||||
|
||||
|
||||
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270134 138bc75d-0d04-0410-961f-82ee72b054a4
|
||||
|
||||
--- gcc/ipa-inline.c
|
||||
+++ gcc/ipa-inline.c
|
||||
@@ -385,12 +385,6 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
||||
e->inline_failed = CIF_ATTRIBUTE_MISMATCH;
|
||||
inlinable = false;
|
||||
}
|
||||
- else if (callee->externally_visible
|
||||
- && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
|
||||
- {
|
||||
- e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
|
||||
- inlinable = false;
|
||||
- }
|
||||
if (!inlinable && report)
|
||||
report_inline_failed_reason (e);
|
||||
return inlinable;
|
||||
@@ -433,6 +427,13 @@ can_inline_edge_by_limits_p (struct cgraph_edge *e, bool report,
|
||||
DECL_ATTRIBUTES (caller->decl))
|
||||
&& !caller_growth_limits (e))
|
||||
inlinable = false;
|
||||
+ else if (callee->externally_visible
|
||||
+ && !DECL_DISREGARD_INLINE_LIMITS (callee->decl)
|
||||
+ && flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC)
|
||||
+ {
|
||||
+ e->inline_failed = CIF_EXTERN_LIVE_ONLY_STATIC;
|
||||
+ inlinable = false;
|
||||
+ }
|
||||
/* Don't inline a function with a higher optimization level than the
|
||||
caller. FIXME: this is really just tip of iceberg of handling
|
||||
optimization attribute. */
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/gcc.dg/live-patching-4.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-options "-O2 -flive-patching=inline-only-static -fdump-tree-einline-optimized" } */
|
||||
+
|
||||
+extern int sum, n, m;
|
||||
+
|
||||
+extern inline __attribute__((always_inline)) int foo (int a);
|
||||
+inline __attribute__((always_inline)) int foo (int a)
|
||||
+{
|
||||
+ return a + n;
|
||||
+}
|
||||
+
|
||||
+static int bar (int b)
|
||||
+{
|
||||
+ return b * m;
|
||||
+}
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ sum = foo (m) + bar (n);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-tree-dump "Inlining foo into main" "einline" } } */
|
@ -1,85 +0,0 @@
|
||||
commit 77e6311332590004c5aec82ceeb45e4d4d93f690
|
||||
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
|
||||
Date: Thu Apr 11 08:52:22 2019 +0000
|
||||
|
||||
Clarify documentation for -flive-patching
|
||||
|
||||
* doc/invoke.texi (Optimize Options): Clarify -flive-patching docs.
|
||||
|
||||
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270276 138bc75d-0d04-0410-961f-82ee72b054a4
|
||||
|
||||
--- gcc/doc/invoke.texi
|
||||
+++ gcc/doc/invoke.texi
|
||||
@@ -9367,24 +9367,24 @@ This flag is enabled by default at @option{-O2} and @option{-Os}.
|
||||
|
||||
@item -flive-patching=@var{level}
|
||||
@opindex flive-patching
|
||||
-Control GCC's optimizations to provide a safe compilation for live-patching.
|
||||
+Control GCC's optimizations to produce output suitable for live-patching.
|
||||
|
||||
If the compiler's optimization uses a function's body or information extracted
|
||||
from its body to optimize/change another function, the latter is called an
|
||||
impacted function of the former. If a function is patched, its impacted
|
||||
functions should be patched too.
|
||||
|
||||
-The impacted functions are decided by the compiler's interprocedural
|
||||
-optimizations. For example, inlining a function into its caller, cloning
|
||||
-a function and changing its caller to call this new clone, or extracting
|
||||
-a function's pureness/constness information to optimize its direct or
|
||||
-indirect callers, etc.
|
||||
+The impacted functions are determined by the compiler's interprocedural
|
||||
+optimizations. For example, a caller is impacted when inlining a function
|
||||
+into its caller,
|
||||
+cloning a function and changing its caller to call this new clone,
|
||||
+or extracting a function's pureness/constness information to optimize
|
||||
+its direct or indirect callers, etc.
|
||||
|
||||
Usually, the more IPA optimizations enabled, the larger the number of
|
||||
impacted functions for each function. In order to control the number of
|
||||
-impacted functions and computed the list of impacted function easily,
|
||||
-we provide control to partially enable IPA optimizations on two different
|
||||
-levels.
|
||||
+impacted functions and more easily compute the list of impacted function,
|
||||
+IPA optimizations can be partially enabled at two different levels.
|
||||
|
||||
The @var{level} argument should be one of the following:
|
||||
|
||||
@@ -9395,7 +9395,7 @@ The @var{level} argument should be one of the following:
|
||||
Only enable inlining and cloning optimizations, which includes inlining,
|
||||
cloning, interprocedural scalar replacement of aggregates and partial inlining.
|
||||
As a result, when patching a function, all its callers and its clones'
|
||||
-callers need to be patched as well.
|
||||
+callers are impacted, therefore need to be patched as well.
|
||||
|
||||
@option{-flive-patching=inline-clone} disables the following optimization flags:
|
||||
@gccoptlist{-fwhole-program -fipa-pta -fipa-reference -fipa-ra @gol
|
||||
@@ -9406,22 +9406,23 @@ callers need to be patched as well.
|
||||
@item inline-only-static
|
||||
|
||||
Only enable inlining of static functions.
|
||||
-As a result, when patching a static function, all its callers need to be
|
||||
-patches as well.
|
||||
+As a result, when patching a static function, all its callers are impacted
|
||||
+and so need to be patched as well.
|
||||
|
||||
-In addition to all the flags that -flive-patching=inline-clone disables,
|
||||
+In addition to all the flags that @option{-flive-patching=inline-clone}
|
||||
+disables,
|
||||
@option{-flive-patching=inline-only-static} disables the following additional
|
||||
optimization flags:
|
||||
@gccoptlist{-fipa-cp-clone -fipa-sra -fpartial-inlining -fipa-cp}
|
||||
|
||||
@end table
|
||||
|
||||
-When -flive-patching specified without any value, the default value
|
||||
-is "inline-clone".
|
||||
+When @option{-flive-patching} is specified without any value, the default value
|
||||
+is @var{inline-clone}.
|
||||
|
||||
This flag is disabled by default.
|
||||
|
||||
-Note that -flive-patching is not supported with link-time optimizer.
|
||||
+Note that @option{-flive-patching} is not supported with link-time optimization
|
||||
(@option{-flto}).
|
||||
|
||||
@item -fisolate-erroneous-paths-dereference
|
@ -1,93 +0,0 @@
|
||||
2018-11-08 Roman Geissler <roman.geissler@amadeus.com>
|
||||
|
||||
* collect2.c (linker_select): Add USE_LLD_LD.
|
||||
(ld_suffixes): Add ld.lld.
|
||||
(main): Handle -fuse-ld=lld.
|
||||
* common.opt (-fuse-ld=lld): New option.
|
||||
* doc/invoke.texi (-fuse-ld=lld): Document.
|
||||
* opts.c (common_handle_option): Handle OPT_fuse_ld_lld.
|
||||
|
||||
--- gcc/collect2.c
|
||||
+++ gcc/collect2.c
|
||||
@@ -831,6 +831,7 @@ main (int argc, char **argv)
|
||||
USE_PLUGIN_LD,
|
||||
USE_GOLD_LD,
|
||||
USE_BFD_LD,
|
||||
+ USE_LLD_LD,
|
||||
USE_LD_MAX
|
||||
} selected_linker = USE_DEFAULT_LD;
|
||||
static const char *const ld_suffixes[USE_LD_MAX] =
|
||||
@@ -838,7 +839,8 @@ main (int argc, char **argv)
|
||||
"ld",
|
||||
PLUGIN_LD_SUFFIX,
|
||||
"ld.gold",
|
||||
- "ld.bfd"
|
||||
+ "ld.bfd",
|
||||
+ "ld.lld"
|
||||
};
|
||||
static const char *const real_ld_suffix = "real-ld";
|
||||
static const char *const collect_ld_suffix = "collect-ld";
|
||||
@@ -1007,6 +1009,8 @@ main (int argc, char **argv)
|
||||
selected_linker = USE_BFD_LD;
|
||||
else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
|
||||
selected_linker = USE_GOLD_LD;
|
||||
+ else if (strcmp (argv[i], "-fuse-ld=lld") == 0)
|
||||
+ selected_linker = USE_LLD_LD;
|
||||
|
||||
#ifdef COLLECT_EXPORT_LIST
|
||||
/* These flags are position independent, although their order
|
||||
@@ -1096,7 +1100,8 @@ main (int argc, char **argv)
|
||||
/* Maybe we know the right file to use (if not cross). */
|
||||
ld_file_name = 0;
|
||||
#ifdef DEFAULT_LINKER
|
||||
- if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD)
|
||||
+ if (selected_linker == USE_BFD_LD || selected_linker == USE_GOLD_LD ||
|
||||
+ selected_linker == USE_LLD_LD)
|
||||
{
|
||||
char *linker_name;
|
||||
# ifdef HOST_EXECUTABLE_SUFFIX
|
||||
@@ -1315,7 +1320,7 @@ main (int argc, char **argv)
|
||||
else if (!use_collect_ld
|
||||
&& strncmp (arg, "-fuse-ld=", 9) == 0)
|
||||
{
|
||||
- /* Do not pass -fuse-ld={bfd|gold} to the linker. */
|
||||
+ /* Do not pass -fuse-ld={bfd|gold|lld} to the linker. */
|
||||
ld1--;
|
||||
ld2--;
|
||||
}
|
||||
--- gcc/common.opt
|
||||
+++ gcc/common.opt
|
||||
@@ -2732,6 +2732,10 @@ fuse-ld=gold
|
||||
Common Driver Negative(fuse-ld=bfd)
|
||||
Use the gold linker instead of the default linker.
|
||||
|
||||
+fuse-ld=lld
|
||||
+Common Driver Negative(fuse-ld=lld)
|
||||
+Use the lld LLVM linker instead of the default linker.
|
||||
+
|
||||
fuse-linker-plugin
|
||||
Common Undocumented Var(flag_use_linker_plugin)
|
||||
|
||||
--- gcc/doc/invoke.texi
|
||||
+++ gcc/doc/invoke.texi
|
||||
@@ -12610,6 +12610,10 @@ Use the @command{bfd} linker instead of the default linker.
|
||||
@opindex fuse-ld=gold
|
||||
Use the @command{gold} linker instead of the default linker.
|
||||
|
||||
+@item -fuse-ld=lld
|
||||
+@opindex fuse-ld=lld
|
||||
+Use the LLVM @command{lld} linker instead of the default linker.
|
||||
+
|
||||
@cindex Libraries
|
||||
@item -l@var{library}
|
||||
@itemx -l @var{library}
|
||||
--- gcc/opts.c
|
||||
+++ gcc/opts.c
|
||||
@@ -2557,6 +2557,7 @@ common_handle_option (struct gcc_options *opts,
|
||||
|
||||
case OPT_fuse_ld_bfd:
|
||||
case OPT_fuse_ld_gold:
|
||||
+ case OPT_fuse_ld_lld:
|
||||
case OPT_fuse_linker_plugin:
|
||||
/* No-op. Used by the driver and passed to us because it starts with f.*/
|
||||
break;
|
@ -1,64 +0,0 @@
|
||||
--- gcc/cp/call.c
|
||||
+++ gcc/cp/call.c
|
||||
@@ -6904,7 +6904,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
||||
elttype = cp_build_qualified_type
|
||||
(elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
|
||||
array = build_array_of_n_type (elttype, len);
|
||||
- array = finish_compound_literal (array, new_ctor, complain, fcl_c99);
|
||||
+ array = finish_compound_literal (array, new_ctor, complain);
|
||||
/* Take the address explicitly rather than via decay_conversion
|
||||
to avoid the error about taking the address of a temporary. */
|
||||
array = cp_build_addr_expr (array, complain);
|
||||
@@ -10984,13 +10984,11 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
|
||||
lvalue-rvalue conversion applied to "a glvalue of literal type
|
||||
that refers to a non-volatile temporary object initialized
|
||||
with a constant expression". Rather than try to communicate
|
||||
- that this VAR_DECL is a temporary, just mark it constexpr.
|
||||
-
|
||||
- Currently this is only useful for initializer_list temporaries,
|
||||
- since reference vars can't appear in constant expressions. */
|
||||
+ that this VAR_DECL is a temporary, just mark it constexpr. */
|
||||
DECL_DECLARED_CONSTEXPR_P (var) = true;
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true;
|
||||
TREE_CONSTANT (var) = true;
|
||||
+ TREE_READONLY (var) = true;
|
||||
}
|
||||
DECL_INITIAL (var) = init;
|
||||
init = NULL_TREE;
|
||||
--- gcc/cp/tree.c
|
||||
+++ gcc/cp/tree.c
|
||||
@@ -442,6 +442,14 @@ build_target_expr (tree decl, tree value, tsubst_flags_t complain)
|
||||
|| useless_type_conversion_p (TREE_TYPE (decl),
|
||||
TREE_TYPE (value)));
|
||||
|
||||
+ /* Set TREE_READONLY for optimization, such as gimplify_init_constructor
|
||||
+ moving a constant aggregate into .rodata. */
|
||||
+ if (CP_TYPE_CONST_NON_VOLATILE_P (type)
|
||||
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
|
||||
+ && !VOID_TYPE_P (TREE_TYPE (value))
|
||||
+ && reduced_constant_expression_p (value))
|
||||
+ TREE_READONLY (decl) = true;
|
||||
+
|
||||
if (complain & tf_no_cleanup)
|
||||
/* The caller is building a new-expr and does not need a cleanup. */
|
||||
t = NULL_TREE;
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/cpp1y/pr95226.C
|
||||
@@ -0,0 +1,17 @@
|
||||
+// PR c++/95226
|
||||
+// { dg-do run { target c++14 } }
|
||||
+
|
||||
+#include <vector>
|
||||
+
|
||||
+struct T {
|
||||
+ unsigned a;
|
||||
+ float b {8.};
|
||||
+};
|
||||
+
|
||||
+int main()
|
||||
+{
|
||||
+ T t = {1};
|
||||
+ std::vector<T> tt = {{1}, {2}};
|
||||
+ if (t.a != 1 || t.b != 8.0f || tt[0].a != 1 || tt[0].b != 8.0f || tt[1].a != 2 || tt[1].b != 8.0f)
|
||||
+ __builtin_abort ();
|
||||
+}
|
@ -1,70 +0,0 @@
|
||||
From 55f40d968b0bd3be4478a9481e829a99ee0fa04f Mon Sep 17 00:00:00 2001
|
||||
From: Jason Merrill <jason@redhat.com>
|
||||
Date: Mon, 5 Apr 2021 22:50:44 -0400
|
||||
Subject: [PATCH] c++: mangling of lambdas in default args [PR91241]
|
||||
|
||||
In this testcase, the parms remembered in LAMBDA_EXPR_EXTRA_SCOPE are no
|
||||
longer the parms of the FUNCTION_DECL they have as their DECL_CONTEXT, so we
|
||||
were mangling both lambdas as parm #0. But since the parms are numbered
|
||||
from right to left we don't need to need to find them in the FUNCTION_DECL,
|
||||
we can measure their own DECL_CHAIN.
|
||||
|
||||
gcc/cp/ChangeLog:
|
||||
|
||||
PR c++/91241
|
||||
* mangle.c (write_compact_number): Add sanity check.
|
||||
(write_local_name): Use list_length for parm number.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
PR c++/91241
|
||||
* g++.dg/abi/lambda-defarg1.C: New test.
|
||||
---
|
||||
gcc/cp/mangle.c | 11 ++---------
|
||||
gcc/testsuite/g++.dg/abi/lambda-defarg1.C | 11 +++++++++++
|
||||
2 files changed, 13 insertions(+), 9 deletions(-)
|
||||
create mode 100644 gcc/testsuite/g++.dg/abi/lambda-defarg1.C
|
||||
|
||||
--- gcc/cp/mangle.c
|
||||
+++ gcc/cp/mangle.c
|
||||
@@ -1628,6 +1628,7 @@ write_literal_operator_name (tree identifier)
|
||||
static void
|
||||
write_compact_number (int num)
|
||||
{
|
||||
+ gcc_checking_assert (num >= 0);
|
||||
if (num > 0)
|
||||
write_unsigned_number (num - 1);
|
||||
write_char ('_');
|
||||
@@ -2027,15 +2028,7 @@ write_local_name (tree function, const tree local_entity,
|
||||
/* For this purpose, parameters are numbered from right-to-left. */
|
||||
if (parm)
|
||||
{
|
||||
- tree t;
|
||||
- int i = 0;
|
||||
- for (t = DECL_ARGUMENTS (function); t; t = DECL_CHAIN (t))
|
||||
- {
|
||||
- if (t == parm)
|
||||
- i = 1;
|
||||
- else if (i)
|
||||
- ++i;
|
||||
- }
|
||||
+ int i = list_length (parm);
|
||||
write_char ('d');
|
||||
write_compact_number (i - 1);
|
||||
}
|
||||
--- /dev/null
|
||||
+++ gcc/testsuite/g++.dg/abi/lambda-defarg1.C
|
||||
@@ -0,0 +1,11 @@
|
||||
+// PR c++/91241
|
||||
+// { dg-do compile { target c++11 } }
|
||||
+
|
||||
+struct A {
|
||||
+ int *b(const int & = []() -> int { return 0; }(),
|
||||
+ const int & = []() -> int { return 0; }());
|
||||
+};
|
||||
+int *A::b(const int &, const int &) { b(); return 0; }
|
||||
+// { dg-final { scan-assembler "_ZN1A1bERKiS1_" } }
|
||||
+// { dg-final { scan-assembler "_ZZN1A1bERKiS1_Ed_NKUlvE_clEv" } }
|
||||
+// { dg-final { scan-assembler "_ZZN1A1bERKiS1_Ed0_NKUlvE_clEv" } }
|
||||
--
|
||||
2.27.0
|
@ -1,456 +0,0 @@
|
||||
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
|
||||
|
@ -1,101 +0,0 @@
|
||||
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. */
|
||||
|
@ -1,103 +0,0 @@
|
||||
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;
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
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);
|
@ -1,75 +0,0 @@
|
||||
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
|
||||
|
@ -1,91 +0,0 @@
|
||||
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. */
|
@ -1,106 +0,0 @@
|
||||
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")])
|
||||
|
@ -1,545 +0,0 @@
|
||||
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\\)" } } */
|
@ -1,11 +0,0 @@
|
||||
--- nvptx-tools/nvptx-as.c.jj 2017-01-20 12:40:18.000000000 +0100
|
||||
+++ nvptx-tools/nvptx-as.c 2017-01-20 12:43:53.864271442 +0100
|
||||
@@ -939,7 +939,7 @@ fork_execute (const char *prog, char *co
|
||||
fatal_error ("%s: %m", errmsg);
|
||||
}
|
||||
else
|
||||
- fatal_error (errmsg);
|
||||
+ fatal_error ("%s", errmsg);
|
||||
}
|
||||
do_wait (prog, pex);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
--- nvptx-tools/configure.ac.jj 2017-01-13 12:48:31.000000000 +0100
|
||||
+++ nvptx-tools/configure.ac 2017-05-03 10:26:57.076092259 +0200
|
||||
@@ -66,6 +66,8 @@ CPPFLAGS=$save_CPPFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
|
||||
+AC_CHECK_DECLS(getopt)
|
||||
+
|
||||
AC_CONFIG_SUBDIRS([libiberty])
|
||||
AC_CONFIG_FILES([Makefile dejagnu.exp])
|
||||
AC_OUTPUT
|
||||
--- nvptx-tools/configure.jj 2017-01-13 12:48:54.000000000 +0100
|
||||
+++ nvptx-tools/configure 2017-05-03 10:27:13.503876809 +0200
|
||||
@@ -3963,6 +3963,18 @@ CPPFLAGS=$save_CPPFLAGS
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
LIBS=$save_LIBS
|
||||
|
||||
+ac_fn_c_check_decl "$LINENO" "getopt" "ac_cv_have_decl_getopt" "$ac_includes_default"
|
||||
+if test "x$ac_cv_have_decl_getopt" = x""yes; then :
|
||||
+ ac_have_decl=1
|
||||
+else
|
||||
+ ac_have_decl=0
|
||||
+fi
|
||||
+
|
||||
+cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_DECL_GETOPT $ac_have_decl
|
||||
+_ACEOF
|
||||
+
|
||||
+
|
||||
|
||||
|
||||
subdirs="$subdirs libiberty"
|
@ -1,947 +0,0 @@
|
||||
--- nvptx-tools/configure.ac
|
||||
+++ nvptx-tools/configure.ac
|
||||
@@ -51,6 +51,7 @@ LIBS="$LIBS -lcuda"
|
||||
AC_CHECK_FUNCS([[cuGetErrorName] [cuGetErrorString]])
|
||||
AC_CHECK_DECLS([[cuGetErrorName], [cuGetErrorString]],
|
||||
[], [], [[#include <cuda.h>]])
|
||||
+AC_CHECK_HEADERS(unistd.h sys/stat.h)
|
||||
|
||||
AC_MSG_CHECKING([for extra programs to build requiring -lcuda])
|
||||
NVPTX_RUN=
|
||||
--- nvptx-tools/include/libiberty.h
|
||||
+++ nvptx-tools/include/libiberty.h
|
||||
@@ -390,6 +390,17 @@ extern void hex_init (void);
|
||||
/* Save files used for communication between processes. */
|
||||
#define PEX_SAVE_TEMPS 0x4
|
||||
|
||||
+/* Max number of alloca bytes per call before we must switch to malloc.
|
||||
+
|
||||
+ ?? Swiped from gnulib's regex_internal.h header. Is this actually
|
||||
+ the case? This number seems arbitrary, though sane.
|
||||
+
|
||||
+ The OS usually guarantees only one guard page at the bottom of the stack,
|
||||
+ and a page size can be as small as 4096 bytes. So we cannot safely
|
||||
+ allocate anything larger than 4096 bytes. Also care for the possibility
|
||||
+ of a few compiler-allocated temporary stack slots. */
|
||||
+#define MAX_ALLOCA_SIZE 4032
|
||||
+
|
||||
/* Prepare to execute one or more programs, with standard output of
|
||||
each program fed to standard input of the next.
|
||||
FLAGS As above.
|
||||
--- nvptx-tools/nvptx-as.c
|
||||
+++ nvptx-tools/nvptx-as.c
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <string.h>
|
||||
#include <wait.h>
|
||||
#include <unistd.h>
|
||||
+#ifdef HAVE_SYS_STAT_H
|
||||
+#include <sys/stat.h>
|
||||
+#endif
|
||||
#include <errno.h>
|
||||
#define obstack_chunk_alloc malloc
|
||||
#define obstack_chunk_free free
|
||||
@@ -42,6 +45,38 @@
|
||||
|
||||
#include "version.h"
|
||||
|
||||
+#ifndef R_OK
|
||||
+#define R_OK 4
|
||||
+#define W_OK 2
|
||||
+#define X_OK 1
|
||||
+#endif
|
||||
+
|
||||
+#ifndef DIR_SEPARATOR
|
||||
+# define DIR_SEPARATOR '/'
|
||||
+#endif
|
||||
+
|
||||
+#if defined (_WIN32) || defined (__MSDOS__) \
|
||||
+ || defined (__DJGPP__) || defined (__OS2__)
|
||||
+# define HAVE_DOS_BASED_FILE_SYSTEM
|
||||
+# define HAVE_HOST_EXECUTABLE_SUFFIX
|
||||
+# define HOST_EXECUTABLE_SUFFIX ".exe"
|
||||
+# ifndef DIR_SEPARATOR_2
|
||||
+# define DIR_SEPARATOR_2 '\\'
|
||||
+# endif
|
||||
+# define PATH_SEPARATOR ';'
|
||||
+#else
|
||||
+# define PATH_SEPARATOR ':'
|
||||
+#endif
|
||||
+
|
||||
+#ifndef DIR_SEPARATOR_2
|
||||
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
|
||||
+#else
|
||||
+# define IS_DIR_SEPARATOR(ch) \
|
||||
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
|
||||
+#endif
|
||||
+
|
||||
+#define DIR_UP ".."
|
||||
+
|
||||
static const char *outname = NULL;
|
||||
|
||||
static void __attribute__ ((format (printf, 1, 2)))
|
||||
@@ -816,7 +851,7 @@ traverse (void **slot, void *data)
|
||||
}
|
||||
|
||||
static void
|
||||
-process (FILE *in, FILE *out)
|
||||
+process (FILE *in, FILE *out, int verify, const char *outname)
|
||||
{
|
||||
symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
|
||||
NULL);
|
||||
@@ -824,6 +859,18 @@ process (FILE *in, FILE *out)
|
||||
const char *input = read_file (in);
|
||||
Token *tok = tokenize (input);
|
||||
|
||||
+ /* By default, when ptxas is not in PATH, do minimalistic verification,
|
||||
+ just require that the first non-comment directive is .version. */
|
||||
+ if (verify < 0)
|
||||
+ {
|
||||
+ size_t i;
|
||||
+ for (i = 0; tok[i].kind == K_comment; i++)
|
||||
+ ;
|
||||
+ if (tok[i].kind != K_dotted || !is_keyword (&tok[i], "version"))
|
||||
+ fatal_error ("missing .version directive at start of file '%s'",
|
||||
+ outname);
|
||||
+ }
|
||||
+
|
||||
do
|
||||
tok = parse_file (tok);
|
||||
while (tok->kind);
|
||||
@@ -897,9 +944,83 @@ fork_execute (const char *prog, char *const *argv)
|
||||
do_wait (prog, pex);
|
||||
}
|
||||
|
||||
+/* Determine if progname is available in PATH. */
|
||||
+static bool
|
||||
+program_available (const char *progname)
|
||||
+{
|
||||
+ char *temp = getenv ("PATH");
|
||||
+ if (temp)
|
||||
+ {
|
||||
+ char *startp, *endp, *nstore, *alloc_ptr = NULL;
|
||||
+ size_t prefixlen = strlen (temp) + 1;
|
||||
+ size_t len;
|
||||
+ if (prefixlen < 2)
|
||||
+ prefixlen = 2;
|
||||
+
|
||||
+ len = prefixlen + strlen (progname) + 1;
|
||||
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
|
||||
+ len += strlen (HOST_EXECUTABLE_SUFFIX);
|
||||
+#endif
|
||||
+ if (len < MAX_ALLOCA_SIZE)
|
||||
+ nstore = (char *) alloca (len);
|
||||
+ else
|
||||
+ alloc_ptr = nstore = (char *) malloc (len);
|
||||
+
|
||||
+ startp = endp = temp;
|
||||
+ while (1)
|
||||
+ {
|
||||
+ if (*endp == PATH_SEPARATOR || *endp == 0)
|
||||
+ {
|
||||
+ if (endp == startp)
|
||||
+ {
|
||||
+ nstore[0] = '.';
|
||||
+ nstore[1] = DIR_SEPARATOR;
|
||||
+ nstore[2] = '\0';
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ memcpy (nstore, startp, endp - startp);
|
||||
+ if (! IS_DIR_SEPARATOR (endp[-1]))
|
||||
+ {
|
||||
+ nstore[endp - startp] = DIR_SEPARATOR;
|
||||
+ nstore[endp - startp + 1] = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ nstore[endp - startp] = 0;
|
||||
+ }
|
||||
+ strcat (nstore, progname);
|
||||
+ if (! access (nstore, X_OK)
|
||||
+#ifdef HAVE_HOST_EXECUTABLE_SUFFIX
|
||||
+ || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
|
||||
+#endif
|
||||
+ )
|
||||
+ {
|
||||
+#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
|
||||
+ struct stat st;
|
||||
+ if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
|
||||
+#endif
|
||||
+ {
|
||||
+ free (alloc_ptr);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (*endp == 0)
|
||||
+ break;
|
||||
+ endp = startp = endp + 1;
|
||||
+ }
|
||||
+ else
|
||||
+ endp++;
|
||||
+ }
|
||||
+ free (alloc_ptr);
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static struct option long_options[] = {
|
||||
{"traditional-format", no_argument, 0, 0 },
|
||||
{"save-temps", no_argument, 0, 0 },
|
||||
+ {"verify", no_argument, 0, 0 },
|
||||
{"no-verify", no_argument, 0, 0 },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"version", no_argument, 0, 'V' },
|
||||
@@ -912,7 +1033,7 @@ main (int argc, char **argv)
|
||||
FILE *in = stdin;
|
||||
FILE *out = stdout;
|
||||
bool verbose __attribute__((unused)) = false;
|
||||
- bool verify = true;
|
||||
+ int verify = -1;
|
||||
const char *smver = "sm_30";
|
||||
|
||||
int o;
|
||||
@@ -923,7 +1044,9 @@ main (int argc, char **argv)
|
||||
{
|
||||
case 0:
|
||||
if (option_index == 2)
|
||||
- verify = false;
|
||||
+ verify = 1;
|
||||
+ else if (option_index == 3)
|
||||
+ verify = 0;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
@@ -948,7 +1071,8 @@ Usage: nvptx-none-as [option...] [asmfile]\n\
|
||||
Options:\n\
|
||||
-o FILE Write output to FILE\n\
|
||||
-v Be verbose\n\
|
||||
+ --verify Do verify output is acceptable to ptxas\n\
|
||||
--no-verify Do not verify output is acceptable to ptxas\n\
|
||||
--help Print this help and exit\n\
|
||||
--version Print version number and exit\n\
|
||||
\n\
|
||||
@@ -983,11 +1108,17 @@ This program has absolutely no warranty.\n",
|
||||
if (!in)
|
||||
fatal_error ("cannot open input ptx file");
|
||||
|
||||
- process (in, out);
|
||||
- if (outname)
|
||||
+ if (outname == NULL)
|
||||
+ verify = 0;
|
||||
+ else if (verify == -1)
|
||||
+ if (program_available ("ptxas"))
|
||||
+ verify = 1;
|
||||
+
|
||||
+ process (in, out, verify, outname);
|
||||
+ if (outname)
|
||||
fclose (out);
|
||||
|
||||
- if (verify && outname)
|
||||
+ if (verify > 0)
|
||||
{
|
||||
struct obstack argv_obstack;
|
||||
obstack_init (&argv_obstack);
|
||||
--- nvptx-tools/configure
|
||||
+++ nvptx-tools/configure
|
||||
@@ -168,7 +168,8 @@ test x\$exitcode = x0 || exit 1"
|
||||
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
|
||||
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
|
||||
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
|
||||
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
|
||||
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
|
||||
+test \$(( 1 + 1 )) = 2 || exit 1"
|
||||
if (eval "$as_required") 2>/dev/null; then :
|
||||
as_have_required=yes
|
||||
else
|
||||
@@ -552,11 +553,50 @@ PACKAGE_URL=
|
||||
|
||||
ac_unique_file="nvptx-tools"
|
||||
ac_unique_file="nvptx-as.c"
|
||||
+# Factoring default headers for most tests.
|
||||
+ac_includes_default="\
|
||||
+#include <stdio.h>
|
||||
+#ifdef HAVE_SYS_TYPES_H
|
||||
+# include <sys/types.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_SYS_STAT_H
|
||||
+# include <sys/stat.h>
|
||||
+#endif
|
||||
+#ifdef STDC_HEADERS
|
||||
+# include <stdlib.h>
|
||||
+# include <stddef.h>
|
||||
+#else
|
||||
+# ifdef HAVE_STDLIB_H
|
||||
+# include <stdlib.h>
|
||||
+# endif
|
||||
+#endif
|
||||
+#ifdef HAVE_STRING_H
|
||||
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
|
||||
+# include <memory.h>
|
||||
+# endif
|
||||
+# include <string.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_STRINGS_H
|
||||
+# include <strings.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_INTTYPES_H
|
||||
+# include <inttypes.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_STDINT_H
|
||||
+# include <stdint.h>
|
||||
+#endif
|
||||
+#ifdef HAVE_UNISTD_H
|
||||
+# include <unistd.h>
|
||||
+#endif"
|
||||
+
|
||||
enable_option_checking=no
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
subdirs
|
||||
NVPTX_RUN
|
||||
+EGREP
|
||||
+GREP
|
||||
+CPP
|
||||
CUDA_DRIVER_LDFLAGS
|
||||
CUDA_DRIVER_CPPFLAGS
|
||||
AR
|
||||
@@ -635,7 +675,8 @@ LIBS
|
||||
CPPFLAGS
|
||||
CXX
|
||||
CXXFLAGS
|
||||
-CCC'
|
||||
+CCC
|
||||
+CPP'
|
||||
ac_subdirs_all='libiberty'
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1267,6 +1308,7 @@ Some influential environment variables:
|
||||
you have headers in a nonstandard directory <include dir>
|
||||
CXX C++ compiler command
|
||||
CXXFLAGS C++ compiler flags
|
||||
+ CPP C preprocessor
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@@ -1575,6 +1617,203 @@ $as_echo "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
|
||||
} # ac_fn_c_check_decl
|
||||
+
|
||||
+# ac_fn_c_try_cpp LINENO
|
||||
+# ----------------------
|
||||
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
|
||||
+ac_fn_c_try_cpp ()
|
||||
+{
|
||||
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
|
||||
+case "(($ac_try" in
|
||||
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
+ *) ac_try_echo=$ac_try;;
|
||||
+esac
|
||||
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
+$as_echo "$ac_try_echo"; } >&5
|
||||
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
|
||||
+ ac_status=$?
|
||||
+ if test -s conftest.err; then
|
||||
+ grep -v '^ *+' conftest.err >conftest.er1
|
||||
+ cat conftest.er1 >&5
|
||||
+ mv -f conftest.er1 conftest.err
|
||||
+ fi
|
||||
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
+ test $ac_status = 0; } >/dev/null && {
|
||||
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
+ test ! -s conftest.err
|
||||
+ }; then :
|
||||
+ ac_retval=0
|
||||
+else
|
||||
+ $as_echo "$as_me: failed program was:" >&5
|
||||
+sed 's/^/| /' conftest.$ac_ext >&5
|
||||
+
|
||||
+ ac_retval=1
|
||||
+fi
|
||||
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
+ return $ac_retval
|
||||
+
|
||||
+} # ac_fn_c_try_cpp
|
||||
+
|
||||
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
|
||||
+# -------------------------------------------------------
|
||||
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
|
||||
+# the include files in INCLUDES and setting the cache variable VAR
|
||||
+# accordingly.
|
||||
+ac_fn_c_check_header_mongrel ()
|
||||
+{
|
||||
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
+$as_echo_n "checking for $2... " >&6; }
|
||||
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+fi
|
||||
+eval ac_res=\$$3
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
+$as_echo "$ac_res" >&6; }
|
||||
+else
|
||||
+ # Is the header compilable?
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
|
||||
+$as_echo_n "checking $2 usability... " >&6; }
|
||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+$4
|
||||
+#include <$2>
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_compile "$LINENO"; then :
|
||||
+ ac_header_compiler=yes
|
||||
+else
|
||||
+ ac_header_compiler=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
|
||||
+$as_echo "$ac_header_compiler" >&6; }
|
||||
+
|
||||
+# Is the header present?
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
|
||||
+$as_echo_n "checking $2 presence... " >&6; }
|
||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <$2>
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
+ ac_header_preproc=yes
|
||||
+else
|
||||
+ ac_header_preproc=no
|
||||
+fi
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
|
||||
+$as_echo "$ac_header_preproc" >&6; }
|
||||
+
|
||||
+# So? What about this header?
|
||||
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
|
||||
+ yes:no: )
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
|
||||
+ ;;
|
||||
+ no:yes:* )
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
|
||||
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
|
||||
+ ;;
|
||||
+esac
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
+$as_echo_n "checking for $2... " >&6; }
|
||||
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ eval "$3=\$ac_header_compiler"
|
||||
+fi
|
||||
+eval ac_res=\$$3
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
+$as_echo "$ac_res" >&6; }
|
||||
+fi
|
||||
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
+
|
||||
+} # ac_fn_c_check_header_mongrel
|
||||
+
|
||||
+# ac_fn_c_try_run LINENO
|
||||
+# ----------------------
|
||||
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
|
||||
+# that executables *can* be run.
|
||||
+ac_fn_c_try_run ()
|
||||
+{
|
||||
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
+ if { { ac_try="$ac_link"
|
||||
+case "(($ac_try" in
|
||||
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
+ *) ac_try_echo=$ac_try;;
|
||||
+esac
|
||||
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
+$as_echo "$ac_try_echo"; } >&5
|
||||
+ (eval "$ac_link") 2>&5
|
||||
+ ac_status=$?
|
||||
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
|
||||
+ { { case "(($ac_try" in
|
||||
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
+ *) ac_try_echo=$ac_try;;
|
||||
+esac
|
||||
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||
+$as_echo "$ac_try_echo"; } >&5
|
||||
+ (eval "$ac_try") 2>&5
|
||||
+ ac_status=$?
|
||||
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
+ test $ac_status = 0; }; }; then :
|
||||
+ ac_retval=0
|
||||
+else
|
||||
+ $as_echo "$as_me: program exited with status $ac_status" >&5
|
||||
+ $as_echo "$as_me: failed program was:" >&5
|
||||
+sed 's/^/| /' conftest.$ac_ext >&5
|
||||
+
|
||||
+ ac_retval=$ac_status
|
||||
+fi
|
||||
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
|
||||
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
+ return $ac_retval
|
||||
+
|
||||
+} # ac_fn_c_try_run
|
||||
+
|
||||
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
|
||||
+# -------------------------------------------------------
|
||||
+# Tests whether HEADER exists and can be compiled using the include files in
|
||||
+# INCLUDES, setting the cache variable VAR accordingly.
|
||||
+ac_fn_c_check_header_compile ()
|
||||
+{
|
||||
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
+$as_echo_n "checking for $2... " >&6; }
|
||||
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+$4
|
||||
+#include <$2>
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_compile "$LINENO"; then :
|
||||
+ eval "$3=yes"
|
||||
+else
|
||||
+ eval "$3=no"
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
+fi
|
||||
+eval ac_res=\$$3
|
||||
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
+$as_echo "$ac_res" >&6; }
|
||||
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
|
||||
+
|
||||
+} # ac_fn_c_check_header_compile
|
||||
cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
@@ -3284,6 +3523,418 @@ cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_CUGETERRORSTRING $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
+ac_ext=c
|
||||
+ac_cpp='$CPP $CPPFLAGS'
|
||||
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
|
||||
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
|
||||
+# On Suns, sometimes $CPP names a directory.
|
||||
+if test -n "$CPP" && test -d "$CPP"; then
|
||||
+ CPP=
|
||||
+fi
|
||||
+if test -z "$CPP"; then
|
||||
+ if test "${ac_cv_prog_CPP+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ # Double quotes because CPP needs to be expanded
|
||||
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
|
||||
+ do
|
||||
+ ac_preproc_ok=false
|
||||
+for ac_c_preproc_warn_flag in '' yes
|
||||
+do
|
||||
+ # Use a header file that comes with gcc, so configuring glibc
|
||||
+ # with a fresh cross-compiler works.
|
||||
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
+ # <limits.h> exists even on freestanding compilers.
|
||||
+ # On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
+ # not just through cpp. "Syntax error" is here to catch this case.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#ifdef __STDC__
|
||||
+# include <limits.h>
|
||||
+#else
|
||||
+# include <assert.h>
|
||||
+#endif
|
||||
+ Syntax error
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
+
|
||||
+else
|
||||
+ # Broken: fails on valid input.
|
||||
+continue
|
||||
+fi
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+
|
||||
+ # OK, works on sane cases. Now check whether nonexistent headers
|
||||
+ # can be detected and how.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <ac_nonexistent.h>
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
+ # Broken: success on invalid input.
|
||||
+continue
|
||||
+else
|
||||
+ # Passes both tests.
|
||||
+ac_preproc_ok=:
|
||||
+break
|
||||
+fi
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+
|
||||
+done
|
||||
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+if $ac_preproc_ok; then :
|
||||
+ break
|
||||
+fi
|
||||
+
|
||||
+ done
|
||||
+ ac_cv_prog_CPP=$CPP
|
||||
+
|
||||
+fi
|
||||
+ CPP=$ac_cv_prog_CPP
|
||||
+else
|
||||
+ ac_cv_prog_CPP=$CPP
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
|
||||
+$as_echo "$CPP" >&6; }
|
||||
+ac_preproc_ok=false
|
||||
+for ac_c_preproc_warn_flag in '' yes
|
||||
+do
|
||||
+ # Use a header file that comes with gcc, so configuring glibc
|
||||
+ # with a fresh cross-compiler works.
|
||||
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
|
||||
+ # <limits.h> exists even on freestanding compilers.
|
||||
+ # On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
+ # not just through cpp. "Syntax error" is here to catch this case.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#ifdef __STDC__
|
||||
+# include <limits.h>
|
||||
+#else
|
||||
+# include <assert.h>
|
||||
+#endif
|
||||
+ Syntax error
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
+
|
||||
+else
|
||||
+ # Broken: fails on valid input.
|
||||
+continue
|
||||
+fi
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+
|
||||
+ # OK, works on sane cases. Now check whether nonexistent headers
|
||||
+ # can be detected and how.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <ac_nonexistent.h>
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_cpp "$LINENO"; then :
|
||||
+ # Broken: success on invalid input.
|
||||
+continue
|
||||
+else
|
||||
+ # Passes both tests.
|
||||
+ac_preproc_ok=:
|
||||
+break
|
||||
+fi
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+
|
||||
+done
|
||||
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
|
||||
+rm -f conftest.err conftest.$ac_ext
|
||||
+if $ac_preproc_ok; then :
|
||||
+
|
||||
+else
|
||||
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
|
||||
+See \`config.log' for more details." "$LINENO" 5; }
|
||||
+fi
|
||||
+
|
||||
+ac_ext=c
|
||||
+ac_cpp='$CPP $CPPFLAGS'
|
||||
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
+
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
|
||||
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
|
||||
+if test "${ac_cv_path_GREP+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ if test -z "$GREP"; then
|
||||
+ ac_path_GREP_found=false
|
||||
+ # Loop through the user's path and test for each of PROGNAME-LIST
|
||||
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
|
||||
+do
|
||||
+ IFS=$as_save_IFS
|
||||
+ test -z "$as_dir" && as_dir=.
|
||||
+ for ac_prog in grep ggrep; do
|
||||
+ for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
|
||||
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
|
||||
+# Check for GNU ac_path_GREP and select it if it is found.
|
||||
+ # Check for GNU $ac_path_GREP
|
||||
+case `"$ac_path_GREP" --version 2>&1` in
|
||||
+*GNU*)
|
||||
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
|
||||
+*)
|
||||
+ ac_count=0
|
||||
+ $as_echo_n 0123456789 >"conftest.in"
|
||||
+ while :
|
||||
+ do
|
||||
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
|
||||
+ mv "conftest.tmp" "conftest.in"
|
||||
+ cp "conftest.in" "conftest.nl"
|
||||
+ $as_echo 'GREP' >> "conftest.nl"
|
||||
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
|
||||
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
|
||||
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
|
||||
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
|
||||
+ # Best one so far, save it but keep looking for a better one
|
||||
+ ac_cv_path_GREP="$ac_path_GREP"
|
||||
+ ac_path_GREP_max=$ac_count
|
||||
+ fi
|
||||
+ # 10*(2^10) chars as input seems more than enough
|
||||
+ test $ac_count -gt 10 && break
|
||||
+ done
|
||||
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
|
||||
+esac
|
||||
+
|
||||
+ $ac_path_GREP_found && break 3
|
||||
+ done
|
||||
+ done
|
||||
+ done
|
||||
+IFS=$as_save_IFS
|
||||
+ if test -z "$ac_cv_path_GREP"; then
|
||||
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
|
||||
+ fi
|
||||
+else
|
||||
+ ac_cv_path_GREP=$GREP
|
||||
+fi
|
||||
+
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
|
||||
+$as_echo "$ac_cv_path_GREP" >&6; }
|
||||
+ GREP="$ac_cv_path_GREP"
|
||||
+
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
|
||||
+$as_echo_n "checking for egrep... " >&6; }
|
||||
+if test "${ac_cv_path_EGREP+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
|
||||
+ then ac_cv_path_EGREP="$GREP -E"
|
||||
+ else
|
||||
+ if test -z "$EGREP"; then
|
||||
+ ac_path_EGREP_found=false
|
||||
+ # Loop through the user's path and test for each of PROGNAME-LIST
|
||||
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
|
||||
+do
|
||||
+ IFS=$as_save_IFS
|
||||
+ test -z "$as_dir" && as_dir=.
|
||||
+ for ac_prog in egrep; do
|
||||
+ for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
|
||||
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
|
||||
+# Check for GNU ac_path_EGREP and select it if it is found.
|
||||
+ # Check for GNU $ac_path_EGREP
|
||||
+case `"$ac_path_EGREP" --version 2>&1` in
|
||||
+*GNU*)
|
||||
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
|
||||
+*)
|
||||
+ ac_count=0
|
||||
+ $as_echo_n 0123456789 >"conftest.in"
|
||||
+ while :
|
||||
+ do
|
||||
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
|
||||
+ mv "conftest.tmp" "conftest.in"
|
||||
+ cp "conftest.in" "conftest.nl"
|
||||
+ $as_echo 'EGREP' >> "conftest.nl"
|
||||
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
|
||||
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
|
||||
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
|
||||
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
|
||||
+ # Best one so far, save it but keep looking for a better one
|
||||
+ ac_cv_path_EGREP="$ac_path_EGREP"
|
||||
+ ac_path_EGREP_max=$ac_count
|
||||
+ fi
|
||||
+ # 10*(2^10) chars as input seems more than enough
|
||||
+ test $ac_count -gt 10 && break
|
||||
+ done
|
||||
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
|
||||
+esac
|
||||
+
|
||||
+ $ac_path_EGREP_found && break 3
|
||||
+ done
|
||||
+ done
|
||||
+ done
|
||||
+IFS=$as_save_IFS
|
||||
+ if test -z "$ac_cv_path_EGREP"; then
|
||||
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
|
||||
+ fi
|
||||
+else
|
||||
+ ac_cv_path_EGREP=$EGREP
|
||||
+fi
|
||||
+
|
||||
+ fi
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
|
||||
+$as_echo "$ac_cv_path_EGREP" >&6; }
|
||||
+ EGREP="$ac_cv_path_EGREP"
|
||||
+
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
|
||||
+$as_echo_n "checking for ANSI C header files... " >&6; }
|
||||
+if test "${ac_cv_header_stdc+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <stdlib.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <string.h>
|
||||
+#include <float.h>
|
||||
+
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+
|
||||
+ ;
|
||||
+ return 0;
|
||||
+}
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_compile "$LINENO"; then :
|
||||
+ ac_cv_header_stdc=yes
|
||||
+else
|
||||
+ ac_cv_header_stdc=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
+
|
||||
+if test $ac_cv_header_stdc = yes; then
|
||||
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <string.h>
|
||||
+
|
||||
+_ACEOF
|
||||
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
+ $EGREP "memchr" >/dev/null 2>&1; then :
|
||||
+
|
||||
+else
|
||||
+ ac_cv_header_stdc=no
|
||||
+fi
|
||||
+rm -f conftest*
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+if test $ac_cv_header_stdc = yes; then
|
||||
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+_ACEOF
|
||||
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
||||
+ $EGREP "free" >/dev/null 2>&1; then :
|
||||
+
|
||||
+else
|
||||
+ ac_cv_header_stdc=no
|
||||
+fi
|
||||
+rm -f conftest*
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+if test $ac_cv_header_stdc = yes; then
|
||||
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
|
||||
+ if test "$cross_compiling" = yes; then :
|
||||
+ :
|
||||
+else
|
||||
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+#include <ctype.h>
|
||||
+#include <stdlib.h>
|
||||
+#if ((' ' & 0x0FF) == 0x020)
|
||||
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
|
||||
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
|
||||
+#else
|
||||
+# define ISLOWER(c) \
|
||||
+ (('a' <= (c) && (c) <= 'i') \
|
||||
+ || ('j' <= (c) && (c) <= 'r') \
|
||||
+ || ('s' <= (c) && (c) <= 'z'))
|
||||
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
|
||||
+#endif
|
||||
+
|
||||
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < 256; i++)
|
||||
+ if (XOR (islower (i), ISLOWER (i))
|
||||
+ || toupper (i) != TOUPPER (i))
|
||||
+ return 2;
|
||||
+ return 0;
|
||||
+}
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_run "$LINENO"; then :
|
||||
+
|
||||
+else
|
||||
+ ac_cv_header_stdc=no
|
||||
+fi
|
||||
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
|
||||
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
+fi
|
||||
+
|
||||
+fi
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
|
||||
+$as_echo "$ac_cv_header_stdc" >&6; }
|
||||
+if test $ac_cv_header_stdc = yes; then
|
||||
+
|
||||
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
|
||||
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
|
||||
+ inttypes.h stdint.h unistd.h
|
||||
+do :
|
||||
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
+"
|
||||
+eval as_val=\$$as_ac_Header
|
||||
+ if test "x$as_val" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
+_ACEOF
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+done
|
||||
+
|
||||
+
|
||||
+for ac_header in unistd.h sys/stat.h
|
||||
+do :
|
||||
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
||||
+eval as_val=\$$as_ac_Header
|
||||
+ if test "x$as_val" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
|
||||
+_ACEOF
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+done
|
||||
+
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for extra programs to build requiring -lcuda" >&5
|
||||
$as_echo_n "checking for extra programs to build requiring -lcuda... " >&6; }
|
File diff suppressed because it is too large
Load Diff
62
gcc14-Wno-format-security.patch
Normal file
62
gcc14-Wno-format-security.patch
Normal file
@ -0,0 +1,62 @@
|
||||
2022-01-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* Makefile.tpl (GOCFLAGS, GDCFLAGS): Filter out -Wformat-security.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
2017-02-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.ac: When adding -Wno-format, also add -Wno-format-security.
|
||||
* configure: Regenerated.
|
||||
|
||||
--- gcc/configure.ac.jj 2017-02-13 12:20:53.000000000 +0100
|
||||
+++ gcc/configure.ac 2017-02-25 12:42:32.859175403 +0100
|
||||
@@ -570,7 +570,7 @@ AC_ARG_ENABLE(build-format-warnings,
|
||||
AS_HELP_STRING([--disable-build-format-warnings],[don't use -Wformat while building GCC]),
|
||||
[],[enable_build_format_warnings=yes])
|
||||
AS_IF([test $enable_build_format_warnings = no],
|
||||
- [wf_opt=-Wno-format],[wf_opt=])
|
||||
+ [wf_opt="-Wno-format -Wno-format-security"],[wf_opt=])
|
||||
ACX_PROG_CXX_WARNING_OPTS(
|
||||
m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings ],
|
||||
[-Wcast-qual $wf_opt])),
|
||||
--- gcc/configure.jj 2017-02-13 12:20:52.000000000 +0100
|
||||
+++ gcc/configure 2017-02-25 12:42:50.041946391 +0100
|
||||
@@ -7077,7 +7077,7 @@ else
|
||||
fi
|
||||
|
||||
if test $enable_build_format_warnings = no; then :
|
||||
- wf_opt=-Wno-format
|
||||
+ wf_opt="-Wno-format -Wno-format-security"
|
||||
else
|
||||
wf_opt=
|
||||
fi
|
||||
--- Makefile.tpl.jj 2023-11-29 13:21:41.680292662 +0100
|
||||
+++ Makefile.tpl 2023-11-29 13:23:24.677839321 +0100
|
||||
@@ -448,9 +448,9 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBCFLAGS = $(CFLAGS)
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
|
||||
-GOCFLAGS = $(CFLAGS)
|
||||
-GDCFLAGS = @GDCFLAGS@
|
||||
-GM2FLAGS = $(CFLAGS)
|
||||
+GOCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
|
||||
+GDCFLAGS = $(filter-out -Wformat-security,@GDCFLAGS@)
|
||||
+GM2FLAGS = $(filter-out -Wformat-security,$(CFLAGS))
|
||||
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
|
||||
--- Makefile.in.jj 2023-11-29 13:21:41.691292507 +0100
|
||||
+++ Makefile.in 2023-11-29 13:24:01.254323180 +0100
|
||||
@@ -445,9 +445,9 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBCFLAGS = $(CFLAGS)
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
|
||||
-GOCFLAGS = $(CFLAGS)
|
||||
-GDCFLAGS = @GDCFLAGS@
|
||||
-GM2FLAGS = $(CFLAGS)
|
||||
+GOCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
|
||||
+GDCFLAGS = $(filter-out -Wformat-security,@GDCFLAGS@)
|
||||
+GM2FLAGS = $(filter-out -Wformat-security,$(CFLAGS))
|
||||
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
|
20
gcc14-d-shared-libphobos.patch
Normal file
20
gcc14-d-shared-libphobos.patch
Normal file
@ -0,0 +1,20 @@
|
||||
2019-01-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* d-spec.cc (lang_specific_driver): Make -shared-libphobos
|
||||
the default rather than -static-libphobos.
|
||||
|
||||
--- gcc/d/d-spec.cc.jj 2019-01-01 12:37:49.502444257 +0100
|
||||
+++ gcc/d/d-spec.cc 2019-01-17 17:09:45.364949246 +0100
|
||||
@@ -408,9 +408,9 @@ lang_specific_driver (cl_decoded_option
|
||||
/* Add `-lgphobos' if we haven't already done so. */
|
||||
if (phobos_library != PHOBOS_NOLINK)
|
||||
{
|
||||
- /* Default to static linking. */
|
||||
- if (phobos_library != PHOBOS_DYNAMIC)
|
||||
- phobos_library = PHOBOS_STATIC;
|
||||
+ /* Default to shared linking. */
|
||||
+ if (phobos_library != PHOBOS_STATIC)
|
||||
+ phobos_library = PHOBOS_DYNAMIC;
|
||||
|
||||
#ifdef HAVE_LD_STATIC_DYNAMIC
|
||||
if (phobos_library == PHOBOS_STATIC && !static_link)
|
215
gcc14-fortran-fdec-duplicates.patch
Normal file
215
gcc14-fortran-fdec-duplicates.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From 23b1fcb104c666429451ffaf936f8da5fcd3d43a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Eggleston <markeggleston@gcc.gnu.org>
|
||||
Date: Fri, 22 Jan 2021 12:29:47 +0000
|
||||
Subject: [PATCH 01/10] Allow duplicate declarations.
|
||||
|
||||
Enabled by -fdec-duplicates and -fdec.
|
||||
|
||||
Some fixes by Jim MacArthur <jim.macarthur@codethink.co.uk>
|
||||
Addition of -fdec-duplicates by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
---
|
||||
gcc/fortran/lang.opt | 4 ++++
|
||||
gcc/fortran/options.cc | 1 +
|
||||
gcc/fortran/symbol.cc | 21 +++++++++++++++++--
|
||||
.../gfortran.dg/duplicate_type_4.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_5.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_6.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_7.f90 | 13 ++++++++++++
|
||||
.../gfortran.dg/duplicate_type_8.f90 | 12 +++++++++++
|
||||
.../gfortran.dg/duplicate_type_9.f90 | 12 +++++++++++
|
||||
9 files changed, 100 insertions(+), 2 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
|
||||
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
|
||||
index 2b1977c523b..52bd522051e 100644
|
||||
--- a/gcc/fortran/lang.opt
|
||||
+++ b/gcc/fortran/lang.opt
|
||||
@@ -469,6 +469,10 @@ Fortran Var(flag_dec_char_conversions)
|
||||
Enable the use of character literals in assignments and data statements
|
||||
for non-character variables.
|
||||
|
||||
+fdec-duplicates
|
||||
+Fortran Var(flag_dec_duplicates)
|
||||
+Allow varibles to be duplicated in the type specification matches.
|
||||
+
|
||||
fdec-include
|
||||
Fortran Var(flag_dec_include)
|
||||
Enable legacy parsing of INCLUDE as statement.
|
||||
diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc
|
||||
index 3a0b98bf1ec..f19ba87f8a0 100644
|
||||
--- a/gcc/fortran/options.cc
|
||||
+++ b/gcc/fortran/options.cc
|
||||
@@ -77,6 +77,7 @@ set_dec_flags (int value)
|
||||
SET_BITFLAG (flag_dec_format_defaults, value, value);
|
||||
SET_BITFLAG (flag_dec_blank_format_item, value, value);
|
||||
SET_BITFLAG (flag_dec_char_conversions, value, value);
|
||||
+ SET_BITFLAG (flag_dec_duplicates, value, value);
|
||||
}
|
||||
|
||||
/* Finalize DEC flags. */
|
||||
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
|
||||
index 3b988d1be22..9843175cc2a 100644
|
||||
--- a/gcc/fortran/symbol.cc
|
||||
+++ b/gcc/fortran/symbol.cc
|
||||
@@ -1995,6 +1995,8 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
if (sym->attr.result && type == BT_UNKNOWN && sym->ns->proc_name)
|
||||
type = sym->ns->proc_name->ts.type;
|
||||
|
||||
+ flavor = sym->attr.flavor;
|
||||
+
|
||||
if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type)
|
||||
&& !(gfc_state_stack->previous && gfc_state_stack->previous->previous
|
||||
&& gfc_state_stack->previous->previous->state == COMP_SUBMODULE)
|
||||
@@ -2007,6 +2009,23 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
else if (sym->attr.function && sym->attr.result)
|
||||
gfc_error ("Symbol %qs at %L already has basic type of %s",
|
||||
sym->ns->proc_name->name, where, gfc_basic_typename (type));
|
||||
+ else if (flag_dec_duplicates)
|
||||
+ {
|
||||
+ /* Ignore temporaries and class/procedure names */
|
||||
+ if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS
|
||||
+ || sym->ts.type == BT_PROCEDURE)
|
||||
+ return false;
|
||||
+
|
||||
+ if (gfc_compare_types (&sym->ts, ts)
|
||||
+ && (flavor == FL_UNKNOWN || flavor == FL_VARIABLE
|
||||
+ || flavor == FL_PROCEDURE))
|
||||
+ {
|
||||
+ return gfc_notify_std (GFC_STD_LEGACY,
|
||||
+ "Symbol '%qs' at %L already has "
|
||||
+ "basic type of %s", sym->name, where,
|
||||
+ gfc_basic_typename (type));
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
gfc_error ("Symbol %qs at %L already has basic type of %s", sym->name,
|
||||
where, gfc_basic_typename (type));
|
||||
@@ -2020,8 +2039,6 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
|
||||
return false;
|
||||
}
|
||||
|
||||
- flavor = sym->attr.flavor;
|
||||
-
|
||||
if (flavor == FL_PROGRAM || flavor == FL_BLOCK_DATA || flavor == FL_MODULE
|
||||
|| flavor == FL_LABEL
|
||||
|| (flavor == FL_PROCEDURE && sym->attr.subroutine)
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_4.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
new file mode 100644
|
||||
index 00000000000..cdd29ea8846
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-std=f95" }
|
||||
+
|
||||
+! PR fortran/30239
|
||||
+! Check for errors when a symbol gets declared a type twice, even if it
|
||||
+! is the same.
|
||||
+
|
||||
+INTEGER FUNCTION foo ()
|
||||
+ IMPLICIT NONE
|
||||
+ INTEGER :: x
|
||||
+ INTEGER :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+END FUNCTION foo
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_5.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
new file mode 100644
|
||||
index 00000000000..00f931809aa
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_6.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
new file mode 100644
|
||||
index 00000000000..f0df27e323c
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-std=legacy -fdec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_7.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
new file mode 100644
|
||||
index 00000000000..f32472ff586
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
|
||||
@@ -0,0 +1,13 @@
|
||||
+! { dg-do run }
|
||||
+! { dg-options "-fdec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+program test
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x! { dg-warning "Legacy Extension" }
|
||||
+ x = 42
|
||||
+ if (x /= 42) stop 1
|
||||
+end program test
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_8.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
new file mode 100644
|
||||
index 00000000000..23c94add179
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
|
||||
@@ -0,0 +1,12 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec -fno-dec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+integer function foo ()
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+end function foo
|
||||
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_9.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
new file mode 100644
|
||||
index 00000000000..d5edee4d8ee
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
|
||||
@@ -0,0 +1,12 @@
|
||||
+! { dg-do compile }
|
||||
+! { dg-options "-fdec-duplicates -fno-dec-duplicates" }
|
||||
+!
|
||||
+! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
|
||||
+!
|
||||
+
|
||||
+integer function foo ()
|
||||
+ implicit none
|
||||
+ integer :: x
|
||||
+ integer :: x ! { dg-error "basic type of" }
|
||||
+ x = 42
|
||||
+end function foo
|
||||
--
|
||||
2.27.0
|
||||
|
@ -1,8 +1,8 @@
|
||||
--- libada/Makefile.in.jj 2009-01-14 12:07:35.000000000 +0100
|
||||
+++ libada/Makefile.in 2009-01-15 14:25:33.000000000 +0100
|
||||
@@ -66,18 +66,40 @@ libsubdir := $(libdir)/gcc/$(target_nonc
|
||||
--- libada/Makefile.in.jj 2019-01-09 13:01:18.015608205 +0100
|
||||
+++ libada/Makefile.in 2019-01-11 18:16:23.441726931 +0100
|
||||
@@ -71,18 +71,40 @@ version := $(shell @get_gcc_base_ver@ $(
|
||||
libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)$(MULTISUBDIR)
|
||||
ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR))
|
||||
ADA_RTS_SUBDIR=./rts$(subst /,_,$(MULTISUBDIR))
|
||||
|
||||
+DEFAULTMULTIFLAGS :=
|
||||
+ifeq ($(MULTISUBDIR),)
|
||||
@ -45,17 +45,17 @@
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG)" \
|
||||
"THREAD_KIND=$(THREAD_KIND)" \
|
||||
"TRACE=$(TRACE)" \
|
||||
@@ -88,7 +110,7 @@ LIBADA_FLAGS_TO_PASS = \
|
||||
@@ -93,7 +115,7 @@ LIBADA_FLAGS_TO_PASS = \
|
||||
"exeext=.exeext.should.not.be.used " \
|
||||
'CC=the.host.compiler.should.not.be.needed' \
|
||||
"GCC_FOR_TARGET=$(CC)" \
|
||||
- "CFLAGS=$(CFLAGS)"
|
||||
+ "CFLAGS=$(CFLAGS) $(DEFAULTMULTIFLAGS)"
|
||||
|
||||
# Rules to build gnatlib.
|
||||
.PHONY: gnatlib gnatlib-plain gnatlib-sjlj gnatlib-zcx gnatlib-shared osconstool
|
||||
--- config-ml.in.jj 2010-06-30 09:50:44.000000000 +0200
|
||||
+++ config-ml.in 2010-07-02 21:24:17.994211151 +0200
|
||||
.PHONY: libada gnatlib gnatlib-shared gnatlib-sjlj gnatlib-zcx osconstool
|
||||
|
||||
--- config-ml.in.jj 2019-01-09 12:50:16.646501448 +0100
|
||||
+++ config-ml.in 2019-01-11 18:16:23.442726914 +0100
|
||||
@@ -511,6 +511,8 @@ multi-do:
|
||||
ADAFLAGS="$(ADAFLAGS) $${flags}" \
|
||||
prefix="$(prefix)" \
|
||||
@ -63,42 +63,44 @@
|
||||
+ mandir="$(mandir)" \
|
||||
+ infodir="$(infodir)" \
|
||||
GOCFLAGS="$(GOCFLAGS) $${flags}" \
|
||||
GDCFLAGS="$(GDCFLAGS) $${flags}" \
|
||||
CXXFLAGS="$(CXXFLAGS) $${flags}" \
|
||||
LIBCFLAGS="$(LIBCFLAGS) $${flags}" \
|
||||
--- libcpp/macro.c.jj 2015-01-14 11:01:34.000000000 +0100
|
||||
+++ libcpp/macro.c 2015-01-14 14:22:19.286949884 +0100
|
||||
@@ -2947,8 +2947,6 @@ create_iso_definition (cpp_reader *pfile
|
||||
cpp_token *token;
|
||||
const cpp_token *ctoken;
|
||||
--- libcpp/macro.cc.jj 2019-01-09 13:01:21.420552123 +0100
|
||||
+++ libcpp/macro.cc 2019-01-11 18:18:17.736876285 +0100
|
||||
@@ -3256,8 +3256,6 @@ static cpp_macro *
|
||||
create_iso_definition (cpp_reader *pfile)
|
||||
{
|
||||
bool following_paste_op = false;
|
||||
- const char *paste_op_error_msg =
|
||||
- N_("'##' cannot appear at either end of a macro expansion");
|
||||
unsigned int num_extra_tokens = 0;
|
||||
|
||||
/* Get the first token of the expansion (or the '(' of a
|
||||
@@ -3059,7 +3057,8 @@ create_iso_definition (cpp_reader *pfile
|
||||
unsigned nparms = 0;
|
||||
cpp_hashnode **params = NULL;
|
||||
@@ -3382,7 +3380,9 @@ create_iso_definition (cpp_reader *pfile
|
||||
function-like macros, but not at the end. */
|
||||
if (following_paste_op)
|
||||
{
|
||||
- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
|
||||
+ cpp_error (pfile, CPP_DL_ERROR,
|
||||
+ "'##' cannot appear at either end of a macro expansion");
|
||||
return false;
|
||||
+ "'##' cannot appear at either end of a macro "
|
||||
+ "expansion");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@@ -3072,7 +3071,8 @@ create_iso_definition (cpp_reader *pfile
|
||||
if (!vaopt_tracker.completed ())
|
||||
@@ -3397,7 +3397,9 @@ create_iso_definition (cpp_reader *pfile
|
||||
function-like macros, but not at the beginning. */
|
||||
if (macro->count == 1)
|
||||
{
|
||||
- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
|
||||
+ cpp_error (pfile, CPP_DL_ERROR,
|
||||
+ "'##' cannot appear at either end of a macro expansion");
|
||||
return false;
|
||||
+ "'##' cannot appear at either end of a macro "
|
||||
+ "expansion");
|
||||
goto out;
|
||||
}
|
||||
|
||||
--- libcpp/expr.c.jj 2015-01-14 11:01:34.000000000 +0100
|
||||
+++ libcpp/expr.c 2015-01-14 14:35:52.851002344 +0100
|
||||
@@ -672,16 +672,17 @@ cpp_classify_number (cpp_reader *pfile,
|
||||
--- libcpp/expr.cc.jj 2019-01-09 13:01:22.415535734 +0100
|
||||
+++ libcpp/expr.cc 2019-01-11 18:16:23.444726882 +0100
|
||||
@@ -803,16 +803,17 @@ cpp_classify_number (cpp_reader *pfile,
|
||||
if ((result & CPP_N_WIDTH) == CPP_N_LARGE
|
||||
&& CPP_OPTION (pfile, cpp_warn_long_long))
|
||||
{
|
||||
@ -121,4 +123,4 @@
|
||||
+ : N_("use of C99 long long integer constant"));
|
||||
}
|
||||
|
||||
result |= CPP_N_INTEGER;
|
||||
if ((result & CPP_N_SIZE_T) == CPP_N_SIZE_T
|
@ -1,15 +1,15 @@
|
||||
--- gcc/Makefile.in.jj 2015-06-06 10:00:25.000000000 +0200
|
||||
+++ gcc/Makefile.in 2015-11-04 14:56:02.643536437 +0100
|
||||
@@ -1046,7 +1046,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
|
||||
@@ -1063,7 +1063,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
|
||||
# and the system's installed libraries.
|
||||
LIBS = @LIBS@ libcommon.a $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBBACKTRACE) \
|
||||
$(LIBIBERTY) $(LIBDECNUMBER) $(HOST_LIBS)
|
||||
-BACKENDLIBS = $(ISLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
|
||||
+BACKENDLIBS = $(if $(ISLLIBS),-ldl) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
|
||||
$(ZLIB)
|
||||
$(ZLIB) $(ZSTD_LIB)
|
||||
# Any system libraries needed just for GNAT.
|
||||
SYSLIBS = @GNAT_LIBEXC@
|
||||
@@ -2196,6 +2196,15 @@ $(out_object_file): $(out_file)
|
||||
@@ -2302,6 +2302,15 @@ $(out_object_file): $(out_file)
|
||||
$(common_out_object_file): $(common_out_file)
|
||||
$(COMPILE) $<
|
||||
$(POSTCOMPILE)
|
||||
@ -26,11 +26,11 @@
|
||||
# Generate header and source files from the machine description,
|
||||
# and compile them.
|
||||
--- gcc/graphite.h.jj 2016-01-27 12:44:06.000000000 +0100
|
||||
+++ gcc/graphite.h 2016-01-27 13:26:38.309876856 +0100
|
||||
@@ -39,6 +39,590 @@ along with GCC; see the file COPYING3.
|
||||
#include <isl/schedule_node.h>
|
||||
#include <isl/id.h>
|
||||
#include <isl/space.h>
|
||||
+++ gcc/graphite.h 2022-11-03 19:14:50.369690720 +0100
|
||||
@@ -24,6 +24,591 @@ along with GCC; see the file COPYING3.
|
||||
|
||||
#include "sese.h"
|
||||
|
||||
+#include <isl/version.h>
|
||||
+#include <dlfcn.h>
|
||||
+
|
||||
@ -41,15 +41,15 @@
|
||||
+ DYNSYM (isl_aff_set_coefficient_si); \
|
||||
+ DYNSYM (isl_aff_set_constant_si); \
|
||||
+ DYNSYM (isl_aff_zero_on_domain); \
|
||||
+ DYNSYM (isl_band_free); \
|
||||
+ DYNSYM (isl_band_get_children); \
|
||||
+ DYNSYM (isl_band_get_partial_schedule); \
|
||||
+ DYNSYM (isl_band_has_children); \
|
||||
+ DYNSYM (isl_band_list_free); \
|
||||
+ DYNSYM (isl_band_list_get_band); \
|
||||
+ DYNSYM (isl_band_list_get_ctx); \
|
||||
+ DYNSYM (isl_band_list_n_band); \
|
||||
+ DYNSYM (isl_band_n_member); \
|
||||
+ /* DYNSYM (isl_band_free); */ \
|
||||
+ /* DYNSYM (isl_band_get_children); */ \
|
||||
+ /* DYNSYM (isl_band_get_partial_schedule); */ \
|
||||
+ /* DYNSYM (isl_band_has_children); */ \
|
||||
+ /* DYNSYM (isl_band_list_free); */ \
|
||||
+ /* DYNSYM (isl_band_list_get_band); */ \
|
||||
+ /* DYNSYM (isl_band_list_get_ctx); */ \
|
||||
+ /* DYNSYM (isl_band_list_n_band); */ \
|
||||
+ /* DYNSYM (isl_band_n_member); */ \
|
||||
+ DYNSYM (isl_basic_map_add_constraint); \
|
||||
+ DYNSYM (isl_basic_map_project_out); \
|
||||
+ DYNSYM (isl_basic_map_universe); \
|
||||
@ -91,7 +91,7 @@
|
||||
+ DYNSYM (isl_map_is_empty); \
|
||||
+ DYNSYM (isl_map_lex_ge); \
|
||||
+ DYNSYM (isl_map_lex_le); \
|
||||
+ DYNSYM (isl_map_n_out); \
|
||||
+ /* DYNSYM (isl_map_n_out); */ \
|
||||
+ DYNSYM (isl_map_range); \
|
||||
+ DYNSYM (isl_map_set_tuple_id); \
|
||||
+ DYNSYM (isl_map_universe); \
|
||||
@ -124,7 +124,7 @@
|
||||
+ DYNSYM (isl_pw_aff_sub); \
|
||||
+ DYNSYM (isl_pw_aff_zero_set); \
|
||||
+ DYNSYM (isl_schedule_free); \
|
||||
+ DYNSYM (isl_schedule_get_band_forest); \
|
||||
+ /* DYNSYM (isl_schedule_get_band_forest); */ \
|
||||
+ DYNSYM (isl_set_add_constraint); \
|
||||
+ DYNSYM (isl_set_add_dims); \
|
||||
+ DYNSYM (isl_set_apply); \
|
||||
@ -615,20 +615,21 @@
|
||||
+#define isl_version (*isl_pointers__.p_isl_version)
|
||||
+#define isl_options_get_on_error (*isl_pointers__.p_isl_options_get_on_error)
|
||||
+#define isl_ctx_reset_error (*isl_pointers__.p_isl_ctx_reset_error)
|
||||
|
||||
+
|
||||
typedef struct poly_dr *poly_dr_p;
|
||||
|
||||
@@ -461,5 +1045,6 @@ extern void build_scops (vec<scop_p> *);
|
||||
typedef struct poly_bb *poly_bb_p;
|
||||
@@ -448,5 +1033,6 @@ extern tree cached_scalar_evolution_in_r
|
||||
extern void dot_all_sese (FILE *, vec<sese_l> &);
|
||||
extern void dot_sese (sese_l &);
|
||||
extern void dot_cfg ();
|
||||
+extern const char *get_isl_version (bool);
|
||||
|
||||
#endif
|
||||
--- gcc/graphite.c.jj 2015-11-04 14:15:32.000000000 +0100
|
||||
+++ gcc/graphite.c 2015-11-04 14:56:02.645536409 +0100
|
||||
--- gcc/graphite.cc.jj 2015-11-04 14:15:32.000000000 +0100
|
||||
+++ gcc/graphite.cc 2015-11-04 14:56:02.645536409 +0100
|
||||
@@ -60,6 +60,35 @@ along with GCC; see the file COPYING3.
|
||||
#include "tree-into-ssa.h"
|
||||
#include "tree-ssa-propagate.h"
|
||||
#include "graphite.h"
|
||||
|
||||
+__typeof (isl_pointers__) isl_pointers__;
|
||||
@ -640,7 +641,7 @@
|
||||
+
|
||||
+ if (isl_pointers__.inited)
|
||||
+ return isl_pointers__.h != NULL;
|
||||
+ h = dlopen ("libisl.so.15", RTLD_LAZY);
|
||||
+ h = dlopen ("libisl.so.23", RTLD_LAZY);
|
||||
+ isl_pointers__.h = h;
|
||||
+ if (h == NULL)
|
||||
+ return false;
|
||||
@ -663,7 +664,7 @@
|
||||
/* Print global statistics to FILE. */
|
||||
|
||||
static void
|
||||
@@ -365,6 +394,15 @@ graphite_transform_loops (void)
|
||||
@@ -424,6 +453,15 @@ graphite_transform_loops (void)
|
||||
if (parallelized_function_p (cfun->decl))
|
||||
return;
|
||||
|
||||
@ -679,7 +680,7 @@
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* We rely on post-dominators during merging of SESE regions so those
|
||||
@@ -455,6 +493,14 @@ graphite_transform_loops (void)
|
||||
@@ -519,6 +557,14 @@ graphite_transform_loops (void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,8 +695,8 @@
|
||||
#else /* If isl is not available: #ifndef HAVE_isl. */
|
||||
|
||||
static void
|
||||
--- gcc/toplev.c.jj 2017-02-19 13:02:31.000000000 +0100
|
||||
+++ gcc/toplev.c 2017-02-19 16:50:25.536301350 +0100
|
||||
--- gcc/toplev.cc.jj 2017-02-19 13:02:31.000000000 +0100
|
||||
+++ gcc/toplev.cc 2017-02-19 16:50:25.536301350 +0100
|
||||
@@ -94,6 +94,7 @@ along with GCC; see the file COPYING3.
|
||||
|
||||
#ifdef HAVE_isl
|
71
gcc14-isl-dl2.patch
Normal file
71
gcc14-isl-dl2.patch
Normal file
@ -0,0 +1,71 @@
|
||||
2011-04-04 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* toplev.cc (toplev_main_argv): New variable.
|
||||
(toplev_main): Initialize it.
|
||||
* graphite.cc (init_isl_pointers): Load libisl.so.23 from gcc's private
|
||||
directory.
|
||||
|
||||
--- gcc/toplev.cc.jj 2008-12-09 23:59:10.000000000 +0100
|
||||
+++ gcc/toplev.cc 2009-01-27 14:33:52.000000000 +0100
|
||||
@@ -113,6 +113,8 @@ static void finalize (bool);
|
||||
static void crash_signal (int) ATTRIBUTE_NORETURN;
|
||||
static void compile_file (void);
|
||||
|
||||
+const char **toplev_main_argv;
|
||||
+
|
||||
/* Decoded options, and number of such options. */
|
||||
struct cl_decoded_option *save_decoded_options;
|
||||
unsigned int save_decoded_options_count;
|
||||
@@ -2239,6 +2241,8 @@ toplev::main (int argc, char **argv)
|
||||
|
||||
expandargv (&argc, &argv);
|
||||
|
||||
+ toplev_main_argv = CONST_CAST2 (const char **, char **, argv);
|
||||
+
|
||||
/* Initialization of GCC's environment, and diagnostics. */
|
||||
general_init (argv[0], m_init_signals);
|
||||
|
||||
--- gcc/graphite.cc.jj 2010-12-01 10:24:32.000000000 -0500
|
||||
+++ gcc/graphite.cc 2010-12-01 11:46:07.832118193 -0500
|
||||
@@ -64,11 +64,39 @@ __typeof (isl_pointers__) isl_pointers__
|
||||
static bool
|
||||
init_isl_pointers (void)
|
||||
{
|
||||
- void *h;
|
||||
+ void *h = NULL;
|
||||
+ extern const char **toplev_main_argv;
|
||||
+ char *buf, *p;
|
||||
+ size_t len;
|
||||
|
||||
if (isl_pointers__.inited)
|
||||
return isl_pointers__.h != NULL;
|
||||
- h = dlopen ("libisl.so.23", RTLD_LAZY);
|
||||
+ len = progname - toplev_main_argv[0];
|
||||
+ buf = XALLOCAVAR (char, len + sizeof "libisl.so.23");
|
||||
+ memcpy (buf, toplev_main_argv[0], len);
|
||||
+ strcpy (buf + len, "libisl.so.23");
|
||||
+ len += sizeof "libisl.so.23";
|
||||
+ p = strstr (buf, "/libexec/");
|
||||
+ if (p != NULL)
|
||||
+ {
|
||||
+ while (1)
|
||||
+ {
|
||||
+ char *q = strstr (p + 8, "/libexec/");
|
||||
+ if (q == NULL)
|
||||
+ break;
|
||||
+ p = q;
|
||||
+ }
|
||||
+ memmove (p + 4, p + 8, len - (p + 8 - buf));
|
||||
+ h = dlopen (buf, RTLD_LAZY);
|
||||
+ if (h == NULL)
|
||||
+ {
|
||||
+ len = progname - toplev_main_argv[0];
|
||||
+ memcpy (buf, toplev_main_argv[0], len);
|
||||
+ strcpy (buf + len, "libisl.so.23");
|
||||
+ }
|
||||
+ }
|
||||
+ if (h == NULL)
|
||||
+ h = dlopen (buf, RTLD_LAZY);
|
||||
isl_pointers__.h = h;
|
||||
if (h == NULL)
|
||||
return false;
|
@ -4,7 +4,7 @@
|
||||
<a class="link" href="https://www.fsf.org" target="_top">FSF
|
||||
</a>
|
||||
</p><p>
|
||||
+ Release 8.5.0
|
||||
+ Release 14.2.1
|
||||
+ </p><p>
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation
|
||||
@ -17,7 +17,7 @@
|
||||
</p><p>
|
||||
- The API documentation, rendered into HTML, can be viewed online
|
||||
+ The API documentation, rendered into HTML, can be viewed locally
|
||||
+ <a class="link" href="api/index.html" target="_top">for the 8.5.0 release</a>,
|
||||
+ <a class="link" href="api/index.html" target="_top">for the 14.2.1 release</a>,
|
||||
+ online
|
||||
<a class="link" href="http://gcc.gnu.org/onlinedocs/" target="_top">for each GCC release</a>
|
||||
and
|
@ -5,7 +5,7 @@ libtool sucks.
|
||||
rpath="$finalize_rpath"
|
||||
test "$mode" != relink && rpath="$compile_rpath$rpath"
|
||||
for libdir in $rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64|/usr/lib/../lib64/lp64d) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
||||
@ -13,7 +13,7 @@ libtool sucks.
|
||||
rpath=
|
||||
hardcode_libdirs=
|
||||
for libdir in $compile_rpath $finalize_rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64|/usr/lib/../lib64/lp64d) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
||||
@ -21,7 +21,7 @@ libtool sucks.
|
||||
rpath=
|
||||
hardcode_libdirs=
|
||||
for libdir in $finalize_rpath; do
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
|
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64|/usr/lib/../lib64/lp64d) continue;; esac
|
||||
if test -n "$hardcode_libdir_flag_spec"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
if test -z "$hardcode_libdirs"; then
|
@ -1,8 +1,6 @@
|
||||
2010-02-08 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* config/rs6000/sysv4.h (LINK_EH_SPEC): Pass --no-add-needed to the
|
||||
linker.
|
||||
* config/gnu-user.h (LINK_EH_SPEC): Likewise.
|
||||
* config/gnu-user.h (LINK_EH_SPEC): Pass --no-add-needed to the linker.
|
||||
* config/alpha/elf.h (LINK_EH_SPEC): Likewise.
|
||||
* config/ia64/linux.h (LINK_EH_SPEC): Likewise.
|
||||
|
||||
@ -28,7 +26,7 @@
|
||||
#define TARGET_INIT_LIBFUNCS ia64_soft_fp_init_libfuncs
|
||||
--- gcc/config/gnu-user.h.jj 2011-01-03 12:53:03.739057299 +0100
|
||||
+++ gcc/config/gnu-user.h 2011-01-04 18:14:10.932814884 +0100
|
||||
@@ -133,7 +133,7 @@ see the files COPYING3 and COPYING.RUNTI
|
||||
@@ -106,7 +106,7 @@ see the files COPYING3 and COPYING.RUNTI
|
||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
@ -36,15 +34,4 @@
|
||||
+#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#undef LINK_GCC_C_SEQUENCE_SPEC
|
||||
--- gcc/config/rs6000/sysv4.h.jj 2011-01-03 13:02:18.255994215 +0100
|
||||
+++ gcc/config/rs6000/sysv4.h 2011-01-04 18:14:10.933888871 +0100
|
||||
@@ -816,7 +816,7 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEF
|
||||
-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
|
||||
|
||||
#if defined(HAVE_LD_EH_FRAME_HDR)
|
||||
-# define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
|
||||
+# define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
|
||||
#endif
|
||||
|
||||
#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
|
||||
#define GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC \
|
76
gcc14-pr101523.patch
Normal file
76
gcc14-pr101523.patch
Normal file
@ -0,0 +1,76 @@
|
||||
Based on Richi's patch:
|
||||
<https://gcc.gnu.org/pipermail/gcc-patches/2024-April/648725.html>
|
||||
~~
|
||||
The following avoids re-walking and re-combining the instructions
|
||||
between i2 and i3 when the pattern of i2 doesn't change.
|
||||
|
||||
Bootstrap and regtest running ontop of a reversal of
|
||||
r14-9692-g839bc42772ba7a.
|
||||
|
||||
It brings down memory use from 9GB to 400MB and compile-time from
|
||||
80s to 3.5s. r14-9692-g839bc42772ba7a does better in both metrics
|
||||
but has shown code generation regressions across architectures.
|
||||
|
||||
PR rtl-optimization/101523
|
||||
* combine.cc (try_combine): When the pattern of i2 doesn't
|
||||
change do not re-start combining at i2 or an earlier insn which
|
||||
had links or notes added.
|
||||
~~
|
||||
But, since the patch affects code generation (for instance,
|
||||
libstdc++-v3/src/c++17/floating_from_chars.o), we limit the bailing out
|
||||
only when I2 hasn't been changed 1000x. I've measured how many times
|
||||
at most is I2 unchanged during a bootstrap + regtest.
|
||||
x86: 134
|
||||
aarch64: 736 (gimple-match-1.cc)
|
||||
s390x: 635 (gimple-match-*)
|
||||
ppc64le: 620 (gimple-match-*)
|
||||
while certain pathological testcases trigger it more than 10,000 times.
|
||||
With the limit in place this patch doesn't affect common code.
|
||||
|
||||
--- a/gcc/combine.cc
|
||||
+++ b/gcc/combine.cc
|
||||
@@ -92,6 +92,11 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "function-abi.h"
|
||||
#include "rtlanal.h"
|
||||
|
||||
+/* Number of times I2 didn't change in try_combine. Used to prevent a
|
||||
+ combinatorial explosion. */
|
||||
+
|
||||
+static int combine_i2_unchanged;
|
||||
+
|
||||
/* Number of attempts to combine instructions in this function. */
|
||||
|
||||
static int combine_attempts;
|
||||
@@ -1127,6 +1132,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
|
||||
return false;
|
||||
|
||||
combine_attempts = 0;
|
||||
+ combine_i2_unchanged = 0;
|
||||
combine_merges = 0;
|
||||
combine_extras = 0;
|
||||
combine_successes = 0;
|
||||
@@ -4196,6 +4201,10 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
||||
adjust_for_new_dest (i3);
|
||||
}
|
||||
|
||||
+ bool i2_i2_unchanged = false;
|
||||
+ if (rtx_equal_p (newi2pat, PATTERN (i2)))
|
||||
+ i2_i2_unchanged = true;
|
||||
+
|
||||
/* We now know that we can do this combination. Merge the insns and
|
||||
update the status of registers and LOG_LINKS. */
|
||||
|
||||
@@ -4762,6 +4771,13 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
||||
combine_successes++;
|
||||
undo_commit ();
|
||||
|
||||
+ if (i2_i2_unchanged)
|
||||
+ {
|
||||
+ if (combine_i2_unchanged == 1000)
|
||||
+ return i3;
|
||||
+ ++combine_i2_unchanged;
|
||||
+ }
|
||||
+
|
||||
rtx_insn *ret = newi2pat ? i2 : i3;
|
||||
if (added_links_insn && DF_INSN_LUID (added_links_insn) < DF_INSN_LUID (ret))
|
||||
ret = added_links_insn;
|
21
gcc14-rh1574936.patch
Normal file
21
gcc14-rh1574936.patch
Normal file
@ -0,0 +1,21 @@
|
||||
crt files and statically linked libgcc objects cause false positives
|
||||
in annobin coverage, so we add the assembler flag to generate notes
|
||||
for them.
|
||||
|
||||
The patch also adds notes to libgcc_s.so, but this is harmless because
|
||||
these notes only confer that there is no other annobin markup.
|
||||
|
||||
2018-07-25 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
* config/t-linux (LIBGCC2_CFLAGS, CRTSTUFF_CFLAGS): Add
|
||||
-Wa,--generate-missing-build-notes=yes.
|
||||
|
||||
--- libgcc/config/t-linux 2022-12-15 19:25:20.581394950 +0100
|
||||
+++ libgcc/config/t-linux 2023-03-21 22:00:37.054478562 +0100
|
||||
@@ -1,3 +1,6 @@
|
||||
# Override t-slibgcc-elf-ver to export some libgcc symbols with
|
||||
# the symbol versions that glibc used.
|
||||
SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
|
||||
+
|
||||
+LIBGCC2_CFLAGS += -Wa,--generate-missing-build-notes=yes
|
||||
+CRTSTUFF_CFLAGS += -Wa,--generate-missing-build-notes=yes
|
@ -1,21 +1,21 @@
|
||||
--- gcc/config.gcc.jj 2008-04-24 15:42:46.000000000 -0500
|
||||
+++ gcc/config.gcc 2008-04-24 15:44:51.000000000 -0500
|
||||
@@ -2790,7 +2790,7 @@ sparc-*-rtems*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp-elf.h sparc/rtemself.h rtems.h newlib-stdint.h"
|
||||
@@ -3330,7 +3330,7 @@ sparc-*-rtems*)
|
||||
tm_file="${tm_file} elfos.h sparc/sysv4.h sparc/sp-elf.h sparc/rtemself.h rtems.h newlib-stdint.h"
|
||||
tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems"
|
||||
;;
|
||||
-sparc-*-linux*)
|
||||
+sparc-*-linux* | sparcv9-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/tso.h"
|
||||
tm_file="${tm_file} elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/tso.h"
|
||||
extra_options="${extra_options} sparc/long-double-switch.opt"
|
||||
case ${target} in
|
||||
@@ -2844,7 +2844,7 @@ sparc64-*-rtems*)
|
||||
@@ -3384,7 +3384,7 @@ sparc64-*-rtems*)
|
||||
extra_options="${extra_options}"
|
||||
tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems-64"
|
||||
;;
|
||||
-sparc64-*-linux*)
|
||||
+sparc64*-*-linux*)
|
||||
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/default64.h sparc/linux64.h sparc/tso.h"
|
||||
tm_file="sparc/biarch64.h ${tm_file} elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/default64.h sparc/linux64.h sparc/tso.h"
|
||||
extra_options="${extra_options} sparc/long-double-switch.opt"
|
||||
tmake_file="${tmake_file} sparc/t-sparc sparc/t-linux64"
|
||||
--- libgcc/config.host.jj 2008-04-24 15:46:19.000000000 -0500
|
85
isl-rh2155127.patch
Normal file
85
isl-rh2155127.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From: Sven Verdoolaege <sven.verdoolaege@gmail.com>
|
||||
Date: Mon, 6 Jun 2022 12:56:02 +0000 (+0200)
|
||||
Subject: update m4/ax_prog_cc_for_build.m4
|
||||
X-Git-Tag: isl-0.25~11
|
||||
X-Git-Url: https://repo.or.cz/isl.git/commitdiff_plain/b4dcdfadc29a6c9f410a72f345f3f32725b1d38b
|
||||
|
||||
update m4/ax_prog_cc_for_build.m4
|
||||
|
||||
In particular, update to the latest version from the autoconf archive,
|
||||
but preserve the changes from isl-0.22.1-358-gcd42abdf2
|
||||
(m4/ax_prog_cc_for_build.m4: do not override host compiler dependency style,
|
||||
Tue Jun 9 10:54:10 2020 +0200).
|
||||
|
||||
Signed-off-by: Sven Verdoolaege <sven.verdoolaege@gmail.com>
|
||||
|
||||
--- isl-0.24/m4/ax_prog_cc_for_build.m4.jj 2021-03-02 12:07:09.000000000 +0100
|
||||
+++ isl-0.24/m4/ax_prog_cc_for_build.m4 2022-12-20 18:11:18.855777817 +0100
|
||||
@@ -32,7 +32,7 @@
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
-#serial 18
|
||||
+#serial 21
|
||||
|
||||
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
|
||||
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
|
||||
@@ -44,6 +44,8 @@ dnl Use the standard macros, but make th
|
||||
dnl
|
||||
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
|
||||
pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl
|
||||
+pushdef([ac_cv_prog_cc_c99], ac_cv_build_prog_cc_c99)dnl
|
||||
+pushdef([ac_cv_prog_cc_c11], ac_cv_build_prog_cc_c11)dnl
|
||||
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
|
||||
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
|
||||
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
|
||||
@@ -86,7 +88,21 @@ AS_IF([test -n "$build"], [ac_build
|
||||
[test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
+
|
||||
+dnl The pushdef([ac_cv_c_compiler_gnu], ...) currently does not cover
|
||||
+dnl the use of this variable in _AC_LANG_COMPILER_GNU called by
|
||||
+dnl AC_PROG_CC. Unset this cache variable temporarily as a workaround.
|
||||
+was_set_c_compiler_gnu=${[ac_cv_c_compiler_gnu]+y}
|
||||
+AS_IF([test ${was_set_c_compiler_gnu}],
|
||||
+ [saved_c_compiler_gnu=$[ac_cv_c_compiler_gnu]
|
||||
+ AS_UNSET([[ac_cv_c_compiler_gnu]])])
|
||||
+
|
||||
AC_PROG_CC
|
||||
+
|
||||
+dnl Restore ac_cv_c_compiler_gnu
|
||||
+AS_IF([test ${was_set_c_compiler_gnu}],
|
||||
+ [[ac_cv_c_compiler_gnu]=$[saved_c_compiler_gnu]])
|
||||
+
|
||||
_AC_COMPILER_EXEEXT
|
||||
_AC_COMPILER_OBJEXT
|
||||
AC_PROG_CPP
|
||||
--- isl-0.24/configure.jj 2021-04-26 11:13:19.000000000 +0200
|
||||
+++ isl-0.24/configure 2022-12-20 18:11:36.882518568 +0100
|
||||
@@ -5002,6 +4990,13 @@ ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR
|
||||
ac_link='$CC_FOR_BUILD -o conftest$ac_build_exeext $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_build_c_compiler_gnu
|
||||
|
||||
+
|
||||
+was_set_c_compiler_gnu=${ac_cv_c_compiler_gnu+y}
|
||||
+if test ${was_set_c_compiler_gnu}; then :
|
||||
+ saved_c_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
+ { ac_cv_c_compiler_gnu=; unset ac_cv_c_compiler_gnu;}
|
||||
+fi
|
||||
+
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP_FOR_BUILD $CPPFLAGS_FOR_BUILD'
|
||||
ac_compile='$CC_FOR_BUILD -c $CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD conftest.$ac_ext >&5'
|
||||
@@ -5728,6 +5723,11 @@ else
|
||||
fi
|
||||
|
||||
|
||||
+
|
||||
+if test ${was_set_c_compiler_gnu}; then :
|
||||
+ ac_cv_c_compiler_gnu=$saved_c_compiler_gnu
|
||||
+fi
|
||||
+
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
4
sources
Normal file
4
sources
Normal file
@ -0,0 +1,4 @@
|
||||
b21f0bfd5767d0ecb9c08ba3e3a605a841d4c6a6008bf9dd8b4c4da366d7e733600eb21095768bda91e5df6536c398bf4a941e44577aef7586e95f1d148a214f ./gcc-14.2.1-20240801.tar.xz
|
||||
aab3bddbda96b801d0f56d2869f943157aad52a6f6e6a61745edd740234c635c38231af20bc3f1a08d416a5e973a90e18249078ed8e4ae2f1d5de57658738e95 ./isl-0.24.tar.bz2
|
||||
31bfc19429797236e268e22b752c5abeabb9c0f39b1058634af8dab329b4f028fc72a35888193c9575f6cee5cf2c069669d79fcb4d4e3a4318f57413452f707d ./newlib-cygwin-d45261f62a15f8abd94a1031020b9a9f455e4eed.tar.xz
|
||||
941e763af8601b89f0e4ec48a2d68ae0a8e70ee1e6ba6859394b021ad7bd7d143cc529f3c35c08d7f84e5554980ddcc97cf05b6c4755c2bc36c91161b79e8cea ./nvptx-tools-87ce9dc5999e5fca2e1d3478a30888d9864c9804.tar.xz
|
Loading…
Reference in New Issue
Block a user