aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog71
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/calls.cc10
-rw-r--r--gcc/cobol/ChangeLog39
-rw-r--r--gcc/cobol/cobol1.cc8
-rw-r--r--gcc/cobol/gcobol.12
-rw-r--r--gcc/cobol/genapi.cc21
-rw-r--r--gcc/cobol/lang.opt10
-rw-r--r--gcc/cobol/lang.opt.urls6
-rw-r--r--gcc/cobol/parse.y12
-rw-r--r--gcc/cobol/scan.l6
-rw-r--r--gcc/cobol/token_names.h2
-rw-r--r--gcc/cobol/util.cc12
-rw-r--r--gcc/common/config/s390/s390-common.cc4
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config.in7
-rw-r--r--gcc/config/i386/i386.cc6
-rw-r--r--gcc/config/s390/9175.md316
-rw-r--r--gcc/config/s390/driver-native.cc4
-rw-r--r--gcc/config/s390/s390-builtins.def8
-rw-r--r--gcc/config/s390/s390-c.cc4
-rw-r--r--gcc/config/s390/s390-opts.h2
-rw-r--r--gcc/config/s390/s390.cc37
-rw-r--r--gcc/config/s390/s390.h18
-rw-r--r--gcc/config/s390/s390.md39
-rw-r--r--gcc/config/s390/s390.opt5
-rwxr-xr-xgcc/configure40
-rw-r--r--gcc/configure.ac15
-rw-r--r--gcc/cp/ChangeLog39
-rw-r--r--gcc/cp/constexpr.cc59
-rw-r--r--gcc/cp/constraint.cc4
-rw-r--r--gcc/cp/module.cc60
-rw-r--r--gcc/d/ChangeLog18
-rw-r--r--gcc/d/d-compiler.cc37
-rw-r--r--gcc/d/d-lang.cc19
-rw-r--r--gcc/d/gdc.texi6
-rw-r--r--gcc/d/lang.opt4
-rw-r--r--gcc/d/lang.opt.urls3
-rw-r--r--gcc/doc/gm2.texi8
-rw-r--r--gcc/doc/install.texi6
-rw-r--r--gcc/doc/invoke.texi2
-rw-r--r--gcc/expmed.cc2
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/interface.cc31
-rw-r--r--gcc/gcc.cc7
-rw-r--r--gcc/ipa-cp.cc158
-rw-r--r--gcc/ipa-prop.cc76
-rw-r--r--gcc/ipa-prop.h15
-rw-r--r--gcc/lto-streamer-out.cc2
-rw-r--r--gcc/lto-streamer.h1
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/ast/rust-ast.h1
-rw-r--r--gcc/rust/ast/rust-expr.h12
-rw-r--r--gcc/rust/checks/errors/rust-const-checker.cc3
-rw-r--r--gcc/rust/expand/rust-macro-builtins-format-args.cc7
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc2
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc21
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.cc72
-rw-r--r--gcc/rust/expand/rust-token-tree-desugar.h55
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc2
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc7
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc12
-rw-r--r--gcc/rust/rust-gcc.cc254
-rw-r--r--gcc/rust/rust-session-manager.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc129
-rw-r--r--gcc/rust/util/rust-attribute-values.h27
-rw-r--r--gcc/rust/util/rust-attributes.cc22
-rw-r--r--gcc/rust/util/rust-attributes.h7
-rw-r--r--gcc/rust/util/rust-lang-item.cc1
-rw-r--r--gcc/rust/util/rust-lang-item.h2
-rw-r--r--gcc/testsuite/ChangeLog70
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic20.C13
-rw-r--r--gcc/testsuite/g++.dg/modules/lambda-8_b.C2
-rw-r--r--gcc/testsuite/g++.dg/modules/leg-merge-4_c.C6
-rw-r--r--gcc/testsuite/g++.dg/modules/noexcept-4_a.H6
-rw-r--r--gcc/testsuite/g++.dg/modules/noexcept-4_b.C18
-rw-r--r--gcc/testsuite/g++.dg/torture/pr119778.C20
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr119318.c38
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr119530.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr118476-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr119757.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119784a.c96
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119784b.c87
-rw-r--r--gcc/testsuite/gdc.dg/import-c/import-c.exp29
-rw-r--r--gcc/testsuite/gdc.dg/import-c/pr119761.d2
-rw-r--r--gcc/testsuite/gdc.dg/import-c/pr119761c.c4
-rw-r--r--gcc/testsuite/gdc.dg/torture/imports/pr109023.d3
-rw-r--r--gcc/testsuite/gdc.dg/torture/pr109023.d6
-rw-r--r--gcc/testsuite/gfortran.dg/interface_59.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/pr119502.f9015
-rw-r--r--gcc/testsuite/gm2.dg/doc/examples/pass/doc-examples-pass.exp18
-rw-r--r--gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd.mod32
-rw-r--r--gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd2.mod32
-rw-r--r--gcc/testsuite/gm2.dg/doc/examples/pass/hello.mod10
-rw-r--r--gcc/testsuite/gm2.dg/doc/examples/pass/hellopim.mod10
-rw-r--r--gcc/testsuite/gnat.dg/lto29.adb9
-rw-r--r--gcc/testsuite/gnat.dg/lto29_pkg.ads15
-rw-r--r--gcc/testsuite/rust/compile/enum_discriminant2.rs9
-rw-r--r--gcc/testsuite/rust/compile/format_args_extra_comma.rs47
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs10
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs80
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs10
-rw-r--r--gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs81
-rw-r--r--gcc/testsuite/rust/compile/track_caller.rs6
-rw-r--r--gcc/testsuite/rust/execute/torture/min_specialization2.rs31
-rw-r--r--gcc/testsuite/rust/execute/torture/min_specialization3.rs36
-rw-r--r--gcc/tree-inline.cc7
-rw-r--r--gcc/tree-pretty-print.cc2
-rw-r--r--gcc/tree-vect-slp.cc24
110 files changed, 2430 insertions, 444 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1530dcb..f970c13 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,74 @@
+2025-04-13 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
+
+ * config/s390/s390.cc: Add z17 scheduler description.
+ * config/s390/s390.h: Ditto.
+ * config/s390/s390.md: Ditto.
+ * config/s390/9175.md: New file.
+
+2025-04-13 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
+
+ * common/config/s390/s390-common.cc: Rename arch15 to z17.
+ * config.gcc: Add z17.
+ * config/s390/driver-native.cc: Detect z17 machine.
+ * config/s390/s390-builtins.def (B_VXE3): Rename arch15 to z17.
+ * config/s390/s390-c.cc (s390_resolve_overloaded_builtin): Ditto.
+ * config/s390/s390-opts.h (enum processor_type): Ditto.
+ * config/s390/s390.cc: Ditto.
+ * config/s390/s390.h: Ditto.
+ * config/s390/s390.md: Ditto.
+ * config/s390/s390.opt: Add z17.
+ * doc/invoke.texi: Ditto.
+
+2025-04-12 Sandra Loosemore <sloosemore@baylibre.com>
+
+ PR target/97585
+ * doc/invoke.texi (x86 Options): Document list of extensions
+ supported by -march=x86_64, according to the declaration of
+ PTA_X86_64_BASELINE in config/i386/i386.h.
+
+2025-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR driver/119727
+ * gcc.cc (files_equal_p): Rewritten using fopen/fgets/fclose instead
+ of open/fstat/read/close. At the start of lines, ignore lowercase
+ hexadecimal addresses followed by space.
+
+2025-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/119722
+ * gimple-lower-bitint.h (build_bitint_stmt_ssa_conflicts): Add
+ CLEAR argument.
+ * gimple-lower-bitint.cc (build_bitint_stmt_ssa_conflicts): Add
+ CLEAR argument. Call clear on gimple_assign_copy_p rhs1 if lhs
+ is large/huge bitint unless lhs is not in names.
+ * tree-ssa-coalesce.cc (build_ssa_conflict_graph): Adjust
+ build_bitint_stmt_ssa_conflicts caller. Move gimple_assign_copy_p
+ handling to after the build_bitint_stmt_ssa_conflicts call.
+
+2025-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/119718
+ * tree-tailcall.cc (maybe_error_musttail): Dump the GIMPLE at the
+ end of the Cannot tail-call line rather than on the line before it.
+ * calls.cc (maybe_complain_about_tail_call): Dump the GENERIC
+ at the end of the ;; Cannot tail-call line rather than on the
+ line before it.
+
+2025-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/119718
+ * tree-tailcall.cc (maybe_error_musttail): Only dump into dump_file
+ if dump_flags & TDF_DETAILS. Use "Cannot tail-call: " prefix instead
+ of "Cannot convert: ".
+ (find_tail_calls, tree_optimize_tail_calls_1): Formatting fixes
+ for maybe_error_musttail calls.
+ * calls.cc (maybe_complain_about_tail_call): Emit also a message
+ into dump_file when dump_flags & TDF_DETAILS for CALL_EXPR_TAILCALL
+ calls.
+ (initialize_argument_information): Formatting fix for
+ maybe_complain_about_tail_call calls.
+ (can_implement_as_sibling_call_p, expand_call): Likewise.
+
2025-04-11 Sandra Loosemore <sloosemore@baylibre.com>
PR c++/106618
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d986e55..1e2b10c 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20250412
+20250414
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index f7a9025..bc92ffe 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2025-04-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/119643
+ * sem_ch8.adb (Inherit_Renamed_Profile): Add guard against the
+ peculiarities of Natural and Positive.
+
2025-04-07 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.cc (convert) <POINTER_TYPE>: Use fold_convert
diff --git a/gcc/calls.cc b/gcc/calls.cc
index 372fab3..076e046 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -1273,11 +1273,6 @@ void
maybe_complain_about_tail_call (tree call_expr, const char *reason)
{
gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
- if (CALL_EXPR_MUST_TAIL_CALL (call_expr))
- {
- error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
- CALL_EXPR_MUST_TAIL_CALL (call_expr) = 0;
- }
if (CALL_EXPR_TAILCALL (call_expr)
&& dump_file
&& (dump_flags & TDF_DETAILS))
@@ -1286,6 +1281,11 @@ maybe_complain_about_tail_call (tree call_expr, const char *reason)
print_generic_expr (dump_file, call_expr, TDF_SLIM);
fprintf (dump_file, "\n");
}
+ if (CALL_EXPR_MUST_TAIL_CALL (call_expr))
+ {
+ error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
+ CALL_EXPR_MUST_TAIL_CALL (call_expr) = 0;
+ }
}
/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog
index a792b3a..07c687c 100644
--- a/gcc/cobol/ChangeLog
+++ b/gcc/cobol/ChangeLog
@@ -1,3 +1,42 @@
+2025-04-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+ Simon Sobisch <simonsobisch@gnu.org>
+
+ PR cobol/119217
+ * parse.y: Rename OVERFLOW to OVERFLOW_kw.
+ Specify type name in %token directive.
+ * scan.l: Likewise.
+ * token_names.h: Regenerate.
+
+2025-04-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR cobol/119217
+ * util.cc (class timespec_t): Rename to cbl_timespec.
+
+2025-04-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * genapi.cc: Include target.h.
+ (section_label): Use ASM_COMMENT_START.
+ (paragraph_label): Likewise.
+ (parser_perform): Likewise.
+ (internal_perform_through): Likewise.
+ (hijack_for_development): Likewise.
+
+2025-04-12 Bob Dubner <rdubner@symas.com>
+
+ PR cobol/119694
+ * cbldiag.h: Eliminate getenv() calls.
+ * cdf.y: Likewise.
+ * cobol1.cc: Likewise.
+ * except.cc: Likewise.
+ * genapi.cc: Likewise.
+ * lexio.cc: Likewise.
+ * parse.y: Likewise.
+ * scan_ante.h: Likewise.
+ * show_parse.h: Likewise.
+ * symbols.cc: Likewise.
+ * symfind.cc: Likewise.
+ * util.cc: Likewise.
+
2025-04-09 Bob Dubner <rdubner@symas.com>
PR cobol/119682
diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc
index 98d15a8..3bd21c7 100644
--- a/gcc/cobol/cobol1.cc
+++ b/gcc/cobol/cobol1.cc
@@ -385,10 +385,6 @@ cobol_langhook_handle_option (size_t scode,
return true;
}
- case OPT_fmax_errors:
- flag_max_errors = atoi(arg);
- return true;
-
case OPT_ffixed_form:
cobol_set_indicator_column(-7);
return true;
@@ -413,8 +409,8 @@ cobol_langhook_handle_option (size_t scode,
}
return true;
case OPT_include:
- if( ! include_file_add(cobol_include) ) {
- cbl_errx( "could not include %s", cobol_include);
+ if( ! include_file_add(arg) ) {
+ cbl_errx( "could not include %s", arg);
}
return true;
diff --git a/gcc/cobol/gcobol.1 b/gcc/cobol/gcobol.1
index 64c017c..4377c14 100644
--- a/gcc/cobol/gcobol.1
+++ b/gcc/cobol/gcobol.1
@@ -224,7 +224,7 @@ had appeared.
Not all exception conditions are implemented. Any that are not
produce a warning message.
.
-.It Fl fmax-errors Ar nerror
+.It Fl fmax-errors Ns Li = Ns Ar nerror
.Ar nerror
represents the number of error messages produced. Without this option,
.Nm
diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 622387f..c8911f9 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -34,6 +34,7 @@
#include "tree-iterator.h"
#include "stringpool.h"
#include "diagnostic-core.h"
+#include "target.h"
#include "../../libgcobol/ec.h"
#include "../../libgcobol/common-defs.h"
@@ -2357,7 +2358,8 @@ section_label(struct cbl_proc_t *procedure)
cbl_label_t *label = procedure->label;
// The _initialize_program section isn't relevant.
- char *psz = xasprintf("# SECTION %s in %s (%ld)",
+ char *psz = xasprintf("%s SECTION %s in %s (%ld)",
+ ASM_COMMENT_START,
label->name,
current_function->our_unmangled_name,
deconflictor);
@@ -2408,7 +2410,8 @@ paragraph_label(struct cbl_proc_t *procedure)
char *psz1 =
xasprintf(
- "# PARAGRAPH %s of %s in %s (%ld)",
+ "%s PARAGRAPH %s of %s in %s (%ld)",
+ ASM_COMMENT_START,
para_name ? para_name: "" ,
section_name ? section_name: "(null)" ,
current_function->our_unmangled_name ? current_function->our_unmangled_name: "" ,
@@ -3006,7 +3009,8 @@ parser_perform(cbl_label_t *label, bool suppress_nexting)
para_name = label->name;
sect_name = section_label->name;
sprintf(ach,
- "# PERFORM %s of %s of %s (%ld)",
+ "%s PERFORM %s of %s of %s (%ld)",
+ ASM_COMMENT_START,
para_name,
sect_name,
program_name,
@@ -3018,7 +3022,8 @@ parser_perform(cbl_label_t *label, bool suppress_nexting)
{
sect_name = label->name;
sprintf(ach,
- "# PERFORM %s of %s (%ld)",
+ "%s PERFORM %s of %s (%ld)",
+ ASM_COMMENT_START,
sect_name,
program_name,
deconflictor);
@@ -3170,8 +3175,8 @@ internal_perform_through( cbl_label_t *proc_1,
pseudo_return_push(proc2, return_addr);
// Create the code that will launch the first procedure
- gg_insert_into_assembler("# PERFORM %s THROUGH %s",
- proc_1->name, proc_2->name);
+ gg_insert_into_assembler("%s PERFORM %s THROUGH %s",
+ ASM_COMMENT_START, proc_1->name, proc_2->name);
if( !suppress_nexting )
{
@@ -13606,7 +13611,7 @@ hijack_for_development(const char *funcname)
// Assume that funcname is lowercase with no hyphens
enter_program_common(funcname, funcname);
parser_display_literal("You have been hijacked by a program named \"dubner\"");
- gg_insert_into_assembler("# HIJACKED DUBNER CODE START");
+ gg_insert_into_assembler("%s HIJACKED DUBNER CODE START", ASM_COMMENT_START);
for(int i=0; i<10; i++)
{
@@ -13619,7 +13624,7 @@ hijack_for_development(const char *funcname)
NULL_TREE);
}
- gg_insert_into_assembler("# HIJACKED DUBNER CODE END");
+ gg_insert_into_assembler("%s HIJACKED DUBNER CODE END", ASM_COMMENT_START);
gg_return(0);
}
diff --git a/gcc/cobol/lang.opt b/gcc/cobol/lang.opt
index 42c4020..59278a1 100644
--- a/gcc/cobol/lang.opt
+++ b/gcc/cobol/lang.opt
@@ -77,10 +77,6 @@ ffixed-form
Cobol RejectNegative
Assume that the source file is fixed form.
-fsyntax-only
-Cobol RejectNegative
-; Documented in c.opt
-
ffree-form
Cobol RejectNegative
Assume that the source file is free form.
@@ -93,10 +89,6 @@ finternal-ebcdic
Cobol Var(cobol_ebcdic, 1) Init(0)
-finternal-ebcdic Internal processing is in EBCDIC Code Page 1140
-fmax-errors
-Cobol Joined Separate
-; Documented in C
-
fstatic-call
Cobol Var(cobol_static_call, 1) Init(1)
Enable/disable static linkage for CALL literals
@@ -118,7 +110,7 @@ Cobol Joined Separate
; Documented in C
include
-Cobol Joined Separate Var(cobol_include)
+Cobol Joined Separate
; Documented in C
isysroot
diff --git a/gcc/cobol/lang.opt.urls b/gcc/cobol/lang.opt.urls
index 6a5dc1c..69f5297 100644
--- a/gcc/cobol/lang.opt.urls
+++ b/gcc/cobol/lang.opt.urls
@@ -13,15 +13,9 @@ UrlSuffix(gcc/Directory-Options.html#index-I) LangUrlSuffix_D(gdc/Directory-Opti
ffixed-form
LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-ffixed-form)
-fsyntax-only
-UrlSuffix(gcc/Warning-Options.html#index-fsyntax-only) LangUrlSuffix_D(gdc/Warnings.html#index-fno-syntax-only) LangUrlSuffix_Fortran(gfortran/Error-and-Warning-Options.html#index-fsyntax-only)
-
ffree-form
LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-ffree-form)
-fmax-errors
-UrlSuffix(gcc/Warning-Options.html#index-fmax-errors) LangUrlSuffix_D(gdc/Warnings.html#index-fmax-errors)
-
iprefix
UrlSuffix(gcc/Directory-Options.html#index-iprefix) LangUrlSuffix_D(gdc/Directory-Options.html#index-iprefix) LangUrlSuffix_Fortran(gfortran/Preprocessing-Options.html#index-iprefix)
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index d14cc31..55c26fe 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -338,7 +338,7 @@
%token <number> INVALID
%token <number> NUMBER NEGATIVE
%token <numstr> NUMSTR "numeric literal"
-%token <number> OVERFLOW
+%token <number> OVERFLOW_kw "OVERFLOW"
%token <computational> COMPUTATIONAL
%token <boolean> PERFORM BACKWARD
@@ -997,7 +997,7 @@
DELETE DISPLAY DIVIDE EVALUATE END EOP EXIT FILLER_kw
GOBACK GOTO
INITIALIZE INSPECT
- MERGE MOVE MULTIPLY OPEN OVERFLOW PARAGRAPH PERFORM
+ MERGE MOVE MULTIPLY OPEN OVERFLOW_kw PARAGRAPH PERFORM
READ RELEASE RETURN REWRITE
SEARCH SET SELECT SORT SORT_MERGE
STRING_kw STOP SUBTRACT START
@@ -9488,7 +9488,7 @@ call_except: EXCEPTION
std::swap($$.on_error, $$.not_error);
}
}
- | OVERFLOW
+ | OVERFLOW_kw
{
$$.not_error = NULL;
$$.on_error = label_add(LblArith,
@@ -9496,7 +9496,7 @@ call_except: EXCEPTION
if( !$$.on_error ) YYERROR;
parser_call_exception( $$.on_error );
- assert( $1 == OVERFLOW || $1 == NOT );
+ assert( $1 == OVERFLOW_kw || $1 == NOT );
if( $1 == NOT ) {
std::swap($$.on_error, $$.not_error);
}
@@ -9751,7 +9751,7 @@ on_overflows: on_overflow[over] statements %prec ADD
}
;
-on_overflow: OVERFLOW
+on_overflow: OVERFLOW_kw
{
$$.not_error = NULL;
$$.on_error = label_add(LblString,
@@ -9759,7 +9759,7 @@ on_overflow: OVERFLOW
if( !$$.on_error ) YYERROR;
parser_string_overflow( $$.on_error );
- assert( $1 == OVERFLOW || $1 == NOT );
+ assert( $1 == OVERFLOW_kw || $1 == NOT );
if( $1 == NOT ) {
std::swap($$.on_error, $$.not_error);
}
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index 2cb7d30..e30634d 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -1543,9 +1543,9 @@ USE({SPC}FOR)? { return USE; }
NOT{SPC}(ON{SPC})?EXCEPTION {
yylval.number = NOT; return EXCEPTION; }
- (ON{SPC})?OVERFLOW { yylval.number = OVERFLOW; return OVERFLOW; }
+ (ON{SPC})?OVERFLOW { yylval.number = OVERFLOW_kw; return OVERFLOW_kw; }
NOT{SPC}(ON{SPC})?OVERFLOW {
- yylval.number = NOT; return OVERFLOW; }
+ yylval.number = NOT; return OVERFLOW_kw; }
(AT{SPC})?END/[[:space:]] { yylval.number = END;
return END; }
@@ -2312,7 +2312,7 @@ BASIS { yy_push_state(basis); return BASIS; }
ORGANIZATION { return ORGANIZATION; }
OTHER { return OTHER; }
OUTPUT { return OUTPUT; }
- OVERFLOW { return OVERFLOW; }
+ OVERFLOW { return OVERFLOW_kw; }
OVERRIDE { return OVERRIDE; }
PACKED-DECIMAL { return PACKED_DECIMAL; }
PAGE { return PAGE; }
diff --git a/gcc/cobol/token_names.h b/gcc/cobol/token_names.h
index a082078..d1e3b5d 100644
--- a/gcc/cobol/token_names.h
+++ b/gcc/cobol/token_names.h
@@ -49,7 +49,7 @@ tokens = {
{ "number", NUMBER }, // 302
{ "negative", NEGATIVE }, // 303
{ "numstr", NUMSTR }, // 304
- { "overflow", OVERFLOW }, // 305
+ { "overflow", OVERFLOW_kw }, // 305
{ "computational", COMPUTATIONAL }, // 306
{ "perform", PERFORM }, // 307
{ "backward", BACKWARD }, // 308
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index f7b89b8..f28fddf 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -2099,20 +2099,20 @@ cobol_fileline_set( const char line[] ) {
return file.name;
}
-class timespec_t {
+class cbl_timespec {
struct timespec now;
public:
- timespec_t() {
+ cbl_timespec() {
clock_gettime(CLOCK_MONOTONIC, &now);
}
double ns() const {
return now.tv_sec * 1000000000 + now.tv_nsec;
}
- friend double operator-( const timespec_t& now, const timespec_t& then );
+ friend double operator-( const cbl_timespec& now, const cbl_timespec& then );
};
double
-operator-( const timespec_t& then, const timespec_t& now ) {
+operator-( const cbl_timespec& then, const cbl_timespec& now ) {
return (now.ns() - then.ns()) / 1000000000;
}
@@ -2125,11 +2125,11 @@ parse_file( const char filename[] )
parser_enter_file(filename);
- timespec_t start;
+ cbl_timespec start;
int erc = yyparse();
- timespec_t finish;
+ cbl_timespec finish;
double dt = finish - start;
parser_leave_file();
diff --git a/gcc/common/config/s390/s390-common.cc b/gcc/common/config/s390/s390-common.cc
index 4b0691d..8a147d7 100644
--- a/gcc/common/config/s390/s390-common.cc
+++ b/gcc/common/config/s390/s390-common.cc
@@ -54,10 +54,10 @@ EXPORTED_CONST int processor_flags_table[] =
| PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 | PF_TX
| PF_Z13 | PF_VX | PF_VXE | PF_Z14 | PF_VXE2 | PF_Z15
| PF_NNPA | PF_Z16,
- /* arch15 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT
+ /* z17 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT
| PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 | PF_TX
| PF_Z13 | PF_VX | PF_VXE | PF_Z14 | PF_VXE2 | PF_Z15
- | PF_NNPA | PF_Z16 | PF_VXE3 | PF_ARCH15
+ | PF_NNPA | PF_Z16 | PF_VXE3 | PF_Z17
};
/* Change optimizations to be performed, depending on the
diff --git a/gcc/config.gcc b/gcc/config.gcc
index f7f2002..40b50dc 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -5756,7 +5756,7 @@ case "${target}" in
for which in arch tune; do
eval "val=\$with_$which"
case ${val} in
- "" | native | z900 | z990 | z9-109 | z9-ec | z10 | z196 | zEC12 | z13 | z14 | z15 | z16 | arch5 | arch6 | arch7 | arch8 | arch9 | arch10 | arch11 | arch12 | arch13 | arch14 | arch15 )
+ "" | native | z900 | z990 | z9-109 | z9-ec | z10 | z196 | zEC12 | z13 | z14 | z15 | z16 | z17 | arch5 | arch6 | arch7 | arch8 | arch9 | arch10 | arch11 | arch12 | arch13 | arch14 | arch15 )
# OK
;;
*)
diff --git a/gcc/config.in b/gcc/config.in
index 7c89cab..a79c51a 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -2320,6 +2320,13 @@
#endif
+/* Define if personality and ADDR_NO_RANDOMIZE are declared in
+ sys/personality.h. */
+#ifndef USED_FOR_TARGET
+#undef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
+#endif
+
+
/* Define which stat syscall is able to handle 64bit indodes. */
#ifndef USED_FOR_TARGET
#undef HOST_STAT_FOR_64BIT_INODES
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 4f8380c4..b172f71 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -458,6 +458,9 @@ int ix86_arch_specified;
indirect thunk pushes the return address onto stack, destroying
red-zone.
+ NB: Don't use red-zone for functions with no_caller_saved_registers
+ and 32 GPRs since 128-byte red-zone is too small for 31 GPRs.
+
TODO: If we can reserve the first 2 WORDs, for PUSH and, another
for CALL, in red-zone, we can allow local indirect jumps with
indirect thunk. */
@@ -467,6 +470,9 @@ ix86_using_red_zone (void)
{
return (TARGET_RED_ZONE
&& !TARGET_64BIT_MS_ABI
+ && (!TARGET_APX_EGPR
+ || (cfun->machine->call_saved_registers
+ != TYPE_NO_CALLER_SAVED_REGISTERS))
&& (!cfun->machine->has_local_indirect_jump
|| cfun->machine->indirect_branch_type == indirect_branch_keep));
}
diff --git a/gcc/config/s390/9175.md b/gcc/config/s390/9175.md
new file mode 100644
index 0000000..d0ac0e1
--- /dev/null
+++ b/gcc/config/s390/9175.md
@@ -0,0 +1,316 @@
+;; Scheduling description for z17.
+;; Copyright (C) 2025 Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 3, or (at your option) any later
+;; version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_attr "z17_unit_fpd" ""
+ (cond [(eq_attr "mnemonic" "ddb,ddbr,deb,debr,dxbr,sqdb,sqdbr,sqeb,sqebr,\
+sqxbr,vdf,vdg,vdlf,vdlg,vdlq,vdq,vfddb,vfdsb,vfsqdb,vfsqsb,vrf,vrg,vrlf,vrlg,\
+vrlq,vrq,wfddb,wfdsb,wfdxb,wfsqdb,wfsqxb")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_unit_fxa" ""
+ (cond [(eq_attr "mnemonic" "a,afi,ag,agf,agfi,agfr,agh,aghi,aghik,agr,agrk,ah,\
+ahi,ahik,ahy,al,alc,alcg,alcgr,alcr,alfi,alg,algf,algfi,algfr,alghsik,algr,\
+algrk,alhsik,alr,alrk,aly,ar,ark,ay,bdepg,bextg,clzg,ctzg,etnd,flogr,ic,icm,\
+icmh,icmy,icy,iihf,iilf,ipm,la,larl,lay,lb,lbr,lcgfr,lcgr,lcr,lgb,lgbr,lgf,\
+lgfi,lgfr,lgfrl,lgh,lghi,lghr,lghrl,lgr,lh,lhi,lhr,lhrl,lhy,llcr,llgcr,llgfr,\
+llghr,llgtr,llhr,llihf,llihh,llihl,llilf,llilh,llill,llxab,llxaf,llxag,llxah,\
+llxaq,lngfr,lngr,lnr,loc,locg,locghi,locgr,lochi,locr,lpgfr,lpgr,lpr,lr,lrv,\
+lrvg,lrvgr,lrvh,lrvr,lt,ltg,ltgf,ltgfr,ltgr,ltr,lxab,lxaf,lxag,lxah,lxaq,m,mfy,\
+mg,mgh,mghi,mgrk,mh,mhi,mhy,ml,mlg,mlgr,mlr,mr,ms,msc,msfi,msg,msgc,msgf,msgfi,\
+msgfr,msgr,msgrkc,msr,msrkc,msy,n,ncgrk,ncrk,ng,ngr,ngrk,nihf,nihh,nihl,nilf,\
+nilh,nill,nngrk,nnrk,nogrk,nork,nr,nrk,nxgrk,nxrk,ny,o,ocgrk,ocrk,og,ogr,ogrk,\
+oihf,oihh,oihl,oilf,oilh,oill,or,ork,oy,pfpo,popcnt,risbg,risbgn,rll,rllg,\
+rnsbg,rosbg,rxsbg,s,selgr,selr,sg,sgf,sgfr,sgh,sgr,sgrk,sh,shy,sl,slb,slbg,\
+slbgr,slbr,sldl,slfi,slg,slgf,slgfi,slgfr,slgr,slgrk,sll,sllg,sllk,slr,slrk,\
+sly,sr,sra,srag,srak,srda,srdl,srk,srl,srlg,srlk,sy,x,xg,xgr,xgrk,xihf,xilf,xr,\
+xrk,xy")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_unit_fxb" ""
+ (cond [(eq_attr "mnemonic" "agsi,algsi,alsi,asi,b,bc,bcr,bi,br,c,cfi,cg,cgf,\
+cgfi,cgfr,cgfrl,cgh,cghi,cghrl,cghsi,cgit,cgr,cgrl,cgrt,ch,chi,chrl,chsi,chy,\
+cit,cl,clfhsi,clfi,clfit,clg,clgf,clgfi,clgfr,clgfrl,clghrl,clghsi,clgit,clgr,\
+clgrl,clgrt,clgt,clhhsi,clhrl,cli,cliy,clm,clmy,clr,clrl,clrt,clt,cly,cr,crl,\
+crt,cy,laa,laag,lan,lang,lao,laog,lat,lax,laxg,lcdfr,ldgr,ldr,lgat,lgdr,lndfr,\
+lpdfr,lxr,lzdr,lzer,lzxr,mvghi,mvhhi,mvhi,mvi,mviy,ni,niy,nop,nopr,ntstg,oi,\
+oiy,ppa,st,stc,stcy,std,stdy,ste,stey,stg,stgrl,sth,sthrl,sthy,stoc,stocg,strl,\
+strv,strvg,strvh,sty,tend,tm,tmh,tmhh,tmhl,tml,tmlh,tmll,tmy,vlgvb,vlgvf,vlgvg,\
+vlgvh,vlr,vlvgb,vlvgf,vlvgg,vlvgh,vlvgp,vscef,vsceg,vst,vstbrf,vstbrg,vstbrh,\
+vstbrq,vstebrf,vstebrg,vstef,vsteg,vsterf,vsterg,vsterh,vstl,vstrl,vstrlr,xi,\
+xiy")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_unit_fxd" ""
+ (cond [(eq_attr "mnemonic" "dlgr,dlr,dr,dsgfr,dsgr")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_unit_lsu" ""
+ (cond [(eq_attr "mnemonic" "clc,ear,l,lam,lcbb,ld,lde,ldy,lg,lgrl,llc,llgc,\
+llgf,llgfrl,llgh,llghrl,llgt,llh,llhrl,lm,lmg,lmy,lpq,lrl,ly,mvcrl,sar,sfpc,\
+tabort,vl,vlbb,vlbrf,vlbrg,vlbrh,vlbrq,vlbrrepf,vlbrrepg,vlbrreph,vlerf,vlerg,\
+vlerh,vll,vllebrzf,vllebrzg,vllebrzh,vllezb,vllezf,vllezg,vllezh,vllezlf,\
+vlrepb,vlrepf,vlrepg,vlreph,vlrl,vlrlr")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_unit_vfu" ""
+ (cond [(eq_attr "mnemonic" "adb,adbr,adtr,aeb,aebr,axbr,axtr,brcl,cdb,cdbr,\
+cdtr,ceb,cebr,cpsdr,cxbr,cxtr,ddtr,dxtr,fidbr,fidbra,fidtr,fiebr,fiebra,fixbr,\
+fixbra,fixtr,j,jg,kdb,kdbr,kdtr,keb,kebr,kxbr,kxtr,lcdbr,lcebr,lcxbr,ldeb,\
+ldebr,ldetr,le,ledbr,ledtr,ler,ley,lndbr,lnebr,lnxbr,lpdbr,lpebr,lpxbr,ltdbr,\
+ltdtr,ltebr,ltxbr,ltxtr,lxdb,lxdbr,lxdtr,lxeb,lxebr,madb,madbr,maeb,maebr,mdb,\
+mdbr,mdtr,meeb,meebr,msdb,msdbr,mseb,msebr,mxbr,mxtr,sdb,sdbr,sdtr,seb,sebr,\
+sxbr,sxtr,tcdb,tceb,tcxb,tdcdt,tdcet,tdcxt,vab,vaccb,vacccq,vaccf,vaccg,vacch,\
+vaccq,vacq,vaf,vag,vah,vaq,vavgb,vavgf,vavgg,vavgh,vavglb,vavglf,vavglg,vavglh,\
+vavglq,vavgq,vblendb,vblendf,vblendg,vblendh,vblendq,vbperm,vcdgb,vcdlgb,vcefb,\
+vcelfb,vceqb,vceqbs,vceqf,vceqfs,vceqg,vceqgs,vceqh,vceqhs,vceqq,vceqqs,vcfeb,\
+vcfn,vcgdb,vchb,vchbs,vchf,vchfs,vchg,vchgs,vchh,vchhs,vchlb,vchlbs,vchlf,\
+vchlfs,vchlg,vchlgs,vchlh,vchlhs,vchlq,vchlqs,vchq,vchqs,vcksm,vclfeb,vclfnh,\
+vclfnl,vclgdb,vclzb,vclzf,vclzg,vclzh,vclzq,vcnf,vcrnf,vctzb,vctzf,vctzg,vctzh,\
+vctzq,verimb,verimf,verimg,verimh,verllb,verllf,verllg,verllh,verllvb,verllvf,\
+verllvg,verllvh,veslb,veslf,veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,\
+vesraf,vesrag,vesrah,vesravb,vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,\
+vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,veval,vfadb,vfasb,vfcedb,vfcedbs,vfcesb,\
+vfcesbs,vfchdb,vfchdbs,vfchedb,vfchedbs,vfchesb,vfchesbs,vfchsb,vfchsbs,vfeeb,\
+vfeef,vfeeh,vfeezbs,vfeezfs,vfeezhs,vfeneb,vfenef,vfeneh,vfenezb,vfenezf,\
+vfenezh,vfidb,vfisb,vfkedb,vfkesb,vfkhdb,vfkhedb,vfkhesb,vfkhsb,vflcdb,vflcsb,\
+vflndb,vflnsb,vflpdb,vflpsb,vfmadb,vfmasb,vfmaxdb,vfmaxsb,vfmdb,vfmindb,\
+vfminsb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmasb,vfnmsdb,vfnmssb,vfsdb,vfssb,\
+vftcidb,vftcisb,vgbm,vgemb,vgemf,vgemg,vgemh,vgemq,vgfmab,vgfmaf,vgfmag,vgfmah,\
+vgfmb,vgfmf,vgfmg,vgfmh,vgm,vistrb,vistrbs,vistrf,vistrfs,vistrh,vistrhs,vlcb,\
+vlcf,vlcg,vlch,vldeb,vleb,vlebrf,vlebrg,vlebrh,vledb,vlef,vleg,vleh,vleib,\
+vleif,vleig,vleih,vlpb,vlpf,vlpg,vlph,vlpq,vmaeb,vmaef,vmaeg,vmaeh,vmahb,vmahf,\
+vmahg,vmahh,vmahq,vmalb,vmaleb,vmalef,vmaleg,vmaleh,vmalf,vmalg,vmalhb,vmalhf,\
+vmalhg,vmalhh,vmalhq,vmalhw,vmalob,vmalof,vmalog,vmaloh,vmalq,vmaob,vmaof,\
+vmaog,vmaoh,vmeb,vmef,vmeg,vmeh,vmhb,vmhf,vmhg,vmhh,vmhq,vmlb,vmleb,vmlef,\
+vmleg,vmleh,vmlf,vmlg,vmlhb,vmlhf,vmlhg,vmlhh,vmlhq,vmlhw,vmlob,vmlof,vmlog,\
+vmloh,vmlq,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,vmnlg,vmnlh,vmnlq,vmnq,vmob,vmof,\
+vmog,vmoh,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,vmslg,vmxb,vmxf,vmxg,\
+vmxh,vmxlb,vmxlf,vmxlg,vmxlh,vmxlq,vmxq,vn,vnc,vnn,vno,vnot,vnx,vo,voc,vone,\
+vpdi,vperm,vpkf,vpkg,vpkh,vpklsf,vpklsfs,vpklsg,vpklsgs,vpklsh,vpklshs,vpksf,\
+vpksfs,vpksg,vpksgs,vpksh,vpkshs,vpopct,vpopctb,vpopctf,vpopctg,vpopcth,vrepb,\
+vrepf,vrepg,vreph,vrepi,vrepib,vrepif,vrepig,vrepih,vsb,vsbcbiq,vsbiq,vscbib,\
+vscbif,vscbig,vscbih,vscbiq,vsegb,vsegf,vsegh,vsel,vsf,vsg,vsh,vsl,vslb,vsld,\
+vsldb,vsq,vsra,vsrab,vsrd,vsrl,vsrlb,vsumb,vsumgf,vsumgh,vsumh,vsumqf,vsumqg,\
+vtm,vuphb,vuphf,vuphg,vuphh,vuplb,vuplf,vuplg,vuplhb,vuplhf,vuplhg,vuplhh,\
+vuplhw,vupllb,vupllf,vupllg,vupllh,vx,vzero,wcdgb,wcdlgb,wcefb,wcelfb,wcfeb,\
+wcgdb,wclfeb,wclgdb,wfadb,wfasb,wfaxb,wfcdb,wfcedb,wfcesb,wfcexb,wfcexbs,\
+wfchdb,wfchedb,wfchesb,wfchexb,wfchexbs,wfchsb,wfchxb,wfchxbs,wfcsb,wfcxb,\
+wfidb,wfisb,wfixb,wfkdb,wfkedb,wfkesb,wfkexb,wfkhdb,wfkhedb,wfkhesb,wfkhexb,\
+wfkhsb,wfkhxb,wfksb,wfkxb,wflcdb,wflcsb,wflcxb,wflld,wflndb,wflnsb,wflnxb,\
+wflpdb,wflpsb,wflpxb,wflrx,wfmadb,wfmasb,wfmaxb,wfmaxxb,wfmdb,wfminxb,wfmsb,\
+wfmsdb,wfmssb,wfmsxb,wfmxb,wfnmaxb,wfnmsxb,wfsdb,wfssb,wfsxb,wftcixb,wldeb,\
+wledb")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_cracked" ""
+ (cond [(eq_attr "mnemonic" "bas,basr,bras,brasl,cdfbr,cdftr,cdgbr,cdgtr,\
+cdlfbr,cdlftr,cdlgbr,cdlgtr,cefbr,cegbr,celfbr,celgbr,cfdbr,cfebr,cfxbr,cgdbr,\
+cgdtr,cgebr,cgxbr,cgxtr,chhsi,clfdbr,clfdtr,clfebr,clfxbr,clfxtr,clgdbr,clgdtr,\
+clgebr,clgxbr,clgxtr,cs,csg,csy,efpc,ex,exrl,lcgfr,lngfr,lpgfr,lpq,lxr,lzxr,\
+mvc,nc,oc,rnsbg,rosbg,rxsbg,stpq,vgef,vgeg,vscef,vsceg,vsteb,vstebrh,vsteh,xc")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_expanded" ""
+ (cond [(eq_attr "mnemonic" "cds,cdsg,cdsy,cxfbr,cxftr,cxgbr,cxgtr,cxlfbr,\
+cxlftr,cxlgbr,cxlgtr,d,dl,dlg,dsg,dsgf,lam,lm,lmg,lmy,sldl,srda,srdl,stam,stm,\
+stmg,stmy,tbegin,tbeginc")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_groupalone" ""
+ (cond [(eq_attr "mnemonic" "alc,alcg,alcgr,alcr,axbr,axtr,clc,cxbr,cxfbr,\
+cxftr,cxgbr,cxgtr,cxlfbr,cxlftr,cxlgbr,cxlgtr,cxtr,d,dl,dlg,dlgr,dlr,dr,dsg,\
+dsgf,dsgfr,dsgr,dxbr,dxtr,ex,exrl,fixbr,fixbra,fixtr,flogr,kxbr,kxtr,lcxbr,\
+lnxbr,lpxbr,ltxbr,ltxtr,lxdb,lxdbr,lxdtr,lxeb,lxebr,m,madb,maeb,maebr,mfy,mg,\
+mgrk,ml,mlg,mlgr,mlr,mr,msdb,mseb,msebr,mvc,mvcrl,mxbr,mxtr,nc,oc,ppa,sfpc,slb,\
+slbg,slbgr,slbr,sqxbr,sxbr,sxtr,tabort,tbegin,tbeginc,tcxb,tdcxt,tend,xc")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_endgroup" ""
+ (cond [(eq_attr "mnemonic" "bas,basr,bcr,br,bras,brasl,cdsg,clfebr,cs,csg,csy,\
+efpc,ex,exrl,ipm,lam,lpq,lxr,nopr,sldl,srda,srdl,stam,stm,stmg,stmy,tbegin,\
+tbeginc")
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z17_groupoftwo" ""
+ (cond [(eq_attr "mnemonic" "cdfbr,cdftr,cdgbr,cdgtr,cdlfbr,cdlftr,cdlgbr,\
+cdlgtr,cefbr,cegbr,celfbr,celgbr,cfdbr,cfebr,cfxbr,cgdbr,cgdtr,cgebr,cgxbr,\
+cgxtr,chhsi,clfdbr,clfdtr,clfxbr,clfxtr,clgdbr,clgdtr,clgebr,clgxbr,clgxtr,\
+lcgfr,lngfr,lpgfr,lzxr,vacccq,vacq,vblendb,vblendf,vblendg,vblendh,vblendq,\
+veval,vfmadb,vfmasb,vfmsdb,vfmssb,vfnmadb,vfnmasb,vfnmsdb,vfnmssb,vgef,vgeg,\
+vgfmab,vgfmaf,vgfmag,vgfmah,vmaeb,vmaef,vmaeg,vmaeh,vmahb,vmahf,vmahg,vmahh,\
+vmahq,vmalb,vmaleb,vmalef,vmaleg,vmaleh,vmalf,vmalg,vmalhb,vmalhf,vmalhg,\
+vmalhh,vmalhq,vmalhw,vmalob,vmalof,vmalog,vmaloh,vmalq,vmaob,vmaof,vmaog,vmaoh,\
+vmslg,vperm,vsbcbiq,vsbiq,vscef,vsceg,vsel,vsteb,vstebrh,vsteh,wfmadb,wfmasb,\
+wfmaxb,wfmsdb,wfmssb,wfmsxb,wfnmaxb,wfnmsxb")
+ (const_int 1)] (const_int 0)))
+
+(define_insn_reservation "z17_0" 0
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "a,afi,ag,agfi,aghi,aghik,agr,agrk,ahi,ahik,al,alfi,alg,\
+algf,algfi,algfr,alghsik,algr,algrk,alhsik,alr,alrk,aly,ar,ark,ay,b,bc,bcr,bi,\
+br,brcl,c,cfi,cg,cgfi,cghi,cghsi,cgit,cgr,cgrl,cgrt,chi,chsi,cit,cl,clfhsi,\
+clfi,clfit,clg,clgf,clgfi,clgfr,clgfrl,clghrl,clghsi,clgit,clgr,clgrl,clgrt,\
+clgt,clhhsi,clhrl,cli,cliy,clr,clrl,clrt,clt,cly,cr,crl,crt,cy,etnd,ic,icm,\
+icmh,icmy,icy,iihf,iilf,j,jg,la,larl,lat,lay,lb,lbr,lcdfr,lcgr,lcr,ldgr,ldr,\
+lgat,lgb,lgbr,lgf,lgfi,lgfr,lgfrl,lgh,lghi,lghr,lghrl,lgr,lh,lhi,lhr,lhrl,lhy,\
+llcr,llgcr,llgfr,llghr,llgtr,llhr,llihf,llihh,llihl,llilf,llilh,llill,lndfr,\
+lngr,lnr,lpdfr,lpgr,lpr,lr,lrv,lrvg,lrvgr,lrvh,lrvr,lt,ltg,ltgf,ltgfr,ltgr,ltr,\
+lzdr,lzer,n,ncgrk,ncrk,ng,ngr,ngrk,nihf,nihh,nihl,nilf,nilh,nill,nngrk,nnrk,\
+nogrk,nop,nopr,nork,nr,nrk,nxgrk,nxrk,ny,o,ocgrk,ocrk,og,ogr,ogrk,oihf,oihh,\
+oihl,oilf,oilh,oill,or,ork,oy,pfpo,risbg,risbgn,rll,rllg,s,sg,sgr,sgrk,sl,sldl,\
+slfi,slg,slgf,slgfi,slgfr,slgr,slgrk,sll,sllg,sllk,slr,slrk,sly,sr,sra,srag,\
+srak,srda,srdl,srk,srl,srlg,srlk,sy,tm,tmh,tmhh,tmhl,tml,tmlh,tmll,tmy,vlr,\
+vlvgb,vlvgf,vlvgg,vlvgh,x,xg,xgr,xgrk,xihf,xilf,xr,xrk,xy")) "nothing")
+
+(define_insn_reservation "z17_1" 1
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "agf,agfr,agh,agsi,ah,ahy,algsi,alsi,asi,cgf,cgfr,cgfrl,\
+cgh,cghrl,ch,chrl,chy,clm,clmy,cpsdr,laa,laag,lan,lang,lao,laog,lax,laxg,le,\
+ler,ley,llxab,llxaf,llxag,llxah,llxaq,loc,locg,locghi,locgr,lochi,locr,lxab,\
+lxaf,lxag,lxah,lxaq,mvghi,mvhhi,mvhi,mvi,mviy,ni,niy,ntstg,oi,oiy,selgr,selr,\
+sgf,sgfr,sgh,sh,shy,st,stc,stcy,stg,stgrl,sth,sthrl,sthy,stoc,stocg,strl,strv,\
+strvg,strvh,sty,vab,vaccb,vacccq,vaccf,vaccg,vacch,vaccq,vacq,vaf,vag,vah,vaq,\
+vavgb,vavgf,vavgg,vavgh,vavglb,vavglf,vavglg,vavglh,vavglq,vavgq,vblendb,\
+vblendf,vblendg,vblendh,vblendq,vbperm,vceqb,vceqbs,vceqf,vceqfs,vceqg,vceqgs,\
+vceqh,vceqhs,vceqq,vceqqs,vcfn,vchb,vchbs,vchf,vchfs,vchg,vchgs,vchh,vchhs,\
+vchlb,vchlbs,vchlf,vchlfs,vchlg,vchlgs,vchlh,vchlhs,vchlq,vchlqs,vchq,vchqs,\
+vclfnh,vclfnl,vclzb,vclzf,vclzg,vclzh,vclzq,vcnf,vcrnf,vctzb,vctzf,vctzg,vctzh,\
+vctzq,verimb,verimf,verimg,verimh,verllb,verllf,verllg,verllh,verllvb,verllvf,\
+verllvg,verllvh,veslb,veslf,veslg,veslh,veslvb,veslvf,veslvg,veslvh,vesrab,\
+vesraf,vesrag,vesrah,vesravb,vesravf,vesravg,vesravh,vesrlb,vesrlf,vesrlg,\
+vesrlh,vesrlvb,vesrlvf,vesrlvg,vesrlvh,veval,vfcedb,vfcedbs,vfcesb,vfcesbs,\
+vfchdb,vfchdbs,vfchedb,vfchedbs,vfchesb,vfchesbs,vfchsb,vfchsbs,vfkedb,vfkesb,\
+vfkhdb,vfkhedb,vfkhesb,vfkhsb,vflcdb,vflcsb,vflndb,vflnsb,vflpdb,vflpsb,\
+vfmaxdb,vfmaxsb,vfmindb,vfminsb,vgbm,vgemb,vgemf,vgemg,vgemh,vgemq,vgm,vlcb,\
+vlcf,vlcg,vlch,vleb,vlebrf,vlebrg,vlebrh,vlef,vleg,vleh,vleib,vleif,vleig,\
+vleih,vlpb,vlpf,vlpg,vlph,vlpq,vmnb,vmnf,vmng,vmnh,vmnlb,vmnlf,vmnlg,vmnlh,\
+vmnlq,vmnq,vmrhb,vmrhf,vmrhg,vmrhh,vmrlb,vmrlf,vmrlg,vmrlh,vmxb,vmxf,vmxg,vmxh,\
+vmxlb,vmxlf,vmxlg,vmxlh,vmxlq,vmxq,vn,vnc,vnn,vno,vnot,vnx,vo,voc,vone,vpdi,\
+vperm,vpkf,vpkg,vpkh,vpklsf,vpklsfs,vpklsg,vpklsgs,vpklsh,vpklshs,vpksf,vpksfs,\
+vpksg,vpksgs,vpksh,vpkshs,vpopct,vpopctb,vpopctf,vpopctg,vpopcth,vrepb,vrepf,\
+vrepg,vreph,vrepi,vrepib,vrepif,vrepig,vrepih,vsb,vsbcbiq,vsbiq,vscbib,vscbif,\
+vscbig,vscbih,vscbiq,vsegb,vsegf,vsegh,vsel,vsf,vsg,vsh,vsl,vslb,vsld,vsldb,\
+vsq,vsra,vsrab,vsrd,vsrl,vsrlb,vuphb,vuphf,vuphg,vuphh,vuplb,vuplf,vuplg,\
+vuplhb,vuplhf,vuplhg,vuplhh,vuplhw,vupllb,vupllf,vupllg,vupllh,vx,vzero,wfcedb,\
+wfcesb,wfcexb,wfcexbs,wfchdb,wfchedb,wfchesb,wfchexb,wfchexbs,wfchsb,wfchxb,\
+wfchxbs,wfkedb,wfkesb,wfkexb,wfkhdb,wfkhedb,wfkhesb,wfkhexb,wfkhsb,wfkhxb,\
+wflcdb,wflcsb,wflcxb,wflndb,wflnsb,wflnxb,wflpdb,wflpsb,wflpxb,wfmaxxb,wfminxb,\
+xi,xiy")) "nothing")
+
+(define_insn_reservation "z17_2" 2
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cdb,cdbr,ceb,cebr,clzg,ctzg,ear,ipm,kdb,kdbr,keb,kebr,l,\
+lcbb,lcdbr,lcebr,ld,lde,ldy,lg,lgdr,lgrl,llc,llgc,llgf,llgfrl,llgh,llghrl,llgt,\
+llh,llhrl,lm,lmg,lmy,lndbr,lnebr,lpdbr,lpebr,lrl,ltdbr,ltebr,ly,popcnt,sar,\
+tcdb,tceb,vfeeb,vfeef,vfeeh,vfeezbs,vfeezfs,vfeezhs,vfeneb,vfenef,vfeneh,\
+vfenezb,vfenezf,vfenezh,vftcidb,vftcisb,vistrb,vistrbs,vistrf,vistrfs,vistrh,\
+vistrhs,vlbrrepf,vlbrrepg,vlbrreph,vlgvb,vlgvf,vlgvg,vlgvh,vllebrzf,vllebrzg,\
+vllebrzh,vllezb,vllezf,vllezg,vllezh,vllezlf,vlrepb,vlrepf,vlrepg,vlreph,vlrl,\
+vlvgp,wfcdb,wfcsb,wfcxb,wfkdb,wfksb,wfkxb,wftcixb")) "nothing")
+
+(define_insn_reservation "z17_3" 3
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "bdepg,bextg,cds,cdsy,mgh,mghi,mh,mhi,mhy,ms,msc,msfi,msg,\
+msgc,msgf,msgfi,msgfr,msgr,msgrkc,msr,msrkc,msy,std,stdy,ste,stey,vcksm,vgfmab,\
+vgfmaf,vgfmag,vgfmah,vgfmb,vgfmf,vgfmg,vgfmh,vl,vlbb,vlbrf,vlbrg,vlbrh,vlbrq,\
+vlerf,vlerg,vlerh,vll,vlrlr,vmaeb,vmaef,vmaeg,vmaeh,vmahb,vmahf,vmahg,vmahh,\
+vmahq,vmalb,vmaleb,vmalef,vmaleg,vmaleh,vmalf,vmalg,vmalhb,vmalhf,vmalhg,\
+vmalhh,vmalhq,vmalhw,vmalob,vmalof,vmalog,vmaloh,vmalq,vmaob,vmaof,vmaog,vmaoh,\
+vmeb,vmef,vmeg,vmeh,vmhb,vmhf,vmhg,vmhh,vmhq,vmlb,vmleb,vmlef,vmleg,vmleh,vmlf,\
+vmlg,vmlhb,vmlhf,vmlhg,vmlhh,vmlhq,vmlhw,vmlob,vmlof,vmlog,vmloh,vmlq,vmob,\
+vmof,vmog,vmoh,vsumb,vsumgf,vsumgh,vsumh,vsumqf,vsumqg,vtm")) "nothing")
+
+(define_insn_reservation "z17_4" 4
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "bas,basr,bras,brasl,chhsi,clc,ex,exrl,lam,lcgfr,lngfr,\
+lpgfr,lxr,lzxr,mvcrl,ppa,rnsbg,rosbg,rxsbg,tabort,tend,vst,vstbrf,vstbrg,\
+vstbrh,vstbrq,vstebrf,vstebrg,vstef,vsteg,vsterf,vsterg,vsterh,vstl,vstrl,\
+vstrlr")) "nothing")
+
+(define_insn_reservation "z17_5" 5
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "adb,adbr,aeb,aebr,alc,alcg,alcgr,alcr,cs,csg,csy,fidbr,\
+fidbra,fiebr,fiebra,ldeb,ldebr,ledbr,madbr,mdb,mdbr,meeb,meebr,msdbr,sdb,sdbr,\
+seb,sebr,slb,slbg,slbgr,slbr,stm,stmg,stmy,vcdgb,vcdlgb,vcefb,vcelfb,vcfeb,\
+vcgdb,vclfeb,vclgdb,vldeb,vledb,vmslg,wcdgb,wcdlgb,wcefb,wcelfb,wcfeb,wcgdb,\
+wclfeb,wclgdb,wflld,wflrx,wldeb,wledb")) "nothing")
+
+(define_insn_reservation "z17_6" 6
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "sfpc")) "nothing")
+
+(define_insn_reservation "z17_7" 7
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "adtr,cdtr,fidtr,kdtr,ldetr,ltdtr,sdtr,tdcdt,tdcet,vfadb,\
+vfasb,vfidb,vfisb,vfsdb,vfssb,vgef,vgeg,wfadb,wfasb,wfaxb,wfidb,wfisb,wfixb,\
+wfsdb,wfssb,wfsxb")) "nothing")
+
+(define_insn_reservation "z17_8" 8
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cdgtr,cdlgtr,cdsg,cxgtr,cxlgtr,flogr,lpq,m,mfy,mg,mgrk,\
+ml,mlg,mlgr,mlr,mr,stpq,vsteb,vstebrh,vsteh")) "nothing")
+
+(define_insn_reservation "z17_9" 9
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cdfbr,cdgbr,cdlfbr,cdlgbr,cefbr,cegbr,celfbr,celgbr,madb,\
+maeb,maebr,msdb,mseb,msebr,stam")) "nothing")
+
+(define_insn_reservation "z17_10" 10
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cgdtr,cgxtr,clfdtr,clfxtr,clgdtr,clgxtr,d,dl,dlg,dsg,\
+dsgf,efpc,lxdb,lxdbr,lxeb,lxebr,vscef,vsceg")) "nothing")
+
+(define_insn_reservation "z17_11" 11
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cfdbr,cfebr,cgdbr,cgebr,clfdbr,clfebr,clgdbr,clgebr")) "nothing")
+
+(define_insn_reservation "z17_12" 12
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cxbr,cxtr,kxbr,kxtr,tbegin,tbeginc,tcxb,tdcxt")) "nothing")
+
+(define_insn_reservation "z17_13" 13
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "axbr,axtr,cxfbr,cxgbr,cxlfbr,cxlgbr,fixbr,fixbra,fixtr,\
+lcxbr,lnxbr,lpxbr,ltxbr,ltxtr,lxdtr,sxbr,sxtr")) "nothing")
+
+(define_insn_reservation "z17_14" 14
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cfxbr,cgxbr,clfxbr,clgxbr,ledtr")) "nothing")
+
+(define_insn_reservation "z17_15" 15
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "nc,oc")) "nothing")
+
+(define_insn_reservation "z17_16" 16
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "cdftr,cdlftr,cxftr,cxlftr")) "nothing")
+
+(define_insn_reservation "z17_18" 18
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "xc")) "nothing")
+
+(define_insn_reservation "z17_20" 20
+ (and (eq_attr "cpu" "z17")
+ (eq_attr "mnemonic" "ddb,ddbr,ddtr,deb,debr,dlgr,dlr,dr,dsgfr,dsgr,dxbr,dxtr,\
+mdtr,mvc,mxbr,mxtr,sqdb,sqdbr,sqeb,sqebr,sqxbr,vdf,vdg,vdlf,vdlg,vdlq,vdq,\
+vfddb,vfdsb,vfmadb,vfmasb,vfmdb,vfmsb,vfmsdb,vfmssb,vfnmadb,vfnmasb,vfnmsdb,\
+vfnmssb,vfsqdb,vfsqsb,vrf,vrg,vrlf,vrlg,vrlq,vrq,wfddb,wfdsb,wfdxb,wfmadb,\
+wfmasb,wfmaxb,wfmdb,wfmsb,wfmsdb,wfmssb,wfmsxb,wfmxb,wfnmaxb,wfnmsxb,wfsqdb,\
+wfsqxb")) "nothing")
+
diff --git a/gcc/config/s390/driver-native.cc b/gcc/config/s390/driver-native.cc
index 49e8fa0..7a7ceea 100644
--- a/gcc/config/s390/driver-native.cc
+++ b/gcc/config/s390/driver-native.cc
@@ -127,6 +127,10 @@ s390_host_detect_local_cpu (int argc, const char **argv)
case 0x3932:
cpu = "arch14";
break;
+ case 0x9175:
+ case 0x9176:
+ cpu = "arch15";
+ break;
default:
cpu = "arch15";
break;
diff --git a/gcc/config/s390/s390-builtins.def b/gcc/config/s390/s390-builtins.def
index d9af9b1..cee2326 100644
--- a/gcc/config/s390/s390-builtins.def
+++ b/gcc/config/s390/s390-builtins.def
@@ -300,8 +300,8 @@
#define B_VXE2 (1 << 4) /* Builtins requiring the z15 vector extensions. */
#define B_DEP (1 << 5) /* Builtin has been deprecated and a warning should be issued. */
#define B_NNPA (1 << 6) /* Builtins requiring the NNPA Facility. */
-#define B_VXE3 (1 << 7) /* Builtins requiring the arch15 vector extensions. */
-#define B_ARCH15 (1 << 8) /* Builtins requiring arch15. */
+#define B_VXE3 (1 << 7) /* Builtins requiring the z17 vector extensions. */
+#define B_Z17 (1 << 8) /* Builtins requiring z17. */
/* B_DEF defines a standard (not overloaded) builtin
B_DEF (<builtin name>, <RTL expander name>, <function attributes>, <builtin flags>, <operand flags, see above>, <fntype>)
@@ -3318,8 +3318,8 @@ B_DEF (s390_vcnf, vcnf_v8hi, 0,
/* arch 15 builtins */
-B_DEF (s390_bdepg, bdepg, 0, B_ARCH15, 0, BT_FN_ULONG_ULONG_ULONG)
-B_DEF (s390_bextg, bextg, 0, B_ARCH15, 0, BT_FN_ULONG_ULONG_ULONG)
+B_DEF (s390_bdepg, bdepg, 0, B_Z17, 0, BT_FN_ULONG_ULONG_ULONG)
+B_DEF (s390_bextg, bextg, 0, B_Z17, 0, BT_FN_ULONG_ULONG_ULONG)
OB_DEF (s390_vec_blend, s390_vec_blend_s8, s390_vec_blend_dbl, B_VXE3, BT_FN_OV4SI_OV4SI_OV4SI_OV4SI)
OB_DEF_VAR (s390_vec_blend_s8, s390_vblendb, 0, 0, BT_OV_V16QI_V16QI_V16QI_V16QI)
diff --git a/gcc/config/s390/s390-c.cc b/gcc/config/s390/s390-c.cc
index 311d74a..a01c44c 100644
--- a/gcc/config/s390/s390-c.cc
+++ b/gcc/config/s390/s390-c.cc
@@ -962,7 +962,7 @@ s390_resolve_overloaded_builtin (location_t loc, tree ob_fndecl,
if (!TARGET_VXE3 && (ob_flags & B_VXE3))
{
- error_at (loc, "%qF requires arch15 or higher", ob_fndecl);
+ error_at (loc, "%qF requires z17 or higher", ob_fndecl);
return error_mark_node;
}
@@ -1056,7 +1056,7 @@ s390_resolve_overloaded_builtin (location_t loc, tree ob_fndecl,
if (!TARGET_VXE3
&& bflags_overloaded_builtin_var[last_match_index] & B_VXE3)
{
- error_at (loc, "%qs matching variant requires arch15 or higher",
+ error_at (loc, "%qs matching variant requires z17 or higher",
IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
return error_mark_node;
}
diff --git a/gcc/config/s390/s390-opts.h b/gcc/config/s390/s390-opts.h
index 437d3b9..9cacb2c 100644
--- a/gcc/config/s390/s390-opts.h
+++ b/gcc/config/s390/s390-opts.h
@@ -39,7 +39,7 @@ enum processor_type
PROCESSOR_3906_Z14,
PROCESSOR_8561_Z15,
PROCESSOR_3931_Z16,
- PROCESSOR_ARCH15,
+ PROCESSOR_9175_Z17,
PROCESSOR_NATIVE,
PROCESSOR_max
};
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 0ff3fd5..d82b16e 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -342,7 +342,7 @@ const struct s390_processor processor_table[] =
{ "z14", "arch12", PROCESSOR_3906_Z14, &zEC12_cost, 12 },
{ "z15", "arch13", PROCESSOR_8561_Z15, &zEC12_cost, 13 },
{ "z16", "arch14", PROCESSOR_3931_Z16, &zEC12_cost, 14 },
- { "arch15", "arch15", PROCESSOR_ARCH15, &zEC12_cost, 15 },
+ { "z17", "arch15", PROCESSOR_9175_Z17, &zEC12_cost, 15 },
{ "native", "", PROCESSOR_NATIVE, NULL, 0 }
};
@@ -916,7 +916,7 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if ((bflags & B_VXE3) && !TARGET_VXE3)
{
- error ("Builtin %qF requires arch15 or higher", fndecl);
+ error ("Builtin %qF requires z17 or higher", fndecl);
return const0_rtx;
}
}
@@ -9204,7 +9204,7 @@ s390_issue_rate (void)
case PROCESSOR_3906_Z14:
case PROCESSOR_8561_Z15:
case PROCESSOR_3931_Z16:
- case PROCESSOR_ARCH15:
+ case PROCESSOR_9175_Z17:
default:
return 1;
}
@@ -15632,7 +15632,6 @@ s390_get_sched_attrmask (rtx_insn *insn)
mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
break;
case PROCESSOR_3931_Z16:
- case PROCESSOR_ARCH15:
if (get_attr_z16_cracked (insn))
mask |= S390_SCHED_ATTR_MASK_CRACKED;
if (get_attr_z16_expanded (insn))
@@ -15644,6 +15643,18 @@ s390_get_sched_attrmask (rtx_insn *insn)
if (get_attr_z16_groupoftwo (insn))
mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
break;
+ case PROCESSOR_9175_Z17:
+ if (get_attr_z17_cracked (insn))
+ mask |= S390_SCHED_ATTR_MASK_CRACKED;
+ if (get_attr_z17_expanded (insn))
+ mask |= S390_SCHED_ATTR_MASK_EXPANDED;
+ if (get_attr_z17_endgroup (insn))
+ mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
+ if (get_attr_z17_groupalone (insn))
+ mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
+ if (get_attr_z17_groupoftwo (insn))
+ mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
+ break;
default:
gcc_unreachable ();
}
@@ -15691,7 +15702,6 @@ s390_get_unit_mask (rtx_insn *insn, int *units)
mask |= 1 << 3;
break;
case PROCESSOR_3931_Z16:
- case PROCESSOR_ARCH15:
*units = 4;
if (get_attr_z16_unit_lsu (insn))
mask |= 1 << 0;
@@ -15702,6 +15712,17 @@ s390_get_unit_mask (rtx_insn *insn, int *units)
if (get_attr_z16_unit_vfu (insn))
mask |= 1 << 3;
break;
+ case PROCESSOR_9175_Z17:
+ *units = 4;
+ if (get_attr_z17_unit_lsu (insn))
+ mask |= 1 << 0;
+ if (get_attr_z17_unit_fxa (insn))
+ mask |= 1 << 1;
+ if (get_attr_z17_unit_fxb (insn))
+ mask |= 1 << 2;
+ if (get_attr_z17_unit_vfu (insn))
+ mask |= 1 << 3;
+ break;
default:
gcc_unreachable ();
}
@@ -15715,7 +15736,8 @@ s390_is_fpd (rtx_insn *insn)
return false;
return get_attr_z13_unit_fpd (insn) || get_attr_z14_unit_fpd (insn)
- || get_attr_z15_unit_fpd (insn) || get_attr_z16_unit_fpd (insn);
+ || get_attr_z15_unit_fpd (insn) || get_attr_z16_unit_fpd (insn)
+ || get_attr_z17_unit_fpd (insn);
}
static bool
@@ -15725,7 +15747,8 @@ s390_is_fxd (rtx_insn *insn)
return false;
return get_attr_z13_unit_fxd (insn) || get_attr_z14_unit_fxd (insn)
- || get_attr_z15_unit_fxd (insn) || get_attr_z16_unit_fxd (insn);
+ || get_attr_z15_unit_fxd (insn) || get_attr_z16_unit_fxd (insn)
+ || get_attr_z17_unit_fxd (insn);
}
/* Returns TRUE if INSN is a long-running instruction. */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 6f7195d..8b04bc9 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -45,12 +45,12 @@ enum processor_flags
PF_NNPA = 32768,
PF_Z16 = 65536,
PF_VXE3 = 131072,
- PF_ARCH15 = 262144
+ PF_Z17 = 262144
};
/* This is necessary to avoid a warning about comparing different enum
types. */
-#define s390_tune_attr ((enum attr_cpu)(s390_tune > PROCESSOR_3931_Z16 ? PROCESSOR_3931_Z16 : s390_tune ))
+#define s390_tune_attr ((enum attr_cpu)(s390_tune > PROCESSOR_9175_Z17 ? PROCESSOR_9175_Z17 : s390_tune ))
/* These flags indicate that the generated code should run on a cpu
providing the respective hardware facility regardless of the
@@ -124,10 +124,10 @@ enum processor_flags
(s390_arch_flags & PF_VXE3)
#define TARGET_CPU_VXE3_P(opts) \
(opts->x_s390_arch_flags & PF_VXE3)
-#define TARGET_CPU_ARCH15 \
- (s390_arch_flags & PF_ARCH15)
-#define TARGET_CPU_ARCH15_P(opts) \
- (opts->x_s390_arch_flags & PF_ARCH15)
+#define TARGET_CPU_Z17 \
+ (s390_arch_flags & PF_Z17)
+#define TARGET_CPU_Z17_P(opts) \
+ (opts->x_s390_arch_flags & PF_Z17)
#define TARGET_HARD_FLOAT_P(opts) (!TARGET_SOFT_FLOAT_P(opts))
@@ -198,9 +198,9 @@ enum processor_flags
(TARGET_VX && TARGET_CPU_VXE3)
#define TARGET_VXE3_P(opts) \
(TARGET_VX_P (opts) && TARGET_CPU_VXE3_P (opts))
-#define TARGET_ARCH15 (TARGET_ZARCH && TARGET_CPU_ARCH15)
-#define TARGET_ARCH15_P(opts) \
- (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_ARCH15_P (opts))
+#define TARGET_Z17 (TARGET_ZARCH && TARGET_CPU_Z17)
+#define TARGET_Z17_P(opts) \
+ (TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_Z17_P (opts))
#if defined(HAVE_AS_VECTOR_LOADSTORE_ALIGNMENT_HINTS_ON_Z13)
#define TARGET_VECTOR_LOADSTORE_ALIGNMENT_HINTS TARGET_Z13
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 9d49580..874974a 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -599,11 +599,11 @@
;; Processor type. This attribute must exactly match the processor_type
;; enumeration in s390.h.
-(define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16"
+(define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16,z17"
(const (symbol_ref "s390_tune_attr")))
(define_attr "cpu_facility"
- "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,z16,nnpa,vxe3,arch15"
+ "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,z16,nnpa,vxe3,z17"
(const_string "standard"))
(define_attr "enabled" ""
@@ -681,8 +681,8 @@
(match_test "TARGET_VXE3"))
(const_int 1)
- (and (eq_attr "cpu_facility" "arch15")
- (match_test "TARGET_ARCH15"))
+ (and (eq_attr "cpu_facility" "z17")
+ (match_test "TARGET_Z17"))
(const_int 1)
]
(const_int 0)))
@@ -725,6 +725,9 @@
;; Pipeline description for z16
(include "3931.md")
+;; Pipeline description for z17
+(include "9175.md")
+
;; Predicates
(include "predicates.md")
@@ -2056,7 +2059,7 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(ashift:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "a"))
(const_int LXAMODEITER)))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"lxa<lxamode>\t%0,0(%1,0)"
[(set_attr "op_type" "RXY")])
@@ -2066,7 +2069,7 @@
(ashift:DI (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a")
(match_operand:SI 2 "const_int_operand")))
(const_int LXAMODEITER)))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"lxa<lxamode>\t%0,%2(%1,0)"
[(set_attr "op_type" "RXY")])
@@ -2076,7 +2079,7 @@
(plus:DI (ashift:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "a"))
(const_int LXAMODEITER))
(match_operand:DI 2 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"lxa<lxamode>\t%0,0(%1,%2)"
[(set_attr "op_type" "RXY")])
@@ -2087,7 +2090,7 @@
(match_operand:SI 2 "const_int_operand")))
(const_int LXAMODEITER))
(match_operand:DI 3 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"lxa<lxamode>\t%0,%2(%1,%3)"
[(set_attr "op_type" "RXY")])
@@ -2096,7 +2099,7 @@
(plus:DI (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a")
(match_operand:SI 2 "const_int_operand")))
(match_operand:DI 3 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"lxab\t%0,%2(%1,%3)"
[(set_attr "op_type" "RXY")])
@@ -2113,7 +2116,7 @@
0)
(const_int LXAMODEITER))
(const_int <LLXAMASK>)))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"llxa<lxamode>\t%0,%2(%1,0)"
[(set_attr "op_type" "RXY")])
@@ -2124,7 +2127,7 @@
(const_int LXAMODEITER))
(const_int <LLXAMASK>))
(match_operand:DI 2 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"llxa<lxamode>\t%0,0(%1,%2)"
[(set_attr "op_type" "RXY")])
@@ -2137,7 +2140,7 @@
(const_int LXAMODEITER))
(const_int <LLXAMASK>))
(match_operand:DI 3 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"llxa<lxamode>\t%0,%2(%1,%3)"
[(set_attr "op_type" "RXY")])
@@ -2146,7 +2149,7 @@
(plus:DI (zero_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "a")
(match_operand:SI 2 "const_int_operand")))
(match_operand:DI 3 "register_operand" "a")))]
- "TARGET_ARCH15 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
+ "TARGET_Z17 && TARGET_64BIT && INTVAL (operands[2]) >= -0x80000 && INTVAL (operands[2]) <= 0x7FFFF"
"llxab\t%0,%2(%1,%3)"
[(set_attr "op_type" "RXY")])
@@ -4940,7 +4943,7 @@
(unspec:DI [(match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "register_operand" "d")]
UNSPEC_BDEPG))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"bdepg\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
@@ -4953,7 +4956,7 @@
(unspec:DI [(match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "register_operand" "d")]
UNSPEC_BEXTG))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"bextg\t%0,%1,%2"
[(set_attr "op_type" "RRF")])
@@ -9580,7 +9583,7 @@
(clz:DI (match_operand:DI 1 "register_operand" "d")))]
"TARGET_EXTIMM && TARGET_ZARCH"
{
- if (!(TARGET_ARCH15 && TARGET_64BIT))
+ if (!(TARGET_Z17 && TARGET_64BIT))
{
rtx_insn *insn;
rtx clz_equal;
@@ -9601,7 +9604,7 @@
(define_insn "*clzg"
[(set (match_operand:DI 0 "register_operand" "=d")
(clz:DI (match_operand:DI 1 "register_operand" "d")))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"clzg\t%0,%1"
[(set_attr "op_type" "RRE")])
@@ -9630,7 +9633,7 @@
(define_insn "ctzdi2"
[(set (match_operand:DI 0 "register_operand" "=d")
(ctz:DI (match_operand:DI 1 "register_operand" "d")))]
- "TARGET_ARCH15 && TARGET_64BIT"
+ "TARGET_Z17 && TARGET_64BIT"
"ctzg\t%0,%1"
[(set_attr "op_type" "RRE")])
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index f064597..6753a93 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -122,7 +122,10 @@ EnumValue
Enum(processor_type) String(z16) Value(PROCESSOR_3931_Z16)
EnumValue
-Enum(processor_type) String(arch15) Value(PROCESSOR_ARCH15)
+Enum(processor_type) String(arch15) Value(PROCESSOR_9175_Z17)
+
+EnumValue
+Enum(processor_type) String(z17) Value(PROCESSOR_9175_Z17)
EnumValue
Enum(processor_type) String(native) Value(PROCESSOR_NATIVE) DriverOnly
diff --git a/gcc/configure b/gcc/configure
index ab6bec1..821f8b4 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -12694,6 +12694,42 @@ $as_echo "#define HOST_HAS_O_NONBLOCK 1" >>confdefs.h
fi
+# Check if personality and ADDR_NO_RANDOMIZE are declared
+# in sys/personality.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for personality ADDR_NO_RANDOMIZE" >&5
+$as_echo_n "checking for personality ADDR_NO_RANDOMIZE... " >&6; }
+if ${ac_cv_personality_addr_no_randomize+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/personality.h>
+int
+main ()
+{
+
+personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_personality_addr_no_randomize=yes
+else
+ ac_cv_personality_addr_no_randomize=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_personality_addr_no_randomize" >&5
+$as_echo "$ac_cv_personality_addr_no_randomize" >&6; }
+if test $ac_cv_personality_addr_no_randomize = yes; then
+
+$as_echo "#define HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE 1" >>confdefs.h
+
+fi
+
# C++ Modules would like some networking features to provide the mapping
# server. You can still use modules without them though.
@@ -21484,7 +21520,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21487 "configure"
+#line 21523 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -21590,7 +21626,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 21593 "configure"
+#line 21629 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index fca0579..3d0a4e6 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1781,6 +1781,21 @@ if test $ac_cv_have_decl_O_NONBLOCK = yes; then
[Define if O_NONBLOCK supported by fcntl.])
fi
+# Check if personality and ADDR_NO_RANDOMIZE are declared
+# in sys/personality.h
+AC_CACHE_CHECK(for personality ADDR_NO_RANDOMIZE,
+ ac_cv_personality_addr_no_randomize, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/personality.h>]], [[
+personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);]])],
+[ac_cv_personality_addr_no_randomize=yes],
+[ac_cv_personality_addr_no_randomize=no])])
+if test $ac_cv_personality_addr_no_randomize = yes; then
+ AC_DEFINE(HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE, 1,
+ [Define if personality and ADDR_NO_RANDOMIZE are declared in
+sys/personality.h.])
+fi
+
# C++ Modules would like some networking features to provide the mapping
# server. You can still use modules without them though.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ed52463..e9e80f8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,42 @@
+2025-04-13 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/115639
+ * constexpr.cc (struct constexpr_call): Add NSDMIs to each
+ field. Replace 'result' data member with 3-element 'results'
+ array and a 'result' accessor function. Remove
+ 'manifestly_const_eval' data member.
+ (constexpr_call_hasher::equal): Adjust after constexpr_call
+ layout change.
+ (cxx_eval_call_expression): Likewise. Define some local
+ variables closer to their first use. Use unknown_type_node
+ instead of NULL_TREE as the "in progress" result. After
+ successully evaluating a call with mce_unknown, also cache the
+ result in the corresponding mce_true and mce_false slots.
+
+2025-04-13 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * module.cc (trees_in::is_matching_decl): Don't check for
+ mismatches when importing a DECL_MAYBE_DELETED function over one
+ that's already finished.
+
+2025-04-13 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * module.cc (trees_in::is_matching_decl): Add custom errors for
+ different kinds of mismatches.
+
+2025-04-12 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/116416
+ * constexpr.cc (maybe_constant_init_1): Generalize type of
+ of manifestly_const_eval parameter from bool to mce_value.
+ (maybe_constant_init): Define 3-parameter version taking a
+ manifestly_const_eval instead of bool parameter.
+ (cxx_constant_init): Adjust.
+ * cp-gimplify.cc (cp_fold_r) <case TARGET_EXPR>: Pass mce_false
+ to maybe_constant_init during prvalue folding if ff_mce_false is
+ set.
+ * cp-tree.h (maybe_constant_init): Declare new overload.
+
2025-04-11 Jason Merrill <jason@redhat.com>
PR c++/114970
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 0242425..7e37582 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -1119,20 +1119,22 @@ explain_invalid_constexpr_fn (tree fun)
struct GTY((for_user)) constexpr_call {
/* Description of the constexpr function definition. */
- constexpr_fundef *fundef;
+ constexpr_fundef *fundef = nullptr;
/* Parameter bindings environment. A TREE_VEC of arguments. */
- tree bindings;
- /* Result of the call.
- NULL means the call is being evaluated.
+ tree bindings = NULL_TREE;
+ /* Result of the call, indexed by the value of
+ constexpr_ctx::manifestly_const_eval.
+ unknown_type_node means the call is being evaluated.
error_mark_node means that the evaluation was erroneous or otherwise
uncacheable (e.g. because it depends on the caller).
Otherwise, the actual value of the call. */
- tree result;
+ tree results[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
/* The hash of this call; we remember it here to avoid having to
recalculate it when expanding the hash table. */
- hashval_t hash;
- /* The value of constexpr_ctx::manifestly_const_eval. */
- enum mce_value manifestly_const_eval;
+ hashval_t hash = 0;
+
+ /* The result slot corresponding to the given mce_value. */
+ tree& result (mce_value mce) { return results[1 + int(mce)]; }
};
struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
@@ -1427,8 +1429,6 @@ constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
return true;
if (lhs->hash != rhs->hash)
return false;
- if (lhs->manifestly_const_eval != rhs->manifestly_const_eval)
- return false;
if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
return false;
return cp_tree_equal (lhs->bindings, rhs->bindings);
@@ -2855,9 +2855,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
{
location_t loc = cp_expr_loc_or_input_loc (t);
tree fun = get_function_named_in_call (t);
- constexpr_call new_call
- = { NULL, NULL, NULL, 0, ctx->manifestly_const_eval };
- int depth_ok;
if (fun == NULL_TREE)
return cxx_eval_internal_function (ctx, t, lval,
@@ -3099,7 +3096,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
if (DECL_IMMEDIATE_FUNCTION_P (fun))
{
new_ctx.manifestly_const_eval = mce_true;
- new_call.manifestly_const_eval = mce_true;
ctx = &new_ctx;
}
@@ -3112,6 +3108,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
|| cp_noexcept_operand);
bool non_constant_args = false;
+ constexpr_call new_call;
new_call.bindings
= cxx_bind_parameters_in_call (ctx, t, fun, non_constant_p,
overflow_p, &non_constant_args);
@@ -3185,7 +3182,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
}
- depth_ok = push_cx_call_context (t);
+ int depth_ok = push_cx_call_context (t);
/* Remember the object we are constructing or destructing. */
tree new_obj = NULL_TREE;
@@ -3227,8 +3224,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
new_call.hash
= iterative_hash_template_arg (new_call.bindings, new_call.hash);
- new_call.hash
- = iterative_hash_object (ctx->manifestly_const_eval, new_call.hash);
/* If we have seen this call before, we are done. */
maybe_initialize_constexpr_call_table ();
@@ -3246,22 +3241,23 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
the slot can move during evaluation of the body. */
*slot = entry = ggc_alloc<constexpr_call> ();
*entry = new_call;
+ entry->result (ctx->manifestly_const_eval) = unknown_type_node;
fb.preserve ();
}
}
- /* Calls that are in progress have their result set to NULL, so that we
- can detect circular dependencies. Now that we only cache up to
- constexpr_cache_depth this won't catch circular dependencies that
+ /* Calls that are in progress have their result set to unknown_type_node,
+ so that we can detect circular dependencies. Now that we only cache
+ up to constexpr_cache_depth this won't catch circular dependencies that
start deeper, but they'll hit the recursion or ops limit. */
- else if (entry->result == NULL)
+ else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
{
if (!ctx->quiet)
error ("call has circular dependency");
*non_constant_p = true;
- entry->result = result = error_mark_node;
+ entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
}
else
- result = entry->result;
+ result = entry->result (ctx->manifestly_const_eval);
}
if (!depth_ok)
@@ -3482,7 +3478,22 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
else if (!result)
result = void_node;
if (entry)
- entry->result = cacheable ? result : error_mark_node;
+ {
+ entry->result (ctx->manifestly_const_eval)
+ = cacheable ? result : error_mark_node;
+
+ if (result != error_mark_node
+ && ctx->manifestly_const_eval == mce_unknown)
+ {
+ /* Evaluation succeeded and was independent of whether we're in a
+ manifestly constant-evaluated context, so we can also reuse
+ this result when evaluating this call with a fixed context. */
+ if (!entry->result (mce_true))
+ entry->result (mce_true) = entry->result (mce_unknown);
+ if (!entry->result (mce_false))
+ entry->result (mce_false) = entry->result (mce_unknown);
+ }
+ }
}
/* The result of a constexpr function must be completely initialized.
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 2f1678c..44fb086 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2704,6 +2704,8 @@ satisfy_declaration_constraints (tree t, sat_info info)
static tree
satisfy_declaration_constraints (tree t, tree args, sat_info info)
{
+ tree orig_args = args;
+
/* Update the declaration for diagnostics. */
info.in_decl = t;
@@ -2732,7 +2734,7 @@ satisfy_declaration_constraints (tree t, tree args, sat_info info)
tree result = boolean_true_node;
if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
{
- if (!push_tinst_level (t, args))
+ if (!push_tinst_level (t, orig_args))
return result;
tree pattern = DECL_TEMPLATE_RESULT (t);
push_to_top_level ();
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 37fab5b..5ff5c46 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -12090,6 +12090,8 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
gcc_checking_assert (TREE_CODE (e_inner) == TREE_CODE (d_inner));
}
+ // FIXME: do more precise errors at point of mismatch
+ const char *mismatch_msg = nullptr;
if (TREE_CODE (d_inner) == FUNCTION_DECL)
{
tree e_ret = fndecl_declared_return_type (existing);
@@ -12099,13 +12101,20 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
&& LAMBDA_TYPE_P (DECL_CONTEXT (d_inner)))
/* This has a recursive type that will compare different. */;
else if (!same_type_p (d_ret, e_ret))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting type for imported declaration %#qD");
+ goto mismatch;
+ }
tree e_type = TREE_TYPE (e_inner);
tree d_type = TREE_TYPE (d_inner);
if (DECL_EXTERN_C_P (d_inner) != DECL_EXTERN_C_P (e_inner))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting language linkage for imported "
+ "declaration %#qD");
+ goto mismatch;
+ }
for (tree e_args = TYPE_ARG_TYPES (e_type),
d_args = TYPE_ARG_TYPES (d_type);
@@ -12113,10 +12122,18 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
e_args = TREE_CHAIN (e_args), d_args = TREE_CHAIN (d_args))
{
if (!(e_args && d_args))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting argument list for imported "
+ "declaration %#qD");
+ goto mismatch;
+ }
if (!same_type_p (TREE_VALUE (d_args), TREE_VALUE (e_args)))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting argument types for imported "
+ "declaration %#qD");
+ goto mismatch;
+ }
}
/* If EXISTING has an undeduced or uninstantiated exception
@@ -12147,9 +12164,14 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
}
}
}
- else if (!DEFERRED_NOEXCEPT_SPEC_P (d_spec)
+ else if (!DECL_MAYBE_DELETED (d_inner)
+ && !DEFERRED_NOEXCEPT_SPEC_P (d_spec)
&& !comp_except_specs (d_spec, e_spec, ce_type))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting %<noexcept%> specifier for "
+ "imported declaration %#qD");
+ goto mismatch;
+ }
/* Similarly if EXISTING has an undeduced return type, but DECL's
is already deduced. */
@@ -12163,16 +12185,26 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
}
else if (type_uses_auto (d_ret)
&& !same_type_p (TREE_TYPE (d_type), TREE_TYPE (e_type)))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting deduced return type for "
+ "imported declaration %#qD");
+ goto mismatch;
+ }
/* Similarly if EXISTING has undeduced constexpr, but DECL's
is already deduced. */
if (DECL_MAYBE_DELETED (e_inner) && !DECL_MAYBE_DELETED (d_inner)
&& DECL_DECLARED_CONSTEXPR_P (d_inner))
DECL_DECLARED_CONSTEXPR_P (e_inner) = true;
+ else if (!DECL_MAYBE_DELETED (e_inner) && DECL_MAYBE_DELETED (d_inner))
+ /* Nothing to do. */;
else if (DECL_DECLARED_CONSTEXPR_P (e_inner)
!= DECL_DECLARED_CONSTEXPR_P (d_inner))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting %<constexpr%> for imported "
+ "declaration %#qD");
+ goto mismatch;
+ }
/* Don't synthesize a defaulted function if we're importing one
we've already determined. */
@@ -12184,13 +12216,17 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
if (!DECL_ORIGINAL_TYPE (e_inner)
|| !same_type_p (DECL_ORIGINAL_TYPE (d_inner),
DECL_ORIGINAL_TYPE (e_inner)))
- goto mismatch;
+ {
+ mismatch_msg = G_("conflicting imported declaration %q#D");
+ goto mismatch;
+ }
}
/* Using cp_tree_equal because we can meet TYPE_ARGUMENT_PACKs
here. I suspect the entities that directly do that are things
that shouldn't go to duplicate_decls (FIELD_DECLs etc). */
else if (!cp_tree_equal (TREE_TYPE (decl), TREE_TYPE (existing)))
{
+ mismatch_msg = G_("conflicting type for imported declaration %#qD");
mismatch:
if (DECL_IS_UNDECLARED_BUILTIN (existing))
/* Just like duplicate_decls, presum the user knows what
@@ -12203,11 +12239,9 @@ trees_in::is_matching_decl (tree existing, tree decl, bool is_typedef)
equality isn't feasible in general for local entities. */;
else
{
- // FIXME:QOI Might be template specialization from a module,
- // not necessarily global module
+ gcc_checking_assert (mismatch_msg);
auto_diagnostic_group d;
- error_at (DECL_SOURCE_LOCATION (decl),
- "conflicting global module declaration %#qD", decl);
+ error_at (DECL_SOURCE_LOCATION (decl), mismatch_msg, decl);
inform (DECL_SOURCE_LOCATION (existing),
"existing declaration %#qD", existing);
return false;
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index ca31897..b0a4f12 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,21 @@
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/109023
+ * d-compiler.cc: Include dmd/errors.h.
+ (Compiler::onImport): Implement.
+ * d-lang.cc (d_handle_option): Handle -finclude-imports.
+ (d_parse_file): Run semantic on included imports.
+ * gdc.texi: Document -finclude-imports.
+ * lang.opt: Add finclude-imports.
+ * lang.opt.urls: Regenerate.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119758
+ * d-lang.cc (d_parse_file): Use endswith in test for -fonly= argument.
+ * d-spec.cc (lang_specific_driver): Rework -fonly= and pass all input
+ files to the front-end compiler when the option is seen.
+
2025-04-11 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd 1b34fea478.
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index 160539d..e18f5d3 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "dmd/compiler.h"
+#include "dmd/errors.h"
#include "dmd/expression.h"
#include "dmd/identifier.h"
#include "dmd/module.h"
@@ -164,7 +165,39 @@ Compiler::onParseModule (Module *m)
driver intends on compiling the import. */
bool
-Compiler::onImport (Module *)
+Compiler::onImport (Module *m)
{
- return false;
+ if (!includeImports)
+ return false;
+
+ if (m->filetype != FileType::d && m->filetype != FileType::c)
+ return false;
+
+ /* All imports modules are included except those in the runtime library. */
+ ModuleDeclaration *md = m->md;
+ if (md && md->id)
+ {
+ if (md->packages.length >= 1)
+ {
+ if (!strcmp (md->packages.ptr[0]->toChars (), "core")
+ || !strcmp (md->packages.ptr[0]->toChars (), "std")
+ || !strcmp (md->packages.ptr[0]->toChars (), "gcc")
+ || !strcmp (md->packages.ptr[0]->toChars (), "etc"))
+ return false;
+ }
+ else if (!strcmp (md->id->toChars (), "object"))
+ return false;
+ }
+ else if (m->ident)
+ {
+ if (!strcmp (m->ident->toChars (), "object"))
+ return false;
+ }
+
+ /* This import will be compiled. */
+ if (global.params.v.verbose)
+ message ("compileimport (%s)", m->srcfile.toChars ());
+
+ compiledImports.push (m);
+ return true;
}
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 0dab76b..ec2ea59 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -523,6 +523,10 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
global.params.ignoreUnsupportedPragmas = value;
break;
+ case OPT_finclude_imports:
+ includeImports = true;
+ break;
+
case OPT_finvariants:
global.params.useInvariants = value ? CHECKENABLEon : CHECKENABLEoff;
break;
@@ -1309,6 +1313,21 @@ d_parse_file (void)
dmd::semantic3 (m, NULL);
}
+ if (includeImports)
+ {
+ for (size_t i = 0; i < compiledImports.length; i++)
+ {
+ Module *m = compiledImports[i];
+ gcc_assert (m->isRoot ());
+
+ if (global.params.v.verbose)
+ message ("semantic3 %s", m->toChars ());
+
+ dmd::semantic3 (m, NULL);
+ modules.push (m);
+ }
+ }
+
Module::runDeferredSemantic3 ();
/* Check again, incase semantic3 pass loaded any more modules. */
diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi
index 2cb0c4a62..3a8bea0 100644
--- a/gcc/d/gdc.texi
+++ b/gcc/d/gdc.texi
@@ -277,6 +277,12 @@ Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202002}.
Sets @code{__traits(getTargetInfo, "cppStd")} to @code{202302}.
@end table
+@opindex finclude-imports
+@item -finclude-imports
+Include imported modules in the compilation, as if they were given on the
+command line. When this option is enabled, all imported modules are compiled
+except those that are part of libphobos.
+
@opindex finvariants
@opindex fno-invariants
@item -fno-invariants
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index 50c6f2f..298ff58 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -327,6 +327,10 @@ fignore-unknown-pragmas
D
Ignore unsupported pragmas.
+finclude-imports
+D RejectNegative
+Include imported modules in the compilation.
+
finvariants
D Var(flag_invariants)
Generate code for class invariant contracts.
diff --git a/gcc/d/lang.opt.urls b/gcc/d/lang.opt.urls
index fa311d4..b4886bf 100644
--- a/gcc/d/lang.opt.urls
+++ b/gcc/d/lang.opt.urls
@@ -155,6 +155,9 @@ LangUrlSuffix_D(gdc/Runtime-Options.html#index-fextern-std)
fignore-unknown-pragmas
LangUrlSuffix_D(gdc/Warnings.html#index-fignore-unknown-pragmas)
+finclude-imports
+LangUrlSuffix_D(gdc/Runtime-Options.html#index-finclude-imports)
+
finvariants
LangUrlSuffix_D(gdc/Runtime-Options.html#index-finvariants)
diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi
index 8baee24..cb52e8c 100644
--- a/gcc/doc/gm2.texi
+++ b/gcc/doc/gm2.texi
@@ -2699,10 +2699,10 @@ PROCEDURE Example (foo, bar: CARDINAL) : CARDINAL ;
VAR
myout: CARDINAL ;
BEGIN
- ASM VOLATILE ("movq %1,%%rax; addq %2,%%rax; movq %%rax,%0"
+ ASM VOLATILE ("movl %1,%%eax; addl %2,%%eax; movl %%eax,%0"
: "=rm" (myout) (* outputs *)
: "rm" (foo), "rm" (bar) (* inputs *)
- : "rax") ; (* we trash *)
+ : "eax") ; (* we trash *)
RETURN( myout )
END Example ;
@end example
@@ -2720,10 +2720,10 @@ VAR
myout: CARDINAL ;
BEGIN
ASM VOLATILE (
- "movq %[left],%%rax; addq %[right],%%rax; movq %%rax,%[output]"
+ "movl %[left],%%eax; addl %[right],%%eax; movl %%eax,%[output]"
: [output] "=rm" (myout) (* outputs *)
: [left] "rm" (foo), [right] "rm" (bar) (* inputs *)
- : "rax") ; (* we trash *)
+ : "eax") ; (* we trash *)
RETURN( myout )
END Example ;
@end example
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index b5509ff..1af0082 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -350,6 +350,12 @@ documentation including the target @code{SYSTEM} definition module.
If Python3 is unavailable Modula-2 documentation will include a target
independent version of the SYSTEM modules.
+@item @anchor{gccrs-prerequisite}gccrs
+
+The official Rust compiler and Rust build system (cargo) are required for
+building various parts of the gccrs frontend, until gccrs can compile them
+by itself. The minimum supported Rust version is 1.49.
+
@item A ``working'' POSIX compatible shell, or GNU bash
Necessary when running @command{configure} because some
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fbaa29f..67155ee 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -33344,7 +33344,7 @@ system representing a certain processor type. Possible values for
@samp{z9-109}, @samp{z9-ec}/@samp{arch7}, @samp{z10}/@samp{arch8},
@samp{z196}/@samp{arch9}, @samp{zEC12}, @samp{z13}/@samp{arch11},
@samp{z14}/@samp{arch12}, @samp{z15}/@samp{arch13},
-@samp{z16}/@samp{arch14}, and @samp{native}.
+@samp{z16}/@samp{arch14}, @samp{z17}/@samp{arch15}, and @samp{native}.
The default is @option{-march=z900}.
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index df09cbc..8cf10d9 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -285,7 +285,7 @@ init_expmed (void)
for (speed = 0; speed < 2; speed++)
{
crtl->maybe_hot_insn_p = speed;
- set_zero_cost (speed, set_src_cost (const0_rtx, mode, speed));
+ set_zero_cost (speed, set_src_cost (const0_rtx, QImode, speed));
for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
mode = (machine_mode)(mode + 1))
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 19a26ba..a10d8df 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,16 @@
+2025-04-13 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/119669
+ * interface.cc (compare_parameter): Error when mismatch between
+ formal argument as subroutine and function. If the dummy
+ argument is a known function, set its typespec.
+
+2025-04-12 Thomas Schwinge <tschwinge@baylibre.com>
+
+ PR fortran/101602
+ * trans-stmt.cc (gfc_trans_concurrent_locality_spec): Fix
+ 'static_assert'.
+
2025-04-09 Harald Anlauf <anlauf@gmx.de>
PR fortran/119656
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index c702239..1e552a3 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2534,16 +2534,33 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
gfc_find_symbol (actual_name, gsym->ns, 0, &global_asym);
if (global_asym != NULL)
{
- gcc_assert (formal->attr.function);
- if (!gfc_compare_types (&global_asym->ts, &formal->ts))
+ if (formal->attr.subroutine)
{
- gfc_error ("Type mismatch at %L passing global "
- "function %qs declared at %L (%s/%s)",
- &actual->where, actual_name, &gsym->where,
- gfc_typename (&global_asym->ts),
- gfc_dummy_typename (&formal->ts));
+ gfc_error ("Mismatch between subroutine and "
+ "function at %L", &actual->where);
return false;
}
+ else if (formal->attr.function)
+ {
+ if (!gfc_compare_types (&global_asym->ts,
+ &formal->ts))
+ {
+ gfc_error ("Type mismatch at %L passing global "
+ "function %qs declared at %L (%s/%s)",
+ &actual->where, actual_name,
+ &gsym->where,
+ gfc_typename (&global_asym->ts),
+ gfc_dummy_typename (&formal->ts));
+ return false;
+ }
+ }
+ else
+ {
+ /* The global symbol is a function. Set the formal
+ argument acordingly. */
+ formal->attr.function = 1;
+ formal->ts = global_asym->ts;
+ }
}
}
}
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 9064671..4fd87f2 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -30,6 +30,9 @@ compilation is specified by a string called a "spec". */
#define INCLUDE_STRING
#include "config.h"
#include "system.h"
+#ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
+#include <sys/personality.h>
+#endif
#include "coretypes.h"
#include "multilib.h" /* before tm.h */
#include "tm.h"
@@ -8003,6 +8006,10 @@ try_generate_repro (const char **argv)
else
new_argv[out_arg] = "-o-";
+#ifdef HOST_HAS_PERSONALITY_ADDR_NO_RANDOMIZE
+ personality (personality (0xffffffffU) | ADDR_NO_RANDOMIZE);
+#endif
+
int status;
for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS; ++attempt)
{
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 2645689..26b1496 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -307,14 +307,21 @@ ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
fprintf (f, "\n");
}
-/* If VALUE has all bits set to one, print "-1" to F, otherwise simply print it
- hexadecimally to F. */
+/* Print VALUE to F in a form which in usual cases does not take thousands of
+ characters. */
static void
ipcp_print_widest_int (FILE *f, const widest_int &value)
{
if (wi::eq_p (wi::bit_not (value), 0))
fprintf (f, "-1");
+ else if (wi::eq_p (wi::bit_not (wi::bit_or (value,
+ wi::sub (wi::lshift (1, 128),
+ 1))), 0))
+ {
+ fprintf (f, "all ones folled by ");
+ print_hex (wi::bit_and (value, wi::sub (wi::lshift (1, 128), 1)), f);
+ }
else
print_hex (value, f);
}
@@ -331,7 +338,7 @@ ipcp_bits_lattice::print (FILE *f)
fprintf (f, " Bits: value = ");
ipcp_print_widest_int (f, get_value ());
fprintf (f, ", mask = ");
- print_hex (get_mask (), f);
+ ipcp_print_widest_int (f, get_mask ());
fprintf (f, "\n");
}
}
@@ -918,6 +925,8 @@ ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask,
m_mask |= m_value;
m_value &= ~m_mask;
+ widest_int cap_mask = wi::bit_not (wi::sub (wi::lshift (1, precision), 1));
+ m_mask |= cap_mask;
if (wi::sext (m_mask, precision) == -1)
return set_to_bottom ();
@@ -996,6 +1005,8 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
adjusted_mask |= adjusted_value;
adjusted_value &= ~adjusted_mask;
}
+ widest_int cap_mask = wi::bit_not (wi::sub (wi::lshift (1, precision), 1));
+ adjusted_mask |= cap_mask;
if (wi::sext (adjusted_mask, precision) == -1)
return set_to_bottom ();
return set_to_constant (adjusted_value, adjusted_mask);
@@ -1467,10 +1478,12 @@ ipacp_value_safe_for_type (tree param_type, tree value)
return NULL_TREE;
}
-/* Return the result of a (possibly arithmetic) operation on the constant value
- INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is the type
- in which any operation is to be performed. Return NULL_TREE if that cannot
- be determined or be considered an interprocedural invariant. */
+/* Return the result of a (possibly arithmetic) operation determined by OPCODE
+ on the constant value INPUT. OPERAND is 2nd operand for binary operation
+ and is required for binary operations. RES_TYPE, required when opcode is
+ not NOP_EXPR, is the type in which any operation is to be performed. Return
+ NULL_TREE if that cannot be determined or be considered an interprocedural
+ invariant. */
static tree
ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
@@ -1491,16 +1504,6 @@ ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
return NULL_TREE;
}
- if (!res_type)
- {
- if (TREE_CODE_CLASS (opcode) == tcc_comparison)
- res_type = boolean_type_node;
- else if (expr_type_first_operand_type_p (opcode))
- res_type = TREE_TYPE (input);
- else
- return NULL_TREE;
- }
-
if (TREE_CODE_CLASS (opcode) == tcc_unary)
res = fold_unary (opcode, res_type, input);
else
@@ -1584,7 +1587,10 @@ ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
return NULL_TREE;
enum tree_code opcode = ipa_get_jf_pass_through_operation (jfunc);
tree op2 = ipa_get_jf_pass_through_operand (jfunc);
- tree cstval = ipa_get_jf_arith_result (opcode, input, op2, NULL_TREE);
+ tree op_type
+ = (opcode == NOP_EXPR) ? NULL_TREE
+ : ipa_get_jf_pass_through_op_type (jfunc);
+ tree cstval = ipa_get_jf_arith_result (opcode, input, op2, op_type);
return ipacp_value_safe_for_type (parm_type, cstval);
}
else
@@ -1724,24 +1730,7 @@ ipa_vr_intersect_with_arith_jfunc (vrange &vr,
const value_range *inter_vr;
if (operation != NOP_EXPR)
{
- /* Since we construct arithmetic jump functions even when there is a
- type conversion in between the operation encoded in the jump
- function and when it is passed in a call argument, the IPA
- propagation phase must also perform the operation and conversion
- in two separate steps.
-
- TODO: In order to remove the use of expr_type_first_operand_type_p
- predicate we would need to stream the operation type, ideally
- encoding the whole jump function as a series of expr_eval_op
- structures. */
-
- tree operation_type;
- if (expr_type_first_operand_type_p (operation))
- operation_type = src_type;
- else if (operation == ABSU_EXPR)
- operation_type = unsigned_type_for (src_type);
- else
- return;
+ tree operation_type = ipa_get_jf_pass_through_op_type (jfunc);
op_res.set_varying (operation_type);
if (!ipa_vr_operation_and_type_effects (op_res, src_vr, operation,
operation_type, src_type))
@@ -1771,14 +1760,7 @@ ipa_vr_intersect_with_arith_jfunc (vrange &vr,
value_range op_vr (TREE_TYPE (operand));
ipa_get_range_from_ip_invariant (op_vr, operand, context_node);
- tree operation_type;
- if (TREE_CODE_CLASS (operation) == tcc_comparison)
- operation_type = boolean_type_node;
- else if (expr_type_first_operand_type_p (operation))
- operation_type = src_type;
- else
- return;
-
+ tree operation_type = ipa_get_jf_pass_through_op_type (jfunc);
value_range op_res (operation_type);
if (!ipa_vr_supported_type_p (operation_type)
|| !handler.operand_check_p (operation_type, src_type, op_vr.type ())
@@ -1918,10 +1900,11 @@ ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
return NULL_TREE;
}
- return ipa_get_jf_arith_result (item->value.pass_through.operation,
- value,
- item->value.pass_through.operand,
- item->type);
+ tree cstval = ipa_get_jf_arith_result (item->value.pass_through.operation,
+ value,
+ item->value.pass_through.operand,
+ item->value.pass_through.op_type);
+ return ipacp_value_safe_for_type (item->type, cstval);
}
/* Process all items in AGG_JFUNC relative to caller (or the node the original
@@ -2150,13 +2133,15 @@ ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
/* A helper function that returns result of operation specified by OPCODE on
the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
value of SRC_VAL. If the operation is binary, OPND2 is a constant value
- acting as its second operand. */
+ acting as its second operand. OP_TYPE is the type in which the operation is
+ performed. */
static tree
get_val_across_arith_op (enum tree_code opcode,
tree opnd1_type,
tree opnd2,
- ipcp_value<tree> *src_val)
+ ipcp_value<tree> *src_val,
+ tree op_type)
{
tree opnd1 = src_val->value;
@@ -2165,17 +2150,19 @@ get_val_across_arith_op (enum tree_code opcode,
&& !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
return NULL_TREE;
- return ipa_get_jf_arith_result (opcode, opnd1, opnd2, NULL_TREE);
+ return ipa_get_jf_arith_result (opcode, opnd1, opnd2, op_type);
}
/* Propagate values through an arithmetic transformation described by a jump
function associated with edge CS, taking values from SRC_LAT and putting
- them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
- OPND2 is a constant value if transformation is a binary operation.
- SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
- a part of the aggregate. SRC_IDX is the index of the source parameter.
- RES_TYPE is the value type of result being propagated into. Return true if
- DEST_LAT changed. */
+ them into DEST_LAT. OPND1_TYPE, if non-NULL, is the expected type for the
+ values in SRC_LAT. OPND2 is a constant value if transformation is a binary
+ operation. SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes
+ lattice of a part of an aggregate, otherwise it should be -1. SRC_IDX is
+ the index of the source parameter. OP_TYPE is the type in which the
+ operation is performed and can be NULL when OPCODE is NOP_EXPR. RES_TYPE is
+ the value type of result being propagated into. Return true if DEST_LAT
+ changed. */
static bool
propagate_vals_across_arith_jfunc (cgraph_edge *cs,
@@ -2186,6 +2173,7 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
ipcp_lattice<tree> *dest_lat,
HOST_WIDE_INT src_offset,
int src_idx,
+ tree op_type,
tree res_type)
{
ipcp_value<tree> *src_val;
@@ -2241,7 +2229,7 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
for (int j = 1; j < max_recursive_depth; j++)
{
tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
- src_val);
+ src_val, op_type);
cstval = ipacp_value_safe_for_type (res_type, cstval);
if (!cstval)
break;
@@ -2266,7 +2254,7 @@ propagate_vals_across_arith_jfunc (cgraph_edge *cs,
}
tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
- src_val);
+ src_val, op_type);
cstval = ipacp_value_safe_for_type (res_type, cstval);
if (cstval)
ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
@@ -2290,11 +2278,13 @@ propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
tree parm_type)
{
gcc_checking_assert (parm_type);
- return propagate_vals_across_arith_jfunc (cs,
- ipa_get_jf_pass_through_operation (jfunc),
- NULL_TREE,
+ enum tree_code opcode = ipa_get_jf_pass_through_operation (jfunc);
+ tree op_type = (opcode == NOP_EXPR) ? NULL_TREE
+ : ipa_get_jf_pass_through_op_type (jfunc);
+ return propagate_vals_across_arith_jfunc (cs, opcode, NULL_TREE,
ipa_get_jf_pass_through_operand (jfunc),
- src_lat, dest_lat, -1, src_idx, parm_type);
+ src_lat, dest_lat, -1, src_idx, op_type,
+ parm_type);
}
/* Propagate values through an ancestor jump function JFUNC associated with
@@ -2507,14 +2497,12 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
return dest_lattice->set_to_bottom ();
}
- unsigned precision = TYPE_PRECISION (parm_type);
- signop sgn = TYPE_SIGN (parm_type);
-
if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
{
ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
tree operand = NULL_TREE;
+ tree op_type = NULL_TREE;
enum tree_code code;
unsigned src_idx;
bool keep_null = false;
@@ -2524,7 +2512,10 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
code = ipa_get_jf_pass_through_operation (jfunc);
src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
if (code != NOP_EXPR)
- operand = ipa_get_jf_pass_through_operand (jfunc);
+ {
+ operand = ipa_get_jf_pass_through_operand (jfunc);
+ op_type = ipa_get_jf_pass_through_op_type (jfunc);
+ }
}
else
{
@@ -2551,6 +2542,11 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
if (!src_lats->bits_lattice.bottom_p ())
{
+ if (!op_type)
+ op_type = ipa_get_type (caller_info, src_idx);
+
+ unsigned precision = TYPE_PRECISION (op_type);
+ signop sgn = TYPE_SIGN (op_type);
bool drop_all_ones
= keep_null && !src_lats->bits_lattice.known_nonzero_p ();
@@ -2570,7 +2566,8 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
= widest_int::from (bm.mask (), TYPE_SIGN (parm_type));
widest_int value
= widest_int::from (bm.value (), TYPE_SIGN (parm_type));
- return dest_lattice->meet_with (value, mask, precision);
+ return dest_lattice->meet_with (value, mask,
+ TYPE_PRECISION (parm_type));
}
}
return dest_lattice->set_to_bottom ();
@@ -2869,6 +2866,7 @@ propagate_aggregate_lattice (struct cgraph_edge *cs,
src_lat, aglat,
src_offset,
src_idx,
+ item->value.pass_through.op_type,
item->type);
if (src_lat->contains_variable)
@@ -5394,11 +5392,14 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
if (self_recursive_pass_through_p (cs, jump_func, i, false))
{
gcc_assert (newval);
- t = ipa_get_jf_arith_result (
- ipa_get_jf_pass_through_operation (jump_func),
- newval,
+ enum tree_code opcode
+ = ipa_get_jf_pass_through_operation (jump_func);
+ tree op_type = (opcode == NOP_EXPR) ? NULL_TREE
+ : ipa_get_jf_pass_through_op_type (jump_func);
+ t = ipa_get_jf_arith_result (opcode, newval,
ipa_get_jf_pass_through_operand (jump_func),
- type);
+ op_type);
+ t = ipacp_value_safe_for_type (type, t);
}
else
t = ipa_value_from_jfunc (ipa_node_params_sum->get (cs->caller),
@@ -5603,10 +5604,13 @@ push_agg_values_for_index_from_edge (struct cgraph_edge *cs, int index,
&& self_recursive_agg_pass_through_p (cs, &agg_jf, index, false)
&& (srcvalue = interim->get_value(index,
agg_jf.offset / BITS_PER_UNIT)))
- value = ipa_get_jf_arith_result (agg_jf.value.pass_through.operation,
- srcvalue,
- agg_jf.value.pass_through.operand,
- agg_jf.type);
+ {
+ value = ipa_get_jf_arith_result (agg_jf.value.pass_through.operation,
+ srcvalue,
+ agg_jf.value.pass_through.operand,
+ agg_jf.value.pass_through.op_type);
+ value = ipacp_value_safe_for_type (agg_jf.type, value);
+ }
else
value = ipa_agg_value_from_jfunc (caller_info, cs->caller,
&agg_jf);
@@ -6426,7 +6430,7 @@ ipcp_store_vr_results (void)
fprintf (dump_file, " param %i: value = ", i);
ipcp_print_widest_int (dump_file, bits->get_value ());
fprintf (dump_file, ", mask = ");
- print_hex (bits->get_mask (), dump_file);
+ ipcp_print_widest_int (dump_file, bits->get_mask ());
fprintf (dump_file, "\n");
}
}
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index a120f94..49d68ab 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-range.h"
#include "value-range-storage.h"
#include "vr-values.h"
+#include "lto-streamer.h"
/* Function summary where the parameter infos are actually stored. */
ipa_node_params_t *ipa_node_params_sum = NULL;
@@ -454,7 +455,11 @@ ipa_dump_jump_function (FILE *f, ipa_jump_func *jump_func,
if (jump_func->value.pass_through.operation != NOP_EXPR)
{
fprintf (f, " ");
- print_generic_expr (f, jump_func->value.pass_through.operand);
+ if (jump_func->value.pass_through.operand)
+ print_generic_expr (f, jump_func->value.pass_through.operand);
+ fprintf (f, " (in type ");
+ print_generic_expr (f, jump_func->value.pass_through.op_type);
+ fprintf (f, ")");
}
if (jump_func->value.pass_through.agg_preserved)
fprintf (f, ", agg_preserved");
@@ -510,7 +515,11 @@ ipa_dump_jump_function (FILE *f, ipa_jump_func *jump_func,
if (item->value.pass_through.operation != NOP_EXPR)
{
fprintf (f, " ");
- print_generic_expr (f, item->value.pass_through.operand);
+ if (item->value.pass_through.operand)
+ print_generic_expr (f, item->value.pass_through.operand);
+ fprintf (f, " (in type ");
+ print_generic_expr (f, jump_func->value.pass_through.op_type);
+ fprintf (f, ")");
}
}
else if (item->jftype == IPA_JF_CONST)
@@ -682,6 +691,7 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = NULL_TREE;
+ jfunc->value.pass_through.op_type = NULL_TREE;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = NOP_EXPR;
jfunc->value.pass_through.agg_preserved = agg_preserved;
@@ -692,10 +702,11 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
static void
ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
- enum tree_code operation)
+ enum tree_code operation, tree op_type)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = NULL_TREE;
+ jfunc->value.pass_through.op_type = op_type;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = operation;
jfunc->value.pass_through.agg_preserved = false;
@@ -705,10 +716,12 @@ ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
static void
ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
- tree operand, enum tree_code operation)
+ tree operand, enum tree_code operation,
+ tree op_type)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
+ jfunc->value.pass_through.op_type = op_type;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = operation;
jfunc->value.pass_through.agg_preserved = false;
@@ -1513,6 +1526,9 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
if (index >= 0)
{
+ if (lto_variably_modified_type_p (TREE_TYPE (name)))
+ return;
+
switch (gimple_assign_rhs_class (stmt))
{
case GIMPLE_BINARY_RHS:
@@ -1526,7 +1542,8 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
return;
ipa_set_jf_arith_pass_through (jfunc, index, op2,
- gimple_assign_rhs_code (stmt));
+ gimple_assign_rhs_code (stmt),
+ TREE_TYPE (name));
break;
}
case GIMPLE_SINGLE_RHS:
@@ -1539,7 +1556,8 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
case GIMPLE_UNARY_RHS:
if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
ipa_set_jf_unary_pass_through (jfunc, index,
- gimple_assign_rhs_code (stmt));
+ gimple_assign_rhs_code (stmt),
+ TREE_TYPE (name));
default:;
}
return;
@@ -1912,6 +1930,7 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
if (!is_gimple_assign (stmt))
break;
+ lhs = gimple_assign_lhs (stmt);
rhs1 = gimple_assign_rhs1 (stmt);
}
@@ -1931,7 +1950,8 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
(the constant from the PHI node). */
- if (gimple_phi_num_args (phi) != 2)
+ if (gimple_phi_num_args (phi) != 2
+ || lto_variably_modified_type_p (TREE_TYPE (lhs)))
return;
tree arg0 = gimple_phi_arg_def (phi, 0);
tree arg1 = gimple_phi_arg_def (phi, 1);
@@ -1956,6 +1976,7 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
code = ASSERT_EXPR;
agg_value->pass_through.operand = operand;
+ agg_value->pass_through.op_type = TREE_TYPE (lhs);
}
else if (is_gimple_assign (stmt))
{
@@ -1980,10 +2001,12 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
with one operand, here we only allow tc_unary operation to avoid
possible problem. Then we can use (opclass == tc_unary) or not to
distinguish unary and binary. */
- if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code))
+ if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code)
+ || lto_variably_modified_type_p (TREE_TYPE (lhs)))
return;
rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
+ agg_value->pass_through.op_type = TREE_TYPE (lhs);
break;
case GIMPLE_BINARY_RHS:
@@ -1992,12 +2015,16 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
gimple *rhs2_stmt = stmt;
tree rhs2 = gimple_assign_rhs2 (stmt);
+ if (lto_variably_modified_type_p (TREE_TYPE (lhs)))
+ return;
+
rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
if (is_gimple_ip_invariant (rhs2))
{
agg_value->pass_through.operand = rhs2;
+ agg_value->pass_through.op_type = TREE_TYPE (lhs);
stmt = rhs1_stmt;
}
else if (is_gimple_ip_invariant (rhs1))
@@ -2008,6 +2035,7 @@ analyze_agg_content_value (struct ipa_func_body_info *fbi,
return;
agg_value->pass_through.operand = rhs1;
+ agg_value->pass_through.op_type = TREE_TYPE (lhs);
stmt = rhs2_stmt;
rhs1 = rhs2;
}
@@ -3520,12 +3548,17 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
}
else if (TREE_CODE_CLASS (operation) == tcc_unary)
- ipa_set_jf_unary_pass_through (dst, formal_id, operation);
+ {
+ tree op_t = ipa_get_jf_pass_through_op_type (src);
+ ipa_set_jf_unary_pass_through (dst, formal_id, operation,
+ op_t);
+ }
else
{
tree operand = ipa_get_jf_pass_through_operand (src);
+ tree op_t = ipa_get_jf_pass_through_op_type (src);
ipa_set_jf_arith_pass_through (dst, formal_id, operand,
- operation);
+ operation, op_t);
}
break;
}
@@ -4935,9 +4968,13 @@ ipa_write_jump_function (struct output_block *ob,
}
else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
== tcc_unary)
- streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
+ {
+ stream_write_tree (ob, jump_func->value.pass_through.op_type, true);
+ streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
+ }
else
{
+ stream_write_tree (ob, jump_func->value.pass_through.op_type, true);
stream_write_tree (ob, jump_func->value.pass_through.operand, true);
streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
}
@@ -4979,6 +5016,8 @@ ipa_write_jump_function (struct output_block *ob,
case IPA_JF_LOAD_AGG:
streamer_write_uhwi (ob, item->value.pass_through.operation);
streamer_write_uhwi (ob, item->value.pass_through.formal_id);
+ if (item->value.pass_through.operation != NOP_EXPR)
+ stream_write_tree (ob, item->value.pass_through.op_type, true);
if (TREE_CODE_CLASS (item->value.pass_through.operation)
!= tcc_unary)
stream_write_tree (ob, item->value.pass_through.operand, true);
@@ -5047,15 +5086,18 @@ ipa_read_jump_function (class lto_input_block *ib,
}
else if (TREE_CODE_CLASS (operation) == tcc_unary)
{
+ tree op_type = stream_read_tree (ib, data_in);
int formal_id = streamer_read_uhwi (ib);
- ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
+ ipa_set_jf_unary_pass_through (jump_func, formal_id, operation,
+ op_type);
}
else
{
+ tree op_type = stream_read_tree (ib, data_in);
tree operand = stream_read_tree (ib, data_in);
int formal_id = streamer_read_uhwi (ib);
ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
- operation);
+ operation, op_type);
}
break;
case IPA_JF_ANCESTOR:
@@ -5103,6 +5145,10 @@ ipa_read_jump_function (class lto_input_block *ib,
operation = (enum tree_code) streamer_read_uhwi (ib);
item.value.pass_through.operation = operation;
item.value.pass_through.formal_id = streamer_read_uhwi (ib);
+ if (operation != NOP_EXPR)
+ item.value.pass_through.op_type = stream_read_tree (ib, data_in);
+ else
+ item.value.pass_through.op_type = NULL_TREE;
if (TREE_CODE_CLASS (operation) == tcc_unary)
item.value.pass_through.operand = NULL_TREE;
else
@@ -6224,6 +6270,10 @@ ipa_agg_pass_through_jf_equivalent_p (ipa_pass_through_data *ipt1,
|| ipt1->formal_id != ipt2->formal_id
|| (!agg_jf && (ipt1->agg_preserved != ipt2->agg_preserved)))
return false;
+ if (ipt1->operation != NOP_EXPR
+ && (TYPE_MAIN_VARIANT (ipt1->op_type)
+ != TYPE_MAIN_VARIANT (ipt2->op_type)))
+ return false;
if (((ipt1->operand != NULL_TREE) != (ipt2->operand != NULL_TREE))
|| (ipt1->operand
&& !values_equal_for_ipcp_p (ipt1->operand, ipt2->operand)))
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 7735b57..3bd442f 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -96,6 +96,9 @@ struct GTY(()) ipa_pass_through_data
/* If an operation is to be performed on the original parameter, this is the
second (constant) operand. */
tree operand;
+ /* The result type of the operation. In case of no operation (represented by
+ NOP_EXPR) it should be NULL_TREE. */
+ tree op_type;
/* Number of the caller's formal parameter being passed. */
int formal_id;
/* Operation that is performed on the argument before it is passed on.
@@ -387,6 +390,18 @@ ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc)
return jfunc->value.pass_through.operand;
}
+/* Return the type of the operation in a non-NOP pass through jmp function
+ JFUNC. */
+
+inline tree
+ipa_get_jf_pass_through_op_type (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH
+ && jfunc->value.pass_through.operation != NOP_EXPR);
+
+ return jfunc->value.pass_through.op_type;
+}
+
/* Return the number of the caller's formal parameter that a pass through jump
function JFUNC refers to. */
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index d5b6ee7..a055d12d 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -130,7 +130,7 @@ destroy_output_block (struct output_block *ob)
/* Wrapper around variably_modified_type_p avoiding type modification
during WPA streaming. */
-static bool
+bool
lto_variably_modified_type_p (tree type)
{
return (in_lto_p
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index ff33bf0..4b7209e3 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -906,6 +906,7 @@ void lto_output_decl_state_streams (struct output_block *,
void lto_output_decl_state_refs (struct output_block *,
struct lto_output_stream *,
struct lto_out_decl_state *);
+bool lto_variably_modified_type_p (tree);
void lto_output_location (struct output_block *, struct bitpack_d *,
location_t);
void lto_output_location_and_block (struct output_block *, struct bitpack_d *,
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 4028b47..835e113 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -115,6 +115,7 @@ GRS_OBJS = \
rust/rust-macro-builtins-format-args.o \
rust/rust-macro-builtins-location.o \
rust/rust-macro-builtins-include.o \
+ rust/rust-token-tree-desugar.o \
rust/rust-fmt.o \
rust/rust-hir.o \
rust/rust-hir-map.o \
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 09e0fce..91611ec 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1018,6 +1018,7 @@ public:
}
DelimType get_delim_type () const { return delim_type; }
+ location_t get_locus () const { return locus; }
};
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 84cdfdb..69538df 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -3004,6 +3004,10 @@ class RangeExpr : public ExprWithoutBlock
{
location_t locus;
+ // Some visitors still check for attributes on RangeExprs, and they will need
+ // to be supported in the future - so keep that for now
+ std::vector<Attribute> empty_attributes = {};
+
protected:
// outer attributes not allowed before range expressions
RangeExpr (location_t locus) : locus (locus) {}
@@ -3013,15 +3017,11 @@ public:
std::vector<Attribute> &get_outer_attrs () override final
{
- // RangeExpr cannot have any outer attributes
- rust_assert (false);
+ return empty_attributes;
}
// should never be called - error if called
- void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override
- {
- rust_assert (false);
- }
+ void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override {}
Expr::Kind get_expr_kind () const override { return Expr::Kind::Range; }
};
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc
index 4904322..4c2257a 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -646,6 +646,9 @@ ConstChecker::visit (Enum &enum_item)
{
check_default_const_generics (enum_item.get_generic_params (),
ConstGenericCtx::Enum);
+
+ for (auto &item : enum_item.get_variants ())
+ item->accept_vis (*this);
}
void
diff --git a/gcc/rust/expand/rust-macro-builtins-format-args.cc b/gcc/rust/expand/rust-macro-builtins-format-args.cc
index 8eb32d5..3e1249d 100644
--- a/gcc/rust/expand/rust-macro-builtins-format-args.cc
+++ b/gcc/rust/expand/rust-macro-builtins-format-args.cc
@@ -55,6 +55,8 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
format_expr = parser.parse_literal_expr ();
+ rust_assert (format_expr);
+
// TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
// macro invocation, what do we do here? return a tl::unexpected?
auto format_str = static_cast<AST::LiteralExpr &> (*format_expr)
@@ -81,6 +83,11 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
{
parser.skip_token (COMMA);
+ // Check in case of an extraneous comma in the args list, which is
+ // allowed - format_args!("fmt", arg, arg2,)
+ if (parser.peek_current_token ()->get_id () == last_token_id)
+ break;
+
if (parser.peek_current_token ()->get_id () == IDENTIFIER
&& parser.peek (1)->get_id () == EQUAL)
{
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 39c4c46..8b406ff 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -83,7 +83,6 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
{"Ord", BuiltinMacro::Ord},
{"PartialOrd", BuiltinMacro::PartialOrd},
{"Hash", BuiltinMacro::Hash},
-
}};
AST::MacroTranscriberFunc
@@ -137,6 +136,7 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"cfg_accessible", MacroBuiltin::sorry},
{"rustc_const_stable", MacroBuiltin::sorry},
{"rustc_const_unstable", MacroBuiltin::sorry},
+ {"track_caller", MacroBuiltin::sorry},
/* Derive builtins do not need a real transcriber, but still need one. It
should however never be called since builtin derive macros get expanded
differently, and benefit from knowing on what kind of items they are
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index cd17a3f..673b8fb 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -28,6 +28,7 @@
#include "rust-cfg-strip.h"
#include "rust-early-name-resolver.h"
#include "rust-proc-macro.h"
+#include "rust-token-tree-desugar.h"
namespace Rust {
@@ -78,7 +79,10 @@ MacroExpander::expand_decl_macro (location_t invoc_locus,
* trees.
*/
- AST::DelimTokenTree &invoc_token_tree = invoc.get_delim_tok_tree ();
+ AST::DelimTokenTree &invoc_token_tree_sugar = invoc.get_delim_tok_tree ();
+
+ // We must first desugar doc comments into proper attributes
+ auto invoc_token_tree = AST::TokenTreeDesugar ().go (invoc_token_tree_sugar);
// find matching arm
AST::MacroRule *matched_rule = nullptr;
@@ -621,9 +625,10 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
// matched fragment get the offset in the token stream
size_t offs_end = source.get_offs ();
- sub_stack.insert_metavar (
- MatchedFragment (fragment->get_ident ().as_string (),
- offs_begin, offs_end));
+ if (valid_current_match)
+ sub_stack.insert_metavar (
+ MatchedFragment (fragment->get_ident ().as_string (),
+ offs_begin, offs_end));
}
break;
@@ -650,15 +655,15 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
}
auto old_stack = sub_stack.pop ();
- // nest metavars into repetitions
- for (auto &ent : old_stack)
- sub_stack.append_fragment (ent.first, std::move (ent.second));
-
// If we've encountered an error once, stop trying to match more
// repetitions
if (!valid_current_match)
break;
+ // nest metavars into repetitions
+ for (auto &ent : old_stack)
+ sub_stack.append_fragment (ent.first, std::move (ent.second));
+
match_amount++;
// Break early if we notice there's too many expressions already
diff --git a/gcc/rust/expand/rust-token-tree-desugar.cc b/gcc/rust/expand/rust-token-tree-desugar.cc
new file mode 100644
index 0000000..3b47180
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-token-tree-desugar.h"
+#include "rust-ast.h"
+#include "rust-token.h"
+
+namespace Rust {
+namespace AST {
+
+DelimTokenTree
+TokenTreeDesugar::go (DelimTokenTree &tts)
+{
+ tts.accept_vis (*this);
+
+ return DelimTokenTree (tts.get_delim_type (), std::move (desugared),
+ tts.get_locus ());
+}
+
+void
+TokenTreeDesugar::append (TokenPtr &&new_token)
+{
+ desugared.emplace_back (std::make_unique<Token> (std::move (new_token)));
+}
+
+void
+TokenTreeDesugar::append (std::unique_ptr<TokenTree> &&new_token)
+{
+ desugared.emplace_back (std::move (new_token));
+}
+
+void
+TokenTreeDesugar::visit (Token &tts)
+{
+ if (tts.get_id () == TokenId::OUTER_DOC_COMMENT
+ || tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ {
+ append (Rust::Token::make (TokenId::HASH, tts.get_locus ()));
+
+ if (tts.get_id () == TokenId::INNER_DOC_COMMENT)
+ append (Rust::Token::make (EXCLAM, tts.get_locus ()));
+
+ append (Rust::Token::make (TokenId::LEFT_SQUARE, tts.get_locus ()));
+ append (Rust::Token::make_identifier (tts.get_locus (), "doc"));
+ append (Rust::Token::make (TokenId::EQUAL, tts.get_locus ()));
+ append (Rust::Token::make_string (tts.get_locus (),
+ std::string (tts.get_str ())));
+ append (Rust::Token::make (TokenId::RIGHT_SQUARE, tts.get_locus ()));
+ }
+ else
+ {
+ append (tts.clone_token ());
+ }
+}
+
+}; // namespace AST
+}; // namespace Rust
diff --git a/gcc/rust/expand/rust-token-tree-desugar.h b/gcc/rust/expand/rust-token-tree-desugar.h
new file mode 100644
index 0000000..ccba53b
--- /dev/null
+++ b/gcc/rust/expand/rust-token-tree-desugar.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_TOKEN_TREE_DESUGAR_H
+#define RUST_TOKEN_TREE_DESUGAR_H
+
+#include "rust-ast-visitor.h"
+#include "rust-system.h"
+#include "rust-ast.h"
+
+namespace Rust {
+namespace AST {
+
+/**
+ * Desugar a given token-tree before parsing it for a macro invocation. At the
+ * moment, the sole purpose of this desugar is to transform doc-comments into
+ * their attribute form (/// comment -> #[doc = "comment"])
+ */
+class TokenTreeDesugar : public DefaultASTVisitor
+{
+public:
+ TokenTreeDesugar () : desugared (std::vector<std::unique_ptr<TokenTree>> ())
+ {}
+
+ DelimTokenTree go (DelimTokenTree &tts);
+
+private:
+ std::vector<std::unique_ptr<TokenTree>> desugared;
+ void append (TokenPtr &&new_token);
+ void append (std::unique_ptr<TokenTree> &&new_token);
+
+ using DefaultASTVisitor::visit;
+
+ virtual void visit (Token &tts) override;
+};
+
+}; // namespace AST
+}; // namespace Rust
+
+#endif //! RUST_TOKEN_TREE_DESUGAR_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index d584961..30f6d43 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -356,6 +356,8 @@ ResolveItem::visit (AST::EnumItemDiscriminant &item)
auto cpath = canonical_prefix.append (decl);
mappings.insert_canonical_path (item.get_node_id (), cpath);
+
+ ResolveExpr::go (item.get_expr (), path, cpath);
}
void
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index afaca1f..36456e1 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -325,10 +325,9 @@ Early::visit_attributes (std::vector<AST::Attribute> &attrs)
auto pm_def = mappings.lookup_derive_proc_macro_def (
definition->get_node_id ());
- rust_assert (pm_def.has_value ());
-
- mappings.insert_derive_proc_macro_invocation (trait,
- pm_def.value ());
+ if (pm_def.has_value ())
+ mappings.insert_derive_proc_macro_invocation (trait,
+ pm_def.value ());
}
}
else if (Analysis::BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 8863be7..ba37dee 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -113,7 +113,17 @@ TopLevel::visit (AST::Module &module)
// This was copied from the old early resolver method
// 'accumulate_escaped_macros'
if (module.get_kind () == AST::Module::UNLOADED)
- module.load_items ();
+ {
+ module.load_items ();
+
+ // If the module was previously unloaded, then we don't want to visit it
+ // this time around as the CfgStrip hasn't run on its inner items yet.
+ // Skip it for now, mark the visitor as dirty and try again
+
+ dirty = true;
+
+ return;
+ }
DefaultResolver::visit (module);
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 72aef08..234721c 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
tree
Bvariable::get_tree (location_t location) const
{
- if (this->t_ == error_mark_node)
+ if (error_operand_p (this->t_))
return error_mark_node;
TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
tree
pointer_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_pointer_type (to_type);
return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
tree
reference_type (tree to_type)
{
- if (to_type == error_mark_node)
+ if (error_operand_p (to_type))
return error_mark_node;
tree type = build_reference_type (to_type);
return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
tree
immutable_type (tree base)
{
- if (base == error_mark_node)
+ if (error_operand_p (base))
return error_mark_node;
tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
return constified;
@@ -472,17 +472,16 @@ function_type (const typed_identifier &receiver,
if (receiver.type != NULL_TREE)
{
tree t = receiver.type;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
}
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
@@ -502,11 +501,11 @@ function_type (const typed_identifier &receiver,
gcc_assert (result_struct != NULL);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -521,21 +520,16 @@ function_type_variadic (const typed_identifier &receiver,
size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
tree *args = XALLOCAVEC (tree, n);
size_t offs = 0;
+ if (error_operand_p (receiver.type))
+ return error_mark_node;
if (receiver.type != NULL_TREE)
- {
- tree t = receiver.type;
- if (t == error_mark_node)
- return error_mark_node;
-
- args[offs++] = t;
- }
+ args[offs++] = receiver.type;
- for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
- p != parameters.end (); ++p)
+ for (const auto &p : parameters)
{
- tree t = p->type;
- if (t == error_mark_node)
+ tree t = p.type;
+ if (error_operand_p (t))
return error_mark_node;
args[offs++] = t;
}
@@ -550,11 +544,11 @@ function_type_variadic (const typed_identifier &receiver,
gcc_assert (result_struct != NULL_TREE);
result = result_struct;
}
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
tree fntype = build_varargs_function_type_array (result, n, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -569,7 +563,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
for (auto &param : parameters)
{
- if (param == error_mark_node)
+ if (error_operand_p (param))
return error_mark_node;
*pp = tree_cons (NULL_TREE, param, NULL_TREE);
@@ -583,7 +577,7 @@ function_ptr_type (tree result_type, const std::vector<tree> &parameters,
result = void_type_node;
tree fntype = build_function_type (result, args);
- if (fntype == error_mark_node)
+ if (error_operand_p (fntype))
return error_mark_node;
return build_pointer_type (fntype);
@@ -613,14 +607,13 @@ fill_in_fields (tree fill, const std::vector<typed_identifier> &fields,
{
tree field_trees = NULL_TREE;
tree *pp = &field_trees;
- for (std::vector<typed_identifier>::const_iterator p = fields.begin ();
- p != fields.end (); ++p)
+ for (const auto &p : fields)
{
- tree name_tree = get_identifier_from_string (p->name);
- tree type_tree = p->type;
- if (type_tree == error_mark_node)
+ tree name_tree = get_identifier_from_string (p.name);
+ tree type_tree = p.type;
+ if (error_operand_p (type_tree))
return error_mark_node;
- tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+ tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
DECL_CONTEXT (field) = fill;
*pp = field;
pp = &DECL_CHAIN (field);
@@ -652,7 +645,7 @@ array_type (tree element_type, tree length)
tree
fill_in_array (tree fill, tree element_type, tree length_tree)
{
- if (element_type == error_mark_node || length_tree == error_mark_node)
+ if (error_operand_p (element_type) || error_operand_p (length_tree))
return error_mark_node;
gcc_assert (TYPE_SIZE (element_type) != NULL_TREE);
@@ -684,7 +677,7 @@ fill_in_array (tree fill, tree element_type, tree length_tree)
tree
named_type (const std::string &name, tree type, location_t location)
{
- if (type == error_mark_node)
+ if (error_operand_p (type))
return error_mark_node;
// The middle-end expects a basic type to have a name. In Rust every
@@ -714,7 +707,7 @@ named_type (const std::string &name, tree type, location_t location)
int64_t
type_size (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
if (t == void_type_node)
return 0;
@@ -732,7 +725,7 @@ type_size (tree t)
int64_t
type_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return TYPE_ALIGN_UNIT (t);
}
@@ -742,7 +735,7 @@ type_alignment (tree t)
int64_t
type_field_alignment (tree t)
{
- if (t == error_mark_node)
+ if (error_operand_p (t))
return 1;
return rust_field_alignment (t);
}
@@ -752,7 +745,7 @@ type_field_alignment (tree t)
int64_t
type_field_offset (tree struct_tree, size_t index)
{
- if (struct_tree == error_mark_node)
+ if (error_operand_p (struct_tree))
return 0;
gcc_assert (TREE_CODE (struct_tree) == RECORD_TYPE);
tree field = TYPE_FIELDS (struct_tree);
@@ -773,7 +766,7 @@ tree
zero_expression (tree t)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
ret = error_mark_node;
else
ret = build_zero_cst (t);
@@ -794,7 +787,7 @@ tree
float_constant_expression (tree t, mpfr_t val)
{
tree ret;
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
REAL_VALUE_TYPE r1;
@@ -845,8 +838,7 @@ boolean_constant_expression (bool val)
tree
convert_expression (tree type_tree, tree expr_tree, location_t location)
{
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
tree ret;
@@ -878,8 +870,7 @@ convert_expression (tree type_tree, tree expr_tree, location_t location)
tree
struct_field_expression (tree struct_tree, size_t index, location_t location)
{
- if (struct_tree == error_mark_node
- || TREE_TYPE (struct_tree) == error_mark_node)
+ if (error_operand_p (struct_tree))
return error_mark_node;
gcc_assert (TREE_CODE (TREE_TYPE (struct_tree)) == RECORD_TYPE
|| TREE_CODE (TREE_TYPE (struct_tree)) == UNION_TYPE);
@@ -895,7 +886,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
field = DECL_CHAIN (field);
gcc_assert (field != NULL_TREE);
}
- if (TREE_TYPE (field) == error_mark_node)
+ if (error_operand_p (TREE_TYPE (field)))
return error_mark_node;
tree ret = fold_build3_loc (location, COMPONENT_REF, TREE_TYPE (field),
struct_tree, field, NULL_TREE);
@@ -909,7 +900,7 @@ struct_field_expression (tree struct_tree, size_t index, location_t location)
tree
compound_expression (tree stat, tree expr, location_t location)
{
- if (stat == error_mark_node || expr == error_mark_node)
+ if (error_operand_p (stat) || error_operand_p (expr))
return error_mark_node;
tree ret
= fold_build2_loc (location, COMPOUND_EXPR, TREE_TYPE (expr), stat, expr);
@@ -923,8 +914,8 @@ tree
conditional_expression (tree, tree type_tree, tree cond_expr, tree then_expr,
tree else_expr, location_t location)
{
- if (type_tree == error_mark_node || cond_expr == error_mark_node
- || then_expr == error_mark_node || else_expr == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (cond_expr)
+ || error_operand_p (then_expr) || error_operand_p (else_expr))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, type_tree, cond_expr, then_expr,
else_expr);
@@ -1021,12 +1012,12 @@ operator_to_tree_code (LazyBooleanOperator op)
}
}
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+ False otherwise. */
bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
{
- auto tree_type = TREE_CODE (TREE_TYPE (t));
- return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+ return FLOAT_TYPE_P (TREE_TYPE (exp));
}
// Return an expression for the negation operation OP EXPR.
@@ -1035,7 +1026,7 @@ negation_expression (NegationOperator op, tree expr_tree, location_t location)
{
/* Check if the expression is an error, in which case we return an error
expression. */
- if (expr_tree == error_mark_node || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (expr_tree))
return error_mark_node;
/* For negation operators, the resulting type should be the same as its
@@ -1071,7 +1062,7 @@ arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
// unwrap the const decls if set
@@ -1182,7 +1173,7 @@ arithmetic_or_logical_expression_checked (ArithmeticOrLogicalOperator op,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left == error_mark_node || right == error_mark_node)
+ if (error_operand_p (left) || error_operand_p (right))
return error_mark_node;
// FIXME: Add `if (!debug_mode)`
@@ -1222,7 +1213,7 @@ comparison_expression (ComparisonOperator op, tree left_tree, tree right_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For comparison operators, the resulting type should be boolean. */
@@ -1242,7 +1233,7 @@ lazy_boolean_expression (LazyBooleanOperator op, tree left_tree,
{
/* Check if either expression is an error, in which case we return an error
expression. */
- if (left_tree == error_mark_node || right_tree == error_mark_node)
+ if (error_operand_p (left_tree) || error_operand_p (right_tree))
return error_mark_node;
/* For lazy boolean operators, the resulting type should be the same as the
@@ -1263,7 +1254,7 @@ constructor_expression (tree type_tree, bool is_variant,
const std::vector<tree> &vals, int union_index,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
vec<constructor_elt, va_gc> *init;
@@ -1305,8 +1296,8 @@ constructor_expression (tree type_tree, bool is_variant,
gcc_assert (field != NULL_TREE);
field = DECL_CHAIN (field);
}
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1336,8 +1327,7 @@ constructor_expression (tree type_tree, bool is_variant,
{
gcc_assert (field != NULL_TREE);
tree val = (*p);
- if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
- || TREE_TYPE (val) == error_mark_node)
+ if (TREE_TYPE (field) == error_mark_node || error_operand_p (val))
return error_mark_node;
if (int_size_in_bytes (TREE_TYPE (field)) == 0)
@@ -1376,7 +1366,7 @@ array_constructor_expression (tree type_tree,
const std::vector<tree> &vals,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return error_mark_node;
gcc_assert (indexes.size () == vals.size ());
@@ -1393,7 +1383,7 @@ array_constructor_expression (tree type_tree,
tree index = size_int (indexes[i]);
tree val = vals[i];
- if (index == error_mark_node || val == error_mark_node)
+ if (error_operand_p (index) || error_operand_p (val))
return error_mark_node;
if (element_size == 0)
@@ -1497,8 +1487,7 @@ array_initializer (tree fndecl, tree block, tree array_type, tree length,
tree
array_index_expression (tree array_tree, tree index_tree, location_t location)
{
- if (array_tree == error_mark_node || TREE_TYPE (array_tree) == error_mark_node
- || index_tree == error_mark_node)
+ if (error_operand_p (array_tree) || error_operand_p (index_tree))
return error_mark_node;
// A function call that returns a zero sized object will have been
@@ -1520,7 +1509,7 @@ tree
call_expression (tree fn, const std::vector<tree> &fn_args, tree chain_expr,
location_t location)
{
- if (fn == error_mark_node || TREE_TYPE (fn) == error_mark_node)
+ if (error_operand_p (fn))
return error_mark_node;
gcc_assert (FUNCTION_POINTER_TYPE_P (TREE_TYPE (fn)));
@@ -1600,7 +1589,7 @@ tree
init_statement (tree, Bvariable *var, tree init_tree)
{
tree var_tree = var->get_decl ();
- if (var_tree == error_mark_node || init_tree == error_mark_node)
+ if (error_operand_p (var_tree) || error_operand_p (init_tree))
return error_mark_node;
gcc_assert (TREE_CODE (var_tree) == VAR_DECL);
@@ -1631,7 +1620,7 @@ init_statement (tree, Bvariable *var, tree init_tree)
tree
assignment_statement (tree lhs, tree rhs, location_t location)
{
- if (lhs == error_mark_node || rhs == error_mark_node)
+ if (error_operand_p (lhs) || error_operand_p (rhs))
return error_mark_node;
// To avoid problems with GNU ld, we don't make zero-sized
@@ -1656,14 +1645,14 @@ assignment_statement (tree lhs, tree rhs, location_t location)
tree
return_statement (tree fntree, tree val, location_t location)
{
- if (fntree == error_mark_node)
+ if (error_operand_p (fntree))
return error_mark_node;
tree result = DECL_RESULT (fntree);
- if (result == error_mark_node)
+ if (error_operand_p (result))
return error_mark_node;
- if (val == error_mark_node)
+ if (error_operand_p (val))
return error_mark_node;
tree set
@@ -1681,8 +1670,8 @@ tree
exception_handler_statement (tree try_stmt, tree except_stmt, tree finally_stmt,
location_t location)
{
- if (try_stmt == error_mark_node || except_stmt == error_mark_node
- || finally_stmt == error_mark_node)
+ if (error_operand_p (try_stmt) || error_operand_p (except_stmt)
+ || error_operand_p (finally_stmt))
return error_mark_node;
if (except_stmt != NULL_TREE)
@@ -1701,8 +1690,8 @@ tree
if_statement (tree, tree cond_tree, tree then_tree, tree else_tree,
location_t location)
{
- if (cond_tree == error_mark_node || then_tree == error_mark_node
- || else_tree == error_mark_node)
+ if (error_operand_p (cond_tree) || error_operand_p (then_tree)
+ || error_operand_p (else_tree))
return error_mark_node;
tree ret = build3_loc (location, COND_EXPR, void_type_node, cond_tree,
then_tree, else_tree);
@@ -1728,15 +1717,12 @@ exit_expression (tree cond_tree, location_t locus)
tree
compound_statement (tree s1, tree s2)
{
- tree stmt_list = NULL_TREE;
- tree t = s1;
- if (t == error_mark_node)
- return error_mark_node;
- append_to_statement_list (t, &stmt_list);
- t = s2;
- if (t == error_mark_node)
+ if (error_operand_p (s1) || error_operand_p (s2))
return error_mark_node;
- append_to_statement_list (t, &stmt_list);
+
+ tree stmt_list = NULL_TREE;
+ append_to_statement_list (s1, &stmt_list);
+ append_to_statement_list (s2, &stmt_list);
// If neither statement has any side effects, stmt_list can be NULL
// at this point.
@@ -1752,11 +1738,9 @@ tree
statement_list (const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree t : statements)
{
- tree t = (*p);
- if (t == error_mark_node)
+ if (error_operand_p (t))
return error_mark_node;
append_to_statement_list (t, &stmt_list);
}
@@ -1808,12 +1792,13 @@ block (tree fndecl, tree enclosing, const std::vector<Bvariable *> &vars,
*pp = block_tree;
}
+ // Chain the variables of the scope together so they are all connected
+ // to the block.
tree *pp = &BLOCK_VARS (block_tree);
- for (std::vector<Bvariable *>::const_iterator pv = vars.begin ();
- pv != vars.end (); ++pv)
+ for (Bvariable *bv : vars)
{
- *pp = (*pv)->get_decl ();
- if (*pp != error_mark_node)
+ *pp = bv->get_decl ();
+ if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -1832,11 +1817,9 @@ void
block_add_statements (tree bind_tree, const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<tree>::const_iterator p = statements.begin ();
- p != statements.end (); ++p)
+ for (tree s : statements)
{
- tree s = (*p);
- if (s != error_mark_node)
+ if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
}
@@ -1914,8 +1897,7 @@ convert_tree (tree type_tree, tree expr_tree, location_t location)
if (type_tree == TREE_TYPE (expr_tree))
return expr_tree;
- if (type_tree == error_mark_node || expr_tree == error_mark_node
- || TREE_TYPE (expr_tree) == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (expr_tree))
return error_mark_node;
if (POINTER_TYPE_P (type_tree) || INTEGRAL_TYPE_P (type_tree)
@@ -1944,7 +1926,7 @@ global_variable (const std::string &var_name, const std::string &asm_name,
tree type_tree, bool is_external, bool is_hidden,
bool in_unique_section, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
// The GNU linker does not like dynamic variables with zero size.
@@ -1983,11 +1965,11 @@ global_variable (const std::string &var_name, const std::string &asm_name,
void
global_variable_set_init (Bvariable *var, tree expr_tree)
{
- if (expr_tree == error_mark_node)
+ if (error_operand_p (expr_tree))
return;
gcc_assert (TREE_CONSTANT (expr_tree));
tree var_decl = var->get_decl ();
- if (var_decl == error_mark_node)
+ if (error_operand_p (var_decl))
return;
DECL_INITIAL (var_decl) = expr_tree;
@@ -2008,7 +1990,7 @@ Bvariable *
local_variable (tree function, const std::string &name, tree type_tree,
Bvariable *decl_var, location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, VAR_DECL, get_identifier_from_string (name),
type_tree);
@@ -2029,7 +2011,7 @@ Bvariable *
parameter_variable (tree function, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2046,7 +2028,7 @@ Bvariable *
static_chain_variable (tree fndecl, const std::string &name, tree type_tree,
location_t location)
{
- if (type_tree == error_mark_node)
+ if (error_operand_p (type_tree))
return Bvariable::error_variable ();
tree decl = build_decl (location, PARM_DECL,
get_identifier_from_string (name), type_tree);
@@ -2080,8 +2062,8 @@ temporary_variable (tree fndecl, tree bind_tree, tree type_tree, tree init_tree,
tree *pstatement)
{
gcc_assert (fndecl != NULL_TREE);
- if (type_tree == error_mark_node || init_tree == error_mark_node
- || fndecl == error_mark_node)
+ if (error_operand_p (type_tree) || error_operand_p (init_tree)
+ || error_operand_p (fndecl))
{
*pstatement = error_mark_node;
return Bvariable::error_variable ();
@@ -2198,13 +2180,13 @@ tree
function (tree functype, const std::string &name, const std::string &asm_name,
unsigned int flags, location_t location)
{
- if (functype != error_mark_node)
- {
- gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
- functype = TREE_TYPE (functype);
- }
+ if (error_operand_p (functype))
+ return error_mark_node;
+
+ gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
+ functype = TREE_TYPE (functype);
tree id = get_identifier_from_string (name);
- if (functype == error_mark_node || id == error_mark_node)
+ if (error_operand_p (id))
return error_mark_node;
tree decl = build_decl (location, FUNCTION_DECL, id, functype);
@@ -2242,8 +2224,8 @@ tree
function_defer_statement (tree function, tree undefer_tree, tree defer_tree,
location_t location)
{
- if (undefer_tree == error_mark_node || defer_tree == error_mark_node
- || function == error_mark_node)
+ if (error_operand_p (undefer_tree) || error_operand_p (defer_tree)
+ || error_operand_p (function))
return error_mark_node;
if (DECL_STRUCT_FUNCTION (function) == NULL)
@@ -2275,16 +2257,15 @@ bool
function_set_parameters (tree function,
const std::vector<Bvariable *> &param_vars)
{
- if (function == error_mark_node)
+ if (error_operand_p (function))
return false;
tree params = NULL_TREE;
tree *pp = &params;
- for (std::vector<Bvariable *>::const_iterator pv = param_vars.begin ();
- pv != param_vars.end (); ++pv)
+ for (Bvariable *bv : param_vars)
{
- *pp = (*pv)->get_decl ();
- gcc_assert (*pp != error_mark_node);
+ *pp = bv->get_decl ();
+ gcc_assert (!error_operand_p (*pp));
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
@@ -2309,23 +2290,19 @@ write_global_definitions (const std::vector<tree> &type_decls,
// Convert all non-erroneous declarations into Gimple form.
size_t i = 0;
- for (std::vector<Bvariable *>::const_iterator p = variable_decls.begin ();
- p != variable_decls.end (); ++p)
+ for (Bvariable *bv : variable_decls)
{
- tree v = (*p)->get_decl ();
- if (v != error_mark_node)
- {
- defs[i] = v;
- rust_preserve_from_gc (defs[i]);
- ++i;
- }
+ tree v = bv->get_decl ();
+ if (error_operand_p (v))
+ continue;
+ defs[i] = v;
+ rust_preserve_from_gc (defs[i]);
+ ++i;
}
- for (std::vector<tree>::const_iterator p = type_decls.begin ();
- p != type_decls.end (); ++p)
+ for (tree type_tree : type_decls)
{
- tree type_tree = (*p);
- if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
+ if (!error_operand_p (type_tree) && IS_TYPE_OR_DECL_P (type_tree))
{
defs[i] = TYPE_NAME (type_tree);
gcc_assert (defs[i] != NULL);
@@ -2333,21 +2310,18 @@ write_global_definitions (const std::vector<tree> &type_decls,
++i;
}
}
- for (std::vector<tree>::const_iterator p = constant_decls.begin ();
- p != constant_decls.end (); ++p)
+ for (tree t : constant_decls)
{
- if ((*p) != error_mark_node)
+ if (!error_operand_p (t))
{
- defs[i] = (*p);
+ defs[i] = t;
rust_preserve_from_gc (defs[i]);
++i;
}
}
- for (std::vector<tree>::const_iterator p = function_decls.begin ();
- p != function_decls.end (); ++p)
+ for (tree decl : function_decls)
{
- tree decl = (*p);
- if (decl != error_mark_node)
+ if (!error_operand_p (decl))
{
rust_preserve_from_gc (decl);
if (DECL_STRUCT_FUNCTION (decl) == NULL)
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 15f21ef..48acbf34 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -611,7 +611,6 @@ Session::compile_crate (const char *filename)
return;
AST::CollectLangItems ().go (parsed_crate);
- AST::DesugarQuestionMark ().go (parsed_crate);
auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
// expansion pipeline stage
@@ -619,6 +618,7 @@ Session::compile_crate (const char *filename)
expansion (parsed_crate, name_resolution_ctx);
AST::DesugarForLoops ().go (parsed_crate);
+ AST::DesugarQuestionMark ().go (parsed_crate);
rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 791795f..b2bcac0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -16,6 +16,8 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "optional.h"
+#include "rust-hir-expr.h"
#include "rust-system.h"
#include "rust-tyty-call.h"
#include "rust-hir-type-check-struct-field.h"
@@ -1154,6 +1156,94 @@ TypeCheckExpr::visit (HIR::FieldAccessExpr &expr)
infered = lookup->get_field_type ();
}
+bool
+is_default_fn (const MethodCandidate &candidate)
+{
+ if (candidate.candidate.is_impl_candidate ())
+ {
+ auto *item = candidate.candidate.item.impl.impl_item;
+
+ if (item->get_impl_item_type () == HIR::ImplItem::FUNCTION)
+ {
+ auto &fn = static_cast<HIR::Function &> (*item);
+
+ return fn.is_default ();
+ }
+ }
+
+ return false;
+}
+
+void
+emit_ambiguous_resolution_error (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ rich_location r (line_table, expr.get_method_name ().get_locus ());
+ std::string rich_msg = "multiple "
+ + expr.get_method_name ().get_segment ().as_string ()
+ + " found";
+
+ // We have to filter out default candidates
+ for (auto &c : candidates)
+ if (!is_default_fn (c))
+ r.add_range (c.candidate.locus);
+
+ r.add_fixit_replace (rich_msg.c_str ());
+
+ rust_error_at (r, ErrorCode::E0592, "duplicate definitions with name %qs",
+ expr.get_method_name ().get_segment ().as_string ().c_str ());
+}
+
+// We are allowed to have multiple candidates if they are all specializable
+// functions or if all of them except one are specializable functions.
+// In the later case, we just return a valid candidate without erroring out
+// about ambiguity. If there are two or more specialized functions, then we
+// error out.
+//
+// FIXME: The first case is not handled at the moment, so we error out
+tl::optional<const MethodCandidate &>
+handle_multiple_candidates (HIR::MethodCallExpr &expr,
+ std::set<MethodCandidate> &candidates)
+{
+ auto all_default = true;
+ tl::optional<const MethodCandidate &> found = tl::nullopt;
+
+ for (auto &c : candidates)
+ {
+ if (!is_default_fn (c))
+ {
+ all_default = false;
+
+ // We haven't found a final candidate yet, so we can select
+ // this one. However, if we already have a candidate, then
+ // that means there are multiple non-default candidates - we
+ // must error out
+ if (!found)
+ {
+ found = c;
+ }
+ else
+ {
+ emit_ambiguous_resolution_error (expr, candidates);
+ return tl::nullopt;
+ }
+ }
+ }
+
+ // None of the candidates were a non-default (specialized) function, so we
+ // error out
+ if (all_default)
+ {
+ rust_sorry_at (expr.get_locus (),
+ "cannot resolve method calls to non-specialized methods "
+ "(all function candidates are %qs)",
+ "default");
+ return tl::nullopt;
+ }
+
+ return found;
+}
+
void
TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
{
@@ -1181,34 +1271,25 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
return;
}
- if (candidates.size () > 1)
- {
- rich_location r (line_table, expr.get_method_name ().get_locus ());
- std::string rich_msg
- = "multiple " + expr.get_method_name ().get_segment ().as_string ()
- + " found";
+ tl::optional<const MethodCandidate &> candidate = *candidates.begin ();
- for (auto &c : candidates)
- r.add_range (c.candidate.locus);
+ if (candidates.size () > 1)
+ candidate = handle_multiple_candidates (expr, candidates);
- r.add_fixit_replace (rich_msg.c_str ());
+ if (!candidate)
+ return;
- rust_error_at (
- r, ErrorCode::E0592, "duplicate definitions with name %qs",
- expr.get_method_name ().get_segment ().as_string ().c_str ());
- return;
- }
+ auto found_candidate = *candidate;
- auto candidate = *candidates.begin ();
rust_debug_loc (expr.get_method_name ().get_locus (),
"resolved method to: {%u} {%s} with [%lu] adjustments",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str (),
- (unsigned long) candidate.adjustments.size ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str (),
+ (unsigned long) found_candidate.adjustments.size ());
// Get the adjusted self
Adjuster adj (receiver_tyty);
- TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
+ TyTy::BaseType *adjusted_self = adj.adjust_type (found_candidate.adjustments);
rust_debug ("receiver: %s adjusted self %s",
receiver_tyty->debug_str ().c_str (),
adjusted_self->debug_str ().c_str ());
@@ -1219,10 +1300,10 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
HirId autoderef_mappings_id
= expr.get_receiver ().get_mappings ().get_hirid ();
context->insert_autoderef_mappings (autoderef_mappings_id,
- std::move (candidate.adjustments));
+ std::move (found_candidate.adjustments));
- PathProbeCandidate &resolved_candidate = candidate.candidate;
- TyTy::BaseType *lookup_tyty = candidate.candidate.ty;
+ PathProbeCandidate &resolved_candidate = found_candidate.candidate;
+ TyTy::BaseType *lookup_tyty = found_candidate.candidate.ty;
NodeId resolved_node_id
= resolved_candidate.is_impl_candidate ()
? resolved_candidate.item.impl.impl_item->get_impl_mappings ()
@@ -1249,8 +1330,8 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
fn->prepare_higher_ranked_bounds ();
rust_debug_loc (expr.get_locus (), "resolved method call to: {%u} {%s}",
- candidate.candidate.ty->get_ref (),
- candidate.candidate.ty->debug_str ().c_str ());
+ found_candidate.candidate.ty->get_ref (),
+ found_candidate.candidate.ty->debug_str ().c_str ());
if (resolved_candidate.is_impl_candidate ())
{
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index 9ef5cc5..47e6a17 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -40,12 +40,14 @@ public:
static constexpr auto &NO_MANGLE = "no_mangle";
static constexpr auto &REPR = "repr";
static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro";
+ static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency";
static constexpr auto &PATH = "path";
static constexpr auto &MACRO_USE = "macro_use";
static constexpr auto &MACRO_EXPORT = "macro_export";
static constexpr auto &PROC_MACRO = "proc_macro";
static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive";
static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute";
+
static constexpr auto &TARGET_FEATURE = "target_feature";
// From now on, these are reserved by the compiler and gated through
// #![feature(rustc_attrs)]
@@ -54,10 +56,35 @@ public:
= "rustc_inherit_overflow_checks";
static constexpr auto &STABLE = "stable";
static constexpr auto &UNSTABLE = "unstable";
+
+ static constexpr auto &RUSTC_PROMOTABLE = "rustc_promotable";
static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable";
static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
+
+ static constexpr auto &RUSTC_SPECIALIZATION_TRAIT
+ = "rustc_specialization_trait";
+ static constexpr auto &RUSTC_UNSAFE_SPECIALIZATION_MARKER
+ = "rustc_unsafe_specialization_marker";
+ static constexpr auto &RUSTC_RESERVATION_IMPL = "rustc_reservation_impl";
+ static constexpr auto &RUSTC_PAREN_SUGAR = "rustc_paren_sugar";
+ static constexpr auto &RUSTC_NONNULL_OPTIMIZATION_GUARANTEED
+ = "rustc_nonnull_optimization_guaranteed";
+
+ static constexpr auto &RUSTC_LAYOUT_SCALAR_VALID_RANGE_START
+ = "rustc_layout_scalar_valid_range_start";
+
static constexpr auto &MAY_DANGLE = "may_dangle";
static constexpr auto &PRELUDE_IMPORT = "prelude_import";
+ static constexpr auto &TRACK_CALLER = "track_caller";
+
+ static constexpr auto &RUSTC_DIAGNOSTIC_ITEM = "rustc_diagnostic_item";
+ static constexpr auto &RUSTC_ON_UNIMPLEMENTED = "rustc_on_unimplemented";
+
+ static constexpr auto &FUNDAMENTAL = "fundamental";
+
+ static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive";
+
+ static constexpr auto &RUSTFMT = "rustfmt";
};
} // namespace Values
} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 03452c7..c77e99c 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -57,6 +57,7 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::NO_MANGLE, CODE_GENERATION},
{Attrs::REPR, CODE_GENERATION},
{Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
+ {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
{Attrs::PATH, EXPANSION},
{Attrs::MACRO_USE, NAME_RESOLUTION},
{Attrs::MACRO_EXPORT, NAME_RESOLUTION},
@@ -72,10 +73,29 @@ static const BuiltinAttrDefinition __definitions[]
{Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
{Attrs::STABLE, STATIC_ANALYSIS},
{Attrs::UNSTABLE, STATIC_ANALYSIS},
+
// assuming we keep these for static analysis
+ {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
{Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
{Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
- {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}};
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+ {Attrs::TRACK_CALLER, CODE_GENERATION},
+ {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
+ {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
+ {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
+ {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
+ {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
+
+ {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
+
+ {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
+
+ {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
+ {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
+
+ {Attrs::FUNDAMENTAL, TYPE_CHECK},
+ {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
+ {Attrs::RUSTFMT, EXTERNAL}};
BuiltinAttributeMappings *
BuiltinAttributeMappings::get ()
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index c928c8e..7c7a1fc 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -40,7 +40,12 @@ enum CompilerPass
HIR_LOWERING,
TYPE_CHECK,
STATIC_ANALYSIS,
- CODE_GENERATION
+ CODE_GENERATION,
+
+ // External Rust tooling attributes, like #[rustfmt::skip]
+ EXTERNAL,
+
+ // Do we need to add something here for const fns?
};
struct BuiltinAttrDefinition
diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index a76cc7f..9aff31b 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -118,6 +118,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{
{"discriminant_kind", Kind::DISCRIMINANT_KIND},
{"discriminant_type", Kind::DISCRIMINANT_TYPE},
+ {"manually_drop", Kind::MANUALLY_DROP},
}};
tl::optional<LangItem::Kind>
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 8f3af36..67a5d9c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -150,6 +150,8 @@ public:
DISCRIMINANT_TYPE,
DISCRIMINANT_KIND,
+
+ MANUALLY_DROP,
};
static const BiMap<std::string, Kind> lang_items;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 330a283..5710dbe3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,73 @@
+2025-04-13 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/119502
+ * gfortran.dg/pr119502.f90: New test.
+
+2025-04-13 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * g++.dg/modules/noexcept-4_a.H: New test.
+ * g++.dg/modules/noexcept-4_b.C: New test.
+
+2025-04-13 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ * g++.dg/modules/lambda-8_b.C: Adjust error.
+ * g++.dg/modules/leg-merge-4_c.C: Likewise.
+
+2025-04-13 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/119669
+ * gfortran.dg/interface_59.f90: New test.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119761
+ * gdc.dg/import-c/import-c.exp: New test.
+ * gdc.dg/import-c/pr119761.d: New test.
+ * gdc.dg/import-c/pr119761c.c: New test.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/109023
+ * gdc.dg/torture/imports/pr109023.d: New test.
+ * gdc.dg/torture/pr109023.d: New test.
+
+2025-04-12 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/119758
+ * gdc.dg/driver_fonly1.d: New test.
+ * gdc.dg/driver_fonly2.d: New test.
+ * gdc.dg/driver_fonly3.d: New test.
+ * gdc.dg/imports/fonly.d: New test.
+
+2025-04-12 Andrew Pinski <quic_apinski@quicinc.com>
+
+ PR testsuite/117706
+ * gcc.dg/ira-shrinkwrap-prep-1.c: Unxfail for i?68-*-* and x86_64-*-*.
+ * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise.
+
+2025-04-12 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/116416
+ * g++.dg/cpp1y/constexpr-prvalue1.C: Adjust to instead inspect
+ the 'original' dump.
+ * g++.dg/cpp1y/constexpr-prvalue1a.C: New test.
+
+2025-04-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/119722
+ * gcc.dg/torture/bitint-77.c: New test.
+
+2025-04-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/renaming17.adb: New test.
+
+2025-04-12 Bob Dubner <rdubner@symas.com>
+
+ PR cobol/119694
+ * cobol.dg/group2/ACCEPT_DATE___DAY_and_intrinsic_functions__2_.cob: GCOBOL_CURRENT_DATE.
+ * cobol.dg/group2/ACCEPT_FROM_TIME___DATE___DAY___DAY-OF-WEEK__2_.cob: Likewise
+ * cobol.dg/group2/FUNCTION_DATE___TIME_OMNIBUS.cob: Likewise
+
2025-04-11 Christophe Lyon <christophe.lyon@linaro.org>
* lib/target-supports.exp: Rename arm_v8_1_lob_ok into
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic20.C b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
new file mode 100644
index 0000000..2bb01db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
@@ -0,0 +1,13 @@
+// PR c++/99214
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A {
+ template <class U> static void f() requires requires { T::fail; };
+};
+
+int main() {
+ A<int>::f<char>(); // { dg-error "no match" }
+}
+
+// { dg-message "In substitution of '\[^\r\n\]* \\\[with U = char\\\]'" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/modules/lambda-8_b.C b/gcc/testsuite/g++.dg/modules/lambda-8_b.C
index 7ace494..96578ba 100644
--- a/gcc/testsuite/g++.dg/modules/lambda-8_b.C
+++ b/gcc/testsuite/g++.dg/modules/lambda-8_b.C
@@ -4,4 +4,4 @@
#include "lambda-8.h"
import "lambda-8_a.H";
-// { dg-error "conflicting global module declaration" "" { target *-*-* } 0 }
+// { dg-error "conflicting imported declaration" "" { target *-*-* } 0 }
diff --git a/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C b/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C
index f1b1aeb..5756057 100644
--- a/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C
+++ b/gcc/testsuite/g++.dg/modules/leg-merge-4_c.C
@@ -11,8 +11,8 @@ void foo ()
X *p;
}
-// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:4:\[0-9]*: error: conflicting global module declaration 'float bob'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:4:\[0-9]*: note: existing declaration 'int bob'\n\[^\n]*leg-merge-4_c.C:9:\[0-9]*: note: during load of binding '::bob'$" }
+// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:4:\[0-9]*: error: conflicting type for imported declaration 'float bob'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:4:\[0-9]*: note: existing declaration 'int bob'\n\[^\n]*leg-merge-4_c.C:9:\[0-9]*: note: during load of binding '::bob'$" }
-// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:5:\[0-9]*: error: conflicting global module declaration 'int frob\\(\\)'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:5:\[0-9]*: note: existing declaration 'void frob\\(\\)'\n\[^\n]*leg-merge-4_c.C:10:\[0-9]*: note: during load of binding '::frob'$" }
+// { dg-regexp "\nIn module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:5:\[0-9]*: error: conflicting type for imported declaration 'int frob\\(\\)'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:5:\[0-9]*: note: existing declaration 'void frob\\(\\)'\n\[^\n]*leg-merge-4_c.C:10:\[0-9]*: note: during load of binding '::frob'$" }
-// { dg-regexp "In module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:6:\[0-9]*: error: conflicting global module declaration 'union X'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:6:\[0-9]*: note: existing declaration 'class X'\n\[^\n]*leg-merge-4_c.C:11:\[0-9]*: note: during load of binding '::X'$" }
+// { dg-regexp "In module \[^\n]*leg-merge-4_b.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_b.H:6:\[0-9]*: error: conflicting type for imported declaration 'union X'\nIn module \[^\n]*leg-merge-4_a.H, imported at \[^\n]*leg-merge-4_c.C:\[0-9]*:\n\[^\n]*leg-merge-4_a.H:6:\[0-9]*: note: existing declaration 'class X'\n\[^\n]*leg-merge-4_c.C:11:\[0-9]*: note: during load of binding '::X'$" }
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-4_a.H b/gcc/testsuite/g++.dg/modules/noexcept-4_a.H
new file mode 100644
index 0000000..b888a1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-4_a.H
@@ -0,0 +1,6 @@
+// { dg-additional-options "-fmodule-header -std=c++20" }
+// { dg-module-cmi {} }
+
+struct exception_ptr {
+ friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
diff --git a/gcc/testsuite/g++.dg/modules/noexcept-4_b.C b/gcc/testsuite/g++.dg/modules/noexcept-4_b.C
new file mode 100644
index 0000000..7cc5531
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noexcept-4_b.C
@@ -0,0 +1,18 @@
+// { dg-additional-options "-fmodules -std=c++20" }
+
+struct exception_ptr {
+ friend bool operator==(const exception_ptr&, const exception_ptr&) = default;
+};
+
+void enqueue() {
+ exception_ptr e;
+ e == e;
+}
+
+import "noexcept-4_a.H";
+
+int main() {
+ constexpr exception_ptr e;
+ static_assert(e == e);
+ static_assert(noexcept(e == e));
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr119778.C b/gcc/testsuite/g++.dg/torture/pr119778.C
new file mode 100644
index 0000000..4948056
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr119778.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-additional-options "-Wall" }
+
+struct jmp_buf { long l[16]; };
+extern "C" int setjmp (jmp_buf *);
+struct S {
+ void foo () { bar (); }
+ virtual char bar () { return 0; }
+};
+void baz ();
+jmp_buf *a;
+
+void
+qux (bool x, S *y)
+{
+ if (x)
+ setjmp (a);
+ y->foo ();
+ baz ();
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr119318.c b/gcc/testsuite/gcc.dg/ipa/pr119318.c
new file mode 100644
index 0000000..8e62ec5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr119318.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+/* { dg-additional-options "-Wno-psabi -w" } */
+/* { dg-options "-Wno-psabi -O2" } */
+
+typedef unsigned V __attribute__((vector_size (64)));
+typedef unsigned __int128 W __attribute__((vector_size (64)));
+
+W a;
+W b;
+W c = { -0xffff, -0xffff, -0xffff, -0xffff };
+
+static __attribute__((__noinline__, __noclone__)) W
+bar (unsigned __int128 u)
+{
+ return u + c;
+}
+
+static inline W
+foo (unsigned short s, V v)
+{
+ V y = (V) bar ((unsigned short) ~s);
+ v >>= y;
+ b ^= (W) a;
+ v *= v;
+ return (W) v + b;
+}
+
+
+int
+main ()
+{
+ W x = foo (0, (V) { 0, 5 });
+ for (unsigned i = 0; i < sizeof(x)/sizeof(x[0]); i++)
+ if (x[i] != (i ? 0 : 0x1900000000))
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr119530.c b/gcc/testsuite/gcc.dg/ipa/pr119530.c
new file mode 100644
index 0000000..f99c4fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr119530.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-tree-vrp -fno-inline" } */
+
+struct a {
+ int b;
+};
+int c;
+signed char d;
+static int e(long long f) { return f < 0; }
+static void g(unsigned f) { c = e(~f); }
+int main() {
+ int h;
+ struct a i = {128};
+ h = d > i.b;
+ g(h);
+ if (h)
+ __builtin_abort();
+ if (c)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr118476-1.c b/gcc/testsuite/gcc.dg/torture/pr118476-1.c
new file mode 100644
index 0000000..33509403
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118476-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+/* PR tree-optimization/118476 */
+
+typedef unsigned long long poly64x1 __attribute__((__vector_size__(1*sizeof(long long))));
+
+poly64x1 vext_p64(poly64x1 a, poly64x1 b, const int n)
+{
+ poly64x1 r = a;
+ unsigned src = (unsigned)n;
+ long long t = b[0];
+ r[0] = (src < 1) ? a[src] : t;
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr119757.c b/gcc/testsuite/gcc.dg/vect/pr119757.c
new file mode 100644
index 0000000..8644299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119757.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+void base64_encode(const char *table64,
+ const char *inputbuff, int insize,
+ char * __restrict output)
+{
+ const unsigned char *in = (const unsigned char *)inputbuff;
+
+ while(insize >= 3) {
+ *output++ = table64[ in[0] >> 2 ];
+ *output++ = table64[ ((in[0] & 0x03) << 4) | (in[1] >> 4) ];
+ *output++ = table64[ ((in[1] & 0x0F) << 2) | ((in[2] & 0xC0) >> 6) ];
+ *output++ = table64[ in[2] & 0x3F ];
+ insize -= 3;
+ in += 3;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr119784a.c b/gcc/testsuite/gcc.target/i386/pr119784a.c
new file mode 100644
index 0000000..8a119d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119784a.c
@@ -0,0 +1,96 @@
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O2 -fno-pic -mtune=generic -mgeneral-regs-only -mapxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/* start must save and restore all caller saved registers. */
+
+/*
+**start:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subq \$248, %rsp
+**...
+** movq %rax, \(%rsp\)
+** movq %rdx, 8\(%rsp\)
+** movq %rcx, 16\(%rsp\)
+** movq %rbx, 24\(%rsp\)
+** movq %rsi, 32\(%rsp\)
+** movq %rdi, 40\(%rsp\)
+**...
+** movq %rbp, 48\(%rsp\)
+** movq %r8, 56\(%rsp\)
+** movq %r9, 64\(%rsp\)
+** movq %r10, 72\(%rsp\)
+** movq %r11, 80\(%rsp\)
+** movq %r12, 88\(%rsp\)
+** movq %r13, 96\(%rsp\)
+** movq %r14, 104\(%rsp\)
+** movq %r15, 112\(%rsp\)
+** movq %r16, 120\(%rsp\)
+** movq %r17, 128\(%rsp\)
+** movq %r18, 136\(%rsp\)
+** movq %r19, 144\(%rsp\)
+** movq %r20, 152\(%rsp\)
+** movq %r21, 160\(%rsp\)
+** movq %r22, 168\(%rsp\)
+** movq %r23, 176\(%rsp\)
+** movq %r24, 184\(%rsp\)
+** movq %r25, 192\(%rsp\)
+** movq %r26, 200\(%rsp\)
+** movq %r27, 208\(%rsp\)
+** movq %r28, 216\(%rsp\)
+** movq %r29, 224\(%rsp\)
+** movq %r30, 232\(%rsp\)
+** movq %r31, 240\(%rsp\)
+**...
+** call \*code\(%rip\)
+** movq \(%rsp\), %rax
+** movq 8\(%rsp\), %rdx
+** movq 16\(%rsp\), %rcx
+** movq 24\(%rsp\), %rbx
+** movq 32\(%rsp\), %rsi
+** movq 40\(%rsp\), %rdi
+** movq 48\(%rsp\), %rbp
+** movq 56\(%rsp\), %r8
+** movq 64\(%rsp\), %r9
+** movq 72\(%rsp\), %r10
+** movq 80\(%rsp\), %r11
+** movq 88\(%rsp\), %r12
+** movq 96\(%rsp\), %r13
+** movq 104\(%rsp\), %r14
+** movq 112\(%rsp\), %r15
+** movq 120\(%rsp\), %r16
+** movq 128\(%rsp\), %r17
+** movq 136\(%rsp\), %r18
+** movq 144\(%rsp\), %r19
+** movq 152\(%rsp\), %r20
+** movq 160\(%rsp\), %r21
+** movq 168\(%rsp\), %r22
+** movq 176\(%rsp\), %r23
+** movq 184\(%rsp\), %r24
+** movq 192\(%rsp\), %r25
+** movq 200\(%rsp\), %r26
+** movq 208\(%rsp\), %r27
+** movq 216\(%rsp\), %r28
+** movq 224\(%rsp\), %r29
+** movq 232\(%rsp\), %r30
+** movq 240\(%rsp\), %r31
+** addq \$248, %rsp
+**...
+** ret
+** .cfi_endproc
+**...
+*/
+
+#define DONT_SAVE_REGS __attribute__((no_callee_saved_registers))
+#define SAVE_REGS __attribute__((no_caller_saved_registers))
+
+typedef DONT_SAVE_REGS void (*op_t)(void);
+
+extern op_t code[];
+
+SAVE_REGS void start()
+{
+ code[0]();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr119784b.c b/gcc/testsuite/gcc.target/i386/pr119784b.c
new file mode 100644
index 0000000..c676197
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr119784b.c
@@ -0,0 +1,87 @@
+/* { dg-do compile { target { *-*-linux* && x32 } } } */
+/* { dg-options "-O2 -fno-pic -mtune=generic -mgeneral-regs-only -mapxf -mtune-ctrl=prologue_using_move,epilogue_using_move" } */
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
+/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {^\t?\.} } } */
+
+/* start must save and restore all caller saved registers. */
+
+/*
+**start:
+**.LFB[0-9]+:
+** .cfi_startproc
+** subl \$248, %esp
+**...
+** movq %rax, \(%rsp\)
+** movq %rdx, 8\(%rsp\)
+** movq %rcx, 16\(%rsp\)
+** movq %rbx, 24\(%rsp\)
+** movq %rsi, 32\(%rsp\)
+** movq %rdi, 40\(%rsp\)
+**...
+** movq %rbp, 48\(%rsp\)
+** movq %r8, 56\(%rsp\)
+** movq %r9, 64\(%rsp\)
+** movq %r10, 72\(%rsp\)
+** movq %r11, 80\(%rsp\)
+** movq %r12, 88\(%rsp\)
+** movq %r13, 96\(%rsp\)
+** movq %r14, 104\(%rsp\)
+** movq %r15, 112\(%rsp\)
+** movq %r16, 120\(%rsp\)
+** movq %r17, 128\(%rsp\)
+** movq %r18, 136\(%rsp\)
+** movq %r19, 144\(%rsp\)
+** movq %r20, 152\(%rsp\)
+** movq %r21, 160\(%rsp\)
+** movq %r22, 168\(%rsp\)
+** movq %r23, 176\(%rsp\)
+** movq %r24, 184\(%rsp\)
+** movq %r25, 192\(%rsp\)
+** movq %r26, 200\(%rsp\)
+** movq %r27, 208\(%rsp\)
+** movq %r28, 216\(%rsp\)
+** movq %r29, 224\(%rsp\)
+** movq %r30, 232\(%rsp\)
+** movq %r31, 240\(%rsp\)
+**...
+** movl code\(%rip\), %ebp
+** call \*%rbp
+** movq \(%rsp\), %rax
+** movq 8\(%rsp\), %rdx
+** movq 16\(%rsp\), %rcx
+** movq 24\(%rsp\), %rbx
+** movq 32\(%rsp\), %rsi
+** movq 40\(%rsp\), %rdi
+** movq 48\(%rsp\), %rbp
+** movq 56\(%rsp\), %r8
+** movq 64\(%rsp\), %r9
+** movq 72\(%rsp\), %r10
+** movq 80\(%rsp\), %r11
+** movq 88\(%rsp\), %r12
+** movq 96\(%rsp\), %r13
+** movq 104\(%rsp\), %r14
+** movq 112\(%rsp\), %r15
+** movq 120\(%rsp\), %r16
+** movq 128\(%rsp\), %r17
+** movq 136\(%rsp\), %r18
+** movq 144\(%rsp\), %r19
+** movq 152\(%rsp\), %r20
+** movq 160\(%rsp\), %r21
+** movq 168\(%rsp\), %r22
+** movq 176\(%rsp\), %r23
+** movq 184\(%rsp\), %r24
+** movq 192\(%rsp\), %r25
+** movq 200\(%rsp\), %r26
+** movq 208\(%rsp\), %r27
+** movq 216\(%rsp\), %r28
+** movq 224\(%rsp\), %r29
+** movq 232\(%rsp\), %r30
+** movq 240\(%rsp\), %r31
+** addl \$248, %esp
+**...
+** ret
+** .cfi_endproc
+**...
+*/
+
+#include "pr119784a.c"
diff --git a/gcc/testsuite/gdc.dg/import-c/import-c.exp b/gcc/testsuite/gdc.dg/import-c/import-c.exp
new file mode 100644
index 0000000..53d1478
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/import-c.exp
@@ -0,0 +1,29 @@
+# Copyright (C) 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib gdc-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+gdc-dg-runtest [lsort \
+ [glob -nocomplain $srcdir/$subdir/*.d ] ] "" \
+ "-I $srcdir/$subdir -finclude-imports"
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gdc.dg/import-c/pr119761.d b/gcc/testsuite/gdc.dg/import-c/pr119761.d
new file mode 100644
index 0000000..20eff31
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/pr119761.d
@@ -0,0 +1,2 @@
+// { dg-do compile }
+import pr119761c;
diff --git a/gcc/testsuite/gdc.dg/import-c/pr119761c.c b/gcc/testsuite/gdc.dg/import-c/pr119761c.c
new file mode 100644
index 0000000..522f1bf
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/import-c/pr119761c.c
@@ -0,0 +1,4 @@
+int f119761(const char *, ...)
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gdc.dg/torture/imports/pr109023.d b/gcc/testsuite/gdc.dg/torture/imports/pr109023.d
new file mode 100644
index 0000000..e85e0ed
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/imports/pr109023.d
@@ -0,0 +1,3 @@
+module imports.pr109023;
+
+void f109023() { }
diff --git a/gcc/testsuite/gdc.dg/torture/pr109023.d b/gcc/testsuite/gdc.dg/torture/pr109023.d
new file mode 100644
index 0000000..3060446
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr109023.d
@@ -0,0 +1,6 @@
+// { dg-do "compile" }
+// { dg-additional-options "-I[srcdir] -finclude-imports" }
+// { dg-additional-files "imports/pr109023.d" }
+// { dg-final { scan-assembler "_D7imports8pr1090237f109023FZv" } }
+module pr109023;
+import imports.pr109023;
diff --git a/gcc/testsuite/gfortran.dg/interface_59.f90 b/gcc/testsuite/gfortran.dg/interface_59.f90
new file mode 100644
index 0000000..c9ccd67
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_59.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/119669 - this used to generate an ICE.
+
+program a
+ implicit real(a-h,o-z)
+ external abstract_caller, caller, func
+! real func
+ call abstract_caller (caller, func, 1.5)
+ call abstract_caller (caller, func, 1.5)
+end program a
+
+function func (x)
+ real func, x
+ func = x * x - 1.
+end
diff --git a/gcc/testsuite/gfortran.dg/pr119502.f90 b/gcc/testsuite/gfortran.dg/pr119502.f90
new file mode 100644
index 0000000..80d7c61
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr119502.f90
@@ -0,0 +1,15 @@
+! { dg-do run }
+
+! PR119502, negative unit numbers are not allowed without using NEWUNIT
+
+program foo
+ integer :: iun = -1
+ integer :: ios
+ open (iun, iostat=ios)
+ if (ios == 0) stop 1
+ write(iun,*, iostat=ios) "This is a test."
+ if (ios == 0) stop 2
+ close (iun, iostat=ios)
+ if (ios == 0) stop 3
+end
+
diff --git a/gcc/testsuite/gm2.dg/doc/examples/pass/doc-examples-pass.exp b/gcc/testsuite/gm2.dg/doc/examples/pass/doc-examples-pass.exp
new file mode 100644
index 0000000..0bfcea0
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/doc/examples/pass/doc-examples-pass.exp
@@ -0,0 +1,18 @@
+# Compile tests, no torture testing.
+#
+# These tests should all pass.
+
+# Load support procs.
+load_lib gm2-dg.exp
+
+gm2_init_pim4 $srcdir/$subdir
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.mod]] "" ""
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd.mod b/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd.mod
new file mode 100644
index 0000000..84020a8
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd.mod
@@ -0,0 +1,32 @@
+(* { dg-do assemble { target { x86_64-*-* } } } *)
+(* { dg-options "-g" } *)
+
+MODULE exampleadd ;
+
+FROM libc IMPORT printf, exit ;
+
+
+PROCEDURE Example (foo, bar: CARDINAL) : CARDINAL ;
+VAR
+ myout: CARDINAL ;
+BEGIN
+ ASM VOLATILE ("movl %1,%%eax; addl %2,%%eax; movl %%eax,%0"
+ : "=rm" (myout) (* outputs *)
+ : "rm" (foo), "rm" (bar) (* inputs *)
+ : "eax") ; (* we trash *)
+ RETURN( myout )
+END Example ;
+
+
+VAR
+ a, b, c: CARDINAL ;
+BEGIN
+ a := 1 ;
+ b := 2 ;
+ c := Example (a, b) ;
+ IF c # 3
+ THEN
+ printf ("Example procedure function failed to return 3, seen %d", c) ;
+ exit (1)
+ END
+END exampleadd.
diff --git a/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd2.mod b/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd2.mod
new file mode 100644
index 0000000..f25397f
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/doc/examples/pass/exampleadd2.mod
@@ -0,0 +1,32 @@
+(* { dg-do assemble { target { x86_64-*-* } } } *)
+(* { dg-options "-g" } *)
+
+MODULE exampleadd2 ;
+
+FROM libc IMPORT printf, exit ;
+
+
+PROCEDURE Example (foo, bar: CARDINAL) : CARDINAL ;
+VAR
+ myout: CARDINAL ;
+BEGIN
+ ASM VOLATILE (
+ "movl %[left],%%eax; addl %[right],%%eax; movl %%eax,%[output]"
+ : [output] "=rm" (myout) (* outputs *)
+ : [left] "rm" (foo), [right] "rm" (bar) (* inputs *)
+ : "eax") ; (* we trash *)
+ RETURN( myout )
+END Example ;
+
+VAR
+ a, b, c: CARDINAL ;
+BEGIN
+ a := 1 ;
+ b := 2 ;
+ c := Example (a, b) ;
+ IF c # 3
+ THEN
+ printf ("Example procedure function failed to return 3, seen %d", c) ;
+ exit (1)
+ END
+END exampleadd2.
diff --git a/gcc/testsuite/gm2.dg/doc/examples/pass/hello.mod b/gcc/testsuite/gm2.dg/doc/examples/pass/hello.mod
new file mode 100644
index 0000000..f9770ec
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/doc/examples/pass/hello.mod
@@ -0,0 +1,10 @@
+(* { dg-do run } *)
+(* { dg-options "-g -fno-scaffold-dynamic" } *)
+
+MODULE hello ;
+
+FROM libc IMPORT printf ;
+
+BEGIN
+ printf ("hello world\n")
+END hello.
diff --git a/gcc/testsuite/gm2.dg/doc/examples/pass/hellopim.mod b/gcc/testsuite/gm2.dg/doc/examples/pass/hellopim.mod
new file mode 100644
index 0000000..b7876cd
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/doc/examples/pass/hellopim.mod
@@ -0,0 +1,10 @@
+(* { dg-do run } *)
+(* { dg-options "-g -fno-scaffold-dynamic" } *)
+
+MODULE hellopim ;
+
+FROM StrIO IMPORT WriteString, WriteLn ;
+
+BEGIN
+ WriteString ("hello world") ; WriteLn
+END hellopim.
diff --git a/gcc/testsuite/gnat.dg/lto29.adb b/gcc/testsuite/gnat.dg/lto29.adb
new file mode 100644
index 0000000..44f556f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/lto29.adb
@@ -0,0 +1,9 @@
+-- { dg-do run }
+-- { dg-options "-O -flto" { target lto } }
+
+with Lto29_Pkg;
+
+procedure Lto29 is
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/lto29_pkg.ads b/gcc/testsuite/gnat.dg/lto29_pkg.ads
new file mode 100644
index 0000000..6008dc5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/lto29_pkg.ads
@@ -0,0 +1,15 @@
+with Ada.Strings.Bounded;
+
+package Lto29_Pkg is
+
+ package M is new Ada.Strings.Bounded.Generic_Bounded_Length (10);
+
+ type T is new M.Bounded_String;
+
+ Null_T : constant T;
+
+private
+
+ Null_T : constant T := To_Bounded_String ("");
+
+end Lto29_Pkg;
diff --git a/gcc/testsuite/rust/compile/enum_discriminant2.rs b/gcc/testsuite/rust/compile/enum_discriminant2.rs
new file mode 100644
index 0000000..351dfbb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_discriminant2.rs
@@ -0,0 +1,9 @@
+fn test() -> isize {
+ 1
+}
+
+enum Foo {
+ Bar = test() // { dg-error "only functions marked as .const." }
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/format_args_extra_comma.rs b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
new file mode 100644
index 0000000..fcc435c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_extra_comma.rs
@@ -0,0 +1,47 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+ () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+ pub mod fmt {
+ pub struct Formatter;
+ pub struct Result;
+
+ pub struct Arguments<'a>;
+
+ impl<'a> Arguments<'a> {
+ pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
+ Arguments
+ }
+ }
+
+ pub struct ArgumentV1<'a>;
+
+ impl<'a> ArgumentV1<'a> {
+ pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) -> ArgumentV1 {
+ ArgumentV1
+ }
+ }
+
+ pub trait Display {
+ fn fmt(&self, _: &mut Formatter) -> Result;
+ }
+
+ impl Display for i32 {
+ fn fmt(&self, _: &mut Formatter) -> Result {
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ Result
+ }
+ }
+ }
+}
+
+fn main() {
+ let _formatted = format_args!("extra commas {} {}", 15, 14,);
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs
new file mode 100644
index 0000000..e990c8b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3693.rs
@@ -0,0 +1,10 @@
+macro_rules! generate_pattern_iterators {
+ {
+ $(#[$forward_iterator_attribute:meta])*
+ } => {
+ }
+}
+
+generate_pattern_iterators! {
+ /// Created with the method [`split`].
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
new file mode 100644
index 0000000..e5b38bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs
@@ -0,0 +1,80 @@
+// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+
+macro_rules! impl_fn_for_zst {
+ ($(
+ $( #[$attr: meta] )*
+ struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+ |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+ $body: block;
+ )+) => {
+ $(
+ $( #[$attr] )*
+ struct $Name;
+
+ impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ $body
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call_mut(
+ &mut self,
+ ($( $arg, )*): ($( $ArgTy, )*)
+ ) -> $ReturnTy {
+ Fn::call(&*self, ($( $arg, )*))
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+ type Output = $ReturnTy;
+
+ #[inline]
+ extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ Fn::call(&self, ($( $arg, )*))
+ }
+ }
+ )+
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "fn"]
+pub trait Fn<Args>: FnMut<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut<Args>: FnOnce<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ #[stable(feature = "fn_once_output", since = "1.12.0")]
+ type Output;
+
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+impl_fn_for_zst! {
+ #[derive(Copy)]
+ struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () {
+ };
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs
new file mode 100644
index 0000000..6fc3a31
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-1.rs
@@ -0,0 +1,10 @@
+macro_rules! doc_comment {
+ (#[ $attr: meta ]) => {
+ #[$attr]
+ struct Generated; // { dg-warning "never constructed" }
+ };
+}
+
+doc_comment! {
+ /// This is a generated struct
+}
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
new file mode 100644
index 0000000..cfc8ab4
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3709-2.rs
@@ -0,0 +1,81 @@
+// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" }
+
+macro_rules! impl_fn_for_zst {
+ ($(
+ $( #[$attr: meta] )*
+ struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+ |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+ $body: block;
+ )+) => {
+ $(
+ $( #[$attr] )*
+ struct $Name;
+
+ impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ $body
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+ #[inline]
+ extern "rust-call" fn call_mut(
+ &mut self,
+ ($( $arg, )*): ($( $ArgTy, )*)
+ ) -> $ReturnTy {
+ Fn::call(&*self, ($( $arg, )*))
+ }
+ }
+
+ impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+ type Output = $ReturnTy;
+
+ #[inline]
+ extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+ Fn::call(&self, ($( $arg, )*))
+ }
+ }
+ )+
+ }
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
+
+#[lang = "fn"]
+pub trait Fn<Args>: FnMut<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_mut"]
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut<Args>: FnOnce<Args> {
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+ /// The returned type after the call operator is used.
+ #[lang = "fn_once_output"]
+ #[stable(feature = "fn_once_output", since = "1.12.0")]
+ type Output;
+
+ /// Performs the call operation.
+ #[unstable(feature = "fn_traits", issue = "29625")]
+ extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+impl_fn_for_zst! {
+ /// Documentation for the zst
+ #[derive(Copy)]
+ struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () {
+ };
+}
diff --git a/gcc/testsuite/rust/compile/track_caller.rs b/gcc/testsuite/rust/compile/track_caller.rs
new file mode 100644
index 0000000..fd1d842
--- /dev/null
+++ b/gcc/testsuite/rust/compile/track_caller.rs
@@ -0,0 +1,6 @@
+#[track_caller]
+fn foo() {}
+
+fn main() {
+ foo();
+}
diff --git a/gcc/testsuite/rust/execute/torture/min_specialization2.rs b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
new file mode 100644
index 0000000..d3239ee
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/min_specialization2.rs
@@ -0,0 +1,31 @@
+#![feature(min_specialization)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn foo(&self) -> i32;
+}
+
+impl<T> Foo for T {
+ default fn foo(&self) -> i32 { // { dg-warning "unused" }
+ 15
+ }
+}
+
+impl Foo for bool {
+ fn foo(&self) -> i32 {
+ if *self {
+ 1
+ } else {
+ 0
+ }
+ }
+}
+
+fn main() -> i32 {
+ let a = 1.foo() - 15;
+ let b = true.foo() - 1;
+
+ a + b
+}
diff --git a/gcc/testsuite/rust/execute/torture/min_specialization3.rs b/gcc/testsuite/rust/execute/torture/min_specialization3.rs
new file mode 100644
index 0000000..9eccd97
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/min_specialization3.rs
@@ -0,0 +1,36 @@
+#![feature(min_specialization)]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+ fn foo(&self) -> i32;
+}
+
+struct Wrap<T>(T);
+
+impl<T> Foo for T {
+ default fn foo(&self) -> i32 {
+ 15
+ }
+}
+
+impl<T> Foo for Wrap<T> {
+ default fn foo(&self) -> i32 {
+ 16
+ }
+}
+
+impl Foo for Wrap<bool> {
+ fn foo(&self) -> i32 {
+ if self.0 {
+ 1
+ } else {
+ 0
+ }
+ }
+}
+
+fn main() -> i32 {
+ Wrap(true).foo() - 1
+}
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 05843b8..3289b4f 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -2729,8 +2729,11 @@ copy_edges_for_bb (basic_block bb, profile_count num, profile_count den,
&& gimple_call_arg (copy_stmt, 0) == boolean_true_node)
nonlocal_goto = false;
else
- make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
- EDGE_ABNORMAL);
+ {
+ make_single_succ_edge (copy_stmt_bb, abnormal_goto_dest,
+ EDGE_ABNORMAL);
+ gimple_call_set_ctrl_altering (copy_stmt, true);
+ }
}
if ((can_throw || nonlocal_goto)
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index a2a4f5b..c1a21e7 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -3201,6 +3201,8 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
pp_string (pp, " [return slot optimization]");
if (CALL_EXPR_TAILCALL (node))
pp_string (pp, " [tail call]");
+ if (CALL_EXPR_MUST_TAIL_CALL (node))
+ pp_string (pp, " [must tail call]");
break;
case WITH_CLEANUP_EXPR:
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index ecb4a65..19beeed 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -1099,7 +1099,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
tree first_lhs = NULL_TREE;
tree first_op1 = NULL_TREE;
stmt_vec_info first_load = NULL, prev_first_load = NULL;
- bool first_stmt_ldst_p = false;
+ bool first_stmt_ldst_p = false, first_stmt_ldst_masklen_p = false;
bool first_stmt_phi_p = false;
int first_reduc_idx = -1;
bool maybe_soft_fail = false;
@@ -1133,6 +1133,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
FOR_EACH_VEC_ELT (stmts, i, stmt_info)
{
bool ldst_p = false;
+ bool ldst_masklen_p = false;
bool phi_p = false;
code_helper rhs_code = ERROR_MARK;
@@ -1195,17 +1196,22 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
else
rhs_code = CALL_EXPR;
- if (cfn == CFN_MASK_LOAD
- || cfn == CFN_GATHER_LOAD
- || cfn == CFN_MASK_GATHER_LOAD
- || cfn == CFN_MASK_LEN_GATHER_LOAD
- || cfn == CFN_SCATTER_STORE
- || cfn == CFN_MASK_SCATTER_STORE
- || cfn == CFN_MASK_LEN_SCATTER_STORE)
+ if (cfn == CFN_GATHER_LOAD
+ || cfn == CFN_SCATTER_STORE)
ldst_p = true;
+ else if (cfn == CFN_MASK_LOAD
+ || cfn == CFN_MASK_GATHER_LOAD
+ || cfn == CFN_MASK_LEN_GATHER_LOAD
+ || cfn == CFN_MASK_SCATTER_STORE
+ || cfn == CFN_MASK_LEN_SCATTER_STORE)
+ {
+ ldst_p = true;
+ ldst_masklen_p = true;
+ }
else if (cfn == CFN_MASK_STORE)
{
ldst_p = true;
+ ldst_masklen_p = true;
rhs_code = CFN_MASK_STORE;
}
else if (cfn == CFN_GOMP_SIMD_LANE)
@@ -1246,6 +1252,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
first_lhs = lhs;
first_stmt_code = rhs_code;
first_stmt_ldst_p = ldst_p;
+ first_stmt_ldst_masklen_p = ldst_masklen_p;
first_stmt_phi_p = phi_p;
first_reduc_idx = STMT_VINFO_REDUC_IDX (stmt_info);
@@ -1364,6 +1371,7 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
&& (STMT_VINFO_GATHER_SCATTER_P (stmt_info)
!= STMT_VINFO_GATHER_SCATTER_P (first_stmt_info)))
|| first_stmt_ldst_p != ldst_p
+ || (ldst_p && first_stmt_ldst_masklen_p != ldst_masklen_p)
|| first_stmt_phi_p != phi_p)
{
if (dump_enabled_p ())