diff options
author | Martin Liska <mliska@suse.cz> | 2021-06-14 11:29:28 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-06-14 11:29:28 +0200 |
commit | 12fc0e1367c1a2aaeaab32ff0d377ce7d569776f (patch) | |
tree | cfce649e39b7e28abe832a138ea0b8fbc119225c | |
parent | 845e0842307f248c7cc2b8fc713e48d1058ac86e (diff) | |
parent | 08ce1f4c5091b80b680d15c53a17237544a3cca8 (diff) | |
download | gcc-12fc0e1367c1a2aaeaab32ff0d377ce7d569776f.zip gcc-12fc0e1367c1a2aaeaab32ff0d377ce7d569776f.tar.gz gcc-12fc0e1367c1a2aaeaab32ff0d377ce7d569776f.tar.bz2 |
Merge branch 'master' into devel/sphinx
147 files changed, 2938 insertions, 727 deletions
diff --git a/config/gettext.m4 b/config/gettext.m4 index 45fa6b4..5b42bb1 100644 --- a/config/gettext.m4 +++ b/config/gettext.m4 @@ -128,6 +128,13 @@ AC_DEFUN([AM_GNU_GETTEXT], AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, [AC_TRY_LINK([#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) @@ -135,10 +142,9 @@ AC_DEFUN([AM_GNU_GETTEXT], changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings;], +], []), [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + __GNU_GETTEXT_SYMBOL_EXPRESSION], gt_cv_func_gnugettext_libc=yes, gt_cv_func_gnugettext_libc=no)]) @@ -160,6 +166,17 @@ return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", LIBS="$LIBS $LIBINTL" dnl Now see whether libintl exists and does not depend on libiconv. AC_TRY_LINK([#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (0)) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) @@ -167,20 +184,26 @@ return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], +], []), [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + __GNU_GETTEXT_SYMBOL_EXPRESSION], gt_cv_func_gnugettext_libintl=yes, gt_cv_func_gnugettext_libintl=no) dnl Now see whether libintl exists and depends on libiconv. if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" AC_TRY_LINK([#include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (0)) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif ]ifelse([$2], [need-formatstring-macros], [#ifndef __GNU_GETTEXT_SUPPORTED_REVISION #define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) @@ -188,14 +211,9 @@ return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", changequote(,)dnl typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; changequote([,])dnl -], [])[extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias ();], +], []), [bindtextdomain ("", ""); -return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + __GNU_GETTEXT_SYMBOL_EXPRESSION], [LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext_libintl=yes diff --git a/contrib/ChangeLog b/contrib/ChangeLog index da7d4d5..d8df6be 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,17 @@ +2021-06-13 Tobias Burnus <tobias@codesourcery.com> + + * gcc-changelog/git_commit.py (pr_regex): Add ?P<pr> for group('pr'). + (subject_pr_regex, subject_pr2_regex): New. + (GitInfo.__init__, GitCommit.parse_changelog): Check subject PRs. + * gcc-changelog/git_email.py (SUBJECT_PREFIX, subject_patch_regex): New. + (GitEmail.__init__): Parse 'Subject:' and pass it to GitInfo. + * gcc-changelog/test_email.py (test_pr_only_in_subject, + test_wrong_pr_comp_in_subject, test_copyright_years): New. + * gcc-changelog/test_patches.txt (0030-PR-c-92746, pr-check1.patch): + Update to avoid triggering the new check. + (0001-rs6000-Support-doubleword, pr-wrong-comp.patch, + copyright-years.patch): New. + 2021-06-11 Martin Liska <mliska@suse.cz> * gcc-changelog/git_update_version.py: Ignore commit that diff --git a/contrib/gcc-changelog/git_commit.py b/contrib/gcc-changelog/git_commit.py index bd8c1ff..d1646bd 100755 --- a/contrib/gcc-changelog/git_commit.py +++ b/contrib/gcc-changelog/git_commit.py @@ -156,7 +156,9 @@ author_line_regex = \ re.compile(r'^(?P<datetime>\d{4}-\d{2}-\d{2})\ {2}(?P<name>.* <.*>)') additional_author_regex = re.compile(r'^\t(?P<spaces>\ *)?(?P<name>.* <.*>)') changelog_regex = re.compile(r'^(?:[fF]or +)?([a-z0-9+-/]*)ChangeLog:?') -pr_regex = re.compile(r'\tPR (?P<component>[a-z+-]+\/)?([0-9]+)$') +subject_pr_regex = re.compile(r'(^|\W)PR\s+(?P<component>[a-zA-Z+-]+)/(?P<pr>\d{4,7})') +subject_pr2_regex = re.compile(r'[(\[]PR\s*(?P<pr>\d{4,7})[)\]]') +pr_regex = re.compile(r'\tPR (?P<component>[a-z+-]+\/)?(?P<pr>[0-9]+)$') dr_regex = re.compile(r'\tDR ([0-9]+)$') star_prefix_regex = re.compile(r'\t\*(?P<spaces>\ *)(?P<content>.*)') end_of_location_regex = re.compile(r'[\[<(:]') @@ -298,6 +300,7 @@ class GitCommit: self.top_level_authors = [] self.co_authors = [] self.top_level_prs = [] + self.subject_prs = set() self.cherry_pick_commit = None self.revert_commit = None self.commit_to_info_hook = commit_to_info_hook @@ -307,6 +310,9 @@ class GitCommit: if self.info.lines and self.info.lines[0] == 'Update copyright years.': return + if self.info.lines and len(self.info.lines) > 1 and self.info.lines[1]: + self.errors.append(Error('Expected empty second line in commit message', info.lines[0])) + # Identify first if the commit is a Revert commit for line in self.info.lines: m = revert_regex.match(line) @@ -316,6 +322,19 @@ class GitCommit: if self.revert_commit: self.info = self.commit_to_info_hook(self.revert_commit) + # The following happens for get_email.py: + if not self.info: + return + + # Extract PR numbers form the subject line + # Match either [PRnnnn] / (PRnnnn) or PR component/nnnn + if self.info.lines and not self.revert_commit: + self.subject_prs = {m.group('pr') for m in subject_pr2_regex.finditer(info.lines[0])} + for m in subject_pr_regex.finditer(info.lines[0]): + if not m.group('component') in bug_components: + self.errors.append(Error('invalid PR component in subject', info.lines[0])) + self.subject_prs.add(m.group('pr')) + # Allow complete deletion of ChangeLog files in a commit project_files = [f for f in self.info.modified_files if (self.is_changelog_filename(f[0], allow_suffix=True) and f[1] != 'D') @@ -346,6 +365,9 @@ class GitCommit: if not self.errors: self.check_mentioned_files() self.check_for_correct_changelog() + if self.subject_prs: + self.errors.append(Error('PR %s in subject but not in changelog' % + ', '.join(self.subject_prs), self.info.lines[0])) @property def success(self): @@ -460,7 +482,9 @@ class GitCommit: else: author_tuple = (m.group('name'), None) elif pr_regex.match(line): - component = pr_regex.match(line).group('component') + m = pr_regex.match(line) + component = m.group('component') + pr = m.group('pr') if not component: self.errors.append(Error('missing PR component', line)) continue @@ -469,6 +493,8 @@ class GitCommit: continue else: pr_line = line.lstrip() + if pr in self.subject_prs: + self.subject_prs.remove(pr) elif dr_regex.match(line): pr_line = line.lstrip() diff --git a/contrib/gcc-changelog/git_email.py b/contrib/gcc-changelog/git_email.py index fa62e3a..87b419c 100755 --- a/contrib/gcc-changelog/git_email.py +++ b/contrib/gcc-changelog/git_email.py @@ -17,6 +17,7 @@ # <http://www.gnu.org/licenses/>. */ import os +import re import sys from itertools import takewhile @@ -28,6 +29,8 @@ from unidiff import PatchSet, PatchedFile DATE_PREFIX = 'Date: ' FROM_PREFIX = 'From: ' +SUBJECT_PREFIX = 'Subject: ' +subject_patch_regex = re.compile(r'^\[PATCH( \d+/\d+)?\] ') unidiff_supports_renaming = hasattr(PatchedFile(), 'is_rename') @@ -37,7 +40,9 @@ class GitEmail(GitCommit): diff = PatchSet.from_filename(filename) date = None author = None + subject = '' + subject_last = False with open(self.filename, 'r') as f: lines = f.read().splitlines() lines = list(takewhile(lambda line: line != '---', lines)) @@ -46,8 +51,21 @@ class GitEmail(GitCommit): date = parse(line[len(DATE_PREFIX):]) elif line.startswith(FROM_PREFIX): author = GitCommit.format_git_author(line[len(FROM_PREFIX):]) + elif line.startswith(SUBJECT_PREFIX): + subject = line[len(SUBJECT_PREFIX):] + subject_last = True + elif subject_last and line.startswith(' '): + subject += line + elif line == '': + break + else: + subject_last = False + + if subject: + subject = subject_patch_regex.sub('', subject) header = list(takewhile(lambda line: line != '', lines)) - body = lines[len(header) + 1:] + # Note: commit message consists of email subject, empty line, email body + message = [subject] + lines[len(header):] modified_files = [] for f in diff: @@ -67,7 +85,7 @@ class GitEmail(GitCommit): else: t = 'M' modified_files.append((target if t != 'D' else source, t)) - git_info = GitInfo(None, date, author, body, modified_files) + git_info = GitInfo(None, date, author, message, modified_files) super().__init__(git_info, commit_to_info_hook=lambda x: None) diff --git a/contrib/gcc-changelog/test_email.py b/contrib/gcc-changelog/test_email.py index 6d65963..319e065 100755 --- a/contrib/gcc-changelog/test_email.py +++ b/contrib/gcc-changelog/test_email.py @@ -427,3 +427,16 @@ class TestGccChangelog(unittest.TestCase): def test_multi_same_file(self): email = self.from_patch_glob('0001-OpenMP-Fix-SIMT') assert email.errors[0].message == 'same file specified multiple times' + + def test_pr_only_in_subject(self): + email = self.from_patch_glob('0001-rs6000-Support-doubleword') + assert (email.errors[0].message == + 'PR 100085 in subject but not in changelog') + + def test_wrong_pr_comp_in_subject(self): + email = self.from_patch_glob('pr-wrong-comp.patch') + assert email.errors[0].message == 'invalid PR component in subject' + + def test_copyright_years(self): + email = self.from_patch_glob('copyright-years.patch') + assert not email.errors diff --git a/contrib/gcc-changelog/test_patches.txt b/contrib/gcc-changelog/test_patches.txt index 39d40b8..ba51627 100644 --- a/contrib/gcc-changelog/test_patches.txt +++ b/contrib/gcc-changelog/test_patches.txt @@ -1461,6 +1461,7 @@ Subject: [PATCH 0030/2034] PR c++/92746 - ICE with noexcept of function Another place that needs to specially handle Concepts TS function-style concepts. + PR c++/92746 * except.c (check_noexcept_r): Handle concept-check. --- gcc/cp/ChangeLog | 3 +++ @@ -1977,7 +1978,7 @@ index aac31d02b6c..56c470f6ecf 100644 From 5194b51ed9714808d88827531e91474895b6c706 Mon Sep 17 00:00:00 2001 From: Jason Merrill <jason@redhat.com> Date: Thu, 16 Jan 2020 16:55:39 -0500 -Subject: [PATCH 0121/2034] PR c++/93286 - ICE with __is_constructible and +Subject: [PATCH 0121/2034] PR c++/12345 - ICE with __is_constructible and variadic template. Here we had been recursing in tsubst_copy_and_build if type2 was a TREE_LIST @@ -3406,3 +3407,60 @@ index 00000000000..21540512e23 + -- 2.25.1 +=== 0001-rs6000-Support-doubleword === +From f700e4b0ee3ef53b48975cf89be26b9177e3a3f3 Mon Sep 17 00:00:00 2001 +From: Xionghu Luo <luoxhu@linux.ibm.com> +Date: Tue, 8 Jun 2021 21:48:12 -0500 +Subject: [PATCH] rs6000: Support doubleword swaps removal in rot64 load store + [PR100085] + +gcc/testsuite/ChangeLog: + + * gcc.target/powerpc/pr100085.c: New test. +--- +diff --git a/gcc/testsuite/gcc.target/powerpc/pr100085.c b/gcc/testsuite/gcc.target/powerpc/pr100085.c +new file mode 100644 +index 00000000000..7d8b147b127 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c +@@ -0,0 +1,1 @@ ++ +-- +2.25.1 +=== pr-wrong-comp.patch === +From 5194b51ed9714808d88827531e91474895b6c706 Mon Sep 17 00:00:00 2001 +From: Jason Merrill <jason@redhat.com> +Date: Thu, 16 Jan 2020 16:55:39 -0500 +Subject: [PATCH 0121/2034] PR some/93286 - ICE with __is_constructible and + variadic template. + +gcc/testsuite/ChangeLog: + + PR c++/93286 + * gcc.target/powerpc/pr100085.c: New test. +--- +diff --git a/gcc/testsuite/gcc.target/powerpc/pr100085.c b/gcc/testsuite/gcc.target/powerpc/pr100085.c +new file mode 100644 +index 00000000000..7d8b147b127 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c +@@ -0,0 +1,1 @@ ++ +-- +2.25.1 +==== copyright-years.patch === +From 99dee82307f1e163e150c9c810452979994047ce Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek <jakub@redhat.com> +Date: Mon, 4 Jan 2021 10:26:59 +0100 +Subject: [PATCH] Update copyright years. + +--- +diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c +new file mode 100644 +index 6f67552d075..32478f070e8 100644 +--- a/lto-plugin/lto-plugin.c ++++ b/lto-plugin/lto-plugin.c +@@ -0,0 +1,1 @@ ++ +-- +2.25.1 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b02695b..a856c27 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,200 @@ +2021-06-13 Uroš Bizjak <ubizjak@gmail.com> + + PR target/101021 + * config/i386/i386-expand.c (expand_vec_perm_pshufb): + Emit constant permutation insn directly from here. + +2021-06-13 Trevor Saunders <tbsaunde@tbsaunde.org> + + * attribs.c (find_attribute_namespace): Iterate over vec<> with + range based for. + * auto-profile.c (afdo_find_equiv_class): Likewise. + * gcc.c (do_specs_vec): Likewise. + (do_spec_1): Likewise. + (driver::set_up_specs): Likewise. + * gimple-loop-jam.c (any_access_function_variant_p): Likewise. + * gimple-ssa-store-merging.c (compatible_load_p): Likewise. + (imm_store_chain_info::try_coalesce_bswap): Likewise. + (imm_store_chain_info::coalesce_immediate_stores): Likewise. + (get_location_for_stmts): Likewise. + * graphite-poly.c (print_iteration_domains): Likewise. + (free_poly_bb): Likewise. + (remove_gbbs_in_scop): Likewise. + (free_scop): Likewise. + (dump_gbb_cases): Likewise. + (dump_gbb_conditions): Likewise. + (print_pdrs): Likewise. + (print_scop): Likewise. + * ifcvt.c (cond_move_process_if_block): Likewise. + * lower-subreg.c (decompose_multiword_subregs): Likewise. + * regcprop.c (pass_cprop_hardreg::execute): Likewise. + * sanopt.c (sanitize_rewrite_addressable_params): Likewise. + * sel-sched-dump.c (dump_insn_vector): Likewise. + * store-motion.c (store_ops_ok): Likewise. + (store_killed_in_insn): Likewise. + * timevar.c (timer::named_items::print): Likewise. + * tree-cfgcleanup.c (cleanup_control_flow_pre): Likewise. + (cleanup_tree_cfg_noloop): Likewise. + * tree-data-ref.c (dump_data_references): Likewise. + (print_dir_vectors): Likewise. + (print_dist_vectors): Likewise. + (dump_data_dependence_relations): Likewise. + (dump_dist_dir_vectors): Likewise. + (dump_ddrs): Likewise. + (create_runtime_alias_checks): Likewise. + (free_subscripts): Likewise. + (save_dist_v): Likewise. + (save_dir_v): Likewise. + (invariant_access_functions): Likewise. + (same_access_functions): Likewise. + (access_functions_are_affine_or_constant_p): Likewise. + (find_data_references_in_stmt): Likewise. + (graphite_find_data_references_in_stmt): Likewise. + (free_dependence_relations): Likewise. + (free_data_refs): Likewise. + * tree-inline.c (copy_debug_stmts): Likewise. + * tree-into-ssa.c (dump_currdefs): Likewise. + (rewrite_update_phi_arguments): Likewise. + * tree-ssa-propagate.c (clean_up_loop_closed_phi): Likewise. + * tree-vect-data-refs.c (vect_analyze_possibly_independent_ddr): + Likewise. + (vect_slp_analyze_node_dependences): Likewise. + (vect_slp_analyze_instance_dependence): Likewise. + (vect_record_base_alignments): Likewise. + (vect_get_peeling_costs_all_drs): Likewise. + (vect_peeling_supportable): Likewise. + * tree-vectorizer.c (vec_info::~vec_info): Likewise. + (vec_info::free_stmt_vec_infos): Likewise. + +2021-06-13 Jeff Law <jeffreyalaw@gmail.com> + + * config/h8300/logical.md (<code>qi3_1<cczn>): New pattern. + (andqi3_1<cczn>): Removed. + (<ors>qi3_1): Do not split for IOR/XOR a single bit. + (H8/SX bit logicals): Split out from other patterns. + * config/h8300/multiply.md (mulqihi3_const<cczn>): Renamed from + mulqihi3_const_clobber_flags. + (mulqihi3<cczn>, mulhisi3_const<cczn>, mulhisi3<cczn>): Similarly + +2021-06-13 H.J. Lu <hjl.tools@gmail.com> + + PR target/101023 + * config/i386/i386.c (ix86_expand_prologue): Set red_zone_used + to true if red zone is used. + (ix86_output_indirect_jmp): Replace ix86_red_zone_size with + ix86_red_zone_used. + * config/i386/i386.h (machine_function): Add red_zone_used. + (ix86_red_zone_size): Removed. + (ix86_red_zone_used): New. + * config/i386/i386.md (peephole2 patterns): Replace + ix86_red_zone_size with ix86_red_zone_used. + +2021-06-12 Jason Merrill <jason@redhat.com> + + * doc/extend.texi (unused variable attribute): Applies to + structure fields as well. + +2021-06-12 Eugene Rozenfeld <erozen@microsoft.com> + + * auto-profile.c (read_profile): fix a typo in an error string + +2021-06-11 Thomas Schwinge <thomas@codesourcery.com> + + * tree-pretty-print.h (dump_omp_clauses): Add 'bool = true' + default argument. + * tree-pretty-print.c (dump_omp_clauses): Update. + (dump_generic_node) <OMP_CLAUSE>: Use it. + +2021-06-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + PR target/101016 + * config/arm/arm_mve.h (__arm_vld1q): Change __ARM_mve_coerce(p0, + int8_t const *) to __ARM_mve_coerce1(p0, int8_t *) in the argument for + the polymorphic variants matching code. + (__arm_vld1q_z): Likewise. + (__arm_vld2q): Likewise. + (__arm_vld4q): Likewise. + (__arm_vldrbq_gather_offset): Likewise. + (__arm_vldrbq_gather_offset_z): Likewise. + +2021-06-11 Roger Sayle <roger@nextmovesoftware.com> + + PR tree-optimization/96392 + * fold-const.h (tree_expr_maybe_real_minus_zero_p): Fix prototype. + +2021-06-11 Roger Sayle <roger@nextmovesoftware.com> + + PR tree-optimization/96392 + * fold-const.c (fold_real_zero_addition_p): Take both arguments + of the addition or subtraction, not just the zero. Use this + other argument in tests for signaling NaNs and signed zeros. + (tree_expr_maybe_real_minus_zero_p): New predicate. + * fold-const.h (fold_real_zero_addition_p): Update prototype. + (tree_expr_maybe_real_minus_zero_p): New function prototype. + * match.pd: Update calls to fold_real_zero_addition_p. + Replace HONOR_NANS with tree_expr_maybe_nan_p. + Replace HONOR_SIGNED_ZEROS with tree_expr_maybe_real_minus_zero_p. + Replace HONOR_SNANS with tree_expr_maybe_signaling_nan_p. + * tree-ssa-reassoc.c (eliminate_using_constants): Update + call to fold_real_zero_addition_p. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101025 + * tree-ssa-loop-im.c (sm_seq_valid_bb): Make sure to process + all refs that require dependence checking. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101028 + * tree-vect-slp.c (vect_build_slp_tree_2): When SLP + reassoc discovery fails fatally, mark appropriate lanes + in matches[] so. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101026 + * tree-vect-slp.c (vect_build_slp_tree_2): Make sure we + have a representative for the associated chain nodes. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/101008 + * simplify-rtx.c (relational_result): New function. + (simplify_logical_relational_operation, + simplify_relational_operation): Use it. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR target/101007 + * config/i386/sse.md (*vec_concat<mode>_0_1): Require TARGET_SSE2. + +2021-06-11 Uroš Bizjak <ubizjak@gmail.com> + + PR target/101021 + * config/i386/i386-expand.c (expand_vec_perm_pshufb): Return + false if the permutation can be implemented with constant + permutation instruction in wider mode. + (canonicalize_vector_int_perm): Move above expand_vec_perm_pshufb. + Handle V8QImode and V4HImode. + +2021-06-11 Martin Liska <mliska@suse.cz> + + PR gcov-profile/100788 + * common.opt: Add new option. + * coverage.c (coverage_begin_function): Emit warning instead on + the internal compiler error. + * doc/invoke.texi: Document the option. + * toplev.c (process_options): Enable it by default. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR middle-end/101009 + * tree-data-ref.c (build_classic_dist_vector_1): Make sure + to set *init_b to true when we encounter a constant equal + index pair. + (compute_affine_dependence): Also dump the actual DR_REF. + 2021-06-10 Aldy Hernandez <aldyh@redhat.com> PR tree-optimization/100984 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 702992b..d9253cc 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210611 +20210614 diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog index f2061ac..400175a 100644 --- a/gcc/analyzer/ChangeLog +++ b/gcc/analyzer/ChangeLog @@ -1,3 +1,27 @@ +2021-06-13 Trevor Saunders <tbsaunde@tbsaunde.org> + + * call-string.cc (call_string::call_string): Use range based for + to iterate over vec<>. + (call_string::to_json): Likewise. + (call_string::hash): Likewise. + (call_string::calc_recursion_depth): Likewise. + * checker-path.cc (checker_path::fixup_locations): Likewise. + * constraint-manager.cc (equiv_class::equiv_class): Likewise. + (equiv_class::to_json): Likewise. + (equiv_class::hash): Likewise. + (constraint_manager::to_json): Likewise. + * engine.cc (impl_region_model_context::on_svalue_leak): + Likewise. + (on_liveness_change): Likewise. + (impl_region_model_context::on_unknown_change): Likewise. + * program-state.cc (sm_state_map::set_state): Likewise. + * region-model.cc (test_canonicalization_4): Likewise. + +2021-06-11 David Malcolm <dmalcolm@redhat.com> + + * engine.cc (worklist::key_t::cmp): Move sort by call_string to + before SCC. + 2021-06-09 David Malcolm <dmalcolm@redhat.com> * region-model.cc (region_model::get_lvalue_1): Make const. diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc index 224b2e2..9f4f77a 100644 --- a/gcc/analyzer/call-string.cc +++ b/gcc/analyzer/call-string.cc @@ -50,9 +50,7 @@ along with GCC; see the file COPYING3. If not see call_string::call_string (const call_string &other) : m_return_edges (other.m_return_edges.length ()) { - const return_superedge *e; - int i; - FOR_EACH_VEC_ELT (other.m_return_edges, i, e) + for (const return_superedge *e : other.m_return_edges) m_return_edges.quick_push (e); } @@ -118,9 +116,7 @@ call_string::to_json () const { json::array *arr = new json::array (); - const return_superedge *e; - int i; - FOR_EACH_VEC_ELT (m_return_edges, i, e) + for (const return_superedge *e : m_return_edges) { json::object *e_obj = new json::object (); e_obj->set ("src_snode_idx", @@ -141,9 +137,7 @@ hashval_t call_string::hash () const { inchash::hash hstate; - int i; - const return_superedge *e; - FOR_EACH_VEC_ELT (m_return_edges, i, e) + for (const return_superedge *e : m_return_edges) hstate.add_ptr (e); return hstate.end (); } @@ -173,9 +167,7 @@ call_string::calc_recursion_depth () const = m_return_edges[m_return_edges.length () - 1]; int result = 0; - const return_superedge *e; - int i; - FOR_EACH_VEC_ELT (m_return_edges, i, e) + for (const return_superedge *e : m_return_edges) if (e == top_return_sedge) ++result; return result; diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc index 7d229bb..e6f838b 100644 --- a/gcc/analyzer/checker-path.cc +++ b/gcc/analyzer/checker-path.cc @@ -1001,9 +1001,7 @@ checker_path::add_final_event (const state_machine *sm, void checker_path::fixup_locations (pending_diagnostic *pd) { - checker_event *e; - int i; - FOR_EACH_VEC_ELT (m_events, i, e) + for (checker_event *e : m_events) e->set_location (pd->fixup_location (e->get_location ())); } diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index 4dadd20..51cf522 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -270,9 +270,7 @@ equiv_class::equiv_class (const equiv_class &other) : m_constant (other.m_constant), m_cst_sval (other.m_cst_sval), m_vars (other.m_vars.length ()) { - int i; - const svalue *sval; - FOR_EACH_VEC_ELT (other.m_vars, i, sval) + for (const svalue *sval : other.m_vars) m_vars.quick_push (sval); } @@ -310,9 +308,7 @@ equiv_class::to_json () const json::object *ec_obj = new json::object (); json::array *sval_arr = new json::array (); - int i; - const svalue *sval; - FOR_EACH_VEC_ELT (m_vars, i, sval) + for (const svalue *sval : m_vars) sval_arr->append (sval->to_json ()); ec_obj->set ("svals", sval_arr); @@ -337,9 +333,7 @@ equiv_class::hash () const inchash::hash hstate; inchash::add_expr (m_constant, hstate); - int i; - const svalue *sval; - FOR_EACH_VEC_ELT (m_vars, i, sval) + for (const svalue * sval : m_vars) hstate.add_ptr (sval); return hstate.end (); } @@ -811,9 +805,7 @@ constraint_manager::to_json () const /* Equivalence classes. */ { json::array *ec_arr = new json::array (); - int i; - equiv_class *ec; - FOR_EACH_VEC_ELT (m_equiv_classes, i, ec) + for (const equiv_class *ec : m_equiv_classes) ec_arr->append (ec->to_json ()); cm_obj->set ("ecs", ec_arr); } @@ -821,10 +813,8 @@ constraint_manager::to_json () const /* Constraints. */ { json::array *con_arr = new json::array (); - int i; - constraint *c; - FOR_EACH_VEC_ELT (m_constraints, i, c) - con_arr->append (c->to_json ()); + for (const constraint &c : m_constraints) + con_arr->append (c.to_json ()); cm_obj->set ("constraints", con_arr); } diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 5b519fd..50652b2 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -121,9 +121,7 @@ void impl_region_model_context::on_svalue_leak (const svalue *sval) { - int sm_idx; - sm_state_map *smap; - FOR_EACH_VEC_ELT (m_new_state->m_checker_states, sm_idx, smap) + for (sm_state_map *smap : m_new_state->m_checker_states) smap->on_svalue_leak (sval, this); } @@ -132,9 +130,7 @@ impl_region_model_context:: on_liveness_change (const svalue_set &live_svalues, const region_model *model) { - int sm_idx; - sm_state_map *smap; - FOR_EACH_VEC_ELT (m_new_state->m_checker_states, sm_idx, smap) + for (sm_state_map *smap : m_new_state->m_checker_states) smap->on_liveness_change (live_svalues, model, this); } @@ -142,9 +138,7 @@ void impl_region_model_context::on_unknown_change (const svalue *sval, bool is_mutable) { - int sm_idx; - sm_state_map *smap; - FOR_EACH_VEC_ELT (m_new_state->m_checker_states, sm_idx, smap) + for (sm_state_map *smap : m_new_state->m_checker_states) smap->on_unknown_change (sval, is_mutable, m_ext_state); } @@ -2004,7 +1998,25 @@ worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb) return cmp; } - /* First, order by SCC. */ + /* Sort by callstring, so that nodes with deeper call strings are processed + before those with shallower call strings. + If we have + splitting BB + / \ + / \ + fn call no fn call + \ / + \ / + join BB + then we want the path inside the function call to be fully explored up + to the return to the join BB before we explore on the "no fn call" path, + so that both enodes at the join BB reach the front of the worklist at + the same time and thus have a chance of being merged. */ + int cs_cmp = call_string::cmp (call_string_a, call_string_b); + if (cs_cmp) + return cs_cmp; + + /* Order by SCC. */ int scc_id_a = ka.get_scc_id (ka.m_enode); int scc_id_b = kb.get_scc_id (kb.m_enode); if (scc_id_a != scc_id_b) @@ -2033,11 +2045,6 @@ worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb) gcc_assert (snode_a == snode_b); - /* The points might vary by callstring; try sorting by callstring. */ - int cs_cmp = call_string::cmp (call_string_a, call_string_b); - if (cs_cmp) - return cs_cmp; - /* Order within supernode via program point. */ int within_snode_cmp = function_point::cmp_within_supernode (point_a.get_function_point (), diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc index 5c690b0..76959c1 100644 --- a/gcc/analyzer/program-state.cc +++ b/gcc/analyzer/program-state.cc @@ -441,10 +441,8 @@ sm_state_map::set_state (const equiv_class &ec, const svalue *origin, const extrinsic_state &ext_state) { - int i; - const svalue *sval; bool any_changed = false; - FOR_EACH_VEC_ELT (ec.m_vars, i, sval) + for (const svalue *sval : ec.m_vars) any_changed |= impl_set_state (sval, state, origin, ext_state); return any_changed; } diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 551ee79..4b9620d 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -4294,9 +4294,7 @@ test_canonicalization_4 () region_model_manager mgr; region_model model (&mgr); - unsigned i; - tree cst; - FOR_EACH_VEC_ELT (csts, i, cst) + for (tree cst : csts) model.get_rvalue (cst, NULL); model.canonicalize (); diff --git a/gcc/attribs.c b/gcc/attribs.c index 70e0a2f..afa485e 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -165,15 +165,12 @@ register_scoped_attributes (const struct attribute_spec *attributes, static scoped_attributes* find_attribute_namespace (const char* ns) { - unsigned ix; - scoped_attributes *iter; - - FOR_EACH_VEC_ELT (attributes_table, ix, iter) - if (ns == iter->ns - || (iter->ns != NULL + for (scoped_attributes &iter : attributes_table) + if (ns == iter.ns + || (iter.ns != NULL && ns != NULL - && !strcmp (iter->ns, ns))) - return iter; + && !strcmp (iter.ns, ns))) + return &iter; return NULL; } diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c index 2a6d9a1..ed788dc 100644 --- a/gcc/auto-profile.c +++ b/gcc/auto-profile.c @@ -939,7 +939,7 @@ read_profile (void) unsigned version = gcov_read_unsigned (); if (version != AUTO_PROFILE_VERSION) { - error ("AutoFDO profile version %u does match %u", + error ("AutoFDO profile version %u does not match %u", version, AUTO_PROFILE_VERSION); return; } @@ -1156,14 +1156,12 @@ afdo_find_equiv_class (bb_set *annotated_bb) FOR_ALL_BB_FN (bb, cfun) { vec<basic_block> dom_bbs; - basic_block bb1; - int i; if (bb->aux != NULL) continue; bb->aux = bb; dom_bbs = get_dominated_by (CDI_DOMINATORS, bb); - FOR_EACH_VEC_ELT (dom_bbs, i, bb1) + for (basic_block bb1 : dom_bbs) if (bb1->aux == NULL && dominated_by_p (CDI_POST_DOMINATORS, bb, bb1) && bb1->loop_father == bb->loop_father) { @@ -1175,7 +1173,7 @@ afdo_find_equiv_class (bb_set *annotated_bb) } } dom_bbs = get_dominated_by (CDI_POST_DOMINATORS, bb); - FOR_EACH_VEC_ELT (dom_bbs, i, bb1) + for (basic_block bb1 : dom_bbs) if (bb1->aux == NULL && dominated_by_p (CDI_DOMINATORS, bb, bb1) && bb1->loop_father == bb->loop_father) { diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 460ced3..c14edd1 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,13 @@ +2021-06-12 Jason Merrill <jason@redhat.com> + + * c-attribs.c (handle_unused_attribute): Handle FIELD_DECL. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/100974 + * c-cppbuiltin.c (c_cpp_builtins): Predefine __cpp_if_consteval for + -std=c++2b for P1938R3 consteval if support. + 2021-06-09 Jason Merrill <jason@redhat.com> PR c++/100879 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 42026a8..6bf492a 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -1568,6 +1568,7 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), || VAR_OR_FUNCTION_DECL_P (decl) || TREE_CODE (decl) == LABEL_DECL || TREE_CODE (decl) == CONST_DECL + || TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == TYPE_DECL) { TREE_USED (decl) = 1; diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 42b7604..f79f939 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -1029,6 +1029,7 @@ c_cpp_builtins (cpp_reader *pfile) { /* Set feature test macros for C++23. */ cpp_define (pfile, "__cpp_size_t_suffix=202011L"); + cpp_define (pfile, "__cpp_if_consteval=202106L"); } if (flag_concepts) { diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h index 1380f3a..83f1003 100644 --- a/gcc/config/arm/arm_mve.h +++ b/gcc/config/arm/arm_mve.h @@ -37565,47 +37565,47 @@ extern void *__ARM_undef; #define __arm_vld1q(p0) (\ _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce(p0, uint32_t const *)), \ - int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_f16 (__ARM_mve_coerce(p0, float16_t const *)), \ - int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_f32 (__ARM_mve_coerce(p0, float32_t const *)))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce1(p0, uint32_t *)), \ + int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_f16 (__ARM_mve_coerce1(p0, float16_t *)), \ + int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_f32 (__ARM_mve_coerce1(p0, float32_t *)))) #define __arm_vld1q_z(p0,p1) ( \ _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce(p0, int8_t const *), p1), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 (__ARM_mve_coerce(p0, int16_t const *), p1), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 (__ARM_mve_coerce(p0, int32_t const *), p1), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce(p0, uint8_t const *), p1), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 (__ARM_mve_coerce(p0, uint16_t const *), p1), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 (__ARM_mve_coerce(p0, uint32_t const *), p1), \ - int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_z_f16 (__ARM_mve_coerce(p0, float16_t const *), p1), \ - int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_z_f32 (__ARM_mve_coerce(p0, float32_t const *), p1))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce1(p0, int8_t *), p1), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 (__ARM_mve_coerce1(p0, int16_t *), p1), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 (__ARM_mve_coerce1(p0, int32_t *), p1), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce1(p0, uint8_t *), p1), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 (__ARM_mve_coerce1(p0, uint16_t *), p1), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 (__ARM_mve_coerce1(p0, uint32_t *), p1), \ + int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld1q_z_f16 (__ARM_mve_coerce1(p0, float16_t *), p1), \ + int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld1q_z_f32 (__ARM_mve_coerce1(p0, float32_t *), p1))) #define __arm_vld2q(p0) ( \ _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld2q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld2q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld2q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld2q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld2q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld2q_u32 (__ARM_mve_coerce(p0, uint32_t const *)), \ - int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld2q_f16 (__ARM_mve_coerce(p0, float16_t const *)), \ - int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld2q_f32 (__ARM_mve_coerce(p0, float32_t const *)))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld2q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld2q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld2q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld2q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld2q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld2q_u32 (__ARM_mve_coerce1(p0, uint32_t *)), \ + int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld2q_f16 (__ARM_mve_coerce1(p0, float16_t *)), \ + int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld2q_f32 (__ARM_mve_coerce1(p0, float32_t *)))) #define __arm_vld4q(p0) ( \ _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld4q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld4q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld4q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld4q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce(p0, uint32_t const *)), \ - int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld4q_f16 (__ARM_mve_coerce(p0, float16_t const *)), \ - int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld4q_f32 (__ARM_mve_coerce(p0, float32_t const *)))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld4q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld4q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld4q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld4q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce1(p0, uint32_t *)), \ + int (*)[__ARM_mve_type_float16_t_ptr]: __arm_vld4q_f16 (__ARM_mve_coerce1(p0, float16_t *)), \ + int (*)[__ARM_mve_type_float32_t_ptr]: __arm_vld4q_f32 (__ARM_mve_coerce1(p0, float32_t *)))) #define __arm_vldrhq_gather_offset(p0,p1) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \ @@ -39631,25 +39631,26 @@ extern void *__ARM_undef; #define __arm_vldrbq_gather_offset(p0,p1) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_s8 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_s16 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_s32 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint32x4_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_u8 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_u16 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_u32 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint32x4_t)));}) + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_s8 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_s16 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_s32 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint32x4_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_u8 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_u16 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_u32 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint32x4_t)));}) #define __arm_vstrwq_scatter_base_p(p0,p1,p2,p3) ({ __typeof(p2) __p2 = (p2); \ _Generic( (int (*)[__ARM_mve_typeid(__p2)])0, \ int (*)[__ARM_mve_type_int32x4_t]: __arm_vstrwq_scatter_base_p_s32 (p0, p1, __ARM_mve_coerce(__p2, int32x4_t), p3), \ int (*)[__ARM_mve_type_uint32x4_t]: __arm_vstrwq_scatter_base_p_u32 (p0, p1, __ARM_mve_coerce(__p2, uint32x4_t), p3));}) -#define __arm_vld1q(p0) (_Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce(p0, uint32_t const *)))) +#define __arm_vld1q(p0) (\ + _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_u32 (__ARM_mve_coerce1(p0, uint32_t *)))) #define __arm_vldrhq_gather_offset(p0,p1) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \ @@ -40146,29 +40147,29 @@ extern void *__ARM_undef; int (*)[__ARM_mve_type_uint32x4_t]: __arm_vbrsrq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), p2, p3));}) #define __arm_vld1q_z(p0,p1) ( _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce(p0, int8_t const *), p1), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 (__ARM_mve_coerce(p0, int16_t const *), p1), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 (__ARM_mve_coerce(p0, int32_t const *), p1), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce(p0, uint8_t const *), p1), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 (__ARM_mve_coerce(p0, uint16_t const *), p1), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 (__ARM_mve_coerce(p0, uint32_t const *), p1))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld1q_z_s8 (__ARM_mve_coerce1(p0, int8_t *), p1), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld1q_z_s16 (__ARM_mve_coerce1(p0, int16_t *), p1), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld1q_z_s32 (__ARM_mve_coerce1(p0, int32_t *), p1), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld1q_z_u8 (__ARM_mve_coerce1(p0, uint8_t *), p1), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld1q_z_u16 (__ARM_mve_coerce1(p0, uint16_t *), p1), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld1q_z_u32 (__ARM_mve_coerce1(p0, uint32_t *), p1))) #define __arm_vld2q(p0) ( _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld2q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld2q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld2q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld2q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld2q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld2q_u32 (__ARM_mve_coerce(p0, uint32_t const *)))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld2q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld2q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld2q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld2q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld2q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld2q_u32 (__ARM_mve_coerce1(p0, uint32_t *)))) #define __arm_vld4q(p0) ( _Generic( (int (*)[__ARM_mve_typeid(p0)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld4q_s8 (__ARM_mve_coerce(p0, int8_t const *)), \ - int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld4q_s16 (__ARM_mve_coerce(p0, int16_t const *)), \ - int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld4q_s32 (__ARM_mve_coerce(p0, int32_t const *)), \ - int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld4q_u8 (__ARM_mve_coerce(p0, uint8_t const *)), \ - int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce(p0, uint16_t const *)), \ - int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce(p0, uint32_t const *)))) + int (*)[__ARM_mve_type_int8_t_ptr]: __arm_vld4q_s8 (__ARM_mve_coerce1(p0, int8_t *)), \ + int (*)[__ARM_mve_type_int16_t_ptr]: __arm_vld4q_s16 (__ARM_mve_coerce1(p0, int16_t *)), \ + int (*)[__ARM_mve_type_int32_t_ptr]: __arm_vld4q_s32 (__ARM_mve_coerce1(p0, int32_t *)), \ + int (*)[__ARM_mve_type_uint8_t_ptr]: __arm_vld4q_u8 (__ARM_mve_coerce1(p0, uint8_t *)), \ + int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce1(p0, uint16_t *)), \ + int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce1(p0, uint32_t *)))) #define __arm_vgetq_lane(p0,p1) ({ __typeof(p0) __p0 = (p0); \ _Generic( (int (*)[__ARM_mve_typeid(__p0)])0, \ @@ -40515,12 +40516,12 @@ extern void *__ARM_undef; #define __arm_vldrbq_gather_offset_z(p0,p1,p2) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_z_s8 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint8x16_t), p2), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_z_s16 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint16x8_t), p2), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_z_s32 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint32x4_t), p2), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_z_u8 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint8x16_t), p2), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_z_u16 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint16x8_t), p2), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_z_u32 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint32x4_t), p2));}) + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_z_s8 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint8x16_t), p2), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_z_s16 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint16x8_t), p2), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_z_s32 (__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint32x4_t), p2), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_z_u8 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint8x16_t), p2), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_z_u16 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint16x8_t), p2), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_z_u32 (__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint32x4_t), p2));}) #define __arm_vqrdmlahq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ @@ -41201,12 +41202,12 @@ extern void *__ARM_undef; #define __arm_vldrbq_gather_offset(p0,p1) ({ __typeof(p1) __p1 = (p1); \ _Generic( (int (*)[__ARM_mve_typeid(p0)][__ARM_mve_typeid(__p1)])0, \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_s8 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_s16 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_s32 (__ARM_mve_coerce(p0, int8_t const *), __ARM_mve_coerce(__p1, uint32x4_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_u8 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint8x16_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_u16 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint16x8_t)), \ - int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_u32 (__ARM_mve_coerce(p0, uint8_t const *), __ARM_mve_coerce(__p1, uint32x4_t)));}) + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_s8(__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_s16(__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \ + int (*)[__ARM_mve_type_int8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_s32(__ARM_mve_coerce1(p0, int8_t *), __ARM_mve_coerce(__p1, uint32x4_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint8x16_t]: __arm_vldrbq_gather_offset_u8(__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint8x16_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint16x8_t]: __arm_vldrbq_gather_offset_u16(__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint16x8_t)), \ + int (*)[__ARM_mve_type_uint8_t_ptr][__ARM_mve_type_uint32x4_t]: __arm_vldrbq_gather_offset_u32(__ARM_mve_coerce1(p0, uint8_t *), __ARM_mve_coerce(__p1, uint32x4_t)));}) #define __arm_vidupq_m(p0,p1,p2,p3) ({ __typeof(p0) __p0 = (p0); \ __typeof(p1) __p1 = (p1); \ diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md index fae3c7c..cb4c638 100644 --- a/gcc/config/h8300/logical.md +++ b/gcc/config/h8300/logical.md @@ -69,14 +69,6 @@ "" [(set_attr "length" "8,2")]) -(define_insn "*andqi3_1<cczn>" - [(set (match_operand:QI 0 "register_operand" "=r") - (and:QI (match_operand:QI 1 "register_operand" "%0") - (match_operand:QI 2 "h8300_src_operand" "rn"))) - (clobber (reg:CC CC_REG))] - "" - "and %X2,%X0" - [(set_attr "length" "2")]) (define_insn_and_split "*andor<mode>3" [(set (match_operand:QHSI 0 "register_operand" "=r") @@ -179,27 +171,49 @@ (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))] "TARGET_H8300SX || register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)" - "#" - "&& reload_completed" + { return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; } + "&& reload_completed && !single_one_operand (operands[2], QImode)" [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2))) - (clobber (reg:CC CC_REG))])]) + (clobber (reg:CC CC_REG))])] + "" + [(set_attr "length" "8")]) -(define_insn "<code>qi3_1_clobber_flags" - [(set (match_operand:QI 0 "bit_operand" "=U,rQ") - (ors:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "h8300_src_operand" "Y2,rQi"))) +(define_insn "*<code>qi3_1<cczn>" + [(set (match_operand:QI 0 "bit_operand" "=rQ") + (ors:QI (match_operand:QI 1 "bit_operand" "%0") + (match_operand:QI 2 "h8300_src_operand" "rQi"))) (clobber (reg:CC CC_REG))] - "TARGET_H8300SX || register_operand (operands[0], QImode) - || single_one_operand (operands[2], QImode)" - { - if (which_alternative == 0) - return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; - else if (which_alternative == 1) - return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; - gcc_unreachable (); + "TARGET_H8300SX" + { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; } + [(set_attr "length" "*") + (set_attr "length_table" "logicb")]) + +(define_insn "*<code>qi3_1<cczn>" + [(set (match_operand:QI 0 "register_operand" "=r") + (ors:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "h8300_src_operand" "ri"))) + (clobber (reg:CC CC_REG))] + "TARGET_H8300SX" + { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; } + [(set_attr "length" "*") + (set_attr "length_table" "logicb")]) + +(define_insn "*<code>qi3_1<cczn>" + [(set (match_operand:QI 0 "register_operand" "=r") + (logicals:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "h8300_src_operand" "rn"))) + (clobber (reg:CC CC_REG))] + "" + { + if (<CODE> == IOR) + return "or\\t%X2,%X0"; + else if (<CODE> == XOR) + return "xor\\t%X2,%X0"; + else if (<CODE> == AND) + return "and\\t%X2,%X0"; + gcc_unreachable (); } - [(set_attr "length" "8,*") - (set_attr "length_table" "*,logicb")]) + [(set_attr "length" "2")]) ;; ---------------------------------------------------------------------- ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS diff --git a/gcc/config/h8300/multiply.md b/gcc/config/h8300/multiply.md index 1d56d47..8b9328c 100644 --- a/gcc/config/h8300/multiply.md +++ b/gcc/config/h8300/multiply.md @@ -26,7 +26,7 @@ (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2))) (clobber (reg:CC CC_REG))])]) -(define_insn "*mulqihi3_const_clobber_flags" +(define_insn "*mulqihi3_const<cczn>" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (match_operand:QI 2 "nibble_operand" "IP4>X"))) @@ -47,7 +47,7 @@ (sign_extend:HI (match_dup 2)))) (clobber (reg:CC CC_REG))])]) -(define_insn "*mulqihi3_clobber_flags" +(define_insn "*mulqihi3<cczn>" [(set (match_operand:HI 0 "register_operand" "=r") (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))) @@ -78,7 +78,7 @@ (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2))) (clobber (reg:CC CC_REG))])]) -(define_insn "*mulhisi3_const_clobber_flags" +(define_insn "*mulhisi3_const<cczn>" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (match_operand:SI 2 "nibble_operand" "IP4>X"))) @@ -99,7 +99,7 @@ (sign_extend:SI (match_dup 2)))) (clobber (reg:CC CC_REG))])]) -(define_insn "*mulhisi3_clobber_flags" +(define_insn "*mulhisi3<cczn>" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0")) (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))) diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 2fa3a18..6e33f6f 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -17593,13 +17593,16 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d) return false; } - /* Try to avoid variable permutation instruction. */ - if (canonicalize_vector_int_perm (d, &nd) && expand_vec_perm_1 (&nd)) - return false; - if (d->testing_p) return true; + /* Try to avoid variable permutation instruction. */ + if (canonicalize_vector_int_perm (d, &nd) && expand_vec_perm_1 (&nd)) + { + emit_move_insn (d->target, gen_lowpart (d->vmode, nd.target)); + return true; + } + if (vmode == V8SImode) for (i = 0; i < 8; ++i) rperm[i] = GEN_INT ((d->perm[i * nelt / 8] * 8 / nelt) & 7); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 05b8dc8..a612558 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8401,10 +8401,14 @@ ix86_expand_prologue (void) || frame.stack_pointer_offset < CHECK_STACK_LIMIT)) { ix86_emit_save_regs_using_mov (frame.reg_save_offset); + cfun->machine->red_zone_used = true; int_registers_saved = true; } } + if (frame.red_zone_size != 0) + cfun->machine->red_zone_used = true; + if (stack_realign_fp) { int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT; @@ -15915,7 +15919,7 @@ ix86_output_indirect_jmp (rtx call_op) { /* We can't have red-zone since "call" in the indirect thunk pushes the return address onto stack, destroying red-zone. */ - if (ix86_red_zone_size != 0) + if (ix86_red_zone_used) gcc_unreachable (); ix86_output_indirect_branch (call_op, "%0", true); diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 919d0b2..182b327 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2663,6 +2663,9 @@ struct GTY(()) machine_function { invalid calls. */ BOOL_BITFIELD silent_p : 1; + /* True if red zone is used. */ + BOOL_BITFIELD red_zone_used : 1; + /* The largest alignment, in bytes, of stack slot actually used. */ unsigned int max_used_stack_alignment; @@ -2693,7 +2696,7 @@ extern GTY(()) tree ms_va_list_type_node; #define ix86_current_function_calls_tls_descriptor \ (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) #define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) -#define ix86_red_zone_size (cfun->machine->frame.red_zone_size) +#define ix86_red_zone_used (cfun->machine->red_zone_used) /* Control behavior of x86_file_start. */ #define X86_FILE_START_VERSION_DIRECTIVE false diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 7743c61e..6e4abf3 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -20491,7 +20491,7 @@ (clobber (mem:BLK (scratch)))])] "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) - && ix86_red_zone_size == 0" + && !ix86_red_zone_used" [(clobber (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (clobber (mem:BLK (scratch)))])]) @@ -20505,7 +20505,7 @@ (clobber (mem:BLK (scratch)))])] "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) - && ix86_red_zone_size == 0" + && !ix86_red_zone_used" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) @@ -20520,7 +20520,7 @@ (clobber (reg:CC FLAGS_REG))])] "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) - && ix86_red_zone_size == 0" + && !ix86_red_zone_used" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) @@ -20532,7 +20532,7 @@ (clobber (reg:CC FLAGS_REG))])] "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) - && ix86_red_zone_size == 0" + && !ix86_red_zone_used" [(clobber (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 8403a07..94296bc 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -22394,7 +22394,7 @@ (match_operand:V 2 "const0_operand")) (match_parallel 3 "movq_parallel" [(match_operand 4 "const_int_operand")])))] - "ix86_pre_reload_split ()" + "TARGET_SSE2 && ix86_pre_reload_split ()" "#" "&& 1" [(set (match_dup 0) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ee5ef36..43f2650 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,61 @@ +2021-06-13 Trevor Saunders <tbsaunde@tbsaunde.org> + + * constexpr.c (cxx_eval_call_expression): Iterate over vec<> + with range based for. + (cxx_eval_store_expression): Likewise. + (cxx_eval_loop_expr): Likewise. + * decl.c (wrapup_namespace_globals): Likewise. + (cp_finish_decl): Likewise. + (cxx_simulate_enum_decl): Likewise. + * parser.c (cp_parser_postfix_expression): Likewise. + +2021-06-12 Jason Merrill <jason@redhat.com> + + PR c++/101029 + * init.c (build_vec_init): Shortcut [0] case. + +2021-06-12 Jason Merrill <jason@redhat.com> + + * pt.c (lookup_template_class_1): Shortcut current_class_type. + +2021-06-11 Patrick Palka <ppalka@redhat.com> + + DR 1227 + PR c++/96560 + * pt.c (tsubst_arg_types): Rearrange so that we substitute into + TYPE_ARG_TYPES in forward order while short circuiting + appropriately. Adjust formatting. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/100974 + * cp-tree.h (struct saved_scope): Add consteval_if_p + member. Formatting fix for the discarded_stmt comment. + (in_consteval_if_p, IF_STMT_CONSTEVAL_P): Define. + * parser.c (cp_parser_lambda_expression): Temporarily disable + in_consteval_if_p when parsing lambda body. + (cp_parser_selection_statement): Parse consteval if. + * decl.c (struct named_label_entry): Add in_consteval_if member. + (level_for_consteval_if): New function. + (poplevel_named_label_1, check_previous_goto_1, check_goto): Handle + consteval if. + * constexpr.c (cxx_eval_builtin_function_call): Clarify in comment + why CP_BUILT_IN_IS_CONSTANT_EVALUATED needs to *non_constant_p + for !ctx->manifestly_const_eval. + (cxx_eval_conditional_expression): For IF_STMT_CONSTEVAL_P evaluate + condition as if it was __builtin_is_constant_evaluated call. + (potential_constant_expression_1): For IF_STMT_CONSTEVAL_P always + recurse on both branches. + * cp-gimplify.c (genericize_if_stmt): Genericize IF_STMT_CONSTEVAL_P + as the else branch. + * pt.c (tsubst_expr) <case IF_STMT>: Copy IF_STMT_CONSTEVAL_P. + Temporarily set in_consteval_if_p when recursing on + IF_STMT_CONSTEVAL_P then branch. + (tsubst_lambda_expr): Temporarily disable + in_consteval_if_p when instantiating lambda body. + * call.c (immediate_invocation_p): Return false when + in_consteval_if_p. + 2021-06-11 Marek Polacek <polacek@redhat.com> PR c++/100995 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d2f6ca8..9f03534 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8840,6 +8840,7 @@ immediate_invocation_p (tree fn, int nargs) || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl)) && (current_binding_level->kind != sk_function_parms || !current_binding_level->immediate_fn_ctx_p) + && !in_consteval_if_p /* As an exception, we defer std::source_location::current () invocations until genericization because LWG3396 mandates special behavior for it. */ diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 01b0c42..a26aead 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1315,7 +1315,10 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun, } /* For __builtin_is_constant_evaluated, defer it if not - ctx->manifestly_const_eval, otherwise fold it to true. */ + ctx->manifestly_const_eval (as sometimes we try to constant evaluate + without manifestly_const_eval even expressions or parts thereof which + will later be manifestly const_eval evaluated), otherwise fold it to + true. */ if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_CONSTANT_EVALUATED, BUILT_IN_FRONTEND)) { @@ -2790,9 +2793,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, /* Forget the saved values of the callee's SAVE_EXPRs and TARGET_EXPRs. */ - unsigned int i; - tree save_expr; - FOR_EACH_VEC_ELT (save_exprs, i, save_expr) + for (tree save_expr : save_exprs) ctx->global->values.remove (save_expr); /* Remove the parms/result from the values map. Is it worth @@ -3298,6 +3299,22 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t, /*lval*/false, non_constant_p, overflow_p); VERIFY_CONSTANT (val); + if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t)) + { + /* Evaluate the condition as if it was + if (__builtin_is_constant_evaluated ()), i.e. defer it if not + ctx->manifestly_const_eval (as sometimes we try to constant evaluate + without manifestly_const_eval even expressions or parts thereof which + will later be manifestly const_eval evaluated), otherwise fold it to + true. */ + if (ctx->manifestly_const_eval) + val = boolean_true_node; + else + { + *non_constant_p = true; + return t; + } + } /* Don't VERIFY_CONSTANT the other operands. */ if (integer_zerop (val)) val = TREE_OPERAND (t, 2); @@ -5476,9 +5493,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, semantics are not applied on an object under construction. They come into effect when the constructor for the most derived object ends." */ - tree elt; - unsigned int i; - FOR_EACH_VEC_ELT (*ctors, i, elt) + for (tree elt : *ctors) if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (const_object_being_modified), TREE_TYPE (elt))) { @@ -5586,12 +5601,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing CONSTRUCTORs, if any. */ - tree elt; - unsigned i; bool c = TREE_CONSTANT (init); bool s = TREE_SIDE_EFFECTS (init); if (!c || s || activated_union_member_p) - FOR_EACH_VEC_ELT (*ctors, i, elt) + for (tree elt : *ctors) { if (!c) TREE_CONSTANT (elt) = false; @@ -5909,9 +5922,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, } /* Forget saved values of SAVE_EXPRs and TARGET_EXPRs. */ - unsigned int i; - tree save_expr; - FOR_EACH_VEC_ELT (save_exprs, i, save_expr) + for (tree save_expr : save_exprs) ctx->global->values.remove (save_expr); save_exprs.truncate (0); @@ -5933,9 +5944,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t, && !*non_constant_p); /* Forget saved values of SAVE_EXPRs and TARGET_EXPRs. */ - unsigned int i; - tree save_expr; - FOR_EACH_VEC_ELT (save_exprs, i, save_expr) + for (tree save_expr : save_exprs) ctx->global->values.remove (save_expr); return NULL_TREE; @@ -8809,10 +8818,17 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, return false; if (!processing_template_decl) tmp = cxx_eval_outermost_constant_expr (tmp, true); - if (integer_zerop (tmp)) - return RECUR (TREE_OPERAND (t, 2), want_rval); - else if (TREE_CODE (tmp) == INTEGER_CST) - return RECUR (TREE_OPERAND (t, 1), want_rval); + /* potential_constant_expression* isn't told if it is called for + manifestly_const_eval or not, so for consteval if always + process both branches as if the condition is not a known + constant. */ + if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t)) + { + if (integer_zerop (tmp)) + return RECUR (TREE_OPERAND (t, 2), want_rval); + else if (TREE_CODE (tmp) == INTEGER_CST) + return RECUR (TREE_OPERAND (t, 1), want_rval); + } tmp = *jump_target; for (i = 1; i < 3; ++i) { diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 9079a5b..96d91b6 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -161,7 +161,13 @@ genericize_if_stmt (tree *stmt_p) if (!else_) else_ = build_empty_stmt (locus); - if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_)) + /* consteval if has been verified not to have the then_/else_ blocks + entered by gotos/case labels from elsewhere, and as then_ block + can contain unfolded immediate function calls, we have to discard + the then_ block regardless of whether else_ has side-effects or not. */ + if (IF_STMT_CONSTEVAL_P (stmt)) + stmt = else_; + else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_)) stmt = then_; else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_)) stmt = else_; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9ac8b52..36f99cc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -478,6 +478,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR) CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR) OVL_HIDDEN_P (in OVERLOAD) + IF_STMT_CONSTEVAL_P (in IF_STMT) SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT) LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR) IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR) @@ -1813,9 +1814,12 @@ struct GTY(()) saved_scope { BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD need_pop_function_context : 1; -/* Nonzero if we are parsing the discarded statement of a constexpr - if-statement. */ + /* Nonzero if we are parsing the discarded statement of a constexpr + if-statement. */ BOOL_BITFIELD discarded_stmt : 1; + /* Nonzero if we are parsing or instantiating the compound-statement + of consteval if statement. */ + BOOL_BITFIELD consteval_if_p : 1; int unevaluated_operand; int inhibit_evaluation_warnings; @@ -1879,6 +1883,7 @@ extern GTY(()) struct saved_scope *scope_chain; #define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation #define in_discarded_stmt scope_chain->discarded_stmt +#define in_consteval_if_p scope_chain->consteval_if_p #define current_ref_temp_count scope_chain->ref_temp_count @@ -5211,6 +5216,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2) #define IF_SCOPE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 3) #define IF_STMT_CONSTEXPR_P(NODE) TREE_LANG_FLAG_0 (IF_STMT_CHECK (NODE)) +#define IF_STMT_CONSTEVAL_P(NODE) TREE_LANG_FLAG_2 (IF_STMT_CHECK (NODE)) /* Like PACK_EXPANSION_EXTRA_ARGS, for constexpr if. IF_SCOPE is used while building an IF_STMT; IF_STMT_EXTRA_ARGS is used after it is complete. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cbf647d..f5596b6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -222,6 +222,7 @@ struct GTY((for_user)) named_label_entry { bool in_omp_scope; bool in_transaction_scope; bool in_constexpr_if; + bool in_consteval_if; }; #define named_labels cp_function_chain->x_named_labels @@ -491,6 +492,16 @@ level_for_constexpr_if (cp_binding_level *b) && IF_STMT_CONSTEXPR_P (b->this_entity)); } +/* True if B is the level for the condition of a consteval if. */ + +static bool +level_for_consteval_if (cp_binding_level *b) +{ + return (b->kind == sk_cond && b->this_entity + && TREE_CODE (b->this_entity) == IF_STMT + && IF_STMT_CONSTEVAL_P (b->this_entity)); +} + /* Update data for defined and undefined labels when leaving a scope. */ int @@ -530,6 +541,8 @@ poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl) case sk_block: if (level_for_constexpr_if (bl->level_chain)) ent->in_constexpr_if = true; + else if (level_for_consteval_if (bl->level_chain)) + ent->in_consteval_if = true; break; default: break; @@ -828,9 +841,7 @@ wrapup_namespace_globals () { if (vec<tree, va_gc> *statics = static_decls) { - tree decl; - unsigned int i; - FOR_EACH_VEC_ELT (*statics, i, decl) + for (tree decl : *statics) { if (warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL @@ -3391,6 +3402,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool complained = false; int identified = 0; bool saw_eh = false, saw_omp = false, saw_tm = false, saw_cxif = false; + bool saw_ceif = false; if (exited_omp) { @@ -3470,6 +3482,12 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, loc = EXPR_LOCATION (b->level_chain->this_entity); saw_cxif = true; } + else if (!saw_ceif && level_for_consteval_if (b->level_chain)) + { + inf = G_(" enters %<consteval if%> statement"); + loc = EXPR_LOCATION (b->level_chain->this_entity); + saw_ceif = true; + } break; default: @@ -3551,12 +3569,13 @@ check_goto (tree decl) unsigned ix; if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope - || ent->in_constexpr_if + || ent->in_constexpr_if || ent->in_consteval_if || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls)) { diagnostic_t diag_kind = DK_PERMERROR; if (ent->in_try_scope || ent->in_catch_scope || ent->in_constexpr_if - || ent->in_transaction_scope || ent->in_omp_scope) + || ent->in_consteval_if || ent->in_transaction_scope + || ent->in_omp_scope) diag_kind = DK_ERROR; complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl), &input_location, diag_kind); @@ -3602,6 +3621,8 @@ check_goto (tree decl) inform (input_location, " enters synchronized or atomic statement"); else if (ent->in_constexpr_if) inform (input_location, " enters %<constexpr if%> statement"); + else if (ent->in_consteval_if) + inform (input_location, " enters %<consteval if%> statement"); } if (ent->in_omp_scope) @@ -8237,8 +8258,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, reference, insert it in the statement-tree now. */ if (cleanups) { - unsigned i; tree t; - FOR_EACH_VEC_ELT (*cleanups, i, t) + for (tree t : *cleanups) push_cleanup (decl, t, false); release_tree_vector (cleanups); } @@ -16392,11 +16412,9 @@ cxx_simulate_enum_decl (location_t loc, const char *name, SET_OPAQUE_ENUM_P (enumtype, false); DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)) = loc; - string_int_pair *value; - unsigned int i; - FOR_EACH_VEC_ELT (values, i, value) - build_enumerator (get_identifier (value->first), - build_int_cst (integer_type_node, value->second), + for (const string_int_pair &value : values) + build_enumerator (get_identifier (value.first), + build_int_cst (integer_type_node, value.second), enumtype, NULL_TREE, loc); finish_enum_value_list (enumtype); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 1b161d5..622d6e9 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -4222,6 +4222,14 @@ build_vec_init (tree base, tree maxindex, tree init, else ptype = atype; + if (integer_all_onesp (maxindex)) + { + /* Shortcut zero element case to avoid unneeded constructor synthesis. */ + if (init && TREE_SIDE_EFFECTS (init)) + base = build2 (COMPOUND_EXPR, void_type_node, init, base); + return base; + } + /* The code we are generating looks like: ({ T* t1 = (T*) base; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d59a829..b5af387 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7299,8 +7299,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, case RID_BUILTIN_LAUNDER: { vec<tree, va_gc> *vec; - unsigned int i; - tree p; cp_lexer_consume_token (parser->lexer); vec = cp_parser_parenthesized_expression_list (parser, non_attr, @@ -7312,7 +7310,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, break; } - FOR_EACH_VEC_ELT (*vec, i, p) + for (tree p : *vec) mark_exp_read (p); switch (keyword) @@ -10902,6 +10900,11 @@ cp_parser_lambda_expression (cp_parser* parser) bool discarded = in_discarded_stmt; in_discarded_stmt = 0; + /* Similarly the body of a lambda in immediate function context is not + in immediate function context. */ + bool save_in_consteval_if_p = in_consteval_if_p; + in_consteval_if_p = false; + /* By virtue of defining a local class, a lambda expression has access to the private variables of enclosing classes. */ @@ -10932,6 +10935,7 @@ cp_parser_lambda_expression (cp_parser* parser) finish_struct (type, /*attributes=*/NULL_TREE); + in_consteval_if_p = save_in_consteval_if_p; in_discarded_stmt = discarded; parser->num_template_parameter_lists = saved_num_template_parameter_lists; @@ -12324,6 +12328,102 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, "%<if constexpr%> only available with " "%<-std=c++17%> or %<-std=gnu++17%>"); } + int ce = 0; + if (keyword == RID_IF && !cx) + { + if (cp_lexer_next_token_is_keyword (parser->lexer, + RID_CONSTEVAL)) + ce = 1; + else if (cp_lexer_next_token_is (parser->lexer, CPP_NOT) + && cp_lexer_nth_token_is_keyword (parser->lexer, 2, + RID_CONSTEVAL)) + { + ce = -1; + cp_lexer_consume_token (parser->lexer); + } + } + if (ce) + { + cp_token *tok = cp_lexer_consume_token (parser->lexer); + if (cxx_dialect < cxx23) + pedwarn (tok->location, OPT_Wc__23_extensions, + "%<if consteval%> only available with " + "%<-std=c++2b%> or %<-std=gnu++2b%>"); + + bool save_in_consteval_if_p = in_consteval_if_p; + statement = begin_if_stmt (); + IF_STMT_CONSTEVAL_P (statement) = true; + condition = finish_if_stmt_cond (boolean_false_node, statement); + + gcc_rich_location richloc = tok->location; + bool non_compound_stmt_p = false; + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)) + { + non_compound_stmt_p = true; + richloc.add_fixit_insert_after (tok->location, "{"); + } + + in_consteval_if_p |= ce > 0; + cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo); + + if (non_compound_stmt_p) + { + location_t before_loc + = cp_lexer_peek_token (parser->lexer)->location; + richloc.add_fixit_insert_before (before_loc, "}"); + error_at (&richloc, + "%<if consteval%> requires compound statement"); + non_compound_stmt_p = false; + } + + finish_then_clause (statement); + + /* If the next token is `else', parse the else-clause. */ + if (cp_lexer_next_token_is_keyword (parser->lexer, + RID_ELSE)) + { + cp_token *else_tok = cp_lexer_peek_token (parser->lexer); + gcc_rich_location else_richloc = else_tok->location; + guard_tinfo = get_token_indent_info (else_tok); + /* Consume the `else' keyword. */ + cp_lexer_consume_token (parser->lexer); + + begin_else_clause (statement); + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)) + { + non_compound_stmt_p = true; + else_richloc.add_fixit_insert_after (else_tok->location, + "{"); + } + + in_consteval_if_p = save_in_consteval_if_p | (ce < 0); + cp_parser_implicitly_scoped_statement (parser, NULL, + guard_tinfo); + + if (non_compound_stmt_p) + { + location_t before_loc + = cp_lexer_peek_token (parser->lexer)->location; + else_richloc.add_fixit_insert_before (before_loc, "}"); + error_at (&else_richloc, + "%<if consteval%> requires compound statement"); + } + + finish_else_clause (statement); + } + + in_consteval_if_p = save_in_consteval_if_p; + if (ce < 0) + { + std::swap (THEN_CLAUSE (statement), ELSE_CLAUSE (statement)); + if (THEN_CLAUSE (statement) == NULL_TREE) + THEN_CLAUSE (statement) = build_empty_stmt (tok->location); + } + + finish_if_stmt (statement); + return statement; + } /* Look for the `('. */ matching_parens parens; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d87382d..d4bb5cc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9833,6 +9833,13 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, /* From here on, we're only interested in the most general template. */ + /* Shortcut looking up the current class scope again. */ + if (current_class_type) + if (tree ti = CLASSTYPE_TEMPLATE_INFO (current_class_type)) + if (gen_tmpl == most_general_template (TI_TEMPLATE (ti)) + && comp_template_args (arglist, TI_ARGS (ti))) + return current_class_type; + /* Calculate the BOUND_ARGS. These will be the args that are actually tsubst'd into the definition to create the instantiation. */ @@ -14946,20 +14953,13 @@ tsubst_arg_types (tree arg_types, tsubst_flags_t complain, tree in_decl) { - tree remaining_arg_types; tree type = NULL_TREE; - int i = 1; + int len = 1; tree expanded_args = NULL_TREE; - tree default_arg; if (!arg_types || arg_types == void_list_node || arg_types == end) return arg_types; - remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types), - args, end, complain, in_decl); - if (remaining_arg_types == error_mark_node) - return error_mark_node; - if (PACK_EXPANSION_P (TREE_VALUE (arg_types))) { /* For a pack expansion, perform substitution on the @@ -14970,7 +14970,7 @@ tsubst_arg_types (tree arg_types, if (TREE_CODE (expanded_args) == TREE_VEC) /* So that we'll spin through the parameters, one by one. */ - i = TREE_VEC_LENGTH (expanded_args); + len = TREE_VEC_LENGTH (expanded_args); else { /* We only partially substituted into the parameter @@ -14979,59 +14979,71 @@ tsubst_arg_types (tree arg_types, expanded_args = NULL_TREE; } } + else + type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl); - while (i > 0) { - --i; - - if (expanded_args) - type = TREE_VEC_ELT (expanded_args, i); - else if (!type) - type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl); + /* Check if a substituted type is erroneous before substituting into + the rest of the chain. */ + for (int i = 0; i < len; i++) + { + if (expanded_args) + type = TREE_VEC_ELT (expanded_args, i); - if (type == error_mark_node) - return error_mark_node; - if (VOID_TYPE_P (type)) - { - if (complain & tf_error) - { - error ("invalid parameter type %qT", type); - if (in_decl) - error ("in declaration %q+D", in_decl); - } - return error_mark_node; + if (type == error_mark_node) + return error_mark_node; + if (VOID_TYPE_P (type)) + { + if (complain & tf_error) + { + error ("invalid parameter type %qT", type); + if (in_decl) + error ("in declaration %q+D", in_decl); + } + return error_mark_node; + } } - /* Do array-to-pointer, function-to-pointer conversion, and ignore - top-level qualifiers as required. */ - type = cv_unqualified (type_decays_to (type)); + /* We do not substitute into default arguments here. The standard + mandates that they be instantiated only when needed, which is + done in build_over_call. */ + tree default_arg = TREE_PURPOSE (arg_types); - /* We do not substitute into default arguments here. The standard - mandates that they be instantiated only when needed, which is - done in build_over_call. */ - default_arg = TREE_PURPOSE (arg_types); + /* Except that we do substitute default arguments under tsubst_lambda_expr, + since the new op() won't have any associated template arguments for us + to refer to later. */ + if (lambda_fn_in_template_p (in_decl)) + default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl, + false/*fn*/, false/*constexpr*/); - /* Except that we do substitute default arguments under tsubst_lambda_expr, - since the new op() won't have any associated template arguments for us - to refer to later. */ - if (lambda_fn_in_template_p (in_decl)) - default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl, - false/*fn*/, false/*constexpr*/); + tree remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types), + args, end, complain, in_decl); + if (remaining_arg_types == error_mark_node) + return error_mark_node; - if (default_arg && TREE_CODE (default_arg) == DEFERRED_PARSE) - { - /* We've instantiated a template before its default arguments - have been parsed. This can happen for a nested template - class, and is not an error unless we require the default - argument in a call of this function. */ - remaining_arg_types = - tree_cons (default_arg, type, remaining_arg_types); - vec_safe_push (DEFPARSE_INSTANTIATIONS (default_arg), - remaining_arg_types); - } - else - remaining_arg_types = - hash_tree_cons (default_arg, type, remaining_arg_types); - } + for (int i = len-1; i >= 0; i--) + { + if (expanded_args) + type = TREE_VEC_ELT (expanded_args, i); + + /* Do array-to-pointer, function-to-pointer conversion, and ignore + top-level qualifiers as required. */ + type = cv_unqualified (type_decays_to (type)); + + if (default_arg && TREE_CODE (default_arg) == DEFERRED_PARSE) + { + /* We've instantiated a template before its default arguments + have been parsed. This can happen for a nested template + class, and is not an error unless we require the default + argument in a call of this function. */ + remaining_arg_types + = tree_cons (default_arg, type, remaining_arg_types); + vec_safe_push (DEFPARSE_INSTANTIATIONS (default_arg), + remaining_arg_types); + } + else + remaining_arg_types + = hash_tree_cons (default_arg, type, remaining_arg_types); + } return remaining_arg_types; } @@ -18413,6 +18425,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case IF_STMT: stmt = begin_if_stmt (); IF_STMT_CONSTEXPR_P (stmt) = IF_STMT_CONSTEXPR_P (t); + IF_STMT_CONSTEVAL_P (stmt) = IF_STMT_CONSTEVAL_P (t); if (IF_STMT_CONSTEXPR_P (t)) args = add_extra_args (IF_STMT_EXTRA_ARGS (t), args); tmp = RECUR (IF_COND (t)); @@ -18433,6 +18446,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, } if (IF_STMT_CONSTEXPR_P (t) && integer_zerop (tmp)) /* Don't instantiate the THEN_CLAUSE. */; + else if (IF_STMT_CONSTEVAL_P (t)) + { + bool save_in_consteval_if_p = in_consteval_if_p; + in_consteval_if_p = true; + RECUR (THEN_CLAUSE (t)); + in_consteval_if_p = save_in_consteval_if_p; + } else { tree folded = fold_non_dependent_expr (tmp, complain); @@ -19385,6 +19405,9 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) local_specialization_stack s (lss_copy); + bool save_in_consteval_if_p = in_consteval_if_p; + in_consteval_if_p = false; + tree body = start_lambda_function (fn, r); /* Now record them for lookup_init_capture_pack. */ @@ -19425,6 +19448,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) finish_lambda_function (body); + in_consteval_if_p = save_in_consteval_if_p; + if (nested) pop_function_context (); else diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 9ba56be..eb17034 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,8 @@ +2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/100999 + * dmd/MERGE: Merge upstream dmd 7a3808254. + 2021-06-10 Iain Buclaw <ibuclaw@gdcproject.org> PR d/100967 diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index a617f28..d20785d 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -4a4e46a6f304a667e0c05d4455706ec2056ffddc +7a3808254878df8cb70a055bea58afc79187b778 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/cond.c b/gcc/d/dmd/cond.c index 6f112ad..6c7dc9e 100644 --- a/gcc/d/dmd/cond.c +++ b/gcc/d/dmd/cond.c @@ -112,6 +112,7 @@ static void lowerArrayAggregate(StaticForeach *sfe, Scope *sc) sfe->aggrfe->aggr = new TupleExp(aggr->loc, es); sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc); sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue); + sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret(); } else { @@ -198,7 +199,8 @@ static TypeStruct *createTupleType(Loc loc, Expressions *e) Type *ty = new TypeTypeof(loc, new TupleExp(loc, e)); sdecl->members->push(new VarDeclaration(loc, ty, fid, NULL)); TypeStruct *r = (TypeStruct *)sdecl->type; - r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file + if (global.params.useTypeInfo && Type::dtypeinfo) + r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file return r; } @@ -312,15 +314,25 @@ static void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc) Identifier *idres = Identifier::generateId("__res"); VarDeclaration *vard = new VarDeclaration(aloc, aty, idres, NULL); Statements *s2 = new Statements(); - s2->push(new ExpStatement(aloc, vard)); - Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); - s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass))); - s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); + + // Run 'typeof' gagged to avoid duplicate errors and if it fails just create + // an empty foreach to expose them. + unsigned olderrors = global.startGagging(); + ety = typeSemantic(ety, aloc, sc); + if (global.endGagging(olderrors)) + s2->push(createForeach(sfe, aloc, pparams[1], NULL)); + else + { + s2->push(new ExpStatement(aloc, vard)); + Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); + s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass))); + s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); + } Expression *aggr; Type *indexty; - if (sfe->rangefe && (indexty = typeSemantic(ety, aloc, sc))->isintegral()) + if (sfe->rangefe && (indexty = ety)->isintegral()) { sfe->rangefe->lwr->type = indexty; sfe->rangefe->upr->type = indexty; @@ -384,11 +396,6 @@ void staticForeachPrepare(StaticForeach *sfe, Scope *sc) sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc); sc = sc->endCTFE(); sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue); - Type *tab = sfe->aggrfe->aggr->type->toBasetype(); - if (tab->ty != Ttuple) - { - sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret(); - } } if (sfe->aggrfe && sfe->aggrfe->aggr->type->toBasetype()->ty == Terror) diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c index 5e71f3b..ab9d88c 100644 --- a/gcc/d/dmd/dinterpret.c +++ b/gcc/d/dmd/dinterpret.c @@ -643,7 +643,16 @@ Expression *ctfeInterpret(Expression *e) case TOKfloat64: case TOKcomplex80: case TOKnull: + case TOKvoid: case TOKstring: + case TOKthis: + case TOKsuper: + case TOKtype: + case TOKtypeid: + case TOKtemplate: // non-eponymous template/instance + case TOKscope: // ditto + case TOKdottd: // ditto, e.e1 doesn't matter here + case TOKdot: // ditto if (e->type->ty == Terror) return new ErrorExp(); /* fall through */ diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c index 88f13e9..153819a 100644 --- a/gcc/d/dmd/expression.c +++ b/gcc/d/dmd/expression.c @@ -1044,7 +1044,7 @@ bool Expression::checkPostblit(Scope *sc, Type *t) t = t->baseElemOf(); if (t->ty == Tstruct) { - if (global.params.useTypeInfo) + if (global.params.useTypeInfo && Type::dtypeinfo) { // Bugzilla 11395: Require TypeInfo generation for array concatenation semanticTypeInfo(sc, t); diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index 4a37d0f..5ae5fe6 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -1082,11 +1082,6 @@ static Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 if (checkUnsafeAccess(sc, e1, true, true)) return new ErrorExp(); } - else if (e1->op == TOKdot) - { - e1->error("expression has no value"); - return new ErrorExp(); - } else if (e1->op == TOKcall) { CallExp *ce = (CallExp *)e1; @@ -4513,11 +4508,18 @@ public: void visit(DotTemplateExp *e) { + if (e->type) + { + result = e; + return; + } if (Expression *ex = unaSemantic(e, sc)) { result = ex; return; } + // 'void' like TemplateExp + e->type = Type::tvoid; result = e; } diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c index 491d9c9..24e534e 100644 --- a/gcc/d/dmd/statementsem.c +++ b/gcc/d/dmd/statementsem.c @@ -563,9 +563,6 @@ public: else { e = resolveProperties(sc, e); - type = e->type; - if (paramtype) - type = paramtype; Initializer *ie = new ExpInitializer(Loc(), e); VarDeclaration *v = new VarDeclaration(loc, type, ident, ie); if (storageClass & STCref) @@ -646,22 +643,23 @@ public: } } p->type = typeSemantic(p->type, loc, sc); - TY keyty = p->type->ty; - if (keyty != Tint32 && keyty != Tuns32) + + if (!p->type->isintegral()) { - if (global.params.isLP64) - { - if (keyty != Tint64 && keyty != Tuns64) - { - fs->error("foreach: key type must be int or uint, long or ulong, not %s", p->type->toChars()); - return false; - } - } - else - { - fs->error("foreach: key type must be int or uint, not %s", p->type->toChars()); - return false; - } + fs->error("foreach: key cannot be of non-integral type `%s`", + p->type->toChars()); + return false; + } + + unsigned length = te ? te->exps->length : tuple->arguments->length; + IntRange dimrange = IntRange(SignExtendedNumber(length)).cast(Type::tsize_t); + // https://issues.dlang.org/show_bug.cgi?id=12504 + dimrange.imax = SignExtendedNumber(dimrange.imax.value-1); + if (!IntRange::fromType(p->type).contains(dimrange)) + { + fs->error("index type `%s` cannot cover index range 0..%llu", + p->type->toChars(), (ulonglong)length); + return false; } Initializer *ie = new ExpInitializer(Loc(), new IntegerExp(k)); VarDeclaration *var = new VarDeclaration(loc, p->type, p->ident, ie); @@ -1073,6 +1071,8 @@ public: { TypeSArray *ta = (TypeSArray *)tab; IntRange dimrange = getIntRange(ta->dim); + // https://issues.dlang.org/show_bug.cgi?id=12504 + dimrange.imax = SignExtendedNumber(dimrange.imax.value-1); if (!IntRange::fromType(var->type).contains(dimrange)) { fs->error("index type `%s` cannot cover index range 0..%llu", p->type->toChars(), ta->dim->toInteger()); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 408979b..8fc66d6 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7516,9 +7516,9 @@ Not all targets support this attribute. @item unused @cindex @code{unused} variable attribute -This attribute, attached to a variable, means that the variable is meant -to be possibly unused. GCC does not produce a warning for this -variable. +This attribute, attached to a variable or structure field, means that +the variable or field is meant to be possibly unused. GCC does not +produce a warning for this variable or field. @item used @cindex @code{used} variable attribute diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 6e5835a..95673d2 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7127,11 +7127,13 @@ fold_binary_op_with_conditional_arg (location_t loc, } -/* Subroutine of fold() that checks for the addition of +/- 0.0. +/* Subroutine of fold() that checks for the addition of ARG +/- 0.0. - If !NEGATE, return true if ADDEND is +/-0.0 and, for all X of type - TYPE, X + ADDEND is the same as X. If NEGATE, return true if X - - ADDEND is the same as X. + If !NEGATE, return true if ZERO_ARG is +/-0.0 and, for all ARG of + type TYPE, ARG + ZERO_ARG is the same as ARG. If NEGATE, return true + if ARG - ZERO_ARG is the same as X. + + If ARG is NULL, check for any value of type TYPE. X + 0 and X - 0 both give X when X is NaN, infinite, or nonzero and finite. The problematic cases are when X is zero, and its mode @@ -7140,13 +7142,14 @@ fold_binary_op_with_conditional_arg (location_t loc, modes, X + 0 is not the same as X because -0 + 0 is 0. */ bool -fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) +fold_real_zero_addition_p (const_tree type, const_tree arg, + const_tree zero_arg, int negate) { - if (!real_zerop (addend)) + if (!real_zerop (zero_arg)) return false; /* Don't allow the fold with -fsignaling-nans. */ - if (HONOR_SNANS (type)) + if (arg ? tree_expr_maybe_signaling_nan_p (arg) : HONOR_SNANS (type)) return false; /* Allow the fold if zeros aren't signed, or their sign isn't important. */ @@ -7158,19 +7161,20 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) return false; /* In a vector or complex, we would need to check the sign of all zeros. */ - if (TREE_CODE (addend) == VECTOR_CST) - addend = uniform_vector_p (addend); - if (!addend || TREE_CODE (addend) != REAL_CST) + if (TREE_CODE (zero_arg) == VECTOR_CST) + zero_arg = uniform_vector_p (zero_arg); + if (!zero_arg || TREE_CODE (zero_arg) != REAL_CST) return false; /* Treat x + -0 as x - 0 and x - -0 as x + 0. */ - if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend))) + if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (zero_arg))) negate = !negate; /* The mode has signed zeros, and we have to honor their sign. - In this situation, there is only one case we can return true for. - X - 0 is the same as X with default rounding. */ - return negate; + In this situation, there are only two cases we can return true for. + (i) X - 0 is the same as X with default rounding. + (ii) X + 0 is X when X can't possibly be -0.0. */ + return negate || (arg && !tree_expr_maybe_real_minus_zero_p (arg)); } /* Subroutine of match.pd that optimizes comparisons of a division by @@ -14375,6 +14379,44 @@ tree_expr_maybe_nan_p (const_tree x) } } +/* Return true if expression X could evaluate to -0.0. + This function returns true if uncertain. */ + +bool +tree_expr_maybe_real_minus_zero_p (const_tree x) +{ + if (!HONOR_SIGNED_ZEROS (x)) + return false; + switch (TREE_CODE (x)) + { + case REAL_CST: + return REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (x)); + case INTEGER_CST: + case FLOAT_EXPR: + case ABS_EXPR: + return false; + case NON_LVALUE_EXPR: + case SAVE_EXPR: + return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 0)); + case COND_EXPR: + return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 1)) + || tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 2)); + case CALL_EXPR: + switch (get_call_combined_fn (x)) + { + CASE_CFN_FABS: + return false; + default: + break; + } + default: + break; + } + /* Ideally !(tree_expr_nonzero_p (X) || tree_expr_nonnegative_p (X)) + * but currently those predicates require tree and not const_tree. */ + return true; +} + #define tree_expr_nonnegative_warnv_p(X, Y) \ _Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0 diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 2a74287..7bac84b 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -164,7 +164,8 @@ extern bool integer_valued_real_call_p (combined_fn, tree, tree, int); extern bool integer_valued_real_single_p (tree, int); extern bool integer_valued_real_p (tree, int = 0); -extern bool fold_real_zero_addition_p (const_tree, const_tree, int); +extern bool fold_real_zero_addition_p (const_tree, const_tree, const_tree, + int); extern tree combine_comparisons (location_t, enum tree_code, enum tree_code, enum tree_code, tree, tree, tree); extern void debug_fold_checksum (const_tree); @@ -195,6 +196,7 @@ extern bool tree_expr_signaling_nan_p (const_tree); extern bool tree_expr_maybe_signaling_nan_p (const_tree); extern bool tree_expr_nan_p (const_tree); extern bool tree_expr_maybe_nan_p (const_tree); +extern bool tree_expr_maybe_real_minus_zero_p (const_tree); extern tree make_range (tree, int *, tree *, tree *, bool *); extern tree make_range_step (location_t, enum tree_code, tree, tree, tree, tree *, tree *, int *, bool *); @@ -5838,10 +5838,7 @@ compile_input_file_p (struct infile *infile) static void do_specs_vec (vec<char_p> vec) { - unsigned ix; - char *opt; - - FOR_EACH_VEC_ELT (vec, ix, opt) + for (char *opt : vec) { do_spec_1 (opt, 1, NULL); /* Make each accumulated option a separate argument. */ @@ -6436,8 +6433,6 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { const char *p1 = p; char *string; - char *opt; - unsigned ix; /* Skip past the option value and make a copy. */ if (*p != '{') @@ -6448,7 +6443,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) string = save_string (p1 + 1, p - p1 - 2); /* See if we already recorded this option. */ - FOR_EACH_VEC_ELT (linker_options, ix, opt) + for (const char *opt : linker_options) if (! strcmp (string, opt)) { free (string); @@ -8316,9 +8311,7 @@ driver::set_up_specs () const && do_spec_2 (startfile_prefix_spec, NULL) == 0 && do_spec_1 (" ", 0, NULL) == 0) { - const char *arg; - int ndx; - FOR_EACH_VEC_ELT (argbuf, ndx, arg) + for (const char *arg : argbuf) add_sysrooted_prefix (&startfile_prefixes, arg, "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1); } diff --git a/gcc/gimple-loop-jam.c b/gcc/gimple-loop-jam.c index 69dbaeb..4842f0d 100644 --- a/gcc/gimple-loop-jam.c +++ b/gcc/gimple-loop-jam.c @@ -365,11 +365,9 @@ static bool any_access_function_variant_p (const struct data_reference *a, const class loop *loop_nest) { - unsigned int i; vec<tree> fns = DR_ACCESS_FNS (a); - tree t; - FOR_EACH_VEC_ELT (fns, i, t) + for (tree t : fns) if (!evolution_function_is_invariant_p (t, loop_nest->num)) return true; diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index eb8320a..61de501 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -158,7 +158,7 @@ pointer_equiv_analyzer::pointer_equiv_analyzer (gimple_ranger *r) pointer_equiv_analyzer::~pointer_equiv_analyzer () { - delete m_global_points; + delete[] m_global_points; } // Set the global pointer equivalency for SSA to POINTEE. diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 123c92d..6329479 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -2541,8 +2541,6 @@ compatible_load_p (merged_store_group *merged_store, clobbers those loads. */ gimple *first = merged_store->first_stmt; gimple *last = merged_store->last_stmt; - unsigned int i; - store_immediate_info *infoc; /* The stores are sorted by increasing store bitpos, so if info->stmt store comes before the so far first load, we'll be changing merged_store->first_stmt. In that case we need to give up if @@ -2550,7 +2548,7 @@ compatible_load_p (merged_store_group *merged_store, range. */ if (info->order < merged_store->first_order) { - FOR_EACH_VEC_ELT (merged_store->stores, i, infoc) + for (store_immediate_info *infoc : merged_store->stores) if (stmts_may_clobber_ref_p (info->stmt, first, infoc->ops[idx].val)) return false; first = info->stmt; @@ -2560,7 +2558,7 @@ compatible_load_p (merged_store_group *merged_store, processed loads. */ else if (info->order > merged_store->last_order) { - FOR_EACH_VEC_ELT (merged_store->stores, i, infoc) + for (store_immediate_info *infoc : merged_store->stores) if (stmts_may_clobber_ref_p (last, info->stmt, infoc->ops[idx].val)) return false; last = info->stmt; @@ -2884,9 +2882,7 @@ imm_store_chain_info::try_coalesce_bswap (merged_store_group *merged_store, gather_bswap_load_refs (&refs, gimple_assign_rhs1 (m_store_info[i]->stmt)); - unsigned int i; - tree ref; - FOR_EACH_VEC_ELT (refs, i, ref) + for (tree ref : refs) if (stmts_may_clobber_ref_p (first_stmt, last_stmt, ref)) return false; n.vuse = NULL_TREE; @@ -3199,9 +3195,7 @@ imm_store_chain_info::coalesce_immediate_stores () } else if (infof->rhs_code == MEM_REF && info->rhs_code != MEM_REF) { - store_immediate_info *infoj; - unsigned int j; - FOR_EACH_VEC_ELT (merged_store->stores, j, infoj) + for (store_immediate_info *infoj : merged_store->stores) { infoj->rhs_code = BIT_INSERT_EXPR; infoj->ops[0].val = gimple_assign_rhs1 (infoj->stmt); @@ -3323,10 +3317,7 @@ get_alias_type_for_stmts (vec<gimple *> &stmts, bool is_load, static location_t get_location_for_stmts (vec<gimple *> &stmts) { - gimple *stmt; - unsigned int i; - - FOR_EACH_VEC_ELT (stmts, i, stmt) + for (gimple *stmt : stmts) if (gimple_has_location (stmt)) return gimple_location (stmt); diff --git a/gcc/graphite-poly.c b/gcc/graphite-poly.c index 2e31b27..1dfc28e 100644 --- a/gcc/graphite-poly.c +++ b/gcc/graphite-poly.c @@ -63,10 +63,7 @@ print_iteration_domain (FILE *file, poly_bb_p pbb) void print_iteration_domains (FILE *file, scop_p scop) { - int i; - poly_bb_p pbb; - - FOR_EACH_VEC_ELT (scop->pbbs, i, pbb) + for (poly_bb_p pbb : scop->pbbs) print_iteration_domain (file, pbb); } @@ -150,16 +147,13 @@ new_poly_bb (scop_p scop, gimple_poly_bb_p black_box) static void free_poly_bb (poly_bb_p pbb) { - int i; - poly_dr_p pdr; - isl_set_free (pbb->domain); pbb->domain = NULL; isl_set_free (pbb->iterators); pbb->iterators = NULL; if (PBB_DRS (pbb).exists ()) - FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr) + for (poly_dr_p pdr : PBB_DRS (pbb)) free_poly_dr (pdr); PBB_DRS (pbb).release (); @@ -243,10 +237,7 @@ free_gimple_poly_bb (gimple_poly_bb_p gbb) static void remove_gbbs_in_scop (scop_p scop) { - int i; - poly_bb_p pbb; - - FOR_EACH_VEC_ELT (scop->pbbs, i, pbb) + for (poly_bb_p pbb : scop->pbbs) free_gimple_poly_bb (PBB_BLACK_BOX (pbb)); } @@ -273,13 +264,10 @@ new_scop (edge entry, edge exit) void free_scop (scop_p scop) { - int i; - poly_bb_p pbb; - remove_gbbs_in_scop (scop); free_sese_info (scop->scop_info); - FOR_EACH_VEC_ELT (scop->pbbs, i, pbb) + for (poly_bb_p pbb : scop->pbbs) free_poly_bb (pbb); scop->pbbs.release (); @@ -309,8 +297,6 @@ print_pbb_domain (FILE *file, poly_bb_p pbb) static void dump_gbb_cases (FILE *file, gimple_poly_bb_p gbb) { - int i; - gimple *stmt; vec<gimple *> cases; if (!gbb) @@ -322,7 +308,7 @@ dump_gbb_cases (FILE *file, gimple_poly_bb_p gbb) fprintf (file, "cases bb_%d (\n", GBB_BB (gbb)->index); - FOR_EACH_VEC_ELT (cases, i, stmt) + for (gimple *stmt : cases) print_gimple_stmt (file, stmt, 0); fprintf (file, ")\n"); @@ -333,8 +319,6 @@ dump_gbb_cases (FILE *file, gimple_poly_bb_p gbb) static void dump_gbb_conditions (FILE *file, gimple_poly_bb_p gbb) { - int i; - gimple *stmt; vec<gimple *> conditions; if (!gbb) @@ -346,7 +330,7 @@ dump_gbb_conditions (FILE *file, gimple_poly_bb_p gbb) fprintf (file, "conditions bb_%d (\n", GBB_BB (gbb)->index); - FOR_EACH_VEC_ELT (conditions, i, stmt) + for (gimple *stmt : conditions) print_gimple_stmt (file, stmt, 0); fprintf (file, ")\n"); @@ -357,8 +341,6 @@ dump_gbb_conditions (FILE *file, gimple_poly_bb_p gbb) void print_pdrs (FILE *file, poly_bb_p pbb) { - int i; - poly_dr_p pdr; int nb_reads = 0; int nb_writes = 0; @@ -367,7 +349,7 @@ print_pdrs (FILE *file, poly_bb_p pbb) fprintf (file, "Data references (\n"); - FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr) + for (poly_dr_p pdr : PBB_DRS (pbb)) if (PDR_TYPE (pdr) == PDR_READ) nb_reads++; else @@ -375,13 +357,13 @@ print_pdrs (FILE *file, poly_bb_p pbb) fprintf (file, "Read data references (\n"); - FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr) + for (poly_dr_p pdr : PBB_DRS (pbb)) if (PDR_TYPE (pdr) == PDR_READ) print_pdr (file, pdr); fprintf (file, ")\n"); fprintf (file, "Write data references (\n"); - FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr) + for (poly_dr_p pdr : PBB_DRS (pbb)) if (PDR_TYPE (pdr) != PDR_READ) print_pdr (file, pdr); fprintf (file, ")\n"); @@ -459,9 +441,6 @@ print_scop_context (FILE *file, scop_p scop) void print_scop (FILE *file, scop_p scop) { - int i; - poly_bb_p pbb; - fprintf (file, "SCoP (\n"); print_scop_context (file, scop); print_scop_params (file, scop); @@ -469,7 +448,7 @@ print_scop (FILE *file, scop_p scop) fprintf (file, "Number of statements: "); fprintf (file, "%d\n", scop->pbbs.length ()); - FOR_EACH_VEC_ELT (scop->pbbs, i, pbb) + for (poly_bb_p pbb : scop->pbbs) print_pbb (file, pbb); fprintf (file, ")\n"); diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d086ce8..017944f 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3889,11 +3889,9 @@ cond_move_process_if_block (struct noce_if_info *if_info) rtx_insn *jump = if_info->jump; rtx cond = if_info->cond; rtx_insn *seq, *loc_insn; - rtx reg; int c; vec<rtx> then_regs = vNULL; vec<rtx> else_regs = vNULL; - unsigned int i; int success_p = FALSE; int limit = param_max_rtl_if_conversion_insns; @@ -3915,7 +3913,7 @@ cond_move_process_if_block (struct noce_if_info *if_info) source register does not change after the assignment. Also count the number of registers set in only one of the blocks. */ c = 0; - FOR_EACH_VEC_ELT (then_regs, i, reg) + for (rtx reg : then_regs) { rtx *then_slot = then_vals.get (reg); rtx *else_slot = else_vals.get (reg); @@ -3934,7 +3932,7 @@ cond_move_process_if_block (struct noce_if_info *if_info) } /* Finish off c for MAX_CONDITIONAL_EXECUTE. */ - FOR_EACH_VEC_ELT (else_regs, i, reg) + for (rtx reg : else_regs) { gcc_checking_assert (else_vals.get (reg)); if (!then_vals.get (reg)) diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 34eb8b1..2107826 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -1731,14 +1731,9 @@ decompose_multiword_subregs (bool decompose_copies) } } - { - unsigned int i; - bitmap b; - - FOR_EACH_VEC_ELT (reg_copy_graph, i, b) - if (b) - BITMAP_FREE (b); - } + for (bitmap b : reg_copy_graph) + if (b) + BITMAP_FREE (b); reg_copy_graph.release (); diff --git a/gcc/match.pd b/gcc/match.pd index bf22bc3..39fb57e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -152,13 +152,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) Likewise if the operands are reversed. */ (simplify (plus:c @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 0)) + (if (fold_real_zero_addition_p (type, @0, @1, 0)) (non_lvalue @0))) /* See if ARG1 is zero and X - ARG1 reduces to X. */ (simplify (minus @0 real_zerop@1) - (if (fold_real_zero_addition_p (type, @1, 1)) + (if (fold_real_zero_addition_p (type, @0, @1, 1)) (non_lvalue @0))) /* Even if the fold_real_zero_addition_p can't simplify X + 0.0 @@ -190,7 +190,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) is volatile. */ (simplify (minus @0 @0) - (if (!FLOAT_TYPE_P (type) || !HONOR_NANS (type)) + (if (!FLOAT_TYPE_P (type) || !tree_expr_maybe_nan_p (@0)) { build_zero_cst (type); })) (simplify (pointer_diff @@0 @0) @@ -206,14 +206,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) negative value by 0 gives -0, not +0. */ (simplify (mult @0 real_zerop@1) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@0) + && !tree_expr_maybe_real_minus_zero_p (@1)) @1)) /* In IEEE floating point, x*1 is not equivalent to x for snans. Likewise for complex arithmetic with signed zeros. */ (simplify (mult @0 real_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (non_lvalue @0))) @@ -221,7 +223,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform x * -1.0 into -x. */ (simplify (mult @0 real_minus_onep) - (if (!HONOR_SNANS (type) + (if (!tree_expr_maybe_signaling_nan_p (@0) && (!HONOR_SIGNED_ZEROS (type) || !COMPLEX_FLOAT_TYPE_P (type))) (negate @0))) @@ -259,7 +261,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? 1.0 : -1.0) into -abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_onep@1 real_minus_onep)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outp (abs @0)))) /* Transform X * (X > 0.0 ? -1.0 : 1.0) into -abs(X). */ /* Transform X * (X >= 0.0 ? -1.0 : 1.0) into -abs(X). */ @@ -267,19 +269,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Transform X * (X <= 0.0 ? -1.0 : 1.0) into abs(X). */ (simplify (mult:c @0 (cond (cmp @0 real_zerop) real_minus_onep real_onep@1)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (outn (abs @0))))) /* Transform X * copysign (1.0, X) into abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep @0)) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (abs @0))) /* Transform X * copysign (1.0, -X) into -abs(X). */ (simplify (mult:c @0 (COPYSIGN_ALL real_onep (negate @0))) - (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)) + (if (!tree_expr_maybe_nan_p (@0) && !HONOR_SIGNED_ZEROS (type)) (negate (abs @0)))) /* Transform copysign (CST, X) into copysign (ABS(CST), X). */ @@ -444,13 +446,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* In IEEE floating point, x/1 is not equivalent to x for snans. */ (simplify (rdiv @0 real_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (non_lvalue @0))) /* In IEEE floating point, x/-1 is not equivalent to -x for snans. */ (simplify (rdiv @0 real_minus_onep) - (if (!HONOR_SNANS (type)) + (if (!tree_expr_maybe_signaling_nan_p (@0)) (negate @0))) (if (flag_reciprocal_math) @@ -3543,7 +3545,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (-ARG1 + ARG0) reduces to -ARG1. */ (simplify (minus real_zerop@0 @1) - (if (fold_real_zero_addition_p (type, @0, 0)) + (if (fold_real_zero_addition_p (type, @1, @0, 0)) (negate @1))) /* Transform x * -1 into -x. */ diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 44f6295..5ca7e8c 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -1404,12 +1404,9 @@ pass_cprop_hardreg::execute (function *fun) changed anything though. */ if (!worklist.is_empty ()) { - unsigned int i; - int index; - any_debug_changes = false; bitmap_clear (visited); - FOR_EACH_VEC_ELT (worklist, i, index) + for (int index : worklist) { bb = BASIC_BLOCK_FOR_FN (fun, index); cprop_hardreg_bb (bb, all_vd, visited); diff --git a/gcc/sanopt.c b/gcc/sanopt.c index 41f20c3..18829ff 100644 --- a/gcc/sanopt.c +++ b/gcc/sanopt.c @@ -1246,9 +1246,7 @@ sanitize_rewrite_addressable_params (function *fun) /* Unset value expr for parameters for which we created debug bind expressions. */ - unsigned i; - tree arg; - FOR_EACH_VEC_ELT (clear_value_expr_list, i, arg) + for (tree arg : clear_value_expr_list) { DECL_HAS_VALUE_EXPR_P (arg) = 0; SET_DECL_VALUE_EXPR (arg, NULL_TREE); diff --git a/gcc/sel-sched-dump.c b/gcc/sel-sched-dump.c index 3d26483..993a16a 100644 --- a/gcc/sel-sched-dump.c +++ b/gcc/sel-sched-dump.c @@ -528,10 +528,7 @@ dump_flist (flist_t l) void dump_insn_vector (rtx_vec_t succs) { - int i; - rtx_insn *succ; - - FOR_EACH_VEC_ELT (succs, i, succ) + for (rtx_insn *succ : succs) if (succ) dump_insn (succ); else diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 04423bb..c82101c 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2294,6 +2294,53 @@ comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode) gcc_unreachable (); } } + +/* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right + false/true value of comparison with MODE where comparison operands + have CMP_MODE. */ + +static rtx +relational_result (machine_mode mode, machine_mode cmp_mode, rtx res) +{ + if (SCALAR_FLOAT_MODE_P (mode)) + { + if (res == const0_rtx) + return CONST0_RTX (mode); +#ifdef FLOAT_STORE_FLAG_VALUE + REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode); + return const_double_from_real_value (val, mode); +#else + return NULL_RTX; +#endif + } + if (VECTOR_MODE_P (mode)) + { + if (res == const0_rtx) + return CONST0_RTX (mode); +#ifdef VECTOR_STORE_FLAG_VALUE + rtx val = VECTOR_STORE_FLAG_VALUE (mode); + if (val == NULL_RTX) + return NULL_RTX; + if (val == const1_rtx) + return CONST1_RTX (mode); + + return gen_const_vec_duplicate (mode, val); +#else + return NULL_RTX; +#endif + } + /* For vector comparison with scalar int result, it is unknown + if the target means here a comparison into an integral bitmask, + or comparison where all comparisons true mean const_true_rtx + whole result, or where any comparisons true mean const_true_rtx + whole result. For const0_rtx all the cases are the same. */ + if (VECTOR_MODE_P (cmp_mode) + && SCALAR_INT_MODE_P (mode) + && res == const_true_rtx) + return NULL_RTX; + + return res; +} /* Simplify a logical operation CODE with result mode MODE, operating on OP0 and OP1, which should be both relational operations. Return 0 if no such @@ -2329,7 +2376,7 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, int mask = mask0 | mask1; if (mask == 15) - return const_true_rtx; + return relational_result (mode, GET_MODE (op0), const_true_rtx); code = mask_to_comparison (mask); @@ -5315,51 +5362,7 @@ simplify_context::simplify_relational_operation (rtx_code code, tem = simplify_const_relational_operation (code, cmp_mode, op0, op1); if (tem) - { - if (SCALAR_FLOAT_MODE_P (mode)) - { - if (tem == const0_rtx) - return CONST0_RTX (mode); -#ifdef FLOAT_STORE_FLAG_VALUE - { - REAL_VALUE_TYPE val; - val = FLOAT_STORE_FLAG_VALUE (mode); - return const_double_from_real_value (val, mode); - } -#else - return NULL_RTX; -#endif - } - if (VECTOR_MODE_P (mode)) - { - if (tem == const0_rtx) - return CONST0_RTX (mode); -#ifdef VECTOR_STORE_FLAG_VALUE - { - rtx val = VECTOR_STORE_FLAG_VALUE (mode); - if (val == NULL_RTX) - return NULL_RTX; - if (val == const1_rtx) - return CONST1_RTX (mode); - - return gen_const_vec_duplicate (mode, val); - } -#else - return NULL_RTX; -#endif - } - /* For vector comparison with scalar int result, it is unknown - if the target means here a comparison into an integral bitmask, - or comparison where all comparisons true mean const_true_rtx - whole result, or where any comparisons true mean const_true_rtx - whole result. For const0_rtx all the cases are the same. */ - if (VECTOR_MODE_P (cmp_mode) - && SCALAR_INT_MODE_P (mode) - && tem == const_true_rtx) - return NULL_RTX; - - return tem; - } + return relational_result (mode, cmp_mode, tem); /* For the following tests, ensure const0_rtx is op1. */ if (swap_commutative_operands_p (op0, op1) diff --git a/gcc/store-motion.c b/gcc/store-motion.c index 3f6e003..dd61701 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -251,9 +251,7 @@ print_store_motion_mems (FILE * file) static bool store_ops_ok (const vec<rtx> &x, int *regs_set) { - unsigned int i; - rtx temp; - FOR_EACH_VEC_ELT (x, i, temp) + for (rtx temp : x) if (regs_set[REGNO (temp)]) return false; @@ -386,9 +384,7 @@ store_killed_in_insn (const_rtx x, const vec<rtx> &x_regs, /* But even a const call reads its parameters. Check whether the base of some of registers used in mem is stack pointer. */ - rtx temp; - unsigned int i; - FOR_EACH_VEC_ELT (x_regs, i, temp) + for (rtx temp : x_regs) if (may_be_sp_based_p (temp)) return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c4c17b..b62ad90 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,124 @@ +2021-06-13 Jason Merrill <jason@redhat.com> + + * gcc.dg/c2x-attr-maybe_unused-1.c: Expect no warnings. + +2021-06-13 H.J. Lu <hjl.tools@gmail.com> + + PR target/101023 + * g++.target/i386/pr101023a.C: New test. + * g++.target/i386/pr101023b.C: Likewise. + +2021-06-12 David Edelsohn <dje.gcc@gmail.com> + + * g++.dg/ext/builtin-shufflevector-2.C: Ignore psabi warning. + * gcc.dg/uninit-pr93100.c: Skip on AIX. + * gcc.target/powerpc/pr100085.c: Require int128 and float128. + +2021-06-12 Jason Merrill <jason@redhat.com> + + * g++.dg/ext/attrib62.C: No longer warn. + * g++.dg/diagnostic/maybe_unused1.C: New test. + +2021-06-12 Jason Merrill <jason@redhat.com> + + PR c++/101029 + * g++.dg/ext/array4.C: New test. + +2021-06-11 Carl Love <cel@us.ibm.com> + + * gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c + (dg-require-effective-target): Change target to p9vector_hw. + +2021-06-11 Thomas Schwinge <thomas@codesourcery.com> + + * gcc.dg/gomp/simd-clones-2.c: Enhance. + +2021-06-11 Patrick Palka <ppalka@redhat.com> + + DR 1227 + PR c++/96560 + * g++.dg/template/sfinae-dr1227.C: New test. + +2021-06-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + PR target/101016 + * gcc.target/arm/mve/intrinsics/pr101016.c: New test. + +2021-06-11 Roger Sayle <roger@nextmovesoftware.com> + + PR tree-optimization/96392 + * gcc.dg/pr96392.c: New test. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101025 + * gcc.dg/torture/pr101025.c: New testcase. + +2021-06-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + PR target/99939 + * gcc.target/arm/cmse/cmse-18.c: Add separate scan-assembler + directives check for target is v8.1-m.main+mve or not before + comparing the assembly output. + * gcc.target/arm/cmse/cmse-20.c: New test. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR c++/100974 + * g++.dg/cpp23/consteval-if1.C: New test. + * g++.dg/cpp23/consteval-if2.C: New test. + * g++.dg/cpp23/consteval-if3.C: New test. + * g++.dg/cpp23/consteval-if4.C: New test. + * g++.dg/cpp23/consteval-if5.C: New test. + * g++.dg/cpp23/consteval-if6.C: New test. + * g++.dg/cpp23/consteval-if7.C: New test. + * g++.dg/cpp23/consteval-if8.C: New test. + * g++.dg/cpp23/consteval-if9.C: New test. + * g++.dg/cpp23/consteval-if10.C: New test. + * g++.dg/cpp23/feat-cxx2b.C: Add __cpp_if_consteval tests. + +2021-06-11 David Malcolm <dmalcolm@redhat.com> + + * gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c: Update + expected number of enodes after the loop. + * gcc.dg/analyzer/paths-8.c: New test. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101028 + * gcc.dg/pr101028.c: New testcase. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101026 + * gfortran.dg/pr101026.f: New testcase. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/101008 + * gcc.dg/pr101008.c: New test. + +2021-06-11 Jakub Jelinek <jakub@redhat.com> + + PR target/101007 + * gcc.target/i386/sse-pr101007.c: New test. + +2021-06-11 Uroš Bizjak <ubizjak@gmail.com> + + PR target/101021 + * gcc.target/i386/pr101021-1.c: New test. + * gcc.target/i386/pr101021-2.c: Ditto. + +2021-06-11 Martin Liska <mliska@suse.cz> + + PR gcov-profile/100788 + * gcc.dg/pr100788.c: New test. + +2021-06-11 Richard Biener <rguenther@suse.de> + + PR middle-end/101009 + * gcc.dg/torture/pr101009.c: New testcase. + 2021-06-11 Kewen Lin <linkw@linux.ibm.com> * gcc.target/powerpc/p9-fpcvt-3.c: New test. diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if1.C b/gcc/testsuite/g++.dg/cpp23/consteval-if1.C new file mode 100644 index 0000000..cff9946 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if1.C @@ -0,0 +1,103 @@ +// P1938R3 +// { dg-do run { target c++20 } } +// { dg-options "" } + +extern "C" void abort (); + +namespace std { + constexpr inline bool + is_constant_evaluated () noexcept + { + if consteval { // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + return true; + } else { + return false; + } + } +} + +consteval int foo (int x) { return x; } +consteval int bar () { return 2; } + +constexpr int +baz (int x) +{ + int r = 0; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (x); + } + else + { + r += bar (); + } + if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 2 * bar (); + } + else + { + r += foo (8 * x); + } + if (std::is_constant_evaluated ()) + r = -r; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (32 * x); + } + if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 32 * bar (); + } + return r; +} + +template <typename T> +constexpr int +qux (T x) +{ + T r = 0; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (x); + } + else + { + r += bar (); + } + if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 2 * bar (); + } + else + { + r += foo (8 * x); + } + if (std::is_constant_evaluated ()) + r = -r; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (32 * x); + } + if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 32 * bar (); + } + return r; +} + +constexpr int a = baz (1); +static_assert (a == 23); +int b = baz (1); +constexpr int c = qux (1); +static_assert (c == 23); +int d = qux<int> (1); + +int +main () +{ + if (b != 23 || d != 23) + abort (); + if (baz (1) != 70 || qux (1) != 70 || qux (1LL) != 70) + abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if10.C b/gcc/testsuite/g++.dg/cpp23/consteval-if10.C new file mode 100644 index 0000000..4c0523f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if10.C @@ -0,0 +1,36 @@ +// P1938R3 +// { dg-do compile { target c++20 } } +// { dg-options "" } + +consteval int foo (int x) { return x; } + +constexpr int +bar (int x) +{ + int r = 0; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + auto y = [=] { foo (x); }; // { dg-error "'x' is not a constant expression" } + y (); + } + return r; +} + +template <typename T> +constexpr T +baz (T x) +{ + T r = 0; + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + auto y = [=] { foo (x); }; // { dg-error "'x' is not a constant expression" } + y (); + } + return r; +} + +int +qux (int x) +{ + return baz (x); +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if2.C b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C new file mode 100644 index 0000000..f7053b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if2.C @@ -0,0 +1,129 @@ +// P1938R3 +// { dg-do compile { target c++20 } } +// { dg-options "" } + +constexpr bool f() +{ + if consteval (true) {} // { dg-error "'if consteval' requires compound statement" } + // { dg-error "expected" "" { target *-*-* } .-1 } + // { dg-warning "'if consteval' only available with" "" { target c++20_only } .-2 } + if not consteval (false) {} // { dg-error "'if consteval' requires compound statement" } + // { dg-error "expected" "" { target *-*-* } .-1 } + // { dg-warning "'if consteval' only available with" "" { target c++20_only } .-2 } + if consteval if (true) {} // { dg-error "'if consteval' requires compound statement" } + // { dg-warning "'if consteval' only available with" "" { target c++20_only } .-1 } + if ! consteval {} else ; // { dg-error "'if consteval' requires compound statement" } + // { dg-warning "'if consteval' only available with" "" { target c++20_only } .-1 } + if consteval {} else if (true) {} // { dg-error "'if consteval' requires compound statement" } + // { dg-warning "'if consteval' only available with" "" { target c++20_only } .-1 } + if (true) + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + } + else ; // { dg-error "'if consteval' requires compound statement" } + return false; +} + +consteval int foo (int x) { return x; } +consteval int bar () { return 2; } + +constexpr int +baz (int x) +{ + int r = 0; + if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (x); // { dg-error "'x' is not a constant expression" } + } + else + { + r += bar (); + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 2 * bar (); + } + else + { + r += foo (8 * x); // { dg-error "'x' is not a constant expression" } + } + if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (32 * x);// { dg-error "'x' is not a constant expression" } + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 32 * bar (); + } + return r; +} + +template <typename T> +constexpr int +qux (int x) +{ + int r = 0; + if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (x); // { dg-error "'x' is not a constant expression" } + } + else + { + r += bar (); + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 2 * bar (); + } + else + { + r += foo (8 * x); // { dg-error "is not a constant expression" } + } + if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (32 * x);// { dg-error "is not a constant expression" } + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 32 * bar (); + } + return r; +} + +template <typename T> +constexpr T +corge (T x) +{ + T r = 0; + if not consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (x); // { dg-error "'x' is not a constant expression" } + } + else + { + r += bar (); + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 2 * bar (); + } + else + { + r += foo (8 * x); // { dg-error "is not a constant expression" } + } + if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += foo (32 * x);// { dg-error "is not a constant expression" } + } + if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } } + { + r += 32 * bar (); + } + return r; +} + +int +garply (int x) +{ + return corge (x); +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if3.C b/gcc/testsuite/g++.dg/cpp23/consteval-if3.C new file mode 100644 index 0000000..9c7e3aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if3.C @@ -0,0 +1,73 @@ +// P1938R3 +// { dg-do run { target c++20 } } +// { dg-options "" } + +constexpr inline bool +is_constant_evaluated () noexcept +{ + if consteval { return true; } else { return false; } // { dg-warning "'if consteval' only available with" "" { target c++20_only } } +} + +template<int N> struct X { int v = N; }; +X<is_constant_evaluated ()> x; // type X<true> +int y = 4; +int a = is_constant_evaluated () ? y : 1; // initializes a to 1 +int b = is_constant_evaluated () ? 2 : y; // initializes b to 2 +int c = y + (is_constant_evaluated () ? 2 : y); // initializes c to 2*y +int d = is_constant_evaluated (); // initializes d to 1 +int e = d + is_constant_evaluated (); // initializes e to 1 + 0 + +struct false_type { static constexpr bool value = false; }; +struct true_type { static constexpr bool value = true; }; +template<class T, class U> +struct is_same : false_type {}; +template<class T> +struct is_same<T, T> : true_type {}; + +constexpr int +foo (int x) +{ + const int n = is_constant_evaluated () ? 13 : 17; // n == 13 + int m = is_constant_evaluated () ? 13 : 17; // m might be 13 or 17 (see below) + char arr[n] = {}; // char[13] + return m + sizeof (arr) + x; +} + +constexpr int +bar () +{ + const int n = is_constant_evaluated() ? 13 : 17; + X<n> x1; + X<is_constant_evaluated() ? 13 : 17> x2; + static_assert (is_same<decltype (x1), decltype (x2)>::value, "x1/x2's type"); + return x1.v + x2.v; +} + +int p = foo (0); // m == 13; initialized to 26 +int q = p + foo (0); // m == 17 for this call; initialized to 56 +static_assert (bar () == 26, "bar"); + +struct S { int a, b; }; + +S s = { is_constant_evaluated () ? 2 : 3, y }; +S t = { is_constant_evaluated () ? 2 : 3, 4 }; + +static_assert (is_same<decltype (x), X<true> >::value, "x's type"); + +int +main () +{ + if (a != 1 || b != 2 || c != 8 || d != 1 || e != 1 || p != 26 || q != 56) + __builtin_abort (); + if (s.a != 3 || s.b != 4 || t.a != 2 || t.b != 4) + __builtin_abort (); + if (foo (y) != 34) + __builtin_abort (); +#if __cplusplus >= 201703L + if constexpr (foo (0) != 26) + __builtin_abort (); +#endif + constexpr int w = foo (0); + if (w != 26) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if4.C b/gcc/testsuite/g++.dg/cpp23/consteval-if4.C new file mode 100644 index 0000000..2760c1c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if4.C @@ -0,0 +1,44 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +void f() +{ + goto l; // { dg-message "from here" } + if consteval // { dg-message "enters 'consteval if'" } + { + l:; // { dg-error "jump to label" } + } +} + +void g() +{ + goto l; // { dg-message "from here" } + if not consteval // { dg-message "enters 'consteval if'" } + { + l:; // { dg-error "jump to label" } + } +} + +void h() +{ + goto l; // { dg-message "from here" } + if consteval // { dg-message "enters 'consteval if'" } + { + } + else + { + l:; // { dg-error "jump to label" } + } +} + +void i() +{ + goto l; // { dg-message "from here" } + if not consteval // { dg-message "enters 'consteval if'" } + { + } + else + { + l:; // { dg-error "jump to label" } + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if5.C b/gcc/testsuite/g++.dg/cpp23/consteval-if5.C new file mode 100644 index 0000000..b1c6192 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if5.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +void f() +{ + if consteval // { dg-message "enters 'consteval if'" } + { + goto l; // { dg-message "from here" } + } + else + { + l:; // { dg-error "jump to label" } + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if6.C b/gcc/testsuite/g++.dg/cpp23/consteval-if6.C new file mode 100644 index 0000000..2b92ccc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if6.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +void f() +{ + if consteval + { + goto l; + l:; + } + else + { + goto l2; + l2:; + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if7.C b/gcc/testsuite/g++.dg/cpp23/consteval-if7.C new file mode 100644 index 0000000..ab9da08 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if7.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +void f() +{ + if not consteval + { + l:; + goto l; + } + else + { + l2:; + goto l2; + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if8.C b/gcc/testsuite/g++.dg/cpp23/consteval-if8.C new file mode 100644 index 0000000..36adaf9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if8.C @@ -0,0 +1,14 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +void f() +{ + if consteval + { + l:; // { dg-error "jump to label" } + } + else + { + goto l; // { dg-message "from here" } + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/consteval-if9.C b/gcc/testsuite/g++.dg/cpp23/consteval-if9.C new file mode 100644 index 0000000..1c7db1a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/consteval-if9.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++20 } } +// { dg-options "-w" } + +constexpr void f(int i) +{ + switch (i) + if consteval // { dg-message "enters 'consteval if'" } + { + case 42:; // { dg-error "jump to case label" } + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C index 283a8ba..7070f59 100644 --- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C +++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C @@ -545,3 +545,9 @@ #elif __cpp_size_t_suffix != 202011 # error "__cpp_size_t_suffix != 202011" #endif + +#ifndef __cpp_if_consteval +# error "__cpp_if_consteval" +#elif __cpp_if_consteval != 202106 +# error "__cpp_if_consteval != 202106" +#endif diff --git a/gcc/testsuite/g++.dg/diagnostic/maybe_unused1.C b/gcc/testsuite/g++.dg/diagnostic/maybe_unused1.C new file mode 100644 index 0000000..70a8ec9 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/maybe_unused1.C @@ -0,0 +1,17 @@ +/* [dcl.attr.unused] The attribute may be applied to the declaration of a + class, a typedef-name, a variable (including a structured binding + declaration), a non-static data member, a function, an enumeration, or an + enumerator. */ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-Wunused -Wextra" } + +class [[maybe_unused]] Test { + [[maybe_unused]] int a_; + void b() {}; +}; + +[[maybe_unused]] typedef Test Test2; + +[[maybe_unused]] int i; +[[maybe_unused]] void f(); +enum [[maybe_unused]] E { e [[maybe_unused]] = 42 }; diff --git a/gcc/testsuite/g++.dg/ext/array4.C b/gcc/testsuite/g++.dg/ext/array4.C new file mode 100644 index 0000000..0068ea8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/array4.C @@ -0,0 +1,172 @@ +// PR c++/101029 +// { dg-do compile { target c++11 } } +// { dg-options "" } allow [0] + +template <int __v> struct integral_constant { + static constexpr int value = __v; + typedef int value_type; + constexpr operator value_type() { return __v; } +}; +template <bool __v> using __bool_constant = integral_constant<__v>; +template <bool, typename> struct conditional; +template <typename...> struct __and_; +template <typename _B1, typename _B2, typename _B3, typename... _Bn> +struct __and_<_B1, _B2, _B3, _Bn...> : conditional<_B1::value, _B1> {}; +template <typename _Tp> +constexpr integral_constant<true> __is_complete_or_unbounded(_Tp) { + return {}; +} +struct Trans_NS_std_formatter; +template <typename _Tp> +struct is_default_constructible : integral_constant<false> { + static_assert(__is_complete_or_unbounded(_Tp{}), ""); +}; +template <typename _Tp, typename _Up> +struct is_same : integral_constant<__is_same_as(_Tp, _Up)> {}; +template <bool> struct enable_if; +template <typename _Iffalse> struct conditional<false, _Iffalse> { + typedef _Iffalse type; +}; +struct pair { + template <typename _U1 = int, typename _U2 = int, + typename enable_if<__and_<is_default_constructible<_U1>, _U2, + int>::valuebool>::type> + pair(); +}; + +class BucketLogger; +struct __shared_ptr_access { + using element_type = BucketLogger; + element_type *operator->(); +}; +struct DcpProducer { + __shared_ptr_access logger; + void bufferAcknowledgement(); +}; +struct atomic { + atomic(long); +}; +inline namespace v7 { +template <bool B, class, class F> +using conditional_t = typename conditional<B, F>::type; +template <typename> struct basic_string_view { basic_string_view(int, int); }; +template <typename, typename> struct formatter; +template <typename, typename> +using has_formatter = + __bool_constant<__is_constructible(Trans_NS_std_formatter)>; +struct fallback_formatter; +template <typename Context> struct custom_value { + using parse_context = typename Context::parse_context_type; + void (*format)(const void *, parse_context &, Context &); +}; +template <typename Context> struct value { + float float_value; + custom_value<Context> custom; + template <typename T> value(T) { + custom.format = + format_custom_arg<T, conditional_t<has_formatter<T, Context>::value, + typename Context::formatter_type<T>, + fallback_formatter>>; + } + template <typename, typename Formatter> + static void format_custom_arg(const void *arg, + typename Context::parse_context_type &, + Context &ctx) { + Formatter f; + f.format(*static_cast<const int *>(arg), ctx); + } +}; +enum { max_packed_args }; +template <typename Context> struct basic_format_arg { value<Context> value_; }; +template <typename Visitor, typename Context> +void visit_format_arg(Visitor vis, Context arg) { + vis(arg.value_.float_value); +} +template <typename Context, typename T> basic_format_arg<Context> make_arg(T); +struct basic_format_context { + using char_type = int; + using parse_context_type = int; + template <typename T> using formatter_type = formatter<T, char_type>; +}; +struct format_arg_store { + using value_type = conditional_t<max_packed_args, basic_format_context, + basic_format_arg<basic_format_context>>; + value_type data_; +}; +template <typename... Args, typename S> +auto make_args_checked(S, Args... args) -> format_arg_store { + return {args...}; +} +struct basic_format_specs {}; +template <typename Char, typename OutputIt, typename T> +void write(OutputIt, T, Char) { + if (is_same<T, float>()) + ; +} +struct arg_formatter_base { + using iterator = int; + using format_specs = basic_format_specs; + iterator out_; + template <typename T> void operator()(T value) { + auto specs = format_specs(); + write(out_, value, specs); + } +}; +struct arg_formatter : arg_formatter_base { + using context_type = basic_format_context; + arg_formatter(context_type, int *, format_specs *); +}; +template <typename T, typename> struct formatter { + template <typename FormatContext> void format(T val, FormatContext ctx) { + using af = arg_formatter; + basic_format_arg<FormatContext> __trans_tmp_2 = make_arg<FormatContext>(val); + visit_format_arg(af(ctx, nullptr, &specs_), __trans_tmp_2); + } + basic_format_specs specs_; +}; +} // namespace v7 +namespace level { +enum level_enum { warn }; +} +struct BucketLogger { + template <typename S, typename... Args> + void log(level::level_enum, const S &, Args &&...); + template <typename... Args> void warn(const char *, const Args &...); +}; +namespace v7 { +struct fallback_formatter : formatter<basic_string_view<int>, int> { + template <typename OutputIt> void format(int, OutputIt ctx) { + basic_string_view<int> str(0, 0); + formatter::format(str, ctx); + } +}; +} // namespace v7 +template <typename S, typename... Args> +void BucketLogger::log(level::level_enum, const S &fmt, Args &&...args) { + make_args_checked(fmt, args...); +} +template <typename... Args> +void BucketLogger::warn(const char *fmt, const Args &...args) { + log(level::warn, fmt, args...); +} +template <class KeyT> struct AtomicHashArray { + static void create(); + atomic isFull_; + atomic numErases_; + pair cells_[0]; + AtomicHashArray(int, KeyT, KeyT, KeyT, double, unsigned); +}; +template <class KeyT> +AtomicHashArray<KeyT>::AtomicHashArray(int, KeyT, KeyT, KeyT, double, unsigned) + : isFull_(0), numErases_(0) {} +template <class KeyT> void AtomicHashArray<KeyT>::create() { + int c_4, capacity; + double c_3; + char c_2, c_1, c_0; + AtomicHashArray(capacity, c_0, c_1, c_2, c_3, c_4); +} +int bufferAcknowledgement_vbucket; +void DcpProducer::bufferAcknowledgement() { + logger->warn("", bufferAcknowledgement_vbucket); +} +void (*makeStreamsMap_p)() = AtomicHashArray<char>::create; diff --git a/gcc/testsuite/g++.dg/ext/attrib62.C b/gcc/testsuite/g++.dg/ext/attrib62.C index 116ee82..d34cd25 100644 --- a/gcc/testsuite/g++.dg/ext/attrib62.C +++ b/gcc/testsuite/g++.dg/ext/attrib62.C @@ -3,5 +3,5 @@ template<typename T> struct A { - T a, __attribute((unused)) b; // { dg-warning "attribute ignored" } + T a, __attribute((unused)) b; }; diff --git a/gcc/testsuite/g++.dg/ext/builtin-shufflevector-2.C b/gcc/testsuite/g++.dg/ext/builtin-shufflevector-2.C index c8d096c..fdf223e 100644 --- a/gcc/testsuite/g++.dg/ext/builtin-shufflevector-2.C +++ b/gcc/testsuite/g++.dg/ext/builtin-shufflevector-2.C @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-additional-options "-Wno-psabi" } typedef double v2df __attribute__((vector_size(2 * sizeof (double)))); diff --git a/gcc/testsuite/g++.dg/template/sfinae-dr1227.C b/gcc/testsuite/g++.dg/template/sfinae-dr1227.C new file mode 100644 index 0000000..821ff03 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae-dr1227.C @@ -0,0 +1,23 @@ +// PR c++/96560 +// DR 1227 +// Test that we substitute function parameter types in lexical order. + +template <class T> +struct A { typedef typename T::type type; }; // { dg-error "void" } + +template <class T> void f(typename T::type, typename A<T>::type); +template <class T> long f(...); + +long x = f<int>(0, 0); // { dg-bogus "" } OK + + +template <class T> void g(T, typename A<T>::type); +template <class T> long g(...); + +long y = g<void>(0, 0); // { dg-bogus "" } OK + + +template <class T> void h(typename A<T>::type, T); +template <class T> long h(...); + +long z = h<void>(0, 0); // { dg-message "required from here" } hard error diff --git a/gcc/testsuite/g++.target/i386/pr101023a.C b/gcc/testsuite/g++.target/i386/pr101023a.C new file mode 100644 index 0000000..04fb8b0 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr101023a.C @@ -0,0 +1,63 @@ +// PR target/101023 +// { dg-do run { target { ! ia32 } } } +// { dg-options "-O2 -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" } + +struct S { + __attribute__((noipa)) int m1 (); + __attribute__((noipa)) void m2 (); +}; +struct T { + __attribute__((noipa)) virtual S m3 (); +}; +struct U : T { + int u; + __attribute__((noipa)) U (int); +}; +int *a; +S *b; +int c; + +int +S::m1 () +{ + return 0; +} + +void +S::m2 () +{ +} + +S +T::m3 () +{ + return S (); +} + +U::U (int) : u (4) +{ +} + +__attribute__((noipa)) int +foo () +{ + if (a) + return 0; + U d(c); + S *e = b; + e->m2 (); + return e->m1(); +} + +int +main () +{ + register int r12 __asm ("r12") = 1; + register int rax __asm ("rax") = 2; + asm volatile ("" : "+r" (r12), "+r" (rax)); + foo (); + asm volatile ("" : "+r" (r12)); + if (r12 != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/g++.target/i386/pr101023b.C b/gcc/testsuite/g++.target/i386/pr101023b.C new file mode 100644 index 0000000..b19791c --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr101023b.C @@ -0,0 +1,5 @@ +// PR target/101023 +// { dg-do run { target { ! ia32 } } } +// { dg-options "-O2 -mno-red-zone -mtune=opteron -mstackrealign --param=hot-bb-frequency-fraction=1" } + +#include "pr101023a.C" diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c index 2b03527..0172c9b 100644 --- a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c +++ b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c @@ -69,6 +69,5 @@ void test(int n) free (it); - __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ - // TODO: why 2 enodes here, rather than 1 + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-8.c b/gcc/testsuite/gcc.dg/analyzer/paths-8.c new file mode 100644 index 0000000..b350d4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/paths-8.c @@ -0,0 +1,17 @@ +#include "analyzer-decls.h" + +static void __attribute__((noinline)) +__analyzer_callee_1 (void) +{ + /* empty. */ +} + +void +test_1 (int flag) +{ + if (flag) + __analyzer_callee_1 (); + + /* Verify that we merge state, whether or not the call happens. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} diff --git a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c index 221ebdd..477f30d 100644 --- a/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c +++ b/gcc/testsuite/gcc.dg/c2x-attr-maybe_unused-1.c @@ -20,7 +20,7 @@ g ([[maybe_unused]] int x, int y) struct [[maybe_unused]] s { double d; }; -struct s2 { [[__maybe_unused__]] int a; int b [[maybe_unused]]; } x; /* { dg-warning "attribute ignored" } */ +struct s2 { [[__maybe_unused__]] int a; int b [[maybe_unused]]; } x; enum e { E1 [[maybe_unused]] }; @@ -28,4 +28,4 @@ union [[maybe_unused]] u { int x; }; enum [[maybe_unused]] eu { E2 }; -union u2 { [[maybe_unused]] int a; int b [[maybe_unused]]; } y; /* { dg-warning "attribute ignored" } */ +union u2 { [[maybe_unused]] int a; int b [[maybe_unused]]; } y; diff --git a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c index 75554de..9f7c84d 100644 --- a/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c +++ b/gcc/testsuite/gcc.dg/gomp/simd-clones-2.c @@ -7,6 +7,7 @@ int addit(int a, int b, int *c) return a + b; } /* { dg-warning "GCC does not currently support mixed size types for 'simd' functions" "" { target aarch64*-*-* } .-4 } */ +/* { dg-final { scan-tree-dump {(?n)^__attribute__\(\(omp declare simd \(notinbranch aligned\(2:32\)\), omp declare simd \(inbranch uniform\(2\) linear\(1:66\)\)\)\)$} "optimized" } } */ #pragma omp declare simd uniform(a) aligned(a:32) linear(k:1) notinbranch float setArray(float *a, float x, int k) @@ -14,6 +15,7 @@ float setArray(float *a, float x, int k) a[k] = a[k] + x; return a[k]; } +/* { dg-final { scan-tree-dump {(?n)^__attribute__\(\(omp declare simd \(notinbranch uniform\(0\) aligned\(0:32\) linear\(2:1\)\)\)\)$} "optimized" } } */ /* { dg-final { scan-tree-dump "_ZGVbN4ua32vl_setArray" "optimized" { target i?86-*-* x86_64-*-* } } } */ /* { dg-final { scan-tree-dump "_ZGVbN4vvva32_addit" "optimized" { target i?86-*-* x86_64-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr101008.c b/gcc/testsuite/gcc.dg/pr101008.c new file mode 100644 index 0000000..c06208d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101008.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/101008 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +typedef unsigned __attribute__((__vector_size__(32))) U; +typedef unsigned __attribute__((__vector_size__(16))) V; + +int c, r; + +V v; + +void +foo(void) +{ + U u = __builtin_shufflevector (v, (V)(v != c) | (V)(c == v), + 4, 3, 5, 5, 1, 2, 3, 0); + r = ((union { U a; int b; }) u).b; +} diff --git a/gcc/testsuite/gcc.dg/pr101028.c b/gcc/testsuite/gcc.dg/pr101028.c new file mode 100644 index 0000000..501e6af --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101028.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +typedef struct { + double x, y; +} PointInfo; + +typedef struct { + PointInfo point; +} PrimitiveInfo; + +int TraceBezier_alpha, TraceBezier_i; +double TraceBezier_weight; +PointInfo *TraceBezier_points; +PrimitiveInfo *TraceBezier_primitive_info; + +void TracePath() { + double *coefficients; + PointInfo point; + long j; + for (; TraceBezier_i; TraceBezier_i++) { + point.x = point.y = TraceBezier_alpha = 1.0; + j = 0; + for (; j < 4; j++) { + point.x += TraceBezier_alpha * coefficients[j] * + TraceBezier_primitive_info->point.x; + point.y += TraceBezier_alpha * TraceBezier_primitive_info->point.y; + TraceBezier_alpha *= TraceBezier_weight; + TraceBezier_primitive_info++; + } + TraceBezier_points[TraceBezier_i] = point; + TraceBezier_weight += 1.0; + } +} diff --git a/gcc/testsuite/gcc.dg/pr96392.c b/gcc/testsuite/gcc.dg/pr96392.c new file mode 100644 index 0000000..662bacb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr96392.c @@ -0,0 +1,33 @@ +/* PR tree-optimization/96392 */ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +double plus0(int x) +{ + return x + 0.0; +} + +double sub0(int x) +{ + return x - 0.0; +} + +double mult0(int x) +{ + return 0.0 * x; +} + +double negate(int x) +{ + return 0.0 - x; +} + +double subtract(int x) +{ + return (double)x - (double)x; +} + +/* { dg-final { scan-tree-dump-not " \\+ " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\- " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/torture/pr101025.c b/gcc/testsuite/gcc.dg/torture/pr101025.c new file mode 100644 index 0000000..483e0ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101025.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ + +int a[10]; +int b, d, g; +volatile char c; +short e; +volatile int f; +int main() +{ + for (; d <= 9; d++) { + b = e = 0; + for (; e < 4; e++) + a[e] = 4; + for (; b <= 3; b++) + if (g) + f = 0; + else + a[b] = c; + } + if (a[1] != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr101031.c b/gcc/testsuite/gcc.dg/torture/pr101031.c new file mode 100644 index 0000000..daf3bcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr101031.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +int a; +char b, e; +static char *c = &b; +static long d; +void f(void); +void __attribute__((noipa)) h() { + int g = 0; + for (; g < 2; ++g) { + d = *c; + *c = 1; + b = 0; + } + f(); +} +void __attribute__((noipa)) f() { + if (d++) + c = &e; + for (; a;) + ; +} +int main() { + h(); + if (b != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pr93100.c b/gcc/testsuite/gcc.dg/uninit-pr93100.c index 61b7e43..531a5c3 100644 --- a/gcc/testsuite/gcc.dg/uninit-pr93100.c +++ b/gcc/testsuite/gcc.dg/uninit-pr93100.c @@ -1,6 +1,7 @@ /* PR tree-optimization/93100 - gcc -fsanitize=address inhibits -Wuninitialized { dg-do compile } - { dg-options "-Wall -fsanitize=address" } */ + { dg-options "-Wall -fsanitize=address" } + { dg-skip-if "sanitize address" { "powerpc-ibm-aix*" } } */ struct A { diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c index e1ff092..db7d975 100644 --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-18.c @@ -8,4 +8,5 @@ void bar(f func, int a) func(a); } -/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r4:SI\\\]\\\]" "final" } } */ +/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r4:SI\\\]\\\]" "final" { target { ! arm_v8_1m_mve_ok } } } } */ +/* { dg-final { scan-rtl-dump "call unspec\\\[\\\[r\[0-7\]:SI\\\]\\\]" "final" { target { arm_v8_1m_mve_ok } } } } */ diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c new file mode 100644 index 0000000..08e89bf --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-20.c @@ -0,0 +1,28 @@ +/* This test is executed only if the execution engine supports CMSE instructions. */ +/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */ + +#include <arm_cmse.h> +#include <stdlib.h> +#include <stdio.h> + +void __attribute__((cmse_nonsecure_entry)) +secure_fun (int a, int *p) +{ + void *b = cmse_check_address_range ((void *)p, a, 1); + + if (b == NULL) + __builtin_abort (); + printf("%d", *((int *)b)); +} + +int +main (void) +{ + int *ptr; + int size = 1; + ptr = (int *) calloc (1, sizeof(int *)); + *ptr = 1315852292; + secure_fun (size, ptr); + free (ptr); + return 0; +} diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr101016.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr101016.c new file mode 100644 index 0000000..b12786d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/pr101016.c @@ -0,0 +1,136 @@ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ + +#include "arm_mve.h" + +void +foo (void) +{ + mve_pred16_t p; + int8x16_t a; + int8_t a1[10]; + int16x8_t b; + int16_t b1[10]; + int32x4_t c; + int32_t c1[10]; + uint8x16_t ua; + uint8_t ua1[10]; + uint16x8_t ub; + uint16_t ub1[10]; + uint32x4_t uc; + uint32_t uc1[10]; + float16x8_t fb; + float16_t fb1[10]; + float32x4_t fc; + float32_t fc1[10]; + + fb = vld1q (fb1); + fc = vld1q (fc1); + b = vld1q (b1); + c = vld1q (c1); + a = vld1q (a1); + ub = vld1q (ub1); + uc = vld1q (uc1); + ua = vld1q (ua1); + fb = vld1q_z (fb1, p); + fc = vld1q_z (fc1, p); + b = vld1q_z (b1, p); + c = vld1q_z (c1, p); + a = vld1q_z (a1, p); + ub = vld1q_z (ub1, p); + uc = vld1q_z (uc1, p); + ua = vld1q_z (ua1, p); +} + +void +foo1 (void) +{ + mve_pred16_t p; + int8x16x2_t a; + int8_t a1[10]; + int16x8x2_t b; + int16_t b1[10]; + int32x4x2_t c; + int32_t c1[10]; + uint8x16x2_t ua; + uint8_t ua1[10]; + uint16x8x2_t ub; + uint16_t ub1[10]; + uint32x4x2_t uc; + uint32_t uc1[10]; + float16x8x2_t fb; + float16_t fb1[10]; + float32x4x2_t fc; + float32_t fc1[10]; + + fb = vld2q (fb1); + fc = vld2q (fc1); + b = vld2q (b1); + c = vld2q (c1); + a = vld2q (a1); + ub = vld2q (ub1); + uc = vld2q (uc1); + ua = vld2q (ua1); +} + +void +foo2 (void) +{ + mve_pred16_t p; + int8x16x4_t a; + int8_t a1[10]; + int16x8x4_t b; + int16_t b1[10]; + int32x4x4_t c; + int32_t c1[10]; + uint8x16x4_t ua; + uint8_t ua1[10]; + uint16x8x4_t ub; + uint16_t ub1[10]; + uint32x4x4_t uc; + uint32_t uc1[10]; + float16x8x4_t fb; + float16_t fb1[10]; + float32x4x4_t fc; + float32_t fc1[10]; + + fb = vld4q (fb1); + fc = vld4q (fc1); + b = vld4q (b1); + c = vld4q (c1); + a = vld4q (a1); + ub = vld4q (ub1); + uc = vld4q (uc1); + ua = vld4q (ua1); +} + +void +foo3 (void) +{ + mve_pred16_t p; + int16x8_t a; + uint16x8_t ua; + int8_t a1[10]; + uint8_t ua1[10]; + uint16x8_t offset_a; + int8x16_t b; + uint8x16_t ub; + uint8x16_t offset_b; + int32x4_t c; + uint32x4_t uc; + uint32x4_t offset_c; + + a = vldrbq_gather_offset (a1, offset_a); + ua = vldrbq_gather_offset (ua1, offset_a); + b = vldrbq_gather_offset (a1, offset_b); + ub = vldrbq_gather_offset (ua1, offset_b); + c = vldrbq_gather_offset (a1, offset_c); + uc = vldrbq_gather_offset (ua1, offset_c); + a = vldrbq_gather_offset_z (a1, offset_a, p); + ua = vldrbq_gather_offset_z (ua1, offset_a, p); + b = vldrbq_gather_offset_z (a1, offset_b, p); + ub = vldrbq_gather_offset_z (ua1, offset_b, p); + c = vldrbq_gather_offset_z (a1, offset_c, p); + uc = vldrbq_gather_offset_z (ua1, offset_c, p); +} +/* { dg-final { scan-assembler-not "__ARM_undef" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse-pr101007.c b/gcc/testsuite/gcc.target/i386/sse-pr101007.c new file mode 100644 index 0000000..65261d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse-pr101007.c @@ -0,0 +1,14 @@ +/* PR target/101007 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse -mno-sse2" } */ + +typedef unsigned __attribute__((__vector_size__ (8))) U; +typedef unsigned __attribute__((__vector_size__ (16))) V; +V v; +U *p; + +void +foo (void) +{ + *p = (U) __builtin_shufflevector ((V)(0 == (V){} >= 0), v, 4, 2); +} diff --git a/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c b/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c index cd67b06..55935ea 100644 --- a/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c +++ b/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-require-effective-target p9vector_hw } */ /* { dg-options "-O2 -mdejagnu-cpu=power9 -save-temps" } */ /* Verify the vec_rlm and vec_rlmi builtins works correctly. */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr100085.c b/gcc/testsuite/gcc.target/powerpc/pr100085.c index 7d8b147..bfb348a 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr100085.c +++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c @@ -1,4 +1,6 @@ /* { dg-do compile } */ +/* { dg-require-effective-target int128 } */ +/* { dg-require-effective-target float128 } */ /* { dg-options "-O2 -mdejagnu-cpu=power8" } */ typedef __vector unsigned __int128 vui128_t; diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d b/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d new file mode 100644 index 0000000..c7060b0 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d @@ -0,0 +1 @@ +module object; diff --git a/gcc/testsuite/gdc.test/compilable/interpret5.d b/gcc/testsuite/gdc.test/compilable/interpret5.d new file mode 100644 index 0000000..ce13a5a --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/interpret5.d @@ -0,0 +1,30 @@ +// https://issues.dlang.org/show_bug.cgi?id=21927 +/* +TEST_OUTPUT: +--- +T1(Args...) +T1!() +T2(Args2...) +T2!() +this.T2(Args2...) +this.T2!() +--- +*/ +template T1(Args...) {} + +pragma(msg, T1); // TOK.template_ +pragma(msg, T1!()); // TOK.scope_ + +struct S +{ + template T2(Args2...) {} + + pragma(msg, S.T2); // TOK.template_ + pragma(msg, S.T2!()); // TOK.scope_ + + void fun() + { + pragma(msg, this.T2); // TOK.dotTemplateDeclaration + pragma(msg, this.T2!()); // TOK.dot + } +} diff --git a/gcc/testsuite/gdc.test/compilable/minimal3.d b/gcc/testsuite/gdc.test/compilable/minimal3.d new file mode 100644 index 0000000..e8106b6 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/minimal3.d @@ -0,0 +1,36 @@ +// DFLAGS: +// REQUIRED_ARGS: -defaultlib= +// EXTRA_SOURCES: extra-files/minimal/object.d + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=19234 +void issue19234() +{ + static struct A {} + A[10] a; + A[10] b; + b[] = a[]; +} + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=22005 +void issue22005() +{ + enum int[4] foo = [1,2,3,4]; + static foreach (i, e; foo) + { + } +} + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=22006 +void issue22006() +{ + alias size_t = typeof(int.sizeof); + alias AliasSeq(T...) = T; + + foreach (size_t i, e; [0, 1, 2, 3]) { } + static foreach (size_t i, e; [0, 1, 2, 3]) { } + foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { } + static foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/staticforeach.d b/gcc/testsuite/gdc.test/compilable/staticforeach.d index 48d06b4..8a54f32 100644 --- a/gcc/testsuite/gdc.test/compilable/staticforeach.d +++ b/gcc/testsuite/gdc.test/compilable/staticforeach.d @@ -115,6 +115,8 @@ bug17688 T foo2 T2 +TestStaticForeach2 +issue22007 1 2 '3' 2 3 '4' 0 1 @@ -840,3 +842,39 @@ struct T2{ struct S{} } static assert(is(__traits(parent,T2.S)==T2)); + +struct TestStaticForeach2 +{ +static: + // StringExp + char[] test(string str)() + { + char[] s; + static foreach (c; str) + { + s ~= c; + } + return s; + } + static assert(test!"tёstñ" == ['t', '\xd1', '\x91', 's', 't', '\xc3', '\xb1']); + + static foreach (c; "") + { + static assert(0); + } + + // NullExp + enum int[] a = null; + static foreach (c; a) + { + static assert(0); + } +} + +//https://issues.dlang.org/show_bug.cgi?id=22007 +void issue22007() +{ + immutable int[32] array = 1; + foreach (size_t a, int b; array) {} + static foreach (size_t a, int b; array) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/test21742.d b/gcc/testsuite/gdc.test/compilable/test21742.d new file mode 100644 index 0000000..b8f5df4b --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21742.d @@ -0,0 +1,13 @@ +// https://issues.dlang.org/show_bug.cgi?id=21742 + +int foo()() { return 0; } + +struct B +{ + int foo()() { return 0; } +} + +static assert(is(typeof(foo) == void)); + +// failed, gagged error: expression B().foo()() has no type +static assert(is(typeof(B().foo) == void)); diff --git a/gcc/testsuite/gdc.test/compilable/test22006.d b/gcc/testsuite/gdc.test/compilable/test22006.d new file mode 100644 index 0000000..913dd85 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22006.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=22006 +void test22006() +{ + alias AliasSeq(TList...) = TList; + { + alias aseq = AliasSeq!(0, 1, 2, 3); + static foreach (ubyte i; 0 .. aseq.length) {} + static foreach (ubyte i, x; aseq) {} + } + { + static foreach (ubyte i; 0 .. [0, 1, 2, 3].length) {} + static foreach (ubyte i, x; [0, 1, 2, 3]) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b12504.d b/gcc/testsuite/gdc.test/fail_compilation/b12504.d new file mode 100644 index 0000000..0bb104e --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b12504.d @@ -0,0 +1,64 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/b12504.d(26): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte` +fail_compilation/b12504.d(27): Error: index type `ubyte` cannot cover index range 0..257 +fail_compilation/b12504.d(31): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte` +fail_compilation/b12504.d(32): Error: index type `byte` cannot cover index range 0..129 +fail_compilation/b12504.d(36): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort` +fail_compilation/b12504.d(37): Error: index type `ushort` cannot cover index range 0..65537 +fail_compilation/b12504.d(41): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short` +fail_compilation/b12504.d(42): Error: index type `short` cannot cover index range 0..32769 +fail_compilation/b12504.d(46): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte` +fail_compilation/b12504.d(47): Error: index type `ubyte` cannot cover index range 0..257 +fail_compilation/b12504.d(51): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte` +fail_compilation/b12504.d(52): Error: index type `byte` cannot cover index range 0..129 +fail_compilation/b12504.d(56): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort` +fail_compilation/b12504.d(57): Error: index type `ushort` cannot cover index range 0..65537 +fail_compilation/b12504.d(61): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short` +fail_compilation/b12504.d(62): Error: index type `short` cannot cover index range 0..32769 +--- +*/ +void main() +{ + { + int[0xFF + 2] sta; + foreach (ubyte i; 0 .. sta.length) {} + foreach (ubyte i, x; sta) {} + } + { + int[0x7F + 2] sta; + foreach (byte i; 0 .. sta.length) {} + foreach (byte i, x; sta) {} + } + { + int[0xFFFF + 2] sta; + foreach (ushort i; 0 .. sta.length) {} + foreach (ushort i, x; sta) {} + } + { + int[0x7FFF + 2] sta; + foreach (short i; 0 .. sta.length) {} + foreach (short i, x; sta) {} + } + { + immutable int[0xFF + 2] sta; + static foreach (ubyte i; 0 .. sta.length) {} + static foreach (ubyte i, x; sta) {} + } + { + immutable int[0x7F + 2] sta; + static foreach (byte i; 0 .. sta.length) {} + static foreach (byte i, x; sta) {} + } + { + immutable int[0xFFFF + 2] sta; + static foreach (ushort i; 0 .. sta.length) {} + static foreach (ushort i, x; sta) {} + } + { + immutable int[0x7FFF + 2] sta; + static foreach (short i; 0 .. sta.length) {} + static foreach (short i, x; sta) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d index ebfb72b..1dbacfd 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d @@ -1,21 +1,37 @@ /* TEST_OUTPUT: --- -fail_compilation/diag16976.d(28): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(29): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(30): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(31): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(32): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(33): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(34): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(35): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(36): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(37): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(38): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(39): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(40): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(41): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(42): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(43): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(44): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(45): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(46): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(47): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(48): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(49): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(50): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(51): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(52): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(53): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(54): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(55): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(56): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(57): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(58): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(59): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(65): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(66): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(67): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(68): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(69): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(70): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(71): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(72): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(73): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(74): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(75): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(76): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(77): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(78): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(79): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(80): Error: foreach: key cannot be of non-integral type `float` --- */ @@ -41,4 +57,25 @@ void main() foreach_reverse(float f, dchar i; sta) {} foreach_reverse(float f, dchar i; str) {} foreach_reverse(float f, dchar i; chr) {} + + immutable int[] idyn = [1,2,3,4,5]; + immutable int[5] ista = [1,2,3,4,5]; + immutable char[] istr = ['1','2','3','4','5']; + immutable char[5] ichr = ['1','2','3','4','5']; + static foreach(float f, i; idyn) {} + static foreach(float f, i; ista) {} + static foreach(float f, i; istr) {} + static foreach(float f, i; ichr) {} + static foreach(float f, dchar i; idyn) {} + static foreach(float f, dchar i; ista) {} + static foreach(float f, dchar i; istr) {} + static foreach(float f, dchar i; ichr) {} + static foreach_reverse(float f, i; idyn) {} + static foreach_reverse(float f, i; ista) {} + static foreach_reverse(float f, i; istr) {} + static foreach_reverse(float f, i; ichr) {} + static foreach_reverse(float f, dchar i; idyn) {} + static foreach_reverse(float f, dchar i; ista) {} + static foreach_reverse(float f, dchar i; istr) {} + static foreach_reverse(float f, dchar i; ichr) {} } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail117.d b/gcc/testsuite/gdc.test/fail_compilation/fail117.d index f39a48d..9279d54 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail117.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail117.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/fail117.d(35): Error: expression has no value -fail_compilation/fail117.d(36): Error: expression has no value +fail_compilation/fail117.d(37): Error: expression `foo.mixin MGettor!(a) geta; +` is `void` and has no value +fail_compilation/fail117.d(38): Error: expression `foo.mixin MGettor!(b) getb; +` is `void` and has no value --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22006.d b/gcc/testsuite/gdc.test/fail_compilation/fail22006.d new file mode 100644 index 0000000..89bbc28 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22006.d @@ -0,0 +1,22 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail22006.d(15): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool` +fail_compilation/fail22006.d(16): Error: index type `bool` cannot cover index range 0..4 +fail_compilation/fail22006.d(19): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool` +fail_compilation/fail22006.d(20): Error: index type `bool` cannot cover index range 0..4 +--- +*/ +void test22006() +{ + alias AliasSeq(TList...) = TList; + { + alias aseq = AliasSeq!(0, 1, 2, 3); + static foreach (bool i; 0 .. aseq.length) {} + static foreach (bool i, x; aseq) {} + } + { + static foreach (bool i; 0 .. [0, 1, 2, 3].length) {} + static foreach (bool i, x; [0, 1, 2, 3]) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d b/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d index cb565ba..a312dc0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d @@ -3,10 +3,10 @@ TEST_OUTPUT: --- fail_compilation/fail238_m32.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `uint` -fail_compilation/fail238_m32.d(24): Error: cannot interpret X!() at compile time -fail_compilation/fail238_m32.d(29): Error: template instance fail238_m32.A!"a" error instantiating -fail_compilation/fail238_m32.d(35): instantiated from here: M!(q) -fail_compilation/fail238_m32.d(35): while evaluating pragma(msg, M!(q)) +fail_compilation/fail238_m32.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)` +fail_compilation/fail238_m32.d(29): Error: template instance `fail238_m32.A!"a"` error instantiating +fail_compilation/fail238_m32.d(35): instantiated from here: `M!(q)` +fail_compilation/fail238_m32.d(35): while evaluating `pragma(msg, M!(q))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d b/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d index 08837b2..dc7a50e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d @@ -3,10 +3,10 @@ TEST_OUTPUT: --- fail_compilation/fail238_m64.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `ulong` -fail_compilation/fail238_m64.d(24): Error: cannot interpret X!() at compile time -fail_compilation/fail238_m64.d(29): Error: template instance fail238_m64.A!"a" error instantiating -fail_compilation/fail238_m64.d(35): instantiated from here: M!(q) -fail_compilation/fail238_m64.d(35): while evaluating pragma(msg, M!(q)) +fail_compilation/fail238_m64.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)` +fail_compilation/fail238_m64.d(29): Error: template instance `fail238_m64.A!"a"` error instantiating +fail_compilation/fail238_m64.d(35): instantiated from here: `M!(q)` +fail_compilation/fail238_m64.d(35): while evaluating `pragma(msg, M!(q))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d index 1a7e092..737958c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424b.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424b.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424b diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d index 1c06540..e804d72 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424c.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424c.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424c diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d index d784a75..5ef9463 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424d.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424d.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424d diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d index 3bf3a2d..ddf4ded 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424e.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424e.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424e diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d index 266163d..751b625 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424f.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424f.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424f diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d index aca6586..d4fa463 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424g.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424g.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d index e08eac1..56184a5 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424h.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424h.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d index 1c2cb1c..37042f7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424i.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424i.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9766.d b/gcc/testsuite/gdc.test/fail_compilation/fail9766.d index d75d1bc..58cabe3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail9766.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail9766.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail9766.d(14): Error: cannot interpret Foo!int at compile time +fail_compilation/fail9766.d(14): Error: integer constant expression expected instead of `Foo!int` +fail_compilation/fail9766.d(14): Error: alignment must be an integer positive power of 2, not Foo!int fail_compilation/fail9766.d(17): Error: alignment must be an integer positive power of 2, not -1 fail_compilation/fail9766.d(20): Error: alignment must be an integer positive power of 2, not 0 fail_compilation/fail9766.d(23): Error: alignment must be an integer positive power of 2, not 3 @@ -9,6 +10,7 @@ fail_compilation/fail9766.d(26): Error: alignment must be an integer positive po --- */ +#line 12 template Foo(T) {} align(Foo!int) diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9406.d b/gcc/testsuite/gdc.test/fail_compilation/ice9406.d index d8c0837..c1807a0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9406.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9406.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9406.d(21): Error: expression has no value +fail_compilation/ice9406.d(22): Error: `s1.mixin Mixin!() t1; +` has no effect --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21927.d b/gcc/testsuite/gdc.test/fail_compilation/test21927.d new file mode 100644 index 0000000..fa23285 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21927.d @@ -0,0 +1,20 @@ +// https://issues.dlang.org/show_bug.cgi?id=21927 +/* +TEST_OUTPUT: +--- +fail_compilation/test21927.d(17): Error: invalid `foreach` aggregate `this.T2(Args2...)` +fail_compilation/test21927.d(18): Error: invalid `foreach` aggregate `this.T2!()` +--- +*/ + +struct S +{ + template T2(Args2...) {} + + void fun() + { + // original test case + static foreach (p; this.T2) {} // ICE + static foreach (p; this.T2!()) {} // ICE + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21939.d b/gcc/testsuite/gdc.test/fail_compilation/test21939.d new file mode 100644 index 0000000..cb755ef --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21939.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=21939 +/* +TEST_OUTPUT: +--- +fail_compilation/test21939.d(9): Error: invalid `foreach` aggregate `Object`, define `opApply()`, range primitives, or use `.tupleof` +--- +*/ + +static foreach (a; Object) {} diff --git a/gcc/testsuite/gfortran.dg/pr101026.f b/gcc/testsuite/gfortran.dg/pr101026.f new file mode 100644 index 0000000..9576d88 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr101026.f @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-options "-Ofast -frounding-math" } + SUBROUTINE PASSB4 (CC,CH) + DIMENSION CC(IDO,4,L1), CH(IDO,L1,*) + DO 103 I=2,IDO,2 + TI4 = CC0-CC(I,4,K) + CI4 = TI1-TI4 + CH(I-1,K,4) = CI4 + CH(I,K,4) = CI4 + 103 CONTINUE + END diff --git a/gcc/timevar.c b/gcc/timevar.c index 8fc122b..5f54215 100644 --- a/gcc/timevar.c +++ b/gcc/timevar.c @@ -198,10 +198,8 @@ timer::named_items::pop () void timer::named_items::print (FILE *fp, const timevar_time_def *total) { - unsigned int i; - const char *item_name; fprintf (fp, "Client items:\n"); - FOR_EACH_VEC_ELT (m_names, i, item_name) + for (const char *item_name : m_names) { timer::timevar_def *def = m_hash_map.get (item_name); gcc_assert (def); diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index b736e17..a016ee4 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -950,9 +950,7 @@ cleanup_control_flow_pre () /* If we've marked .ABNORMAL_DISPATCHER basic block(s) as visited above, but haven't marked any of their successors as visited, unmark them now, so that they can be removed as useless. */ - basic_block dispatcher_bb; - unsigned int k; - FOR_EACH_VEC_ELT (abnormal_dispatchers, k, dispatcher_bb) + for (basic_block dispatcher_bb : abnormal_dispatchers) { edge e; edge_iterator ei; @@ -1015,9 +1013,7 @@ cleanup_tree_cfg_noloop (unsigned ssa_update_flags) if (!dom_info_available_p (CDI_DOMINATORS)) mark_dfs_back_edges (); - loop_p loop; - unsigned i; - FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop) + for (loop_p loop : *get_loops (cfun)) if (loop && loop->header) { basic_block bb = loop->header; diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index b37c234..6f3352f 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -170,10 +170,7 @@ ref_contains_union_access_p (tree ref) static void dump_data_references (FILE *file, vec<data_reference_p> datarefs) { - unsigned int i; - struct data_reference *dr; - - FOR_EACH_VEC_ELT (datarefs, i, dr) + for (data_reference *dr : datarefs) dump_data_reference (file, dr); } @@ -378,10 +375,7 @@ DEBUG_FUNCTION void print_dir_vectors (FILE *outf, vec<lambda_vector> dir_vects, int length) { - unsigned j; - lambda_vector v; - - FOR_EACH_VEC_ELT (dir_vects, j, v) + for (lambda_vector v : dir_vects) print_direction_vector (outf, v, length); } @@ -403,10 +397,7 @@ DEBUG_FUNCTION void print_dist_vectors (FILE *outf, vec<lambda_vector> dist_vects, int length) { - unsigned j; - lambda_vector v; - - FOR_EACH_VEC_ELT (dist_vects, j, v) + for (lambda_vector v : dist_vects) print_lambda_vector (outf, v, length); } @@ -499,10 +490,7 @@ DEBUG_FUNCTION void dump_data_dependence_relations (FILE *file, vec<ddr_p> ddrs) { - unsigned int i; - struct data_dependence_relation *ddr; - - FOR_EACH_VEC_ELT (ddrs, i, ddr) + for (data_dependence_relation *ddr : ddrs) dump_data_dependence_relation (file, ddr); } @@ -538,21 +526,17 @@ debug_data_dependence_relations (vec<ddr_p> ddrs) DEBUG_FUNCTION void dump_dist_dir_vectors (FILE *file, vec<ddr_p> ddrs) { - unsigned int i, j; - struct data_dependence_relation *ddr; - lambda_vector v; - - FOR_EACH_VEC_ELT (ddrs, i, ddr) + for (data_dependence_relation *ddr : ddrs) if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE && DDR_AFFINE_P (ddr)) { - FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), j, v) + for (lambda_vector v : DDR_DIST_VECTS (ddr)) { fprintf (file, "DISTANCE_V ("); print_lambda_vector (file, v, DDR_NB_LOOPS (ddr)); fprintf (file, ")\n"); } - FOR_EACH_VEC_ELT (DDR_DIR_VECTS (ddr), j, v) + for (lambda_vector v : DDR_DIR_VECTS (ddr)) { fprintf (file, "DIRECTION_V ("); print_direction_vector (file, v, DDR_NB_LOOPS (ddr)); @@ -568,10 +552,7 @@ dump_dist_dir_vectors (FILE *file, vec<ddr_p> ddrs) DEBUG_FUNCTION void dump_ddrs (FILE *file, vec<ddr_p> ddrs) { - unsigned int i; - struct data_dependence_relation *ddr; - - FOR_EACH_VEC_ELT (ddrs, i, ddr) + for (data_dependence_relation *ddr : ddrs) dump_data_dependence_relation (file, ddr); fprintf (file, "\n\n"); @@ -2668,19 +2649,17 @@ create_runtime_alias_checks (class loop *loop, tree part_cond_expr; fold_defer_overflow_warnings (); - dr_with_seg_len_pair_t *alias_pair; - unsigned int i; - FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) + for (const dr_with_seg_len_pair_t &alias_pair : alias_pairs) { - gcc_assert (alias_pair->flags); + gcc_assert (alias_pair.flags); if (dump_enabled_p ()) dump_printf (MSG_NOTE, "create runtime check for data references %T and %T\n", - DR_REF (alias_pair->first.dr), - DR_REF (alias_pair->second.dr)); + DR_REF (alias_pair.first.dr), + DR_REF (alias_pair.second.dr)); /* Create condition expression for each pair data references. */ - create_intersect_range_checks (loop, &part_cond_expr, *alias_pair); + create_intersect_range_checks (loop, &part_cond_expr, alias_pair); if (*cond_expr) *cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, *cond_expr, part_cond_expr); @@ -3436,10 +3415,7 @@ free_conflict_function (conflict_function *f) static void free_subscripts (vec<subscript_p> subscripts) { - unsigned i; - subscript_p s; - - FOR_EACH_VEC_ELT (subscripts, i, s) + for (subscript_p s : subscripts) { free_conflict_function (s->conflicting_iterations_in_a); free_conflict_function (s->conflicting_iterations_in_b); @@ -4980,10 +4956,7 @@ analyze_overlapping_iterations (tree chrec_a, static void save_dist_v (struct data_dependence_relation *ddr, lambda_vector dist_v) { - unsigned i; - lambda_vector v; - - FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, v) + for (lambda_vector v : DDR_DIST_VECTS (ddr)) if (lambda_vector_equal (v, dist_v, DDR_NB_LOOPS (ddr))) return; @@ -4995,10 +4968,7 @@ save_dist_v (struct data_dependence_relation *ddr, lambda_vector dist_v) static void save_dir_v (struct data_dependence_relation *ddr, lambda_vector dir_v) { - unsigned i; - lambda_vector v; - - FOR_EACH_VEC_ELT (DDR_DIR_VECTS (ddr), i, v) + for (lambda_vector v : DDR_DIR_VECTS (ddr)) if (lambda_vector_equal (v, dir_v, DDR_NB_LOOPS (ddr))) return; @@ -5135,10 +5105,7 @@ static bool invariant_access_functions (const struct data_dependence_relation *ddr, int lnum) { - unsigned i; - subscript *sub; - - FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub) + for (subscript *sub : DDR_SUBSCRIPTS (ddr)) if (!evolution_function_is_invariant_p (SUB_ACCESS_FN (sub, 0), lnum) || !evolution_function_is_invariant_p (SUB_ACCESS_FN (sub, 1), lnum)) return false; @@ -5307,10 +5274,7 @@ add_distance_for_zero_overlaps (struct data_dependence_relation *ddr) static inline bool same_access_functions (const struct data_dependence_relation *ddr) { - unsigned i; - subscript *sub; - - FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub) + for (subscript *sub : DDR_SUBSCRIPTS (ddr)) if (!eq_evolutions_p (SUB_ACCESS_FN (sub, 0), SUB_ACCESS_FN (sub, 1))) return false; @@ -5587,11 +5551,8 @@ static bool access_functions_are_affine_or_constant_p (const struct data_reference *a, const class loop *loop_nest) { - unsigned int i; vec<tree> fns = DR_ACCESS_FNS (a); - tree t; - - FOR_EACH_VEC_ELT (fns, i, t) + for (tree t : fns) if (!evolution_function_is_invariant_p (t, loop_nest->num) && !evolution_function_is_affine_multivariate_p (t, loop_nest->num)) return false; @@ -5902,20 +5863,18 @@ opt_result find_data_references_in_stmt (class loop *nest, gimple *stmt, vec<data_reference_p> *datarefs) { - unsigned i; auto_vec<data_ref_loc, 2> references; - data_ref_loc *ref; data_reference_p dr; if (get_references_in_stmt (stmt, &references)) return opt_result::failure_at (stmt, "statement clobbers memory: %G", stmt); - FOR_EACH_VEC_ELT (references, i, ref) + for (const data_ref_loc &ref : references) { dr = create_data_ref (nest ? loop_preheader_edge (nest) : NULL, - loop_containing_stmt (stmt), ref->ref, - stmt, ref->is_read, ref->is_conditional_in_stmt); + loop_containing_stmt (stmt), ref.ref, + stmt, ref.is_read, ref.is_conditional_in_stmt); gcc_assert (dr != NULL); datarefs->safe_push (dr); } @@ -5933,19 +5892,17 @@ bool graphite_find_data_references_in_stmt (edge nest, loop_p loop, gimple *stmt, vec<data_reference_p> *datarefs) { - unsigned i; auto_vec<data_ref_loc, 2> references; - data_ref_loc *ref; bool ret = true; data_reference_p dr; if (get_references_in_stmt (stmt, &references)) return false; - FOR_EACH_VEC_ELT (references, i, ref) + for (const data_ref_loc &ref : references) { - dr = create_data_ref (nest, loop, ref->ref, stmt, ref->is_read, - ref->is_conditional_in_stmt); + dr = create_data_ref (nest, loop, ref.ref, stmt, ref.is_read, + ref.is_conditional_in_stmt); gcc_assert (dr != NULL); datarefs->safe_push (dr); } @@ -6253,10 +6210,7 @@ free_dependence_relation (struct data_dependence_relation *ddr) void free_dependence_relations (vec<ddr_p> dependence_relations) { - unsigned int i; - struct data_dependence_relation *ddr; - - FOR_EACH_VEC_ELT (dependence_relations, i, ddr) + for (data_dependence_relation *ddr : dependence_relations) if (ddr) free_dependence_relation (ddr); @@ -6268,10 +6222,7 @@ free_dependence_relations (vec<ddr_p> dependence_relations) void free_data_refs (vec<data_reference_p> datarefs) { - unsigned int i; - struct data_reference *dr; - - FOR_EACH_VEC_ELT (datarefs, i, dr) + for (data_reference *dr : datarefs) free_data_ref (dr); datarefs.release (); } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 9eb08d2..4a0dc3b 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3260,13 +3260,10 @@ copy_debug_stmt (gdebug *stmt, copy_body_data *id) static void copy_debug_stmts (copy_body_data *id) { - size_t i; - gdebug *stmt; - if (!id->debug_stmts.exists ()) return; - FOR_EACH_VEC_ELT (id->debug_stmts, i, stmt) + for (gdebug *stmt : id->debug_stmts) copy_debug_stmt (stmt, id); id->debug_stmts.release (); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 85adb1a..8045e34 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1638,14 +1638,11 @@ debug_defs_stack (int n) void dump_currdefs (FILE *file) { - unsigned i; - tree var; - if (symbols_to_rename.is_empty ()) return; fprintf (file, "\n\nCurrent reaching definitions\n\n"); - FOR_EACH_VEC_ELT (symbols_to_rename, i, var) + for (tree var : symbols_to_rename) { common_info *info = get_common_info (var); fprintf (file, "CURRDEF ("); @@ -2069,18 +2066,16 @@ rewrite_update_phi_arguments (basic_block bb) { edge e; edge_iterator ei; - unsigned i; FOR_EACH_EDGE (e, ei, bb->succs) { - gphi *phi; vec<gphi *> phis; if (!bitmap_bit_p (blocks_with_phis_to_rewrite, e->dest->index)) continue; phis = phis_to_rewrite[e->dest->index]; - FOR_EACH_VEC_ELT (phis, i, phi) + for (gphi *phi : phis) { tree arg, lhs_sym, reaching_def = NULL; use_operand_p arg_p; diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index d8a4f55..bcbe669 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -442,8 +442,9 @@ dump_omp_iterators (pretty_printer *pp, tree iter, int spc, dump_flags_t flags) } -/* Dump OpenMP clause CLAUSE. PP, CLAUSE, SPC and FLAGS are as in - dump_generic_node. */ +/* Dump OMP clause CLAUSE, without following OMP_CLAUSE_CHAIN. + + PP, CLAUSE, SPC and FLAGS are as in dump_generic_node. */ static void dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) @@ -1315,23 +1316,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) } -/* Dump the list of OpenMP clauses. PP, SPC and FLAGS are as in - dump_generic_node. */ +/* Dump chain of OMP clauses. + + PP, SPC and FLAGS are as in dump_generic_node. */ void -dump_omp_clauses (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) +dump_omp_clauses (pretty_printer *pp, tree clause, int spc, dump_flags_t flags, + bool leading_space) { - if (clause == NULL) - return; - - pp_space (pp); - while (1) + while (clause) { + if (leading_space) + pp_space (pp); dump_omp_clause (pp, clause, spc, flags); + leading_space = true; + clause = OMP_CLAUSE_CHAIN (clause); - if (clause == NULL) - return; - pp_space (pp); } } @@ -3641,7 +3641,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, goto dump_omp_body; case OMP_CLAUSE: - dump_omp_clause (pp, node, spc, flags); + /* If we come here, we're dumping something that's not an OMP construct, + for example, OMP clauses attached to a function's '__attribute__'. + Dump the whole OMP clause chain. */ + dump_omp_clauses (pp, node, spc, flags, false); is_expr = false; break; diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h index 92eb412..cafe9aa 100644 --- a/gcc/tree-pretty-print.h +++ b/gcc/tree-pretty-print.h @@ -39,7 +39,8 @@ extern void print_generic_stmt (FILE *, tree, dump_flags_t = TDF_NONE); extern void print_generic_stmt_indented (FILE *, tree, dump_flags_t, int); extern void print_generic_expr (FILE *, tree, dump_flags_t = TDF_NONE); extern char *print_generic_expr_to_str (tree); -extern void dump_omp_clauses (pretty_printer *, tree, int, dump_flags_t); +extern void dump_omp_clauses (pretty_printer *, tree, int, dump_flags_t, + bool = true); extern void dump_omp_atomic_memory_order (pretty_printer *, enum omp_memory_order); extern void dump_omp_loop_non_rect_expr (pretty_printer *, tree, int, diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 8034cf6..1c865b2 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -2169,6 +2169,7 @@ execute_sm (class loop *loop, im_mem_ref *ref, enum sm_kind { sm_ord, sm_unord, sm_other }; struct seq_entry { + seq_entry () {} seq_entry (unsigned f, sm_kind k, tree fr = NULL) : first (f), second (k), from (fr) {} unsigned first; @@ -2352,6 +2353,8 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef, unsigned min_len = MIN(first_edge_seq.length (), edge_seq.length ()); /* Incrementally merge seqs into first_edge_seq. */ + int first_uneq = -1; + auto_vec<seq_entry, 2> extra_refs; for (unsigned int i = 0; i < min_len; ++i) { /* ??? We can more intelligently merge when we face different @@ -2367,6 +2370,11 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef, bitmap_set_bit (refs_not_supported, edge_seq[i].first); first_edge_seq[i].second = sm_other; first_edge_seq[i].from = NULL_TREE; + /* Record the dropped refs for later processing. */ + if (first_uneq == -1) + first_uneq = i; + extra_refs.safe_push (seq_entry (edge_seq[i].first, + sm_other, NULL_TREE)); } /* sm_other prevails. */ else if (first_edge_seq[i].second != edge_seq[i].second) @@ -2399,10 +2407,36 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef, } else if (edge_seq.length () > first_edge_seq.length ()) { + if (first_uneq == -1) + first_uneq = first_edge_seq.length (); for (unsigned i = first_edge_seq.length (); i < edge_seq.length (); ++i) - if (edge_seq[i].second == sm_ord) - bitmap_set_bit (refs_not_supported, edge_seq[i].first); + { + if (edge_seq[i].second == sm_ord) + bitmap_set_bit (refs_not_supported, edge_seq[i].first); + extra_refs.safe_push (seq_entry (edge_seq[i].first, + sm_other, NULL_TREE)); + } + } + /* Put unmerged refs at first_uneq to force dependence checking + on them. */ + if (first_uneq != -1) + { + /* Missing ordered_splice_at. */ + if ((unsigned)first_uneq == first_edge_seq.length ()) + first_edge_seq.safe_splice (extra_refs); + else + { + unsigned fes_length = first_edge_seq.length (); + first_edge_seq.safe_grow (fes_length + + extra_refs.length ()); + memmove (&first_edge_seq[first_uneq + extra_refs.length ()], + &first_edge_seq[first_uneq], + (fes_length - first_uneq) * sizeof (seq_entry)); + memcpy (&first_edge_seq[first_uneq], + extra_refs.address (), + extra_refs.length () * sizeof (seq_entry)); + } } } /* Use the sequence from the first edge and push SMs down. */ diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index b3dcd43..d93ec90 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -1258,8 +1258,6 @@ propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val) unsigned clean_up_loop_closed_phi (function *fun) { - unsigned i; - edge e; gphi *phi; tree rhs; tree lhs; @@ -1280,7 +1278,7 @@ clean_up_loop_closed_phi (function *fun) { /* Check each exit edege of loop. */ auto_vec<edge> exits = get_loop_exit_edges (loop); - FOR_EACH_VEC_ELT (exits, i, e) + for (edge e : exits) if (single_pred_p (e->dest)) /* Walk over loop-closed PHIs. */ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);) diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 6dfc703..2dd4435 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -1062,7 +1062,7 @@ eliminate_using_constants (enum tree_code opcode, if (integer_zerop (oelast->op) || (FLOAT_TYPE_P (type) && (opcode == PLUS_EXPR || opcode == MINUS_EXPR) - && fold_real_zero_addition_p (type, oelast->op, + && fold_real_zero_addition_p (type, 0, oelast->op, opcode == MINUS_EXPR))) { if (ops->length () != 1) diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 423075b..6add8c9 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1284,16 +1284,19 @@ maybe_invalidate (gimple *stmt, bool zero_write = false) continue; ao_ref r; - tree size = NULL_TREE; - if (si->nonzero_chars) + tree size = si->nonzero_chars; + ao_ref_init_from_ptr_and_size (&r, si->ptr, size); + /* Include the terminating nul in the size of the string + to consider when determining possible clobber. But do not + add it to 'size' since we don't know whether it would + actually fit the allocated area. */ + if (known_size_p (r.size)) { - /* Include the terminating nul in the size of the string - to consider when determining possible clobber. */ - tree type = TREE_TYPE (si->nonzero_chars); - size = fold_build2 (PLUS_EXPR, type, si->nonzero_chars, - build_int_cst (type, 1)); + if (known_le (r.size, HOST_WIDE_INT_MAX - BITS_PER_UNIT)) + r.max_size += BITS_PER_UNIT; + else + r.max_size = -1; } - ao_ref_init_from_ptr_and_size (&r, si->ptr, size); if (stmt_may_clobber_ref_p_1 (stmt, &r)) { if (dump_file && (dump_flags & TDF_DETAILS)) diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index b317df5..2694d1a 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -290,9 +290,7 @@ vect_analyze_possibly_independent_ddr (data_dependence_relation *ddr, int loop_depth, unsigned int *max_vf) { class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - lambda_vector dist_v; - unsigned int i; - FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v) + for (lambda_vector &dist_v : DDR_DIST_VECTS (ddr)) { int dist = dist_v[loop_depth]; if (dist != 0 && !(dist > 0 && DDR_REVERSED_P (ddr))) @@ -729,9 +727,8 @@ vect_slp_analyze_node_dependences (vec_info *vinfo, slp_tree node, { if (stmt_info != last_store_info) continue; - unsigned i; - stmt_vec_info store_info; - FOR_EACH_VEC_ELT (stores, i, store_info) + + for (stmt_vec_info &store_info : stores) { data_reference *store_dr = STMT_VINFO_DATA_REF (store_info); @@ -804,9 +801,8 @@ vect_slp_analyze_node_dependences (vec_info *vinfo, slp_tree node, { if (stmt_info != last_store_info) continue; - unsigned i; - stmt_vec_info store_info; - FOR_EACH_VEC_ELT (stores, i, store_info) + + for (stmt_vec_info &store_info : stores) { data_reference *store_dr = STMT_VINFO_DATA_REF (store_info); @@ -868,9 +864,7 @@ vect_slp_analyze_instance_dependence (vec_info *vinfo, slp_instance instance) /* Verify we can sink loads to the vectorized stmt insert location, special-casing stores of this instance. */ - slp_tree load; - unsigned int i; - FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, load) + for (slp_tree &load : SLP_INSTANCE_LOADS (instance)) if (! vect_slp_analyze_node_dependences (vinfo, load, store ? SLP_TREE_SCALAR_STMTS (store) @@ -927,9 +921,7 @@ vect_record_base_alignments (vec_info *vinfo) { loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); class loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL; - data_reference *dr; - unsigned int i; - FOR_EACH_VEC_ELT (vinfo->shared->datarefs, i, dr) + for (data_reference *dr : vinfo->shared->datarefs) { dr_vec_info *dr_info = vinfo->lookup_dr (dr); stmt_vec_info stmt_info = dr_info->stmt; @@ -1463,10 +1455,8 @@ vect_get_peeling_costs_all_drs (loop_vec_info loop_vinfo, bool unknown_misalignment) { vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); - unsigned i; - data_reference *dr; - FOR_EACH_VEC_ELT (datarefs, i, dr) + for (data_reference *dr : datarefs) { dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr); if (!vect_relevant_for_alignment_p (dr_info)) @@ -1575,13 +1565,11 @@ static bool vect_peeling_supportable (loop_vec_info loop_vinfo, dr_vec_info *dr0_info, unsigned npeel) { - unsigned i; - struct data_reference *dr = NULL; vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo); enum dr_alignment_support supportable_dr_alignment; /* Ensure that all data refs can be vectorized after the peel. */ - FOR_EACH_VEC_ELT (datarefs, i, dr) + for (data_reference *dr : datarefs) { int save_misalignment; diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 6237a61..9ded585 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1849,18 +1849,34 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, mismatch still hard-FAIL. */ if (chain_len == 0) hard_fail = false; + else + { + matches[lane] = false; + /* ??? We might want to process the other lanes, but + make sure to not give false matching hints to the + caller for lanes we did not process. */ + if (lane != group_size - 1) + matches[0] = false; + } break; } else if (chain_len == 0) chain_len = chain.length (); else if (chain.length () != chain_len) - /* ??? Here we could slip in magic to compensate with - neutral operands. */ - break; + { + /* ??? Here we could slip in magic to compensate with + neutral operands. */ + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; + break; + } chains.quick_push (chain.copy ()); chain.truncate (0); } - if (chains.length () == group_size) + if (chains.length () == group_size + /* We cannot yet use SLP_TREE_CODE to communicate the operation. */ + && op_stmt_info) { /* Now we have a set of chains with the same length. */ /* 1. pre-sort according to def_type and operation. */ @@ -1903,6 +1919,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, dump_printf_loc (MSG_NOTE, vect_location, "giving up on chain due to mismatched " "def types\n"); + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; goto out; } if (dt == vect_constant_def @@ -1981,6 +2000,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, dump_printf_loc (MSG_NOTE, vect_location, "failed to match up op %d\n", n); op_stmts.release (); + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; goto out; } if (dump_enabled_p ()) diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 63ba594..9748043 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -469,10 +469,7 @@ vec_info::vec_info (vec_info::vec_kind kind_in, void *target_cost_data_in, vec_info::~vec_info () { - slp_instance instance; - unsigned int i; - - FOR_EACH_VEC_ELT (slp_instances, i, instance) + for (slp_instance &instance : slp_instances) vect_free_slp_instance (instance); destroy_cost_data (target_cost_data); @@ -739,9 +736,7 @@ vec_info::set_vinfo_for_stmt (gimple *stmt, stmt_vec_info info, bool check_ro) void vec_info::free_stmt_vec_infos (void) { - unsigned int i; - stmt_vec_info info; - FOR_EACH_VEC_ELT (stmt_vec_infos, i, info) + for (stmt_vec_info &info : stmt_vec_infos) if (info != NULL) free_stmt_vec_info (info); stmt_vec_infos.release (); diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 9047e27..93609f3 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -397,14 +397,20 @@ get_range_global (irange &r, tree name) r.set_varying (type); } -// ?? Like above, but only for default definitions of NAME. This is -// so VRP passes using ranger do not start with known ranges, -// otherwise we'd eliminate builtin_unreachables too early because of -// inlining. +// This is where the ranger picks up global info to seed initial +// requests. It is a slightly restricted version of +// get_range_global() above. +// +// The reason for the difference is that we can always pick the +// default definition of an SSA with no adverse effects, but for other +// SSAs, if we pick things up to early, we may prematurely eliminate +// builtin_unreachables. // // Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has -// all of its unreachable calls removed too early. We should -// investigate whether we should just adjust the test above. +// all of its unreachable calls removed too early. +// +// See discussion here: +// https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html value_range gimple_range_global (tree name) @@ -412,7 +418,7 @@ gimple_range_global (tree name) gcc_checking_assert (gimple_range_ssa_p (name)); tree type = TREE_TYPE (name); - if (SSA_NAME_IS_DEFAULT_DEF (name)) + if (SSA_NAME_IS_DEFAULT_DEF (name) || (cfun && cfun->after_inlining)) { value_range vr; get_range_global (vr, name); diff --git a/intl/configure b/intl/configure index 1e10039..9d4f500 100755 --- a/intl/configure +++ b/intl/configure @@ -5983,13 +5983,19 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif + int main () { bindtextdomain ("", ""); -return (int) gettext ("") + (int) ngettext ("", "", 0) + _nl_msg_cat_cntr + *_nl_domain_bindings +return (int) gettext ("") + (int) ngettext ("", "", 0) + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } @@ -6412,17 +6418,23 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (0)) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif + int main () { bindtextdomain ("", ""); -return (int) gettext ("") + (int) ngettext ("", "", 0) + _nl_msg_cat_cntr + *_nl_expand_alias (0) +return (int) gettext ("") + (int) ngettext ("", "", 0) + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } @@ -6439,17 +6451,23 @@ rm -f core conftest.err conftest.$ac_objext \ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <libintl.h> +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (0)) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif + int main () { bindtextdomain ("", ""); -return (int) gettext ("") + (int) ngettext ("", "", 0) + _nl_msg_cat_cntr + *_nl_expand_alias (0) +return (int) gettext ("") + (int) ngettext ("", "", 0) + __GNU_GETTEXT_SYMBOL_EXPRESSION ; return 0; } diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 62852e6..dc52ff5 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,11 @@ +2021-06-11 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + PR target/99939 + * config/arm/cmse_nonsecure_call.S: Add __ARM_FEATURE_MVE + macro. + * config/arm/t-arm: To link cmse.o and cmse_nonsecure_call.o + on passing -mcmse option. + 2021-06-10 Segher Boessenkool <segher@kernel.crashing.org> * config/rs6000/quad-float128.h: Guard all uses of [U]TItype_ppc by diff --git a/libgcc/config/arm/cmse_nonsecure_call.S b/libgcc/config/arm/cmse_nonsecure_call.S index 146f3ed..00830ad 100644 --- a/libgcc/config/arm/cmse_nonsecure_call.S +++ b/libgcc/config/arm/cmse_nonsecure_call.S @@ -25,7 +25,7 @@ .syntax unified #ifdef __ARM_PCS_VFP -# if __ARM_FP & 0x8 +# if (__ARM_FP & 0x8) || (__ARM_FEATURE_MVE & 1) .fpu fpv5-d16 # else .fpu fpv4-sp-d16 @@ -59,7 +59,7 @@ vmov s24, s25, r5, r5 vmov s26, s27, r5, r5 vmov s28, s29, r5, r5 vmov s30, s31, r5, r5 -#elif __ARM_FP & 0x08 +#elif (__ARM_FP & 0x8) || (__ARM_FEATURE_MVE & 1) vmov.f64 d9, d8 vmov.f64 d10, d8 vmov.f64 d11, d8 diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm index 3625a25..c1553d4 100644 --- a/libgcc/config/arm/t-arm +++ b/libgcc/config/arm/t-arm @@ -3,18 +3,17 @@ LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \ _thumb1_case_uhi _thumb1_case_si _speculation_barrier HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - </dev/null)) -HAVE_V81M:=$(findstring armv8.1-m.main,$(gcc_compile_bare)) ifeq ($(shell $(gcc_compile_bare) -E -mcmse - </dev/null >/dev/null 2>/dev/null; echo $$?),0) CMSE_OPTS:=-mcmse endif ifdef HAVE_CMSE -ifndef HAVE_V81M + libgcc-objects += cmse.o cmse_nonsecure_call.o cmse.o: $(srcdir)/config/arm/cmse.c $(gcc_compile) -c $(CMSE_OPTS) $< + cmse_nonsecure_call.o: $(srcdir)/config/arm/cmse_nonsecure_call.S $(gcc_compile) -c $< endif -endif diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog index 7b57d92..60a67a9 100644 --- a/libphobos/ChangeLog +++ b/libphobos/ChangeLog @@ -1,3 +1,8 @@ +2021-06-11 Iain Buclaw <ibuclaw@gdcproject.org> + + PR d/100999 + * src/MERGE: Merge upstream phobos 55bb17543. + 2021-05-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * src/std/process.d (unittest): Remove tmpname on exit. diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index ac709f9..01cf594 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -63f4caa900e17c541042617b2fa187059b86bf88 +55bb17543138a87c376a84745f2a30ec00bdecd9 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index 55119fc..84e876f 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -5935,13 +5935,7 @@ mixin template Proxy(alias a) // built-in type field, manifest constant, and static non-mutable field enum opDispatch = mixin("a."~name); } - else static if (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0) - { - // field or property function - @property auto ref opDispatch(this X)() { return mixin("a."~name); } - @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } - } - else + else static if (__traits(isTemplate, mixin("a."~name))) { // member template template opDispatch(T...) @@ -5950,6 +5944,13 @@ mixin template Proxy(alias a) auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); } } } + else + { + // field or property function + @property auto ref opDispatch(this X)() { return mixin("a."~name); } + @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } + } + } import std.traits : isArray; diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 583ca4d..dfcf9bf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2021-06-11 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/fs_path.h (operator==, operator<=>): Use new + _S_compare function. + (path::_S_compare): New function to call path::compare in a + context where path::iterator is complete. + * include/experimental/bits/fs_path.h (operator<, operator==): + Define after path::iterator is complete. + * testsuite/27_io/filesystem/path/native/conv_c++23.cc: New + test. + * testsuite/experimental/filesystem/path/native/conv_c++23.cc: + New test. + 2021-06-09 Thomas Rodgers <rodgert@appliantology.com> * testsuite/29_atomics/atomic_ref/wait_notify.cc: Guard diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index ad2518f..5e28520 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -513,13 +513,13 @@ namespace __detail /// Compare paths friend bool operator==(const path& __lhs, const path& __rhs) noexcept - { return __lhs.compare(__rhs) == 0; } + { return path::_S_compare(__lhs, __rhs) == 0; } #if __cpp_lib_three_way_comparison /// Compare paths friend strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept - { return __lhs.compare(__rhs) <=> 0; } + { return path::_S_compare(__lhs, __rhs) <=> 0; } #else /// Compare paths friend bool operator!=(const path& __lhs, const path& __rhs) noexcept @@ -627,6 +627,11 @@ namespace __detail static basic_string<_CharT, _Traits, _Allocator> _S_str_convert(basic_string_view<value_type>, const _Allocator&); + // Returns lhs.compare(rhs), but defined after path::iterator is complete. + __attribute__((__always_inline__)) + static int + _S_compare(const path& __lhs, const path& __rhs) noexcept; + void _M_split_cmpts(); _Type _M_type() const noexcept { return _M_cmpts.type(); } @@ -1330,6 +1335,14 @@ namespace __detail return _M_at_end == __rhs._M_at_end; } + // Define this now that path and path::iterator are complete. + // It needs to consider the string_view(Range&&) constructor during + // overload resolution, which depends on whether range<path> is satisfied, + // which depends on whether path::iterator is complete. + inline int + path::_S_compare(const path& __lhs, const path& __rhs) noexcept + { return __lhs.compare(__rhs); } + /// @} group filesystem _GLIBCXX_END_NAMESPACE_CXX11 } // namespace filesystem diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 1ecf2f3..1fb84ec 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -551,8 +551,7 @@ namespace __detail size_t hash_value(const path& __p) noexcept; /// Compare paths - inline bool operator<(const path& __lhs, const path& __rhs) noexcept - { return __lhs.compare(__rhs) < 0; } + inline bool operator<(const path& __lhs, const path& __rhs) noexcept; /// Compare paths inline bool operator<=(const path& __lhs, const path& __rhs) noexcept @@ -567,8 +566,7 @@ namespace __detail { return !(__lhs < __rhs); } /// Compare paths - inline bool operator==(const path& __lhs, const path& __rhs) noexcept - { return __lhs.compare(__rhs) == 0; } + inline bool operator==(const path& __lhs, const path& __rhs) noexcept; /// Compare paths inline bool operator!=(const path& __lhs, const path& __rhs) noexcept @@ -1275,6 +1273,16 @@ namespace __detail return _M_at_end == __rhs._M_at_end; } + // Define these now that path and path::iterator are complete. + // They needs to consider the string_view(Range&&) constructor during + // overload resolution, which depends on whether range<path> is satisfied, + // which depends on whether path::iterator is complete. + inline bool operator<(const path& __lhs, const path& __rhs) noexcept + { return __lhs.compare(__rhs) < 0; } + + inline bool operator==(const path& __lhs, const path& __rhs) noexcept + { return __lhs.compare(__rhs) == 0; } + /// @} group filesystem-ts _GLIBCXX_END_NAMESPACE_CXX11 } // namespace v1 diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/native/conv_c++23.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/native/conv_c++23.cc new file mode 100644 index 0000000..b4efed2 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/native/conv_c++23.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++23" } +// { dg-do compile { target c++23 } } + +#include <filesystem> + +void +test01() +{ + using std::filesystem::path; + path p; + path::string_type s(p); +} diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/native/conv_c++23.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/native/conv_c++23.cc new file mode 100644 index 0000000..f3c3f88 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/path/native/conv_c++23.cc @@ -0,0 +1,12 @@ +// { dg-options "-std=gnu++23" } +// { dg-do compile { target c++23 } } + +#include <experimental/filesystem> + +void +test01() +{ + using std::experimental::filesystem::path; + path p; + path::string_type s(p); +} |