
21 changed files with 5385 additions and 200 deletions
@ -0,0 +1,516 @@
@@ -0,0 +1,516 @@
|
||||
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c |
||||
index d93dcfa..f47565c 100644 |
||||
--- a/gcc/fortran/io.c |
||||
+++ b/gcc/fortran/io.c |
||||
@@ -909,6 +909,13 @@ data_desc: |
||||
|
||||
if (u != FMT_POSINT) |
||||
{ |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume a default width based on the variable size. */ |
||||
+ saved_token = u; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
format_locus.nextc += format_string_pos; |
||||
gfc_error ("Positive width required in format " |
||||
"specifier %s at %L", token_to_string (t), |
||||
@@ -1030,6 +1037,13 @@ data_desc: |
||||
goto fail; |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume the default width is expected here and continue lexing. */ |
||||
+ value = 0; /* It doesn't matter what we set the value to here. */ |
||||
+ saved_token = t; |
||||
+ break; |
||||
+ } |
||||
error = nonneg_required; |
||||
goto syntax; |
||||
} |
||||
@@ -1099,8 +1113,17 @@ data_desc: |
||||
goto fail; |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
- error = nonneg_required; |
||||
- goto syntax; |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume the default width is expected here and continue lexing. */ |
||||
+ value = 0; /* It doesn't matter what we set the value to here. */ |
||||
+ saved_token = t; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ error = nonneg_required; |
||||
+ goto syntax; |
||||
+ } |
||||
} |
||||
else if (is_input && t == FMT_ZERO) |
||||
{ |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..b087b8f |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 |
||||
@@ -0,0 +1,43 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+! |
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float |
||||
+! values to a higher precision than the type can actually store, the results |
||||
+! are implementation dependent: some platforms print zeros, others print random |
||||
+! numbers. Don't depend on this behaviour in tests because they will not be |
||||
+! portable. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ |
||||
+ real*4 :: real_4 |
||||
+ real*8 :: real_8 |
||||
+ real*16 :: real_16 |
||||
+ integer :: len |
||||
+ |
||||
+ real_4 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 4.1799998:") call abort |
||||
+ |
||||
+ real_4 = 0.00000018 |
||||
+ write(buffer, '(A, F, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.0000002:") call abort |
||||
+ |
||||
+ real_8 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_8,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 27) call abort |
||||
+ |
||||
+ real_16 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_16,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 44) call abort |
||||
+end |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..3d3a476 |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 |
||||
@@ -0,0 +1,48 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+! |
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float |
||||
+! values to a higher precision than the type can actually store, the results |
||||
+! are implementation dependent: some platforms print zeros, others print random |
||||
+! numbers. Don't depend on this behaviour in tests because they will not be |
||||
+! portable. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ |
||||
+ real*4 :: real_4 |
||||
+ real*8 :: real_8 |
||||
+ real*16 :: real_16 |
||||
+ integer :: len |
||||
+ |
||||
+ real_4 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 4.180000 :") call abort |
||||
+ |
||||
+ real_4 = 0.00000018 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.1800000E-06:") call abort |
||||
+ |
||||
+ real_4 = 18000000.4 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.1800000E+08:") call abort |
||||
+ |
||||
+ real_8 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_8,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 27) call abort |
||||
+ |
||||
+ real_16 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_16,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 44) call abort |
||||
+end |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..ac4e165 |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 |
||||
@@ -0,0 +1,38 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ character(1) :: colon |
||||
+ |
||||
+ integer*2 :: integer_2 |
||||
+ integer*4 :: integer_4 |
||||
+ integer*8 :: integer_8 |
||||
+ |
||||
+ write(buffer, '(A, I, A)') ':',12340,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 12340:") call abort |
||||
+ |
||||
+ read(buffer, '(A1, I, A1)') colon, integer_4, colon |
||||
+ if (integer_4.ne.12340) call abort |
||||
+ |
||||
+ integer_2 = -99 |
||||
+ write(buffer, '(A, I, A)') ':',integer_2,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": -99:") call abort |
||||
+ |
||||
+ integer_8 = -11112222 |
||||
+ write(buffer, '(A, I, A)') ':',integer_8,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": -11112222:") call abort |
||||
+ |
||||
+! If the width is 7 and there are 7 leading zeroes, the result should be zero. |
||||
+ integer_2 = 789 |
||||
+ buffer = '0000000789' |
||||
+ read(buffer, '(I)') integer_2 |
||||
+ if (integer_2.ne.0) call abort |
||||
+end |
||||
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c |
||||
index c2abdd7..692b1ff 100644 |
||||
--- a/libgfortran/io/format.c |
||||
+++ b/libgfortran/io/format.c |
||||
@@ -956,12 +956,33 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
*seen_dd = true; |
||||
if (u != FMT_POSINT && u != FMT_ZERO) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.real.w = DEFAULT_WIDTH; |
||||
+ tail->u.real.d = 0; |
||||
+ tail->u.real.e = -1; |
||||
+ fmt->saved_token = u; |
||||
+ break; |
||||
+ } |
||||
fmt->error = nonneg_required; |
||||
goto finished; |
||||
} |
||||
} |
||||
+ else if (u == FMT_ZERO) |
||||
+ { |
||||
+ fmt->error = posint_required; |
||||
+ goto finished; |
||||
+ } |
||||
else if (u != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.real.w = DEFAULT_WIDTH; |
||||
+ tail->u.real.d = 0; |
||||
+ tail->u.real.e = -1; |
||||
+ fmt->saved_token = u; |
||||
+ break; |
||||
+ } |
||||
fmt->error = posint_required; |
||||
goto finished; |
||||
} |
||||
@@ -1099,6 +1120,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
{ |
||||
if (t != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.integer.w = DEFAULT_WIDTH; |
||||
+ tail->u.integer.m = -1; |
||||
+ fmt->saved_token = t; |
||||
+ break; |
||||
+ } |
||||
fmt->error = posint_required; |
||||
goto finished; |
||||
} |
||||
@@ -1107,6 +1135,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
{ |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.integer.w = DEFAULT_WIDTH; |
||||
+ tail->u.integer.m = -1; |
||||
+ fmt->saved_token = t; |
||||
+ break; |
||||
+ } |
||||
fmt->error = nonneg_required; |
||||
goto finished; |
||||
} |
||||
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h |
||||
index 5583183..d1d08e8 100644 |
||||
--- a/libgfortran/io/io.h |
||||
+++ b/libgfortran/io/io.h |
||||
@@ -981,5 +981,55 @@ memset4 (gfc_char4_t *p, gfc_char4_t c, int k) |
||||
*p++ = c; |
||||
} |
||||
|
||||
+/* Used in width fields to indicate that the default should be used */ |
||||
+#define DEFAULT_WIDTH -1 |
||||
+ |
||||
+/* Defaults for certain format field descriptors. These are decided based on |
||||
+ * the type of the value being formatted. |
||||
+ * |
||||
+ * The behaviour here is modelled on the Oracle Fortran compiler. At the time |
||||
+ * of writing, the details were available at this URL: |
||||
+ * |
||||
+ * https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnc3/index.html#z4000743746d |
||||
+ */ |
||||
+ |
||||
+static inline int |
||||
+default_width_for_integer (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 1: |
||||
+ case 2: return 7; |
||||
+ case 4: return 12; |
||||
+ case 8: return 23; |
||||
+ case 16: return 44; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
+static inline int |
||||
+default_width_for_float (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 4: return 15; |
||||
+ case 8: return 25; |
||||
+ case 16: return 42; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
+static inline int |
||||
+default_precision_for_float (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 4: return 7; |
||||
+ case 8: return 16; |
||||
+ case 16: return 33; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
#endif |
||||
|
||||
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c |
||||
index 2c9de48..e911e35 100644 |
||||
--- a/libgfortran/io/read.c |
||||
+++ b/libgfortran/io/read.c |
||||
@@ -629,6 +629,12 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) |
||||
|
||||
w = f->u.w; |
||||
|
||||
+ /* This is a legacy extension, and the frontend will only allow such cases |
||||
+ * through when -fdec-format-defaults is passed. |
||||
+ */ |
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (length); |
||||
+ |
||||
p = read_block_form (dtp, &w); |
||||
|
||||
if (p == NULL) |
||||
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c |
||||
index a7307a8..c8e52fb 100644 |
||||
--- a/libgfortran/io/write.c |
||||
+++ b/libgfortran/io/write.c |
||||
@@ -684,9 +684,8 @@ write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len) |
||||
p[wlen - 1] = (n) ? 'T' : 'F'; |
||||
} |
||||
|
||||
- |
||||
static void |
||||
-write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n) |
||||
+write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len) |
||||
{ |
||||
int w, m, digits, nzero, nblank; |
||||
char *p; |
||||
@@ -719,6 +718,9 @@ write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n) |
||||
/* Select a width if none was specified. The idea here is to always |
||||
print something. */ |
||||
|
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (len); |
||||
+ |
||||
if (w == 0) |
||||
w = ((digits < m) ? m : digits); |
||||
|
||||
@@ -845,6 +847,8 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source, |
||||
|
||||
/* Select a width if none was specified. The idea here is to always |
||||
print something. */ |
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (len); |
||||
|
||||
if (w == 0) |
||||
w = ((digits < m) ? m : digits) + nsign; |
||||
@@ -1187,13 +1191,13 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = btoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = btoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1208,13 +1212,13 @@ write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = otoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = otoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1228,13 +1232,13 @@ write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = ztoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1504,7 +1508,7 @@ size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind) |
||||
{ |
||||
int size; |
||||
|
||||
- if (f->format == FMT_F && f->u.real.w == 0) |
||||
+ if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH) |
||||
{ |
||||
switch (kind) |
||||
{ |
||||
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def |
||||
index 7f0aa1d..73dc910 100644 |
||||
--- a/libgfortran/io/write_float.def |
||||
+++ b/libgfortran/io/write_float.def |
||||
@@ -113,7 +113,8 @@ determine_precision (st_parameter_dt * d |
||||
static void |
||||
build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer, |
||||
size_t size, int nprinted, int precision, int sign_bit, |
||||
- bool zero_flag, int npad, char *result, size_t *len) |
||||
+ bool zero_flag, int npad, int default_width, char *result, |
||||
+ size_t *len) |
||||
{ |
||||
char *put; |
||||
char *digits; |
||||
@@ -132,8 +133,17 @@ build_float_string (st_parameter_dt *dtp |
||||
sign_t sign; |
||||
|
||||
ft = f->format; |
||||
- w = f->u.real.w; |
||||
- d = f->u.real.d; |
||||
+ if (f->u.real.w == DEFAULT_WIDTH) |
||||
+ /* This codepath can only be reached with -fdec-format-defaults. */ |
||||
+ { |
||||
+ w = default_width; |
||||
+ d = precision; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ w = f->u.real.w; |
||||
+ d = f->u.real.d; |
||||
+ } |
||||
p = dtp->u.p.scale_factor; |
||||
*len = 0; |
||||
|
||||
@@ -959,6 +969,11 @@ determine_en_precision (st_parameter_dt |
||||
int save_scale_factor;\ |
||||
volatile GFC_REAL_ ## x temp;\ |
||||
save_scale_factor = dtp->u.p.scale_factor;\ |
||||
+ if (w == DEFAULT_WIDTH)\ |
||||
+ {\ |
||||
+ w = default_width;\ |
||||
+ d = precision;\ |
||||
+ }\ |
||||
switch (dtp->u.p.current_unit->round_status)\ |
||||
{\ |
||||
case ROUND_ZERO:\ |
||||
@@ -1034,7 +1049,8 @@ determine_en_precision (st_parameter_dt |
||||
nprinted = FDTOA(y,precision,m);\ |
||||
}\ |
||||
build_float_string (dtp, &newf, buffer, size, nprinted, precision,\ |
||||
- sign_bit, zero_flag, npad, result, res_len);\ |
||||
+ sign_bit, zero_flag, npad, default_width,\ |
||||
+ result, res_len);\ |
||||
dtp->u.p.scale_factor = save_scale_factor;\ |
||||
}\ |
||||
else\ |
||||
@@ -1044,7 +1060,8 @@ determine_en_precision (st_parameter_dt |
||||
else\ |
||||
nprinted = DTOA(y,precision,m);\ |
||||
build_float_string (dtp, f, buffer, size, nprinted, precision,\ |
||||
- sign_bit, zero_flag, npad, result, res_len);\ |
||||
+ sign_bit, zero_flag, npad, default_width,\ |
||||
+ result, res_len);\ |
||||
}\ |
||||
}\ |
||||
|
||||
@@ -1058,6 +1075,16 @@ get_float_string (st_parameter_dt *dtp, |
||||
{ |
||||
int sign_bit, nprinted; |
||||
bool zero_flag; |
||||
+ int default_width = 0; |
||||
+ |
||||
+ if (f->u.real.w == DEFAULT_WIDTH) |
||||
+ /* This codepath can only be reached with -fdec-format-defaults. The default |
||||
+ * values are based on those used in the Oracle Fortran compiler. |
||||
+ */ |
||||
+ { |
||||
+ default_width = default_width_for_float (kind); |
||||
+ precision = default_precision_for_float (kind); |
||||
+ } |
||||
|
||||
switch (kind) |
||||
{ |
@ -0,0 +1,125 @@
@@ -0,0 +1,125 @@
|
||||
commit 366dbfaa2132186e5e8b0688df05662967e628c7 |
||||
Author: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> |
||||
Date: Wed Mar 28 11:59:06 2018 +0000 |
||||
|
||||
* gfortran.h (gfc_dt): Rename default_exp field to dec_ext. |
||||
* ioparm.def (IOPARM_dt_default_exp): Rename to ... |
||||
(IOPARM_dt_dec_ext): ... this. |
||||
* trans-io.c (build_dt): Adjust for default_exp renaming to |
||||
dec_ext and IOPARM_dt_default_exp renaming to IOPARM_dt_dec_ext. |
||||
* io.c (match_io): Likewise. |
||||
|
||||
* io/io.h (IOPARM_DT_DEFAULT_EXP): Rename to ... |
||||
(IOPARM_DT_DEC_EXT): ... this. |
||||
* io/list_read.c (parse_real): Adjust for IOPARM_DT_DEFAULT_EXP |
||||
renaming to IOPARM_DT_DEC_EXT. |
||||
(read_real): Likewise. |
||||
* io/read.c (read_f): Likewise. |
||||
|
||||
|
||||
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@258920 138bc75d-0d04-0410-961f-82ee72b054a4 |
||||
|
||||
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h |
||||
index 2bfd1e3019d..507570ccbff 100644 |
||||
--- a/gcc/fortran/gfortran.h |
||||
+++ b/gcc/fortran/gfortran.h |
||||
@@ -2437,7 +2437,7 @@ typedef struct |
||||
gfc_expr *io_unit, *format_expr, *rec, *advance, *iostat, *size, *iomsg, |
||||
*id, *pos, *asynchronous, *blank, *decimal, *delim, *pad, *round, |
||||
*sign, *extra_comma, *dt_io_kind, *udtio; |
||||
- char default_exp; |
||||
+ char dec_ext; |
||||
|
||||
gfc_symbol *namelist; |
||||
/* A format_label of `format_asterisk' indicates the "*" format */ |
||||
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c |
||||
index 10b7e827dab..0aa31bb6a4f 100644 |
||||
--- a/gcc/fortran/io.c |
||||
+++ b/gcc/fortran/io.c |
||||
@@ -4291,9 +4291,10 @@ get_io_list: |
||||
goto syntax; |
||||
} |
||||
|
||||
- /* See if we want to use defaults for missing exponents in real transfers. */ |
||||
+ /* See if we want to use defaults for missing exponents in real transfers |
||||
+ and other DEC runtime extensions. */ |
||||
if (flag_dec) |
||||
- dt->default_exp = 1; |
||||
+ dt->dec_ext = 1; |
||||
|
||||
/* A full IO statement has been matched. Check the constraints. spec_end is |
||||
supplied for cases where no locus is supplied. */ |
||||
diff --git a/gcc/fortran/ioparm.def b/gcc/fortran/ioparm.def |
||||
index b9dc58f26a7..9ab3b58946e 100644 |
||||
--- a/gcc/fortran/ioparm.def |
||||
+++ b/gcc/fortran/ioparm.def |
||||
@@ -118,5 +118,5 @@ IOPARM (dt, round, 1 << 23, char2) |
||||
IOPARM (dt, sign, 1 << 24, char1) |
||||
#define IOPARM_dt_f2003 (1 << 25) |
||||
#define IOPARM_dt_dtio (1 << 26) |
||||
-#define IOPARM_dt_default_exp (1 << 27) |
||||
+#define IOPARM_dt_dec_ext (1 << 27) |
||||
IOPARM (dt, u, 0, pad) |
||||
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c |
||||
index 9058712c695..2626c4651e2 100644 |
||||
--- a/gcc/fortran/trans-io.c |
||||
+++ b/gcc/fortran/trans-io.c |
||||
@@ -1958,8 +1958,8 @@ build_dt (tree function, gfc_code * code) |
||||
if (dt->udtio) |
||||
mask |= IOPARM_dt_dtio; |
||||
|
||||
- if (dt->default_exp) |
||||
- mask |= IOPARM_dt_default_exp; |
||||
+ if (dt->dec_ext) |
||||
+ mask |= IOPARM_dt_dec_ext; |
||||
|
||||
if (dt->namelist) |
||||
{ |
||||
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h |
||||
index 3c2a2cae38a..ccbaf47ff90 100644 |
||||
--- a/libgfortran/io/io.h |
||||
+++ b/libgfortran/io/io.h |
||||
@@ -442,7 +442,7 @@ st_parameter_inquire; |
||||
#define IOPARM_DT_HAS_SIGN (1 << 24) |
||||
#define IOPARM_DT_HAS_F2003 (1 << 25) |
||||
#define IOPARM_DT_HAS_UDTIO (1 << 26) |
||||
-#define IOPARM_DT_DEFAULT_EXP (1 << 27) |
||||
+#define IOPARM_DT_DEC_EXT (1 << 27) |
||||
/* Internal use bit. */ |
||||
#define IOPARM_DT_IONML_SET (1u << 31) |
||||
|
||||
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c |
||||
index d052d1fa828..300c3bd23f3 100644 |
||||
--- a/libgfortran/io/list_read.c |
||||
+++ b/libgfortran/io/list_read.c |
||||
@@ -1380,7 +1380,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length) |
||||
if (!isdigit (c)) |
||||
{ |
||||
/* Extension: allow default exponent of 0 when omitted. */ |
||||
- if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
{ |
||||
push_char (dtp, '0'); |
||||
goto done; |
||||
@@ -1831,7 +1831,7 @@ read_real (st_parameter_dt *dtp, void *dest, int length) |
||||
if (!isdigit (c)) |
||||
{ |
||||
/* Extension: allow default exponent of 0 when omitted. */ |
||||
- if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
{ |
||||
push_char (dtp, '0'); |
||||
goto done; |
||||
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c |
||||
index 87adfb8a41d..976020af448 100644 |
||||
--- a/libgfortran/io/read.c |
||||
+++ b/libgfortran/io/read.c |
||||
@@ -1093,7 +1093,7 @@ exponent: |
||||
if (w == 0) |
||||
{ |
||||
/* Extension: allow default exponent of 0 when omitted. */ |
||||
- if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
goto done; |
||||
else |
||||
goto bad_float; |
@ -0,0 +1,516 @@
@@ -0,0 +1,516 @@
|
||||
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c |
||||
index d93dcfa..f47565c 100644 |
||||
--- a/gcc/fortran/io.c |
||||
+++ b/gcc/fortran/io.c |
||||
@@ -909,6 +909,13 @@ data_desc: |
||||
|
||||
if (u != FMT_POSINT) |
||||
{ |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume a default width based on the variable size. */ |
||||
+ saved_token = u; |
||||
+ break; |
||||
+ } |
||||
+ |
||||
format_locus.nextc += format_string_pos; |
||||
gfc_error ("Positive width required in format " |
||||
"specifier %s at %L", token_to_string (t), |
||||
@@ -1030,6 +1037,13 @@ data_desc: |
||||
goto fail; |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume the default width is expected here and continue lexing. */ |
||||
+ value = 0; /* It doesn't matter what we set the value to here. */ |
||||
+ saved_token = t; |
||||
+ break; |
||||
+ } |
||||
error = nonneg_required; |
||||
goto syntax; |
||||
} |
||||
@@ -1099,8 +1113,17 @@ data_desc: |
||||
goto fail; |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
- error = nonneg_required; |
||||
- goto syntax; |
||||
+ if (flag_dec) |
||||
+ { |
||||
+ /* Assume the default width is expected here and continue lexing. */ |
||||
+ value = 0; /* It doesn't matter what we set the value to here. */ |
||||
+ saved_token = t; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ error = nonneg_required; |
||||
+ goto syntax; |
||||
+ } |
||||
} |
||||
else if (is_input && t == FMT_ZERO) |
||||
{ |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..b087b8f |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 |
||||
@@ -0,0 +1,43 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+! |
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float |
||||
+! values to a higher precision than the type can actually store, the results |
||||
+! are implementation dependent: some platforms print zeros, others print random |
||||
+! numbers. Don't depend on this behaviour in tests because they will not be |
||||
+! portable. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ |
||||
+ real*4 :: real_4 |
||||
+ real*8 :: real_8 |
||||
+ real*16 :: real_16 |
||||
+ integer :: len |
||||
+ |
||||
+ real_4 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 4.1799998:") call abort |
||||
+ |
||||
+ real_4 = 0.00000018 |
||||
+ write(buffer, '(A, F, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.0000002:") call abort |
||||
+ |
||||
+ real_8 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_8,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 27) call abort |
||||
+ |
||||
+ real_16 = 4.18 |
||||
+ write(buffer, '(A, F, A)') ':',real_16,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 44) call abort |
||||
+end |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..3d3a476 |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 |
||||
@@ -0,0 +1,48 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+! |
||||
+! libgfortran uses printf() internally to implement FORMAT. If you print float |
||||
+! values to a higher precision than the type can actually store, the results |
||||
+! are implementation dependent: some platforms print zeros, others print random |
||||
+! numbers. Don't depend on this behaviour in tests because they will not be |
||||
+! portable. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ |
||||
+ real*4 :: real_4 |
||||
+ real*8 :: real_8 |
||||
+ real*16 :: real_16 |
||||
+ integer :: len |
||||
+ |
||||
+ real_4 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 4.180000 :") call abort |
||||
+ |
||||
+ real_4 = 0.00000018 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.1800000E-06:") call abort |
||||
+ |
||||
+ real_4 = 18000000.4 |
||||
+ write(buffer, '(A, G, A)') ':',real_4,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 0.1800000E+08:") call abort |
||||
+ |
||||
+ real_8 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_8,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 27) call abort |
||||
+ |
||||
+ real_16 = 4.18 |
||||
+ write(buffer, '(A, G, A)') ':',real_16,':' |
||||
+ print *,buffer |
||||
+ len = len_trim(buffer) |
||||
+ if (len /= 44) call abort |
||||
+end |
||||
diff --git a/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 |
||||
new file mode 100644 |
||||
index 0000000..ac4e165 |
||||
--- /dev/null |
||||
+++ b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 |
||||
@@ -0,0 +1,38 @@ |
||||
+! { dg-do run } |
||||
+! { dg-options -fdec } |
||||
+! |
||||
+! Test case for the default field widths enabled by the -fdec-format-defaults flag. |
||||
+! |
||||
+! This feature is not part of any Fortran standard, but it is supported by the |
||||
+! Oracle Fortran compiler and others. |
||||
+ |
||||
+ character(50) :: buffer |
||||
+ character(1) :: colon |
||||
+ |
||||
+ integer*2 :: integer_2 |
||||
+ integer*4 :: integer_4 |
||||
+ integer*8 :: integer_8 |
||||
+ |
||||
+ write(buffer, '(A, I, A)') ':',12340,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": 12340:") call abort |
||||
+ |
||||
+ read(buffer, '(A1, I, A1)') colon, integer_4, colon |
||||
+ if (integer_4.ne.12340) call abort |
||||
+ |
||||
+ integer_2 = -99 |
||||
+ write(buffer, '(A, I, A)') ':',integer_2,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": -99:") call abort |
||||
+ |
||||
+ integer_8 = -11112222 |
||||
+ write(buffer, '(A, I, A)') ':',integer_8,':' |
||||
+ print *,buffer |
||||
+ if (buffer.ne.": -11112222:") call abort |
||||
+ |
||||
+! If the width is 7 and there are 7 leading zeroes, the result should be zero. |
||||
+ integer_2 = 789 |
||||
+ buffer = '0000000789' |
||||
+ read(buffer, '(I)') integer_2 |
||||
+ if (integer_2.ne.0) call abort |
||||
+end |
||||
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c |
||||
index c2abdd7..692b1ff 100644 |
||||
--- a/libgfortran/io/format.c |
||||
+++ b/libgfortran/io/format.c |
||||
@@ -956,12 +956,33 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
*seen_dd = true; |
||||
if (u != FMT_POSINT && u != FMT_ZERO) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.real.w = DEFAULT_WIDTH; |
||||
+ tail->u.real.d = 0; |
||||
+ tail->u.real.e = -1; |
||||
+ fmt->saved_token = u; |
||||
+ break; |
||||
+ } |
||||
fmt->error = nonneg_required; |
||||
goto finished; |
||||
} |
||||
} |
||||
+ else if (u == FMT_ZERO) |
||||
+ { |
||||
+ fmt->error = posint_required; |
||||
+ goto finished; |
||||
+ } |
||||
else if (u != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.real.w = DEFAULT_WIDTH; |
||||
+ tail->u.real.d = 0; |
||||
+ tail->u.real.e = -1; |
||||
+ fmt->saved_token = u; |
||||
+ break; |
||||
+ } |
||||
fmt->error = posint_required; |
||||
goto finished; |
||||
} |
||||
@@ -1099,6 +1120,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
{ |
||||
if (t != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.integer.w = DEFAULT_WIDTH; |
||||
+ tail->u.integer.m = -1; |
||||
+ fmt->saved_token = t; |
||||
+ break; |
||||
+ } |
||||
fmt->error = posint_required; |
||||
goto finished; |
||||
} |
||||
@@ -1107,6 +1135,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) |
||||
{ |
||||
if (t != FMT_ZERO && t != FMT_POSINT) |
||||
{ |
||||
+ if (dtp->common.flags & IOPARM_DT_DEC_EXT) |
||||
+ { |
||||
+ tail->u.integer.w = DEFAULT_WIDTH; |
||||
+ tail->u.integer.m = -1; |
||||
+ fmt->saved_token = t; |
||||
+ break; |
||||
+ } |
||||
fmt->error = nonneg_required; |
||||
goto finished; |
||||
} |
||||
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h |
||||
index 5583183..d1d08e8 100644 |
||||
--- a/libgfortran/io/io.h |
||||
+++ b/libgfortran/io/io.h |
||||
@@ -981,5 +981,55 @@ memset4 (gfc_char4_t *p, gfc_char4_t c, int k) |
||||
*p++ = c; |
||||
} |
||||
|
||||
+/* Used in width fields to indicate that the default should be used */ |
||||
+#define DEFAULT_WIDTH -1 |
||||
+ |
||||
+/* Defaults for certain format field descriptors. These are decided based on |
||||
+ * the type of the value being formatted. |
||||
+ * |
||||
+ * The behaviour here is modelled on the Oracle Fortran compiler. At the time |
||||
+ * of writing, the details were available at this URL: |
||||
+ * |
||||
+ * https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnc3/index.html#z4000743746d |
||||
+ */ |
||||
+ |
||||
+static inline int |
||||
+default_width_for_integer (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 1: |
||||
+ case 2: return 7; |
||||
+ case 4: return 12; |
||||
+ case 8: return 23; |
||||
+ case 16: return 44; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
+static inline int |
||||
+default_width_for_float (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 4: return 15; |
||||
+ case 8: return 25; |
||||
+ case 16: return 42; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
+static inline int |
||||
+default_precision_for_float (int kind) |
||||
+{ |
||||
+ switch (kind) |
||||
+ { |
||||
+ case 4: return 7; |
||||
+ case 8: return 16; |
||||
+ case 16: return 33; |
||||
+ default: return 0; |
||||
+ } |
||||
+} |
||||
+ |
||||
#endif |
||||
|
||||
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c |
||||
index 2c9de48..e911e35 100644 |
||||
--- a/libgfortran/io/read.c |
||||
+++ b/libgfortran/io/read.c |
||||
@@ -629,6 +629,12 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) |
||||
|
||||
w = f->u.w; |
||||
|
||||
+ /* This is a legacy extension, and the frontend will only allow such cases |
||||
+ * through when -fdec-format-defaults is passed. |
||||
+ */ |
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (length); |
||||
+ |
||||
p = read_block_form (dtp, &w); |
||||
|
||||
if (p == NULL) |
||||
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c |
||||
index a7307a8..c8e52fb 100644 |
||||
--- a/libgfortran/io/write.c |
||||
+++ b/libgfortran/io/write.c |
||||
@@ -684,9 +684,8 @@ write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len) |
||||
p[wlen - 1] = (n) ? 'T' : 'F'; |
||||
} |
||||
|
||||
- |
||||
static void |
||||
-write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n) |
||||
+write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len) |
||||
{ |
||||
int w, m, digits, nzero, nblank; |
||||
char *p; |
||||
@@ -719,6 +718,9 @@ write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n) |
||||
/* Select a width if none was specified. The idea here is to always |
||||
print something. */ |
||||
|
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (len); |
||||
+ |
||||
if (w == 0) |
||||
w = ((digits < m) ? m : digits); |
||||
|
||||
@@ -845,6 +847,8 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source, |
||||
|
||||
/* Select a width if none was specified. The idea here is to always |
||||
print something. */ |
||||
+ if (w == DEFAULT_WIDTH) |
||||
+ w = default_width_for_integer (len); |
||||
|
||||
if (w == 0) |
||||
w = ((digits < m) ? m : digits) + nsign; |
||||
@@ -1187,13 +1191,13 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = btoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = btoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1208,13 +1212,13 @@ write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = otoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = otoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1228,13 +1232,13 @@ write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len) |
||||
if (len > (int) sizeof (GFC_UINTEGER_LARGEST)) |
||||
{ |
||||
p = ztoa_big (source, itoa_buf, len, &n); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
else |
||||
{ |
||||
n = extract_uint (source, len); |
||||
p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf)); |
||||
- write_boz (dtp, f, p, n); |
||||
+ write_boz (dtp, f, p, n, len); |
||||
} |
||||
} |
||||
|
||||
@@ -1504,7 +1508,7 @@ size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind) |
||||
{ |
||||
int size; |
||||
|
||||
- if (f->format == FMT_F && f->u.real.w == 0) |
||||
+ if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH) |
||||
{ |
||||
switch (kind) |
||||
{ |
||||
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def |
||||
index 7f0aa1d..73dc910 100644 |
||||
--- a/libgfortran/io/write_float.def |
||||
+++ b/libgfortran/io/write_float.def |
||||
@@ -113,7 +113,8 @@ determine_precision (st_parameter_dt * dtp, const fnode * f, int len) |
||||
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, const fnode *f, char *buffer, |
||||
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; |
||||
|
||||
rchar = '5'; |
||||
@@ -958,6 +968,11 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f, |
||||
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:\ |
||||
@@ -1033,7 +1048,8 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f, |
||||
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\ |
||||
@@ -1043,7 +1059,8 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f, |
||||
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);\ |
||||
}\ |
||||
}\ |
||||
|
||||
@@ -1057,6 +1074,16 @@ get_float_string (st_parameter_dt *dtp, const fnode *f, const char *source, |
||||
{ |
||||
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) |
||||
{ |
@ -0,0 +1,180 @@
@@ -0,0 +1,180 @@
|
||||
|
||||
PR target/84128 |
||||
* config/i386/i386.c (release_scratch_register_on_entry): Add new |
||||
OFFSET and RELEASE_VIA_POP arguments. Use SP+OFFSET to restore |
||||
the scratch if RELEASE_VIA_POP is false. |
||||
(ix86_adjust_stack_and_probe_stack_clash): Un-constify SIZE. |
||||
If we have to save a temporary register, decrement SIZE appropriately. |
||||
Pass new arguments to release_scratch_register_on_entry. |
||||
(ix86_adjust_stack_and_probe): Likewise. |
||||
(ix86_emit_probe_stack_range): Pass new arguments to |
||||
release_scratch_register_on_entry. |
||||
|
||||
PR target/84128 |
||||
* gcc.target/i386/pr84128.c: New test. |
||||
|
||||
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c |
||||
index fef34a1..3196ac4 100644 |
||||
--- gcc/config/i386/i386.c |
||||
+++ gcc/config/i386/i386.c |
||||
@@ -12567,22 +12567,39 @@ get_scratch_register_on_entry (struct scratch_reg *sr) |
||||
} |
||||
} |
||||
|
||||
-/* Release a scratch register obtained from the preceding function. */ |
||||
+/* Release a scratch register obtained from the preceding function. |
||||
+ |
||||
+ If RELEASE_VIA_POP is true, we just pop the register off the stack |
||||
+ to release it. This is what non-Linux systems use with -fstack-check. |
||||
+ |
||||
+ Otherwise we use OFFSET to locate the saved register and the |
||||
+ allocated stack space becomes part of the local frame and is |
||||
+ deallocated by the epilogue. */ |
||||
|
||||
static void |
||||
-release_scratch_register_on_entry (struct scratch_reg *sr) |
||||
+release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset, |
||||
+ bool release_via_pop) |
||||
{ |
||||
if (sr->saved) |
||||
{ |
||||
- struct machine_function *m = cfun->machine; |
||||
- rtx x, insn = emit_insn (gen_pop (sr->reg)); |
||||
+ if (release_via_pop) |
||||
+ { |
||||
+ struct machine_function *m = cfun->machine; |
||||
+ rtx x, insn = emit_insn (gen_pop (sr->reg)); |
||||
|
||||
- /* The RTX_FRAME_RELATED_P mechanism doesn't know about pop. */ |
||||
- RTX_FRAME_RELATED_P (insn) = 1; |
||||
- x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD)); |
||||
- x = gen_rtx_SET (stack_pointer_rtx, x); |
||||
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, x); |
||||
- m->fs.sp_offset -= UNITS_PER_WORD; |
||||
+ /* The RX FRAME_RELATED_P mechanism doesn't know about pop. */ |
||||
+ RTX_FRAME_RELATED_P (insn) = 1; |
||||
+ x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (UNITS_PER_WORD)); |
||||
+ x = gen_rtx_SET (stack_pointer_rtx, x); |
||||
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, x); |
||||
+ m->fs.sp_offset -= UNITS_PER_WORD; |
||||
+ } |
||||
+ else |
||||
+ { |
||||
+ rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); |
||||
+ x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x)); |
||||
+ emit_insn (x); |
||||
+ } |
||||
} |
||||
} |
||||
|
||||
@@ -12597,7 +12614,7 @@ release_scratch_register_on_entry (struct scratch_reg *sr) |
||||
pushed on the stack. */ |
||||
|
||||
static void |
||||
-ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size, |
||||
+ix86_adjust_stack_and_probe_stack_clash (HOST_WIDE_INT size, |
||||
const bool int_registers_saved) |
||||
{ |
||||
struct machine_function *m = cfun->machine; |
||||
@@ -12713,6 +12730,12 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size, |
||||
struct scratch_reg sr; |
||||
get_scratch_register_on_entry (&sr); |
||||
|
||||
+ /* If we needed to save a register, then account for any space |
||||
+ that was pushed (we are not going to pop the register when |
||||
+ we do the restore). */ |
||||
+ if (sr.saved) |
||||
+ size -= UNITS_PER_WORD; |
||||
+ |
||||
/* Step 1: round SIZE down to a multiple of the interval. */ |
||||
HOST_WIDE_INT rounded_size = size & -probe_interval; |
||||
|
||||
@@ -12761,7 +12784,9 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size, |
||||
m->fs.cfa_reg == stack_pointer_rtx); |
||||
dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size); |
||||
|
||||
- release_scratch_register_on_entry (&sr); |
||||
+ /* This does not deallocate the space reserved for the scratch |
||||
+ register. That will be deallocated in the epilogue. */ |
||||
+ release_scratch_register_on_entry (&sr, size, false); |
||||
} |
||||
|
||||
/* Make sure nothing is scheduled before we are done. */ |
||||
@@ -12774,7 +12799,7 @@ ix86_adjust_stack_and_probe_stack_clash (const HOST_WIDE_INT size, |
||||
pushed on the stack. */ |
||||
|
||||
static void |
||||
-ix86_adjust_stack_and_probe (const HOST_WIDE_INT size, |
||||
+ix86_adjust_stack_and_probe (HOST_WIDE_INT size, |
||||
const bool int_registers_saved) |
||||
{ |
||||
/* We skip the probe for the first interval + a small dope of 4 words and |
||||
@@ -12847,6 +12872,11 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size, |
||||
|
||||
get_scratch_register_on_entry (&sr); |
||||
|
||||
+ /* If we needed to save a register, then account for any space |
||||
+ that was pushed (we are not going to pop the register when |
||||
+ we do the restore). */ |
||||
+ if (sr.saved) |
||||
+ size -= UNITS_PER_WORD; |
||||
|
||||
/* Step 1: round SIZE to the previous multiple of the interval. */ |
||||
|
||||
@@ -12906,7 +12936,9 @@ ix86_adjust_stack_and_probe (const HOST_WIDE_INT size, |
||||
(get_probe_interval () |
||||
+ dope)))); |
||||
|
||||
- release_scratch_register_on_entry (&sr); |
||||
+ /* This does not deallocate the space reserved for the scratch |
||||
+ register. That will be deallocated in the epilogue. */ |
||||
+ release_scratch_register_on_entry (&sr, size, false); |
||||
} |
||||
|
||||
/* Even if the stack pointer isn't the CFA register, we need to correctly |
||||
@@ -13055,7 +13087,7 @@ ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size, |
||||
sr.reg), |
||||
rounded_size - size)); |
||||
|
||||
- release_scratch_register_on_entry (&sr); |
||||
+ release_scratch_register_on_entry (&sr, size, true); |
||||
} |
||||
|
||||
/* Make sure nothing is scheduled before we are done. */ |
||||
|
||||
diff --git a/gcc/testsuite/gcc.target/i386/pr84128.c b/gcc/testsuite/gcc.target/i386/pr84128.c |
||||
new file mode 100644 |
||||
index 0000000..a8323fd6 |
||||
--- /dev/null |
||||
+++ gcc/testsuite/gcc.target/i386/pr84128.c |
||||
@@ -0,0 +1,30 @@ |
||||
+/* { dg-do run } */ |
||||
+/* { dg-options "-O2 -march=i686 -mtune=generic -fstack-clash-protection" } */ |
||||
+/* { dg-require-effective-target ia32 } */ |
||||
+ |
||||
+__attribute__ ((noinline, noclone, weak, regparm (3))) |
||||
+int |
||||
+f1 (long arg0, int (*pf) (long, void *)) |
||||
+{ |
||||
+ unsigned char buf[32768]; |
||||
+ return pf (arg0, buf); |
||||
+} |
||||
+ |
||||
+__attribute__ ((noinline, noclone, weak)) |
||||
+int |
||||
+f2 (long arg0, void *ignored) |
||||
+{ |
||||
+ if (arg0 != 17) |
||||
+ __builtin_abort (); |
||||
+ return 19; |
||||
+} |
||||
+ |
||||
+int |
||||
+main (void) |
||||
+{ |
||||
+ if (f1 (17, f2) != 19) |
||||
+ __builtin_abort (); |
||||
+ return 0; |
||||
+} |
||||
+ |
||||
+ |
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
2018-02-23 Jakub Jelinek <jakub@redhat.com> |
||||
|
||||
PR target/84524 |
||||
* config/i386/sse.md (*<code><mode>3): Replace <mask_prefix3> with |
||||
orig,vex. |
||||
(*<plusminus_insn><mode>3): Likewise. Remove <mask_operand3> uses. |
||||
|
||||
* gcc.c-torture/execute/pr84524.c: New test. |
||||
* gcc.target/i386/avx512bw-pr84524.c: New test. |
||||
|
||||
--- gcc/config/i386/sse.md.jj 2018-02-13 09:31:24.769607162 +0100 |
||||
+++ gcc/config/i386/sse.md 2018-02-23 11:51:00.271477979 +0100 |
||||
@@ -9938,11 +9938,11 @@ (define_insn "*<plusminus_insn><mode>3" |
||||
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" |
||||
"@ |
||||
p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2} |
||||
- vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}" |
||||
+ vp<plusminus_mnemonic><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" |
||||
[(set_attr "isa" "noavx,avx") |
||||
(set_attr "type" "sseiadd") |
||||
(set_attr "prefix_data16" "1,*") |
||||
- (set_attr "prefix" "<mask_prefix3>") |
||||
+ (set_attr "prefix" "orig,vex") |
||||
(set_attr "mode" "<sseinsnmode>")]) |
||||
|
||||
(define_insn "*<plusminus_insn><mode>3_mask" |
||||
@@ -11822,7 +11822,7 @@ (define_insn "*<code><mode>3" |
||||
(eq_attr "mode" "TI")) |
||||
(const_string "1") |
||||
(const_string "*"))) |
||||
- (set_attr "prefix" "<mask_prefix3>") |
||||
+ (set_attr "prefix" "orig,vex") |
||||
(set (attr "mode") |
||||
(cond [(and (match_test "<MODE_SIZE> == 16") |
||||
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) |
||||
--- gcc/testsuite/gcc.c-torture/execute/pr84524.c.jj 2018-02-23 11:54:51.913492631 +0100 |
||||
+++ gcc/testsuite/gcc.c-torture/execute/pr84524.c 2018-02-23 11:59:55.467511836 +0100 |
||||
@@ -0,0 +1,41 @@ |
||||
+/* PR target/84524 */ |
||||
+ |
||||
+__attribute__((noipa)) void |
||||
+foo (unsigned short *x) |
||||
+{ |
||||
+ unsigned short i, v; |
||||
+ unsigned char j; |
||||
+ for (i = 0; i < 256; i++) |
||||
+ { |
||||
+ v = i << 8; |
||||
+ for (j = 0; j < 8; j++) |
||||
+ if (v & 0x8000) |
||||
+ v = (v << 1) ^ 0x1021; |
||||
+ else |
||||
+ v = v << 1; |
||||
+ x[i] = v; |
||||
+ } |
||||
+} |
||||
+ |
||||
+int |
||||
+main () |
||||
+{ |
||||
+ unsigned short a[256]; |
||||
+ |
||||
+ foo (a); |
||||
+ for (int i = 0; i < 256; i++) |
||||
+ { |
||||
+ unsigned short v = i << 8; |
||||
+ for (int j = 0; j < 8; j++) |
||||
+ { |
||||
+ asm volatile ("" : "+r" (v)); |
||||
+ if (v & 0x8000) |
||||
+ v = (v << 1) ^ 0x1021; |
||||
+ else |
||||
+ v = v << 1; |
||||
+ } |
||||
+ if (a[i] != v) |
||||
+ __builtin_abort (); |
||||
+ } |
||||
+ return 0; |
||||
+} |
||||
--- gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c.jj 2018-02-23 11:58:16.919505601 +0100 |
||||
+++ gcc/testsuite/gcc.target/i386/avx512bw-pr84524.c 2018-02-23 11:58:57.377508169 +0100 |
||||
@@ -0,0 +1,14 @@ |
||||
+/* PR target/84524 */ |
||||
+/* { dg-do run { target avx512bw } } */ |
||||
+/* { dg-options "-O3 -mavx512bw" } */ |
||||
+ |
||||
+#include "avx512bw-check.h" |
||||
+ |
||||
+#define main() do_main() |
||||
+#include "../../gcc.c-torture/execute/pr84524.c" |
||||
+ |
||||
+static void |
||||
+avx512bw_test (void) |
||||
+{ |
||||
+ do_main (); |
||||
+} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,81 @@
@@ -0,0 +1,81 @@
|
||||
commit 63256634cd46529bb3e839838f03dc4164feaa4c |
||||
Author: foreese <foreese@138bc75d-0d04-0410-961f-82ee72b054a4> |
||||
Date: Thu Aug 10 12:36:44 2017 +0000 |
||||
|
||||
2017-08-10 Fritz Reese <Reese-Fritz@zai.com> |
||||
|
||||
gcc/fortran/ChangeLog: |
||||
|
||||
* options.c (set_dec_flags, gfc_post_options): Only set flag_d_lines |
||||
with -fdec when not set by user. |
||||
|
||||
gcc/testsuite/ChangeLog: |
||||
|
||||
gfortran.dg/ |
||||
* dec_d_lines_1.f, dec_d_lines_2.f: New. |
||||
|
||||
|
||||
|
||||
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@251024 138bc75d-0d04-0410-961f-82ee72b054a4 |
||||
|
||||
diff --git gcc/fortran/options.c gcc/fortran/options.c |
||||
index 283c8354e06..cd254e93229 100644 |
||||
--- gcc/fortran/options.c |
||||
+++ gcc/fortran/options.c |
||||
@@ -57,9 +57,6 @@ set_dec_flags (int value) |
||||
| GFC_STD_GNU | GFC_STD_LEGACY; |
||||
gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL); |
||||
|
||||
- /* Set -fd-lines-as-comments by default. */ |
||||
- if (value && gfc_current_form != FORM_FREE && gfc_option.flag_d_lines == -1) |
||||
- gfc_option.flag_d_lines = 0; |
||||
|
||||
/* Set other DEC compatibility extensions. */ |
||||
flag_dollar_ok |= value; |
||||
@@ -339,8 +336,15 @@ gfc_post_options (const char **pfilename) |
||||
diagnostic_classify_diagnostic (global_dc, OPT_Wline_truncation, |
||||
DK_ERROR, UNKNOWN_LOCATION); |
||||
} |
||||
- else if (warn_line_truncation == -1) |
||||
- warn_line_truncation = 0; |
||||
+ else |
||||
+ { |
||||
+ /* With -fdec, set -fd-lines-as-comments by default in fixed form. */ |
||||
+ if (flag_dec && gfc_option.flag_d_lines == -1) |
||||
+ gfc_option.flag_d_lines = 0; |
||||
+ |
||||
+ if (warn_line_truncation == -1) |
||||
+ warn_line_truncation = 0; |
||||
+ } |
||||
|
||||
/* If -pedantic, warn about the use of GNU extensions. */ |
||||
if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0) |
||||
diff --git gcc/testsuite/gfortran.dg/dec_d_lines_1.f gcc/testsuite/gfortran.dg/dec_d_lines_1.f |
||||
new file mode 100644 |
||||
index 00000000000..2cc7a01daff |
||||
--- /dev/null |
||||
+++ gcc/testsuite/gfortran.dg/dec_d_lines_1.f |
||||
@@ -0,0 +1,9 @@ |
||||
+! { dg-do compile } |
||||
+! { dg-options "-ffixed-form -fd-lines-as-code -fdec" } |
||||
+! |
||||
+! Ensure -fd-lines-as-code is not overridden by -fdec. |
||||
+! |
||||
+ i = 0 |
||||
+d end |
||||
+ subroutine s |
||||
+D end |
||||
diff --git gcc/testsuite/gfortran.dg/dec_d_lines_2.f gcc/testsuite/gfortran.dg/dec_d_lines_2.f |
||||
new file mode 100644 |
||||
index 00000000000..31eaf5f2328 |
||||
--- /dev/null |
||||
+++ gcc/testsuite/gfortran.dg/dec_d_lines_2.f |
||||
@@ -0,0 +1,8 @@ |
||||
+! { dg-do compile } |
||||
+! { dg-options "-ffixed-form -fdec" } |
||||
+! |
||||
+! Ensure -fd-lines-as-comments is enabled by default with -fdec. |
||||
+! |
||||
+d This is a comment. |
||||
+D This line, too. |
||||
+ end |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
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 |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
--- gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c.jj 2011-01-03 06:50:42.000000000 -0500 |
||||
+++ gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c 2011-02-18 06:28:53.858200077 -0500 |
||||
@@ -1501,6 +1501,8 @@ generate_random_tests (enum FEATURE feat |
||||
int i, r; |
||||
if (len > 'z' - 'a' + 1) |
||||
abort (); |
||||
+ if (getenv ("ALT_CXX_UNDER_TEST") != NULL) |
||||
+ features &= ~FEATURE_VECTOR; |
||||
memset (e, 0, sizeof (e)); |
||||
r = generate_random (); |
||||
if ((r & 7) == 0) |
||||
--- gcc/testsuite/g++.dg/compat/compat.exp.jj 2011-01-03 06:50:42.000000000 -0500 |
||||
+++ gcc/testsuite/g++.dg/compat/compat.exp 2011-02-18 06:30:54.248200398 -0500 |
||||
@@ -116,7 +116,12 @@ if [info exists ALT_CXX_UNDER_TEST] then |
||||
} |
||||
|
||||
# Main loop. |
||||
-foreach src [lsort [find $srcdir/$subdir *_main.C]] { |
||||
+set tests [lsort [find $srcdir/$subdir *_main.C]] |
||||
+if { $use_alt != 0 } then { |
||||
+ set tests [prune $tests $srcdir/$subdir/decimal/*] |
||||
+} |
||||
+ |
||||
+foreach src $tests { |
||||
# If we're only testing specific files and this isn't one of them, skip it. |
||||
if ![runtest_file_p $runtests $src] then { |
||||
continue |
||||
--- gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c.jj 2011-01-03 06:49:58.000000000 -0500 |
||||
+++ gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c 2011-02-18 06:27:54.922262671 -0500 |
||||
@@ -1912,6 +1912,8 @@ generate_random_tests (enum FEATURE feat |
||||
int i, r; |
||||
if (len > 'z' - 'a' + 1) |
||||
abort (); |
||||
+ if (getenv ("ALT_CC_UNDER_TEST") != NULL) |
||||
+ features &= ~FEATURE_VECTOR; |
||||
memset (e, 0, sizeof (e)); |
||||
r = generate_random (); |
||||
if ((r & 7) == 0) |
||||
--- gcc/testsuite/lib/c-compat.exp.jj 2011-01-03 06:48:38.000000000 -0500 |
||||
+++ gcc/testsuite/lib/c-compat.exp 2011-02-18 06:38:19.124265008 -0500 |
||||
@@ -75,7 +75,7 @@ proc compat_setup_dfp { } { |
||||
# If there is an alternate compiler, does it support decimal float types? |
||||
if { $compat_have_dfp == 1 && $compat_use_alt == 1 && $compat_same_alt == 0 } { |
||||
compat-use-alt-compiler |
||||
- set compat_have_dfp [check_effective_target_dfprt_nocache] |
||||
+ set compat_have_dfp 0 |
||||
compat-use-tst-compiler |
||||
verbose "compat_have_dfp for alt compiler: $compat_have_dfp" 2 |
||||
} |
@ -0,0 +1,117 @@
@@ -0,0 +1,117 @@
|
||||
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, |
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
--- 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 |
||||
ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR)) |
||||
ADA_RTS_SUBDIR=./rts$(subst /,_,$(MULTISUBDIR)) |
||||
|
||||
+DEFAULTMULTIFLAGS := |
||||
+ifeq ($(MULTISUBDIR),) |
||||
+targ:=$(subst -, ,$(target)) |
||||
+arch:=$(word 1,$(targ)) |
||||
+ifeq ($(words $(targ)),2) |
||||
+osys:=$(word 2,$(targ)) |
||||
+else |
||||
+osys:=$(word 3,$(targ)) |
||||
+endif |
||||
+ifeq ($(strip $(filter-out i%86 x86_64 powerpc% ppc% s390% sparc% linux%, $(arch) $(osys))),) |
||||
+ifeq ($(shell $(CC) $(CFLAGS) -print-multi-os-directory),../lib64) |
||||
+DEFAULTMULTIFLAGS := -m64 |
||||
+else |
||||
+ifeq ($(strip $(filter-out s390%, $(arch))),) |
||||
+DEFAULTMULTIFLAGS := -m31 |
||||
+else |
||||
+DEFAULTMULTIFLAGS := -m32 |
||||
+endif |
||||
+endif |
||||
+endif |
||||
+endif |
||||
+ |
||||
# exeext should not be used because it's the *host* exeext. We're building |
||||
# a *target* library, aren't we?!? Likewise for CC. Still, provide bogus |
||||
# definitions just in case something slips through the safety net provided |
||||
# by recursive make invocations in gcc/ada/Makefile.in |
||||
LIBADA_FLAGS_TO_PASS = \ |
||||
"MAKEOVERRIDES=" \ |
||||
- "LDFLAGS=$(LDFLAGS)" \ |
||||
+ "LDFLAGS=$(LDFLAGS) $(DEFAULTMULTIFLAGS)" \ |
||||
"LN_S=$(LN_S)" \ |
||||
"SHELL=$(SHELL)" \ |
||||
- "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS)" \ |
||||
- "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS)" \ |
||||
- "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS)" \ |
||||
+ "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ |
||||
+ "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ |
||||
+ "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \ |
||||
"PICFLAG_FOR_TARGET=$(PICFLAG)" \ |
||||
"THREAD_KIND=$(THREAD_KIND)" \ |
||||
"TRACE=$(TRACE)" \ |
||||
@@ -88,7 +110,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 |
||||
@@ -511,6 +511,8 @@ multi-do: |
||||
ADAFLAGS="$(ADAFLAGS) $${flags}" \ |
||||
prefix="$(prefix)" \ |
||||
exec_prefix="$(exec_prefix)" \ |
||||
+ mandir="$(mandir)" \ |
||||
+ infodir="$(infodir)" \ |
||||
GOCFLAGS="$(GOCFLAGS) $${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; |
||||
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 |
||||
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; |
||||
} |
||||
break; |
||||
@@ -3072,7 +3071,8 @@ 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; |
||||
} |
||||
|
||||
--- 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, |
||||
if ((result & CPP_N_WIDTH) == CPP_N_LARGE |
||||
&& CPP_OPTION (pfile, cpp_warn_long_long)) |
||||
{ |
||||
- const char *message = CPP_OPTION (pfile, cplusplus) |
||||
- ? N_("use of C++11 long long integer constant") |
||||
- : N_("use of C99 long long integer constant"); |
||||
- |
||||
if (CPP_OPTION (pfile, c99)) |
||||
cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location, |
||||
- 0, message); |
||||
+ 0, CPP_OPTION (pfile, cplusplus) |
||||
+ ? N_("use of C++11 long long integer constant") |
||||
+ : N_("use of C99 long long integer constant")); |
||||
else |
||||
cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG, |
||||
- virtual_location, 0, message); |
||||
+ virtual_location, 0, |
||||
+ CPP_OPTION (pfile, cplusplus) |
||||
+ ? N_("use of C++11 long long integer constant") |
||||
+ : N_("use of C99 long long integer constant")); |
||||
} |
||||
|
||||
result |= CPP_N_INTEGER; |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
--- libitm/config/x86/target.h.jj 2013-06-23 20:43:50.000000000 +0200 |
||||
+++ libitm/config/x86/target.h 2013-08-13 17:14:57.540012109 +0200 |
||||
@@ -64,7 +64,7 @@ cpu_relax (void) |
||||
|
||||
// Use Intel RTM if supported by the assembler. |
||||
// See gtm_thread::begin_transaction for how these functions are used. |
||||
-#ifdef HAVE_AS_RTM |
||||
+#if 1 /* def HAVE_AS_RTM */ |
||||
#define USE_HTM_FASTPATH |
||||
#ifdef __x86_64__ |
||||
// Use the custom fastpath in ITM_beginTransaction. |
||||
@@ -97,7 +97,10 @@ htm_init () |
||||
static inline uint32_t |
||||
htm_begin () |
||||
{ |
||||
- return _xbegin(); |
||||
+// return _xbegin(); |
||||
+ uint32_t ret; |
||||
+ __asm volatile ("movl $-1, %%eax; .byte 0xc7, 0xf8, 0, 0, 0, 0" : "=a" (ret) : : "memory"); |
||||
+ return ret; |
||||
} |
||||
|
||||
static inline bool |
||||
@@ -109,7 +112,8 @@ htm_begin_success (uint32_t begin_ret) |
||||
static inline void |
||||
htm_commit () |
||||
{ |
||||
- _xend(); |
||||
+// _xend(); |
||||
+ __asm volatile (".byte 0x0f, 0x01, 0xd5" : : : "memory"); |
||||
} |
||||
|
||||
static inline void |
||||
@@ -117,7 +121,8 @@ htm_abort () |
||||
{ |
||||
// ??? According to a yet unpublished ABI rule, 0xff is reserved and |
||||
// supposed to signal a busy lock. Source: andi.kleen@intel.com |
||||
- _xabort(0xff); |
||||
+// _xabort(0xff); |
||||
+ __asm volatile (".byte 0xc6, 0xf8, 0xff" : : : "memory"); |
||||
} |
||||
|
||||
static inline bool |
||||
@@ -130,7 +135,10 @@ htm_abort_should_retry (uint32_t begin_r |
||||
static inline bool |
||||
htm_transaction_active () |
||||
{ |
||||
- return _xtest() != 0; |
||||
+// return _xtest() != 0; |
||||
+ bool ret; |
||||
+ __asm volatile (".byte 0x0f, 0x01, 0xd6; setne %%al" : "=a" (ret) : : "memory"); |
||||
+ return ret; |
||||
} |
||||
#endif |
||||
|
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
--- 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 |
||||
;; |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
2008-06-09 Jakub Jelinek <jakub@redhat.com> |
||||
|
||||
* omp.h.in (omp_nest_lock_t): Fix up for Linux multilibs. |
||||
|
||||
--- libgomp/omp.h.in.jj 2008-06-09 13:34:05.000000000 +0200 |
||||
+++ libgomp/omp.h.in 2008-06-09 13:34:48.000000000 +0200 |
||||
@@ -42,8 +42,8 @@ typedef struct |
||||
|
||||
typedef struct |
||||
{ |
||||
- unsigned char _x[@OMP_NEST_LOCK_SIZE@] |
||||
- __attribute__((__aligned__(@OMP_NEST_LOCK_ALIGN@))); |
||||
+ unsigned char _x[8 + sizeof (void *)] |
||||
+ __attribute__((__aligned__(sizeof (void *)))); |
||||
} omp_nest_lock_t; |
||||
#endif |
||||
|
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
libtool sucks. |
||||
--- ltmain.sh.jj 2007-12-07 14:53:21.000000000 +0100 |
||||
+++ ltmain.sh 2008-09-05 21:51:48.000000000 +0200 |
||||
@@ -5394,6 +5394,7 @@ EOF |
||||
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 |
||||
if test -n "$hardcode_libdir_flag_spec"; then |
||||
if test -n "$hardcode_libdir_separator"; then |
||||
if test -z "$hardcode_libdirs"; then |
||||
@@ -6071,6 +6072,7 @@ EOF |
||||
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 |
||||
if test -n "$hardcode_libdir_flag_spec"; then |
||||
if test -n "$hardcode_libdir_separator"; then |
||||
if test -z "$hardcode_libdirs"; then |
||||
@@ -6120,6 +6122,7 @@ EOF |
||||
rpath= |
||||
hardcode_libdirs= |
||||
for libdir in $finalize_rpath; do |
||||
+ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac |
||||
if test -n "$hardcode_libdir_flag_spec"; then |
||||
if test -n "$hardcode_libdir_separator"; then |
||||
if test -z "$hardcode_libdirs"; then |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
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 |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
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/alpha/elf.h (LINK_EH_SPEC): Likewise. |
||||
* config/ia64/linux.h (LINK_EH_SPEC): Likewise. |
||||
|
||||
--- gcc/config/alpha/elf.h.jj 2011-01-03 12:52:31.118056764 +0100 |
||||
+++ gcc/config/alpha/elf.h 2011-01-04 18:14:10.931874160 +0100 |
||||
@@ -168,5 +168,5 @@ extern int alpha_this_gpdisp_sequence_nu |
||||
I imagine that other systems will catch up. In the meantime, it |
||||
doesn't harm to make sure that the data exists to be used later. */ |
||||
#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 |
||||
--- gcc/config/ia64/linux.h.jj 2011-01-03 13:02:11.462994522 +0100 |
||||
+++ gcc/config/ia64/linux.h 2011-01-04 18:14:10.931874160 +0100 |
||||
@@ -76,7 +76,7 @@ do { \ |
||||
Signalize that because we have fde-glibc, we don't need all C shared libs |
||||
linked against -lgcc_s. */ |
||||
#undef LINK_EH_SPEC |
||||
-#define LINK_EH_SPEC "" |
||||
+#define LINK_EH_SPEC "--no-add-needed " |
||||
|
||||
#undef TARGET_INIT_LIBFUNCS |
||||
#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 |
||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC |
||||
|
||||
#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 |
||||
|
||||
#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__ \ |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
2014-07-23 Jonathan Wakely <jwakely@redhat.com> |
||||
|
||||
* testsuite/30_threads/condition_variable_any/rh1118870.cc: New test. |
||||
|
||||
--- libstdc++-v3/testsuite/30_threads/condition_variable_any/rh1118870.cc |
||||
+++ libstdc++-v3/testsuite/30_threads/condition_variable_any/rh1118870.cc |
||||
@@ -0,0 +1,13 @@ |
||||
+// { dg-options " -std=gnu++11 -pthread" } |
||||
+#include <condition_variable> |
||||
+#include <cstring> |
||||
+ |
||||
+int main() |
||||
+{ |
||||
+ const size_t sz = sizeof(std::condition_variable_any); |
||||
+ char garbage[sz]; |
||||
+ memset(garbage, 0xff, sz); |
||||
+ auto cond = new ((void*)garbage) std::condition_variable_any(); |
||||
+ cond->notify_all(); |
||||
+ cond->~condition_variable_any(); |
||||
+} |
@ -0,0 +1,445 @@
@@ -0,0 +1,445 @@
|
||||
--- 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*] } { |
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
--- 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" |
||||
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" |
||||
extra_options="${extra_options} sparc/long-double-switch.opt" |
||||
case ${target} in |
||||
@@ -2844,7 +2844,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" |
||||
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 |
||||
+++ libgcc/config.host 2008-04-24 15:46:49.000000000 -0500 |
||||
@@ -1002,7 +1002,7 @@ sparc-*-elf*) |
||||
tmake_file="${tmake_file} t-fdpbit t-crtfm" |
||||
extra_parts="$extra_parts crti.o crtn.o crtfastmath.o" |
||||
;; |
||||
-sparc-*-linux*) # SPARC's running GNU/Linux, libc6 |
||||
+sparc-*-linux* | sparcv9-*-linux*) # SPARC's running GNU/Linux, libc6 |
||||
tmake_file="${tmake_file} t-crtfm" |
||||
if test "${host_address}" = 64; then |
||||
tmake_file="$tmake_file sparc/t-linux64" |
||||
@@ -1050,7 +1050,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd* |
||||
tmake_file="$tmake_file t-crtfm" |
||||
extra_parts="$extra_parts crtfastmath.o" |
||||
;; |
||||
-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux |
||||
+sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux |
||||
extra_parts="$extra_parts crtfastmath.o" |
||||
tmake_file="${tmake_file} t-crtfm sparc/t-linux" |
||||
if test "${host_address}" = 64; then |
Loading…
Reference in new issue