diff options
author | Martin Liska <mliska@suse.cz> | 2021-05-18 11:25:25 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-05-18 11:25:25 +0200 |
commit | 905b28242c5afcf0a46d74580f800c3b0bd1f6ae (patch) | |
tree | 2bb433d1de21259c7902fa89492224f208406a0e | |
parent | 6ec928c2ae25f84be1ca022be60dadea5140c155 (diff) | |
parent | 6806469dbed7e2613fad5468a94830c2cc817c95 (diff) | |
download | gcc-905b28242c5afcf0a46d74580f800c3b0bd1f6ae.zip gcc-905b28242c5afcf0a46d74580f800c3b0bd1f6ae.tar.gz gcc-905b28242c5afcf0a46d74580f800c3b0bd1f6ae.tar.bz2 |
Merge branch 'master' into devel/sphinx
107 files changed, 1372 insertions, 312 deletions
@@ -1,3 +1,7 @@ +2021-05-17 Serge Belyshev <belyshev@depni.sinp.msu.ru> + + * MAINTAINERS (Write After Approval): Add myself. + 2021-05-12 Marcel Vollweiler <marcel@codesourcery.com> * MAINTAINERS (Write After Approval): Add myself. diff --git a/MAINTAINERS b/MAINTAINERS index 5b10f21..fbaa183 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -317,6 +317,7 @@ Gergö Barany <gergo@codesourcery.com> Charles Baylis <charles.baylis@linaro.org> Tejas Belagod <tejas.belagod@arm.com> Matthew Beliveau <mbelivea@redhat.com> +Serge Belyshev <belyshev@depni.sinp.msu.ru> Jon Beniston <jon@beniston.com> Andrew Bennett <andrew.bennett@imgtec.com> Andrew Benson <abensonca@gmail.com> diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 8e393b7..b97710f 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,16 @@ +2021-05-17 Richard Biener <rguenther@suse.de> + + * download_prerequisites: Update mpfr version to 3.1.6. + * prerequisites.md5: Update. + * prerequisites.sha512: Likewise. + +2021-05-17 Richard Biener <rguenther@suse.de> + + Revert: + 2021-05-14 Martin Liska <mliska@suse.cz> + + * download_prerequisites: Use version 4.1.0. + 2021-05-14 Martin Liska <mliska@suse.cz> * download_prerequisites: Use version 4.1.0. diff --git a/contrib/gcc-changelog/git_email.py b/contrib/gcc-changelog/git_email.py index 6933e3d..fa62e3a 100755 --- a/contrib/gcc-changelog/git_email.py +++ b/contrib/gcc-changelog/git_email.py @@ -110,7 +110,7 @@ if __name__ == '__main__': print() print('Successfully parsed: %d/%d' % (success, len(allfiles))) else: - email = GitEmail(sys.argv[1], False) + email = GitEmail(sys.argv[1]) if email.success: print('OK') email.print_output() diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eeb293a..fe5132d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,118 @@ +2021-05-17 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/100512 + * gimple-range-cache.cc (ranger_cache::set_global_range): Mark const + and non-zero pointer ranges as invariant. + * gimple-range.cc (gimple_ranger::range_of_stmt): Remove pointer + processing from here. + +2021-05-17 Tom de Vries <tdevries@suse.de> + + PR target/100497 + * config/nvptx/nvptx-protos.h (nvptx_output_atomic_insn): Declare + * config/nvptx/nvptx.c (nvptx_output_barrier) + (nvptx_output_atomic_insn): New function. + (nvptx_print_operand): Add support for 'B'. + * config/nvptx/nvptx.md: Use nvptx_output_atomic_insn for atomic + insns. + +2021-05-17 Aldy Hernandez <aldyh@redhat.com> + + PR tree-optimization/100349 + * vr-values.c (bounds_of_var_in_loop): Bail if scev returns + NULL. + +2021-05-17 Tamar Christina <tamar.christina@arm.com> + + * config/aarch64/driver-aarch64.c (DEFAULT_ARCH): New. + (host_detect_local_cpu): Use it. + +2021-05-17 Martin Liska <mliska@suse.cz> + + * doc/invoke.texi: Add 2 missing dots. + +2021-05-17 Marius Hillenbrand <mhillen@linux.ibm.com> + + PR bootstrap/100552 + * configure.ac: Replace pattern substitution with call to sed. + * configure: Regenerate. + +2021-05-17 Richard Biener <rguenther@suse.de> + + PR middle-end/100582 + * tree.c (array_at_struct_end_p): Get to the base of the + reference before looking for the underlying decl. + +2021-05-17 Joern Rennecke <joern.rennecke@embecosm.com> + + * genoutput.c (validate_insn_alternatives) Make "wrong number of + alternatives" message more specific, and remove assumption on where + the problem is. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * config/arm/iterators.md (V16): New iterator. + (VH_cvtto): New iterator. + (v_cmp_result): Added V4HF and V8HF support. + * config/arm/vec-common.md (vec_cmp<mode><v_cmp_result>): Use VDQWH. + (vcond<mode><mode>): Likewise. + (vcond_mask_<mode><v_cmp_result>): Likewise. + (vcond<VH_cvtto><mode>): New expander. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * config/arm/arm-protos.h (arm_expand_vector_compare): Update + prototype. + * config/arm/arm.c (arm_expand_vector_compare): Add support for + MVE. + (arm_expand_vcond): Likewise. + * config/arm/iterators.md (supf): Remove VCMPNEQ_S, VCMPEQQ_S, + VCMPEQQ_N_S, VCMPNEQ_N_S. + (VCMPNEQ, VCMPEQQ, VCMPEQQ_N, VCMPNEQ_N): Remove. + * config/arm/mve.md (@mve_vcmp<mve_cmp_op>q_<mode>): Add '@' prefix. + (@mve_vcmp<mve_cmp_op>q_f<mode>): Likewise. + (@mve_vcmp<mve_cmp_op>q_n_f<mode>): Likewise. + (@mve_vpselq_<supf><mode>): Likewise. + (@mve_vpselq_f<mode>"): Likewise. + * config/arm/neon.md (vec_cmp<mode><v_cmp_result): Enable for MVE + and move to vec-common.md. + (vec_cmpu<mode><mode>): Likewise. + (vcond<mode><mode>): Likewise. + (vcond<V_cvtto><mode>): Likewise. + (vcondu<mode><v_cmp_result>): Likewise. + (vcond_mask_<mode><v_cmp_result>): Likewise. + * config/arm/unspecs.md (VCMPNEQ_U, VCMPNEQ_S, VCMPEQQ_S) + (VCMPEQQ_N_S, VCMPNEQ_N_S, VCMPEQQ_U, CMPEQQ_N_U, VCMPNEQ_N_U) + (VCMPGEQ_N_S, VCMPGEQ_S, VCMPGTQ_N_S, VCMPGTQ_S, VCMPLEQ_N_S) + (VCMPLEQ_S, VCMPLTQ_N_S, VCMPLTQ_S, VCMPCSQ_N_U, VCMPCSQ_U) + (VCMPHIQ_N_U, VCMPHIQ_U): Remove. + * config/arm/vec-common.md (vec_cmp<mode><v_cmp_result): Moved + from neon.md. + (vec_cmpu<mode><mode>): Likewise. + (vcond<mode><mode>): Likewise. + (vcond<V_cvtto><mode>): Likewise. + (vcondu<mode><v_cmp_result>): Likewise. + (vcond_mask_<mode><v_cmp_result>): Likewise. Added unsafe math + condition. + +2021-05-17 liuhongt <hongtao.liu@intel.com> + + PR target/100549 + * config/i386/i386.c (ix86_gimple_fold_builtin): Use + gsi_insert_seq_before instead. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * doc/sourcebuild.texi (arm_qbit_ok): Rename into... + (arm_sat_ok): ...this. + +2021-05-17 Martin Liska <mliska@suse.cz> + + * lto-wrapper.c (merge_flto_options): Factor out a new function. + (merge_and_complain): Use it. + (run_gcc): Merge also linker command line -flto=foo argument + with IL files. + 2021-05-16 Christophe Lyon <christophe.lyon@linaro.org> * config/arm/arm.h (CPP_SPEC): Remove error message about diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 915a0b2..7fa5a77 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210517 +20210518 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1b5d3f4..1164554 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3030,7 +3030,7 @@ CFLAGS-build/genversion.o += -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ -DDEVPHASE=$(DEVPHASE_s) -DPKGVERSION=$(PKGVERSION_s) \ -DBUGURL=$(BUGURL_s) -build/genversion.o: genversion.c $(BCONFIG_H) $(SYSTEM_H) +build/genversion.o: genversion.c $(BCONFIG_H) $(SYSTEM_H) $(srcdir)/DATESTAMP build/genversion$(build_exeext): build/genversion.o +$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) \ diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7fc64a5..cc1019c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2021-05-17 Joern Rennecke <joern.rennecke@embecosm.com> + + * c-common.c (braced_list_to_string): Return CTOR unchanged + if host and target character sizes don't match. + 2021-05-14 Martin Liska <mliska@suse.cz> * c.opt: Add Warning keyword for 2 options. diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index f54388e..ecb32c7 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -4245,10 +4245,22 @@ type_valid_for_vector_size (tree type, tree atname, tree args, if (nunits & (nunits - 1)) { if (error_p) - error ("number of components of the vector not a power of two"); + error ("number of vector components %wu not a power of two", nunits); else warning (OPT_Wattributes, - "number of components of the vector not a power of two"); + "number of vector components %wu not a power of two", nunits); + return NULL_TREE; + } + + if (nunits >= (unsigned HOST_WIDE_INT)INT_MAX) + { + if (error_p) + error ("number of vector components %wu exceeds %d", + nunits, INT_MAX - 1); + else + warning (OPT_Wattributes, + "number of vector components %wu exceeds %d", + nunits, INT_MAX - 1); return NULL_TREE; } diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index a75832b..7d34f7c 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2021-05-17 Richard Biener <rguenther@suse.de> + + PR c/100625 + * gimple-parser.c (c_parser_gimple_label): Avoid building + a GIMPLE label with NULL label decl. + 2021-05-13 Martin Sebor <msebor@redhat.com> PR c/100550 diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index 3a6e72e..dfacf23 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -877,6 +877,11 @@ c_parser_gimple_statement (gimple_parser &parser, gimple_seq *seq) rhs.value = build3_loc (loc, COND_EXPR, TREE_TYPE (trueval.value), rhs.value, trueval.value, falseval.value); } + if (get_gimple_rhs_class (TREE_CODE (rhs.value)) == GIMPLE_INVALID_RHS) + { + c_parser_error (parser, "unexpected RHS for assignment"); + return; + } assign = gimple_build_assign (lhs.value, rhs.value); gimple_seq_add_stmt_without_update (seq, assign); gimple_set_location (assign, loc); @@ -1754,6 +1759,12 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser, c_parser_gimple_expr_list (parser, &exprlist); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + if (!FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr.value))) + { + c_parser_error (parser, "invalid call to non-function"); + expr.set_error (); + break; + } expr.value = build_call_array_loc (expr_loc, TREE_TYPE (TREE_TYPE (expr.value)), expr.value, exprlist.length (), exprlist.address ()); @@ -1887,7 +1898,8 @@ c_parser_gimple_label (gimple_parser &parser, gimple_seq *seq) gcc_assert (c_parser_next_token_is (parser, CPP_COLON)); c_parser_consume_token (parser); tree label = define_label (loc1, name); - gimple_seq_add_stmt_without_update (seq, gimple_build_label (label)); + if (label) + gimple_seq_add_stmt_without_update (seq, gimple_build_label (label)); return; } diff --git a/gcc/common/config/aarch64/aarch64-common.c b/gcc/common/config/aarch64/aarch64-common.c index 6763191..6d200a1 100644 --- a/gcc/common/config/aarch64/aarch64-common.c +++ b/gcc/common/config/aarch64/aarch64-common.c @@ -219,7 +219,7 @@ aarch64_parse_extension (const char *str, uint64_t *isa_flags, else len = strlen (str); - if (len >= 2 && strncmp (str, "no", 2) == 0) + if (len >= 2 && startswith (str, "no")) { adding_ext = 0; len -= 2; diff --git a/gcc/common/config/bfin/bfin-common.c b/gcc/common/config/bfin/bfin-common.c index 48a6fe8..a3ee4b5 100644 --- a/gcc/common/config/bfin/bfin-common.c +++ b/gcc/common/config/bfin/bfin-common.c @@ -313,7 +313,7 @@ bfin_handle_option (struct gcc_options *opts, i = 0; while ((p = bfin_cpus[i].name) != NULL) { - if (strncmp (arg, p, strlen (p)) == 0) + if (startswith (arg, p)) break; i++; } diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c index 34b74e5..d17bea6 100644 --- a/gcc/common/config/riscv/riscv-common.c +++ b/gcc/common/config/riscv/riscv-common.c @@ -804,12 +804,12 @@ riscv_subset_list::parse (const char *arch, location_t loc) riscv_subset_list *subset_list = new riscv_subset_list (arch, loc); riscv_subset_t *itr; const char *p = arch; - if (strncmp (p, "rv32", 4) == 0) + if (startswith (p, "rv32")) { subset_list->m_xlen = 32; p += 4; } - else if (strncmp (p, "rv64", 4) == 0) + else if (startswith (p, "rv64")) { subset_list->m_xlen = 64; p += 4; diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc index e16c81c..2cc3fba 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc @@ -191,12 +191,12 @@ parse_type (const function_instance &instance, const char *&format) if (ch == 'e') { - if (strncmp (format, "pattern", 7) == 0) + if (startswith (format, "pattern")) { format += 7; return acle_svpattern; } - if (strncmp (format, "prfop", 5) == 0) + if (startswith (format, "prfop")) { format += 5; return acle_svprfop; diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 85fd80e..0835646 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -17377,7 +17377,7 @@ aarch64_process_one_target_attr (char *arg_str) if (*str_to_check == '+') return aarch64_handle_attr_isa_flags (str_to_check); - if (len > 3 && strncmp (str_to_check, "no-", 3) == 0) + if (len > 3 && startswith (str_to_check, "no-")) { invert = true; str_to_check += 3; diff --git a/gcc/config/aarch64/driver-aarch64.c b/gcc/config/aarch64/driver-aarch64.c index e2935a1..b58591d 100644 --- a/gcc/config/aarch64/driver-aarch64.c +++ b/gcc/config/aarch64/driver-aarch64.c @@ -58,6 +58,8 @@ struct aarch64_core_data #define INVALID_IMP ((unsigned char) -1) #define INVALID_CORE ((unsigned)-1) #define ALL_VARIANTS ((unsigned)-1) +/* Default architecture to use if -mcpu=native did not detect a known CPU. */ +#define DEFAULT_ARCH "8A" #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \ { CORE_NAME, #ARCH, IMP, PART, VARIANT, FLAGS }, @@ -390,10 +392,18 @@ host_detect_local_cpu (int argc, const char **argv) && (aarch64_cpu_data[i].variant == ALL_VARIANTS || variants[0] == aarch64_cpu_data[i].variant)) break; + if (aarch64_cpu_data[i].name == NULL) - goto not_found; + { + aarch64_arch_driver_info* arch_info + = get_arch_from_id (DEFAULT_ARCH); + + gcc_assert (arch_info); - if (arch) + res = concat ("-march=", arch_info->name, NULL); + default_flags = arch_info->flags; + } + else if (arch) { const char *arch_id = aarch64_cpu_data[i].arch; aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 335f1db..c702e68 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -9457,11 +9457,11 @@ alpha_elf_section_type_flags (tree decl, const char *name, int reloc) unsigned int flags = 0; if (strcmp (name, ".sdata") == 0 - || strncmp (name, ".sdata.", 7) == 0 - || strncmp (name, ".gnu.linkonce.s.", 16) == 0 + || startswith (name, ".sdata.") + || startswith (name, ".gnu.linkonce.s.") || strcmp (name, ".sbss") == 0 - || strncmp (name, ".sbss.", 6) == 0 - || strncmp (name, ".gnu.linkonce.sb.", 17) == 0) + || startswith (name, ".sbss.") + || startswith (name, ".gnu.linkonce.sb.")) flags = SECTION_SMALL; flags |= default_section_type_flags (decl, name, reloc); diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md index c7ca306..dd63f93 100644 --- a/gcc/config/arc/simdext.md +++ b/gcc/config/arc/simdext.md @@ -2056,7 +2056,7 @@ [(set (match_operand:VCT 0 "register_operand" "=r") (neg:VCT (match_operand:VCT 1 "register_operand" "r")))] "TARGET_PLUS_DMPY" - "vsub<V_suffix)>\\t%0,0,%1" + "vsub<V_suffix>\\t%0,0,%1" [(set_attr "length" "8") (set_attr "type" "multi")]) diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c index 24711d5..0dbdc56 100644 --- a/gcc/config/arm/aarch-common.c +++ b/gcc/config/arm/aarch-common.c @@ -542,7 +542,7 @@ arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/, for (unsigned i = 0, n = outputs.length (); i < n; ++i) { const char *con = constraints[i]; - if (strncmp (con, "=@cc", 4) != 0) + if (!startswith (con, "=@cc")) continue; con += 4; if (strchr (con, ',') != NULL) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index eee3671..28cfd81 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -28169,7 +28169,7 @@ arm_file_start (void) else arm_print_asm_arch_directives (); } - else if (strncmp (arm_active_target.core_name, "generic", 7) == 0) + else if (startswith (arm_active_target.core_name, "generic")) { asm_fprintf (asm_out_file, "\t.arch %s\n", arm_active_target.core_name + 8); @@ -33054,7 +33054,7 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) else if (!strcmp (q, "general-regs-only")) opts->x_target_flags |= MASK_GENERAL_REGS_ONLY; - else if (!strncmp (q, "fpu=", 4)) + else if (startswith (q, "fpu=")) { int fpu_index; if (! opt_enum_arg_to_value (OPT_mfpu_, q + 4, @@ -33073,7 +33073,7 @@ arm_valid_target_attribute_rec (tree args, struct gcc_options *opts) } opts->x_arm_fpu_index = (enum fpu_type) fpu_index; } - else if (!strncmp (q, "arch=", 5)) + else if (startswith (q, "arch=")) { char *arch = q + 5; const arch_option *arm_selected_arch @@ -34105,7 +34105,7 @@ thumb1_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/, HARD_REG_SET & /*clobbered_regs*/) { for (unsigned i = 0, n = outputs.length (); i < n; ++i) - if (strncmp (constraints[i], "=@cc", 4) == 0) + if (startswith (constraints[i], "=@cc")) { sorry ("asm flags not supported in thumb1 mode"); break; diff --git a/gcc/config/arm/driver-arm.c b/gcc/config/arm/driver-arm.c index 21ae2d7..247eab3 100644 --- a/gcc/config/arm/driver-arm.c +++ b/gcc/config/arm/driver-arm.c @@ -82,7 +82,7 @@ host_detect_local_cpu (int argc, const char **argv) while (fgets (buf, sizeof (buf), f) != NULL) { /* Find the vendor table associated with this implementer. */ - if (strncmp (buf, "CPU implementer", sizeof ("CPU implementer") - 1) == 0) + if (startswith (buf, "CPU implementer")) { int i; for (i = 0; vendors_table[i].vendor_no != NULL; i++) @@ -94,7 +94,7 @@ host_detect_local_cpu (int argc, const char **argv) } /* Detect arch/cpu. */ - if (strncmp (buf, "CPU part", sizeof ("CPU part") - 1) == 0) + if (startswith (buf, "CPU part")) { int i; diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 06c84d5..c95c436 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -63,9 +63,6 @@ /* Maximal allowed offset for an address in the LD command */ #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) -/* Return true if STR starts with PREFIX and false, otherwise. */ -#define STR_PREFIX_P(STR,PREFIX) (strncmp (STR, PREFIX, strlen (PREFIX)) == 0) - /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the address space where data is to be located. As the only non-generic address spaces are all located in flash, @@ -1092,7 +1089,7 @@ avr_set_current_function (tree decl) that the name of the function is "__vector_NN" so as to catch when the user misspells the vector name. */ - if (!STR_PREFIX_P (name, "__vector")) + if (!startswith (name, "__vector")) warning_at (loc, OPT_Wmisspelled_isr, "%qs appears to be a misspelled " "%qs handler, missing %<__vector%> prefix", name, isr); #endif // AVR-LibC naming conventions @@ -9642,7 +9639,7 @@ static tree avr_handle_addr_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add) { - bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0); + bool io_p = startswith (IDENTIFIER_POINTER (name), "io"); location_t loc = DECL_SOURCE_LOCATION (*node); if (!VAR_P (*node)) @@ -10055,7 +10052,7 @@ avr_asm_output_aligned_decl_common (FILE * stream, /* __gnu_lto_slim is just a marker for the linker injected by toplev.c. There is no need to trigger __do_clear_bss code for them. */ - if (!STR_PREFIX_P (name, "__gnu_lto")) + if (!startswith (name, "__gnu_lto")) avr_need_clear_bss_p = true; if (local_p) @@ -10154,7 +10151,7 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl) const char *old_prefix = ".rodata"; const char *new_prefix = avr_addrspace[as].section_name; - if (STR_PREFIX_P (name, old_prefix)) + if (startswith (name, old_prefix)) { const char *sname = ACONCAT ((new_prefix, name + strlen (old_prefix), NULL)); @@ -10167,19 +10164,19 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl) } if (!avr_need_copy_data_p) - avr_need_copy_data_p = (STR_PREFIX_P (name, ".data") - || STR_PREFIX_P (name, ".gnu.linkonce.d")); + avr_need_copy_data_p = (startswith (name, ".data") + || startswith (name, ".gnu.linkonce.d")); if (!avr_need_copy_data_p #if defined HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH && avr_arch->flash_pm_offset == 0 #endif ) - avr_need_copy_data_p = (STR_PREFIX_P (name, ".rodata") - || STR_PREFIX_P (name, ".gnu.linkonce.r")); + avr_need_copy_data_p = (startswith (name, ".rodata") + || startswith (name, ".gnu.linkonce.r")); if (!avr_need_clear_bss_p) - avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss"); + avr_need_clear_bss_p = startswith (name, ".bss"); default_elf_asm_named_section (name, flags, decl); } @@ -10192,7 +10189,7 @@ avr_section_type_flags (tree decl, const char *name, int reloc) { unsigned int flags = default_section_type_flags (decl, name, reloc); - if (STR_PREFIX_P (name, ".noinit")) + if (startswith (name, ".noinit")) { if (decl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl) == NULL_TREE) @@ -10402,7 +10399,7 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) const char * old_prefix = ".rodata"; const char * new_prefix = avr_addrspace[as].section_name; - if (STR_PREFIX_P (name, old_prefix)) + if (startswith (name, old_prefix)) { const char *sname = ACONCAT ((new_prefix, name + strlen (old_prefix), NULL)); diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index f9ad1e5..e7e1d6c 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -862,14 +862,14 @@ c6x_in_small_data_p (const_tree exp) const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".neardata") == 0 - || strncmp (section, ".neardata.", 10) == 0 - || strncmp (section, ".gnu.linkonce.s.", 16) == 0 + || startswith (section, ".neardata.") + || startswith (section, ".gnu.linkonce.s.") || strcmp (section, ".bss") == 0 - || strncmp (section, ".bss.", 5) == 0 - || strncmp (section, ".gnu.linkonce.sb.", 17) == 0 + || startswith (section, ".bss.") + || startswith (section, ".gnu.linkonce.sb.") || strcmp (section, ".rodata") == 0 - || strncmp (section, ".rodata.", 8) == 0 - || strncmp (section, ".gnu.linkonce.s2.", 17) == 0) + || startswith (section, ".rodata.") + || startswith (section, ".gnu.linkonce.s2.")) return true; } else @@ -1063,7 +1063,7 @@ c6x_section_type_flags (tree decl, const char *name, int reloc) unsigned int flags = 0; if (strcmp (name, ".far") == 0 - || strncmp (name, ".far.", 5) == 0) + || startswith (name, ".far.")) flags |= SECTION_BSS; flags |= default_section_type_flags (decl, name, reloc); diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c index b0424a9..951a998 100644 --- a/gcc/config/darwin-c.c +++ b/gcc/config/darwin-c.c @@ -808,8 +808,7 @@ darwin_cfstring_ref_p (const_tree strp) tn = DECL_NAME (tn); return (tn && IDENTIFIER_POINTER (tn) - && !strncmp (IDENTIFIER_POINTER (tn), "CFStringRef", - strlen ("CFStringRef"))); + && startswith (IDENTIFIER_POINTER (tn), "CFStringRef")); } /* At present the behavior of this is undefined and it does nothing. */ @@ -843,7 +842,7 @@ darwin_objc_declare_unresolved_class_reference (const char *name) size_t len = strlen (reference) + strlen(name) + 2; char *buf = (char *) alloca (len); - gcc_checking_assert (!strncmp (name, ".objc_class_name_", 17)); + gcc_checking_assert (startswith (name, ".objc_class_name_")); snprintf (buf, len, "%s%s", reference, name); symtab->finalize_toplevel_asm (build_string (strlen (buf), buf)); @@ -856,8 +855,8 @@ darwin_objc_declare_class_definition (const char *name) size_t len = strlen (xname) + 7 + 5; char *buf = (char *) alloca (len); - gcc_checking_assert (!strncmp (name, ".objc_class_name_", 17) - || !strncmp (name, "*.objc_category_name_", 21)); + gcc_checking_assert (startswith (name, ".objc_class_name_") + || startswith (name, "*.objc_category_name_")); /* Mimic default_globalize_label. */ snprintf (buf, len, ".globl\t%s", xname); diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 5d17391..c4016fe 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -329,7 +329,7 @@ indirect_data (rtx sym_ref) lprefix = (((name[0] == '*' || name[0] == '&') && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L'))) - || (strncmp (name, "_OBJC_", 6) == 0)); + || (startswith (name, "_OBJC_"))); return ! lprefix; } @@ -1284,7 +1284,7 @@ darwin_encode_section_info (tree decl, rtx rtl, int first) tree o2meta = lookup_attribute ("OBJC2META", DECL_ATTRIBUTES (decl)); o2meta = o2meta ? TREE_VALUE (o2meta) : NULL_TREE; - if (o2meta && strncmp (IDENTIFIER_POINTER (o2meta), "V2_IVRF",7) == 0) + if (o2meta && startswith (IDENTIFIER_POINTER (o2meta), "V2_IVRF")) SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_MUST_INDIRECT; #endif } @@ -1443,58 +1443,58 @@ darwin_objc2_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) /* Most of the OBJC2 META-data end up in the base section, so check it first. */ - if (!strncmp (p, "V2_BASE", 7)) + if (startswith (p, "V2_BASE")) return base; - else if (!strncmp (p, "V2_CNAM", 7)) + else if (startswith (p, "V2_CNAM")) return darwin_sections[objc2_class_names_section]; - else if (!strncmp (p, "V2_MNAM", 7)) + else if (startswith (p, "V2_MNAM")) return darwin_sections[objc2_method_names_section]; - else if (!strncmp (p, "V2_MTYP", 7)) + else if (startswith (p, "V2_MTYP")) return darwin_sections[objc2_method_types_section]; - else if (!strncmp (p, "V2_STRG", 7)) + else if (startswith (p, "V2_STRG")) return darwin_sections[cstring_section]; - else if (!strncmp (p, "G2_META", 7) || !strncmp (p, "G2_CLAS", 7)) + else if (startswith (p, "G2_META") || startswith (p, "G2_CLAS")) return darwin_sections[objc2_classdefs_section]; - else if (!strncmp (p, "V2_PCOL", 7)) + else if (startswith (p, "V2_PCOL")) return ld_uses_coal_sects ? darwin_sections[data_coal_section] : darwin_sections[objc2_data_section]; - else if (!strncmp (p, "V2_MREF", 7)) + else if (startswith (p, "V2_MREF")) return darwin_sections[objc2_message_refs_section]; - else if (!strncmp (p, "V2_CLRF", 7)) + else if (startswith (p, "V2_CLRF")) return darwin_sections[objc2_classrefs_section]; - else if (!strncmp (p, "V2_SURF", 7)) + else if (startswith (p, "V2_SURF")) return darwin_sections[objc2_super_classrefs_section]; - else if (!strncmp (p, "V2_NLCL", 7)) + else if (startswith (p, "V2_NLCL")) return darwin_sections[objc2_nonlazy_class_section]; - else if (!strncmp (p, "V2_CLAB", 7)) + else if (startswith (p, "V2_CLAB")) { classes_seen = 1; return darwin_sections[objc2_classlist_section]; } - else if (!strncmp (p, "V2_SRFS", 7)) + else if (startswith (p, "V2_SRFS")) return darwin_sections[objc2_selector_refs_section]; - else if (!strncmp (p, "V2_NLCA", 7)) + else if (startswith (p, "V2_NLCA")) return darwin_sections[objc2_nonlazy_category_section]; - else if (!strncmp (p, "V2_CALA", 7)) + else if (startswith (p, "V2_CALA")) return darwin_sections[objc2_categorylist_section]; - else if (!strncmp (p, "V2_PLST", 7)) + else if (startswith (p, "V2_PLST")) return darwin_sections[objc2_protocollist_section]; - else if (!strncmp (p, "V2_PRFS", 7)) + else if (startswith (p, "V2_PRFS")) return darwin_sections[objc2_protocolrefs_section]; - else if (!strncmp (p, "V2_INFO", 7)) + else if (startswith (p, "V2_INFO")) return darwin_sections[objc2_image_info_section]; - else if (!strncmp (p, "V2_EHTY", 7)) + else if (startswith (p, "V2_EHTY")) return ld_uses_coal_sects ? darwin_sections[data_coal_section] : data_section; - else if (!strncmp (p, "V2_CSTR", 7)) + else if (startswith (p, "V2_CSTR")) return darwin_sections[objc2_constant_string_object_section]; - else if (!strncmp (p, "V2_IVRF", 7)) + else if (startswith (p, "V2_IVRF")) return darwin_sections[objc2_ivar_section]; /* Not recognized, default. */ @@ -1515,72 +1515,72 @@ darwin_objc1_section (tree decl ATTRIBUTE_UNUSED, tree meta, section * base) objc_metadata_seen = 1; /* String sections first, cos there are lots of strings. */ - if (!strncmp (p, "V1_STRG", 7)) + if (startswith (p, "V1_STRG")) return darwin_sections[cstring_section]; - else if (!strncmp (p, "V1_CLSN", 7)) + else if (startswith (p, "V1_CLSN")) return darwin_sections[objc_class_names_section]; - else if (!strncmp (p, "V1_METN", 7)) + else if (startswith (p, "V1_METN")) return darwin_sections[objc_meth_var_names_section]; - else if (!strncmp (p, "V1_METT", 7)) + else if (startswith (p, "V1_METT")) return darwin_sections[objc_meth_var_types_section]; - else if (!strncmp (p, "V1_CLAS", 7)) + else if (startswith (p, "V1_CLAS")) { classes_seen = 1; return darwin_sections[objc_class_section]; } - else if (!strncmp (p, "V1_META", 7)) + else if (startswith (p, "V1_META")) return darwin_sections[objc_meta_class_section]; - else if (!strncmp (p, "V1_CATG", 7)) + else if (startswith (p, "V1_CATG")) return darwin_sections[objc_category_section]; - else if (!strncmp (p, "V1_PROT", 7)) + else if (startswith (p, "V1_PROT")) return darwin_sections[objc_protocol_section]; - else if (!strncmp (p, "V1_CLCV", 7)) + else if (startswith (p, "V1_CLCV")) return darwin_sections[objc_class_vars_section]; - else if (!strncmp (p, "V1_CLIV", 7)) + else if (startswith (p, "V1_CLIV")) return darwin_sections[objc_instance_vars_section]; - else if (!strncmp (p, "V1_CLCM", 7)) + else if (startswith (p, "V1_CLCM")) return darwin_sections[objc_cls_meth_section]; - else if (!strncmp (p, "V1_CLIM", 7)) + else if (startswith (p, "V1_CLIM")) return darwin_sections[objc_inst_meth_section]; - else if (!strncmp (p, "V1_CACM", 7)) + else if (startswith (p, "V1_CACM")) return darwin_sections[objc_cat_cls_meth_section]; - else if (!strncmp (p, "V1_CAIM", 7)) + else if (startswith (p, "V1_CAIM")) return darwin_sections[objc_cat_inst_meth_section]; - else if (!strncmp (p, "V1_PNSM", 7)) + else if (startswith (p, "V1_PNSM")) return darwin_sections[objc_cat_inst_meth_section]; - else if (!strncmp (p, "V1_PCLM", 7)) + else if (startswith (p, "V1_PCLM")) return darwin_sections[objc_cat_cls_meth_section]; - else if (!strncmp (p, "V1_CLPR", 7)) + else if (startswith (p, "V1_CLPR")) return darwin_sections[objc_cat_cls_meth_section]; - else if (!strncmp (p, "V1_CAPR", 7)) + else if (startswith (p, "V1_CAPR")) return darwin_sections[objc_category_section]; /* ??? CHECK me. */ - else if (!strncmp (p, "V1_PRFS", 7)) + else if (startswith (p, "V1_PRFS")) return darwin_sections[objc_cat_cls_meth_section]; - else if (!strncmp (p, "V1_CLRF", 7)) + else if (startswith (p, "V1_CLRF")) return darwin_sections[objc_cls_refs_section]; - else if (!strncmp (p, "V1_SRFS", 7)) + else if (startswith (p, "V1_SRFS")) return darwin_sections[objc_selector_refs_section]; - else if (!strncmp (p, "V1_MODU", 7)) + else if (startswith (p, "V1_MODU")) return darwin_sections[objc_module_info_section]; - else if (!strncmp (p, "V1_SYMT", 7)) + else if (startswith (p, "V1_SYMT")) return darwin_sections[objc_symbols_section]; - else if (!strncmp (p, "V1_INFO", 7)) + else if (startswith (p, "V1_INFO")) return darwin_sections[objc_image_info_section]; - else if (!strncmp (p, "V1_PLST", 7)) + else if (startswith (p, "V1_PLST")) return darwin_sections[objc1_prop_list_section]; - else if (!strncmp (p, "V1_PEXT", 7)) + else if (startswith (p, "V1_PEXT")) return darwin_sections[objc1_protocol_ext_section]; - else if (!strncmp (p, "V1_CEXT", 7)) + else if (startswith (p, "V1_CEXT")) return darwin_sections[objc1_class_ext_section]; - else if (!strncmp (p, "V2_CSTR", 7)) + else if (startswith (p, "V2_CSTR")) return darwin_sections[objc_constant_string_object_section]; return base; @@ -1747,7 +1747,7 @@ machopic_select_section (tree decl, && DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE && IDENTIFIER_POINTER (DECL_NAME (decl)) - && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6)) + && startswith (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_")) /* c) legacy meta-data selection was deprecated at 4.6, removed now. */ gcc_unreachable (); @@ -1869,15 +1869,15 @@ finalize_dtors () void darwin_globalize_label (FILE *stream, const char *name) { - if (!!strncmp (name, "_OBJC_", 6)) + if (!startswith (name, "_OBJC_")) default_globalize_label (stream, name); /* We have some Objective C cases that need to be global, but only on newer OS versions. */ if (flag_objc_abi < 2 || flag_next_runtime < 100700) return; - if (!strncmp (name+6, "LabelPro", 8)) + if (startswith (name+6, "LabelPro")) default_globalize_label (stream, name); - if (!strncmp (name+6, "Protocol_", 9)) + if (startswith (name+6, "Protocol_")) default_globalize_label (stream, name); } @@ -1897,7 +1897,7 @@ darwin_label_is_anonymous_local_objc_name (const char *name) while (*p >= '0' && *p <= '9') p++; } - if (strncmp ((const char *)p, "_OBJC_", 6) != 0) + if (!startswith ((const char *)p, "_OBJC_")) return false; /* We need some of the objective c meta-data symbols to be visible to the @@ -1908,36 +1908,36 @@ darwin_label_is_anonymous_local_objc_name (const char *name) return true; p += 6; - if (!strncmp ((const char *)p, "ClassRef", 8)) + if (startswith ((const char *)p, "ClassRef")) return false; - else if (!strncmp ((const char *)p, "SelRef", 6)) + else if (startswith ((const char *)p, "SelRef")) return false; - else if (!strncmp ((const char *)p, "Category", 8)) + else if (startswith ((const char *)p, "Category")) { if (p[8] == '_' || p[8] == 'I' || p[8] == 'P' || p[8] == 'C' ) return false; return true; } - else if (!strncmp ((const char *)p, "ClassMethods", 12)) + else if (startswith ((const char *)p, "ClassMethods")) return false; - else if (!strncmp ((const char *)p, "Instance", 8)) + else if (startswith ((const char *)p, "Instance")) { if (p[8] == 'I' || p[8] == 'M') return false; return true; } - else if (!strncmp ((const char *)p, "CLASS_RO", 8)) + else if (startswith ((const char *)p, "CLASS_RO")) return false; - else if (!strncmp ((const char *)p, "METACLASS_RO", 12)) + else if (startswith ((const char *)p, "METACLASS_RO")) return false; - else if (!strncmp ((const char *)p, "Protocol", 8)) + else if (startswith ((const char *)p, "Protocol")) { if (p[8] == '_' || p[8] == 'I' || p[8] == 'P' || p[8] == 'M' || p[8] == 'C' || p[8] == 'O') return false; return true; } - else if (!strncmp ((const char *)p, "LabelPro", 8)) + else if (startswith ((const char *)p, "LabelPro")) return false; return true; } @@ -2032,8 +2032,7 @@ darwin_asm_named_section (const char *name, { /* LTO sections go in a special section that encapsulates the (unlimited) number of GNU LTO sections within a single mach-o one. */ - if (strncmp (name, LTO_SECTION_NAME_PREFIX, - strlen (LTO_SECTION_NAME_PREFIX)) == 0) + if (startswith (name, LTO_SECTION_NAME_PREFIX)) { darwin_lto_section_e e; /* We expect certain flags to be set... */ @@ -2062,9 +2061,9 @@ darwin_asm_named_section (const char *name, vec_alloc (lto_section_names, 16); vec_safe_push (lto_section_names, e); } - else if (strncmp (name, "__DWARF,", 8) == 0) + else if (startswith (name, "__DWARF,")) darwin_asm_dwarf_section (name, flags, decl, false); - else if (strncmp (name, "__GNU_DWARF_LTO,", 16) == 0) + else if (startswith (name, "__GNU_DWARF_LTO,")) darwin_asm_dwarf_section (name, flags, decl, true); else fprintf (asm_out_file, "\t.section %s\n", name); @@ -2973,9 +2972,9 @@ darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab, const char *lto_add = ""; gcc_checking_assert (base->common.flags & SECTION_NAMED); - is_for_lto = strncmp (base->named.name, "__GNU_DWARF_LTO,", 16) == 0; + is_for_lto = startswith (base->named.name, "__GNU_DWARF_LTO,"); gcc_checking_assert (is_for_lto - || strncmp (base->named.name, "__DWARF,", 8) == 0); + || startswith (base->named.name, "__DWARF,")); const char *name = strchr (base->named.name, ',') + 1; gcc_checking_assert (name); diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 8201a20..a7f7f08 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -262,7 +262,6 @@ static frv_stack_t *frv_stack_cache = (frv_stack_t *)0; static void frv_option_override (void); static bool frv_legitimate_address_p (machine_mode, rtx, bool); static int frv_default_flags_for_cpu (void); -static int frv_string_begins_with (const char *, const char *); static FRV_INLINE bool frv_small_data_reloc_p (rtx, int); static void frv_print_operand (FILE *, rtx, int); static void frv_print_operand_address (FILE *, machine_mode, rtx); @@ -783,17 +782,6 @@ frv_option_override (void) } -/* Return true if NAME (a STRING_CST node) begins with PREFIX. */ - -static int -frv_string_begins_with (const char *name, const char *prefix) -{ - const int prefix_len = strlen (prefix); - - /* Remember: NAME's length includes the null terminator. */ - return (strncmp (name, prefix, prefix_len) == 0); -} - /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ static void @@ -9312,9 +9300,9 @@ frv_in_small_data_p (const_tree decl) section_name = DECL_SECTION_NAME (decl); if (section_name) { - if (frv_string_begins_with (section_name, ".sdata")) + if (startswith (section_name, ".sdata")) return true; - if (frv_string_begins_with (section_name, ".sbss")) + if (startswith (section_name, ".sbss")) return true; return false; } diff --git a/gcc/config/gcn/mkoffload.c b/gcc/config/gcn/mkoffload.c index dc9d518..1469a68 100644 --- a/gcc/config/gcn/mkoffload.c +++ b/gcc/config/gcn/mkoffload.c @@ -826,7 +826,7 @@ main (int argc, char **argv) for (int i = 1; i < argc; i++) { #define STR "-foffload-abi=" - if (strncmp (argv[i], STR, strlen (STR)) == 0) + if (startswith (argv[i], STR)) { if (strcmp (argv[i] + strlen (STR), "lp64") == 0) offload_abi = OFFLOAD_ABI_LP64; @@ -995,9 +995,9 @@ main (int argc, char **argv) obstack_ptr_grow (&ld_argv_obstack, "-lgomp"); for (int i = 1; i < argc; i++) - if (strncmp (argv[i], "-l", 2) == 0 - || strncmp (argv[i], "-Wl", 3) == 0 - || strncmp (argv[i], "-march", 6) == 0) + if (startswith (argv[i], "-l") + || startswith (argv[i], "-Wl") + || startswith (argv[i], "-march")) obstack_ptr_grow (&ld_argv_obstack, argv[i]); obstack_ptr_grow (&cc_argv_obstack, "-dumpdir"); diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c index 8036aed..204e290 100644 --- a/gcc/config/i386/i386-builtins.c +++ b/gcc/config/i386/i386-builtins.c @@ -1992,7 +1992,7 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) while (token != NULL) { /* Do not process "arch=" */ - if (strncmp (token, "arch=", 5) == 0) + if (startswith (token, "arch=")) { token = strtok (NULL, ","); continue; diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index 64c6ef4..0eccb54 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -1904,7 +1904,7 @@ ix86_option_override_internal (bool main_args_p, /* opts->x_ix86_tune_string is set to opts->x_ix86_arch_string or defaulted. We need to use a sensible tune option. */ - if (!strncmp (opts->x_ix86_tune_string, "x86-64", 6) + if (startswith (opts->x_ix86_tune_string, "x86-64") && (opts->x_ix86_tune_string[6] == '\0' || (!strcmp (opts->x_ix86_tune_string + 6, "-v2") || !strcmp (opts->x_ix86_tune_string + 6, "-v3") diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index befe69e..743d8a2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -752,9 +752,8 @@ x86_64_elf_section_type_flags (tree decl, const char *name, int reloc) flags |= SECTION_RELRO; if (strcmp (name, ".lbss") == 0 - || strncmp (name, ".lbss.", sizeof (".lbss.") - 1) == 0 - || strncmp (name, ".gnu.linkonce.lb.", - sizeof (".gnu.linkonce.lb.") - 1) == 0) + || startswith (name, ".lbss.") + || startswith (name, ".gnu.linkonce.lb.")) flags |= SECTION_BSS; return flags; @@ -21500,7 +21499,7 @@ ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/, for (unsigned i = 0, n = outputs.length (); i < n; ++i) { const char *con = constraints[i]; - if (strncmp (con, "=@cc", 4) != 0) + if (!startswith (con, "=@cc")) continue; con += 4; if (strchr (con, ',') != NULL) diff --git a/gcc/config/i386/intelmic-mkoffload.c b/gcc/config/i386/intelmic-mkoffload.c index 475f071..03858e6 100644 --- a/gcc/config/i386/intelmic-mkoffload.c +++ b/gcc/config/i386/intelmic-mkoffload.c @@ -614,7 +614,7 @@ main (int argc, char **argv) for (int i = 1; i < argc; i++) { #define STR "-foffload-abi=" - if (strncmp (argv[i], STR, strlen (STR)) == 0) + if (startswith (argv[i], STR)) { if (strcmp (argv[i] + strlen (STR), "lp64") == 0) offload_abi = OFFLOAD_ABI_LP64; diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index b66263a..4158a45 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -505,8 +505,7 @@ i386_pe_asm_named_section (const char *name, unsigned int flags, /* LTO sections need 1-byte alignment to avoid confusing the zlib decompression algorithm with trailing zero pad bytes. */ - if (strncmp (name, LTO_SECTION_NAME_PREFIX, - strlen (LTO_SECTION_NAME_PREFIX)) == 0) + if (startswith (name, LTO_SECTION_NAME_PREFIX)) *f++ = '0'; *f = '\0'; @@ -797,7 +796,7 @@ i386_pe_file_end (void) oname = name; if (name[0] == '.') ++name; - if (strncmp (name, "refptr.", 7) != 0) + if (!startswith (name, "refptr.")) continue; name += 7; fprintf (asm_out_file, "\t.section\t.rdata$%s, \"dr\"\n" diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index f1a6de1..632b9df 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -10007,11 +10007,11 @@ ia64_in_small_data_p (const_tree exp) const char *section = DECL_SECTION_NAME (exp); if (strcmp (section, ".sdata") == 0 - || strncmp (section, ".sdata.", 7) == 0 - || strncmp (section, ".gnu.linkonce.s.", 16) == 0 + || startswith (section, ".sdata.") + || startswith (section, ".gnu.linkonce.s.") || strcmp (section, ".sbss") == 0 - || strncmp (section, ".sbss.", 6) == 0 - || strncmp (section, ".gnu.linkonce.sb.", 17) == 0) + || startswith (section, ".sbss.") + || startswith (section, ".gnu.linkonce.sb.")) return true; } else @@ -10869,13 +10869,13 @@ ia64_section_type_flags (tree decl, const char *name, int reloc) unsigned int flags = 0; if (strcmp (name, ".sdata") == 0 - || strncmp (name, ".sdata.", 7) == 0 - || strncmp (name, ".gnu.linkonce.s.", 16) == 0 - || strncmp (name, ".sdata2.", 8) == 0 - || strncmp (name, ".gnu.linkonce.s2.", 17) == 0 + || startswith (name, ".sdata.") + || startswith (name, ".gnu.linkonce.s.") + || startswith (name, ".sdata2.") + || startswith (name, ".gnu.linkonce.s2.") || strcmp (name, ".sbss") == 0 - || strncmp (name, ".sbss.", 6) == 0 - || strncmp (name, ".gnu.linkonce.sb.", 17) == 0) + || startswith (name, ".sbss.") + || startswith (name, ".gnu.linkonce.sb.")) flags = SECTION_SMALL; flags |= default_section_type_flags (decl, name, reloc); diff --git a/gcc/config/mips/driver-native.c b/gcc/config/mips/driver-native.c index eaf5f7e..46bb3ca 100644 --- a/gcc/config/mips/driver-native.c +++ b/gcc/config/mips/driver-native.c @@ -57,7 +57,7 @@ host_detect_local_cpu (int argc, const char **argv) return NULL; while (fgets (buf, sizeof (buf), f) != NULL) - if (strncmp (buf, "cpu model", sizeof ("cpu model") - 1) == 0) + if (startswith (buf, "cpu model")) { if (strstr (buf, "Godson2 V0.2") != NULL || strstr (buf, "Loongson-2 V0.2") != NULL diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 3155459..e5ba273 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1513,14 +1513,14 @@ mips_handle_interrupt_attr (tree *node ATTRIBUTE_UNUSED, tree name, tree args, *no_add_attrs = true; } else if (strcmp (TREE_STRING_POINTER (cst), "eic") != 0 - && strncmp (TREE_STRING_POINTER (cst), "vector=", 7) != 0) + && !startswith (TREE_STRING_POINTER (cst), "vector=")) { warning (OPT_Wattributes, "argument to %qE attribute is neither eic, nor " "vector=<line>", name); *no_add_attrs = true; } - else if (strncmp (TREE_STRING_POINTER (cst), "vector=", 7) == 0) + else if (startswith (TREE_STRING_POINTER (cst), "vector=")) { const char *arg = TREE_STRING_POINTER (cst) + 7; @@ -1849,7 +1849,7 @@ static bool mips16_stub_function_p (const_rtx x) { return (GET_CODE (x) == SYMBOL_REF - && strncmp (XSTR (x, 0), "__mips16_", 9) == 0); + && startswith (XSTR (x, 0), "__mips16_")); } /* Return true if function X is a locally-defined and locally-binding @@ -9323,7 +9323,7 @@ mips_function_rodata_section (tree decl, bool) if (decl && DECL_SECTION_NAME (decl)) { const char *name = DECL_SECTION_NAME (decl); - if (DECL_COMDAT_GROUP (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0) + if (DECL_COMDAT_GROUP (decl) && startswith (name, ".gnu.linkonce.t.")) { char *rname = ASTRDUP (name); rname[14] = 'd'; @@ -9331,7 +9331,7 @@ mips_function_rodata_section (tree decl, bool) } else if (flag_function_sections && flag_data_sections - && strncmp (name, ".text.", 6) == 0) + && startswith (name, ".text.")) { char *rname = ASTRDUP (name); memcpy (rname + 1, "data", 4); diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 581e051..1cdacb7 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -122,7 +122,7 @@ msp430_mcu_name (void) /* The 'i' in the device name symbol for msp430i* devices must be lower case, to match the expected symbol in msp430.h. */ - if (strncmp (target_mcu, "msp430i", 7) == 0) + if (startswith (target_mcu, "msp430i")) { snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__", target_mcu + 7); @@ -2466,7 +2466,7 @@ msp430_function_section (tree decl, enum node_frequency freq, bool startup, const char * prefix = gen_prefix (decl); if (prefix == NULL - || strncmp (name, prefix, strlen (prefix)) == 0) + || startswith (name, prefix)) return default_function_section (decl, freq, startup, exit); name = ACONCAT ((prefix, name, NULL)); @@ -2479,11 +2479,11 @@ msp430_function_section (tree decl, enum node_frequency freq, bool startup, unsigned int msp430_section_type_flags (tree decl, const char * name, int reloc) { - if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0) + if (startswith (name, lower_prefix)) name += strlen (lower_prefix); - else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0) + else if (startswith (name, upper_prefix)) name += strlen (upper_prefix); - else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0) + else if (startswith (name, either_prefix)) name += strlen (either_prefix); return default_section_type_flags (decl, name, reloc); @@ -3243,8 +3243,7 @@ msp430_expand_helper (rtx *operands, const char *helper_name, machine_mode arg0mode = GET_MODE (operands[0]); machine_mode arg1mode = GET_MODE (operands[1]); machine_mode arg2mode = GET_MODE (operands[2]); - int expand_mpy = strncmp (helper_name, "__mspabi_mpy", - sizeof ("__mspabi_mpy") - 1) == 0; + int expand_mpy = startswith (helper_name, "__mspabi_mpy"); /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a hwmpy function. */ gcc_assert (!(expand_mpy && const_variants)); diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index bf5e2be..26d4333 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -2336,9 +2336,9 @@ static bool nios2_small_section_name_p (const char *section) { return (strcmp (section, ".sbss") == 0 - || strncmp (section, ".sbss.", 6) == 0 + || startswith (section, ".sbss.") || strcmp (section, ".sdata") == 0 - || strncmp (section, ".sdata.", 7) == 0 + || startswith (section, ".sdata.") || (nios2_gprel_sec && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0)); } @@ -4199,12 +4199,12 @@ nios2_valid_target_attribute_rec (tree args) *p = '\0'; if (eq) *eq = '\0'; - if (!strncmp (argstr, "no-", 3)) + if (startswith (argstr, "no-")) { no_opt = true; argstr += 3; } - if (!strncmp (argstr, "custom-fpu-cfg", 14)) + if (startswith (argstr, "custom-fpu-cfg")) { char *end_eq = p; if (no_opt) @@ -4225,13 +4225,12 @@ nios2_valid_target_attribute_rec (tree args) nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true); } - else if (!strncmp (argstr, "custom-", 7)) + else if (startswith (argstr, "custom-")) { int code = -1; unsigned int i; for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) - if (!strncmp (argstr + 7, N2FPU_NAME (i), - strlen (N2FPU_NAME (i)))) + if (startswith (argstr + 7, N2FPU_NAME (i))) { /* Found insn. */ code = i; diff --git a/gcc/config/nvptx/mkoffload.c b/gcc/config/nvptx/mkoffload.c index b0a4dfa..17f17e5 100644 --- a/gcc/config/nvptx/mkoffload.c +++ b/gcc/config/nvptx/mkoffload.c @@ -256,13 +256,13 @@ process (FILE *in, FILE *out) case '\n': fprintf (out, "\\n\"\n\t\""); /* Look for mappings on subsequent lines. */ - while (strncmp (input + i, "//:", 3) == 0) + while (startswith (input + i, "//:")) { i += 3; - if (strncmp (input + i, "VAR_MAP ", 8) == 0) + if (startswith (input + i, "VAR_MAP ")) record_id (input + i + 8, &vars_tail); - else if (strncmp (input + i, "FUNC_MAP ", 9) == 0) + else if (startswith (input + i, "FUNC_MAP ")) record_id (input + i + 9, &funcs_tail); else abort (); @@ -482,7 +482,7 @@ main (int argc, char **argv) for (int i = 1; i < argc; i++) { #define STR "-foffload-abi=" - if (strncmp (argv[i], STR, strlen (STR)) == 0) + if (startswith (argv[i], STR)) { if (strcmp (argv[i] + strlen (STR), "lp64") == 0) offload_abi = OFFLOAD_ABI_LP64; diff --git a/gcc/config/nvptx/nvptx-protos.h b/gcc/config/nvptx/nvptx-protos.h index 1512209..b7e6ae2 100644 --- a/gcc/config/nvptx/nvptx-protos.h +++ b/gcc/config/nvptx/nvptx-protos.h @@ -57,5 +57,6 @@ extern const char *nvptx_output_set_softstack (unsigned); extern const char *nvptx_output_simt_enter (rtx, rtx, rtx); extern const char *nvptx_output_simt_exit (rtx); extern const char *nvptx_output_red_partition (rtx, rtx); +extern const char *nvptx_output_atomic_insn (const char *, rtx *, int, int); #endif #endif diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index ebbfa92..722b0fa 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -2444,6 +2444,53 @@ nvptx_output_mov_insn (rtx dst, rtx src) return "%.\tcvt%t0%t1\t%0, %1;"; } +/* Output a pre/post barrier for MEM_OPERAND according to MEMMODEL. */ + +static void +nvptx_output_barrier (rtx *mem_operand, int memmodel, bool pre_p) +{ + bool post_p = !pre_p; + + switch (memmodel) + { + case MEMMODEL_RELAXED: + return; + case MEMMODEL_CONSUME: + case MEMMODEL_ACQUIRE: + case MEMMODEL_SYNC_ACQUIRE: + if (post_p) + break; + return; + case MEMMODEL_RELEASE: + case MEMMODEL_SYNC_RELEASE: + if (pre_p) + break; + return; + case MEMMODEL_ACQ_REL: + case MEMMODEL_SEQ_CST: + case MEMMODEL_SYNC_SEQ_CST: + if (pre_p || post_p) + break; + return; + default: + gcc_unreachable (); + } + + output_asm_insn ("%.\tmembar%B0;", mem_operand); +} + +const char * +nvptx_output_atomic_insn (const char *asm_template, rtx *operands, int mem_pos, + int memmodel_pos) +{ + nvptx_output_barrier (&operands[mem_pos], INTVAL (operands[memmodel_pos]), + true); + output_asm_insn (asm_template, operands); + nvptx_output_barrier (&operands[mem_pos], INTVAL (operands[memmodel_pos]), + false); + return ""; +} + static void nvptx_print_operand (FILE *, rtx, int); /* Output INSN, which is a call to CALLEE with result RESULT. For ptx, this @@ -2660,6 +2707,36 @@ nvptx_print_operand (FILE *file, rtx x, int code) switch (code) { + case 'B': + if (SYMBOL_REF_P (XEXP (x, 0))) + switch (SYMBOL_DATA_AREA (XEXP (x, 0))) + { + case DATA_AREA_GENERIC: + /* Assume worst-case: global. */ + gcc_fallthrough (); /* FALLTHROUGH. */ + case DATA_AREA_GLOBAL: + break; + case DATA_AREA_SHARED: + fputs (".cta", file); + return; + case DATA_AREA_LOCAL: + case DATA_AREA_CONST: + case DATA_AREA_PARAM: + default: + gcc_unreachable (); + } + + /* There are 2 cases where membar.sys differs from membar.gl: + - host accesses global memory (f.i. systemwide atomics) + - 2 or more devices are setup in peer-to-peer mode, and one + peer can access global memory of other peer. + Neither are currently supported by openMP/OpenACC on nvptx, but + that could change, so we default to membar.sys. We could support + this more optimally by adding DATA_AREA_SYS and then emitting + .gl for DATA_AREA_GLOBAL and .sys for DATA_AREA_SYS. */ + fputs (".sys", file); + return; + case 'A': x = XEXP (x, 0); gcc_fallthrough (); /* FALLTHROUGH. */ diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md index 00bb8fe..108de1c 100644 --- a/gcc/config/nvptx/nvptx.md +++ b/gcc/config/nvptx/nvptx.md @@ -1642,7 +1642,11 @@ (set (match_dup 1) (unspec_volatile:SDIM [(const_int 0)] UNSPECV_CAS))] "" - "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;" + { + const char *t + = "%.\\tatom%A1.cas.b%T0\\t%0, %1, %2, %3;"; + return nvptx_output_atomic_insn (t, operands, 1, 4); + } [(set_attr "atomic" "true")]) (define_insn "atomic_exchange<mode>" @@ -1654,7 +1658,11 @@ (set (match_dup 1) (match_operand:SDIM 2 "nvptx_nonmemory_operand" "Ri"))] ;; input "" - "%.\\tatom%A1.exch.b%T0\\t%0, %1, %2;" + { + const char *t + = "%.\tatom%A1.exch.b%T0\t%0, %1, %2;"; + return nvptx_output_atomic_insn (t, operands, 1, 3); + } [(set_attr "atomic" "true")]) (define_insn "atomic_fetch_add<mode>" @@ -1667,7 +1675,11 @@ (set (match_operand:SDIM 0 "nvptx_register_operand" "=R") (match_dup 1))] "" - "%.\\tatom%A1.add%t0\\t%0, %1, %2;" + { + const char *t + = "%.\\tatom%A1.add%t0\\t%0, %1, %2;"; + return nvptx_output_atomic_insn (t, operands, 1, 3); + } [(set_attr "atomic" "true")]) (define_insn "atomic_fetch_addsf" @@ -1680,7 +1692,11 @@ (set (match_operand:SF 0 "nvptx_register_operand" "=R") (match_dup 1))] "" - "%.\\tatom%A1.add%t0\\t%0, %1, %2;" + { + const char *t + = "%.\\tatom%A1.add%t0\\t%0, %1, %2;"; + return nvptx_output_atomic_insn (t, operands, 1, 3); + } [(set_attr "atomic" "true")]) (define_code_iterator any_logic [and ior xor]) @@ -1696,7 +1712,12 @@ (set (match_operand:SDIM 0 "nvptx_register_operand" "=R") (match_dup 1))] "<MODE>mode == SImode || TARGET_SM35" - "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;" + { + const char *t + = "%.\\tatom%A1.b%T0.<logic>\\t%0, %1, %2;"; + return nvptx_output_atomic_insn (t, operands, 1, 3); + } + [(set_attr "atomic" "true")]) (define_expand "atomic_test_and_set" diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h index d25a2ed..05cc315 100644 --- a/gcc/config/pa/som.h +++ b/gcc/config/pa/som.h @@ -47,32 +47,29 @@ along with GCC; see the file COPYING3. If not see do { \ static int in_shlib_list = 0; \ while (*PTR == ' ') PTR++; \ - if (strncmp (PTR, "shared library list:", \ - sizeof ("shared library list:") - 1) == 0) \ + if (startswith (PTR, "shared library list:")) \ { \ PTR = 0; \ in_shlib_list = 1; \ } \ - else if (strncmp (PTR, "shared library binding:", \ - sizeof ("shared library binding:") - 1) == 0)\ + else if (startswith (PTR, "shared library binding:")) \ { \ PTR = 0; \ in_shlib_list = 0; \ } \ - else if (strncmp (PTR, "static branch prediction disabled", \ - sizeof ("static branch prediction disabled") - 1) == 0)\ + else if (startswith (PTR, "static branch prediction disabled")) \ { \ PTR = 0; \ in_shlib_list = 0; \ } \ else if (in_shlib_list \ - && strncmp (PTR, "dynamic", sizeof ("dynamic") - 1) == 0) \ + && startswith (PTR, "dynamic")) \ { \ PTR += sizeof ("dynamic") - 1; \ while (*p == ' ') PTR++; \ } \ else if (in_shlib_list \ - && strncmp (PTR, "static", sizeof ("static") - 1) == 0) \ + && startswith (PTR, "static")) \ { \ PTR += sizeof ("static") - 1; \ while (*p == ' ') PTR++; \ diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index eb3bea4..b663b43 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -2251,7 +2251,7 @@ static void pdp11_output_ident (const char *ident) { if (TARGET_DEC_ASM) { - if (strncmp (ident, "GCC:", 4) != 0) + if (!startswith (ident, "GCC:")) fprintf (asm_out_file, "\t.ident\t\"%s\"\n", ident); } diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 27665e5..1baa299 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -3593,7 +3593,7 @@ riscv_elf_select_rtx_section (machine_mode mode, rtx x, if (riscv_size_ok_for_small_data_p (GET_MODE_SIZE (mode))) { - if (strncmp (s->named.name, ".rodata.cst", strlen (".rodata.cst")) == 0) + if (startswith (s->named.name, ".rodata.cst")) { /* Rename .rodata.cst* to .srodata.cst*. */ char *name = (char *) alloca (strlen (s->named.name) + 2); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 53a9f54..c304596 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -17205,12 +17205,12 @@ toc_hasher::equal (toc_hash_struct *h1, toc_hash_struct *h2) instead, there should be some programmatic way of inquiring as to whether or not an object is a vtable. */ -#define VTABLE_NAME_P(NAME) \ - (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \ - || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \ - || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \ - || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \ - || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0) +#define VTABLE_NAME_P(NAME) \ + (startswith (name, "_vt.") \ + || startswith (name, "_ZTV") \ + || startswith (name, "_ZTT") \ + || startswith (name, "_ZTI") \ + || startswith (name, "_ZTC")) #ifdef NO_DOLLAR_IN_LABEL /* Return a GGC-allocated character string translating dollar signs in @@ -24204,7 +24204,7 @@ rs6000_inner_target_options (tree args, bool attr_p) const char *cpu_opt = NULL; p = NULL; - if (strncmp (q, "cpu=", 4) == 0) + if (startswith (q, "cpu=")) { int cpu_index = rs6000_cpu_name_lookup (q+4); if (cpu_index >= 0) @@ -24215,7 +24215,7 @@ rs6000_inner_target_options (tree args, bool attr_p) cpu_opt = q+4; } } - else if (strncmp (q, "tune=", 5) == 0) + else if (startswith (q, "tune=")) { int tune_index = rs6000_cpu_name_lookup (q+5); if (tune_index >= 0) @@ -24233,7 +24233,7 @@ rs6000_inner_target_options (tree args, bool attr_p) char *r = q; error_p = true; - if (strncmp (r, "no-", 3) == 0) + if (startswith (r, "no-")) { invert = true; r += 3; diff --git a/gcc/config/s390/driver-native.c b/gcc/config/s390/driver-native.c index c024715..71c4ff6 100644 --- a/gcc/config/s390/driver-native.c +++ b/gcc/config/s390/driver-native.c @@ -73,7 +73,7 @@ s390_host_detect_local_cpu (int argc, const char **argv) (has_features == 0 || has_processor == 0) && fgets (buf, sizeof (buf), f) != NULL; ) { - if (has_processor == 0 && strncmp (buf, "processor", 9) == 0) + if (has_processor == 0 && startswith (buf, "processor")) { const char *p; long machine_id; @@ -128,7 +128,7 @@ s390_host_detect_local_cpu (int argc, const char **argv) break; } } - if (has_features == 0 && strncmp (buf, "features", 8) == 0) + if (has_features == 0 && startswith (buf, "features")) { const char *p; @@ -144,13 +144,13 @@ s390_host_detect_local_cpu (int argc, const char **argv) p++; for (i = 0; !ISSPACE (p[i]) && p[i] != 0; i++) ; - if (i == 3 && strncmp (p, "dfp", 3) == 0) + if (i == 3 && startswith (p, "dfp")) has_dfp = 1; - else if (i == 2 && strncmp (p, "te", 2) == 0) + else if (i == 2 && startswith (p, "te")) has_te = 1; - else if (i == 2 && strncmp (p, "vx", 2) == 0) + else if (i == 2 && startswith (p, "vx")) has_vx = 1; - else if (i == 8 && strncmp (p, "highgprs", 8) == 0) + else if (i == 8 && startswith (p, "highgprs")) has_highgprs = 1; p += i; } diff --git a/gcc/config/s390/s390-c.c b/gcc/config/s390/s390-c.c index 7dbd8bf..4cce261 100644 --- a/gcc/config/s390/s390-c.c +++ b/gcc/config/s390/s390-c.c @@ -367,6 +367,8 @@ s390_cpu_cpp_builtins_internal (cpp_reader *pfile, old_opts, opts, "vector=vector", "vector"); s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR), old_opts, opts, "bool=bool", "bool"); + s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR), + old_opts, opts, "_Bool=_Bool", "_Bool"); if (TARGET_ZVECTOR_P (opts->x_target_flags) && __vector_keyword == NULL) { __vector_keyword = get_identifier ("__vector"); diff --git a/gcc/config/sparc/driver-sparc.c b/gcc/config/sparc/driver-sparc.c index f70c53f..698c18e 100644 --- a/gcc/config/sparc/driver-sparc.c +++ b/gcc/config/sparc/driver-sparc.c @@ -148,7 +148,7 @@ host_detect_local_cpu (int argc, const char **argv) return NULL; while (fgets (buf, sizeof (buf), f) != NULL) - if (strncmp (buf, "cpu\t\t:", sizeof ("cpu\t\t:") - 1) == 0) + if (startswith (buf, "cpu\t\t:")) { for (i = 0; cpu_names [i].name; i++) if (strstr (buf, cpu_names [i].name) != NULL) diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 96a7925..3aacd1e 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -1325,10 +1325,10 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, be shorter (1 opcode byte + 1 addrmode byte + 8 immediate value bytes .vs. 2 opcode bytes + 2 addrmode bytes + 8 immediate value value bytes. */ - if ((!strncmp (pattern_lo, "movl", 4) - && !strncmp (pattern_hi, "movl", 4)) - || (!strncmp (pattern_lo, "pushl", 5) - && !strncmp (pattern_hi, "pushl", 5))) + if ((startswith (pattern_lo, "movl") + && startswith (pattern_hi, "movl")) + || (startswith (pattern_lo, "pushl") + && startswith (pattern_hi, "pushl"))) return "movq %1,%0"; if (MEM_P (operands[0]) diff --git a/gcc/config/vms/vms-ld.c b/gcc/config/vms/vms-ld.c index 451ad0d..121aebd 100644 --- a/gcc/config/vms/vms-ld.c +++ b/gcc/config/vms/vms-ld.c @@ -94,6 +94,14 @@ static int translate_unix (char *, int); #endif +/* Return 1 if STR string starts with PREFIX. */ + +static inline int +startswith (const char *str, const char *prefix) +{ + return strncmp (str, prefix, strlen (prefix)) == 0; +} + /* Append STR to the command line to invoke the linker. Expand the line as necessary to accommodate. */ @@ -319,7 +327,7 @@ process_args (int argc, char **argv) for (i = 1; i < argc; i++) { - if (strncmp (argv[i], "-L", 2) == 0) + if (startswith (argv[i], "-L")) { search_dirs = XRESIZEVEC(const char *, search_dirs, search_dirs_len + 1); @@ -341,7 +349,7 @@ process_args (int argc, char **argv) } else if (strcmp (argv[i], "-g0") == 0) addarg ("/notraceback"); - else if (strncmp (argv[i], "-g", 2) == 0) + else if (startswith (argv[i], "-g")) { addarg ("/debug"); debug = 1; @@ -654,7 +662,7 @@ main (int argc, char **argv) /* Already handled. */ i++; } - else if (arg_len > 2 && strncmp (argv[i], "-l", 2) == 0) + else if (arg_len > 2 && startswith (argv[i], "-l")) { const char *libname; @@ -676,17 +684,17 @@ main (int argc, char **argv) } } else if (strcmp (argv[i], "-v" ) == 0 - || strncmp (argv[i], "-g", 2 ) == 0 + || startswith (argv[i], "-g") || strcmp (argv[i], "-static" ) == 0 || strcmp (argv[i], "-map" ) == 0 || strcmp (argv[i], "-save-temps") == 0 || strcmp (argv[i], "--noinhibit-exec") == 0 - || (arg_len > 2 && strncmp (argv[i], "-L", 2) == 0) - || (arg_len >= 6 && strncmp (argv[i], "-share", 6) == 0)) + || (arg_len > 2 && startswith (argv[i], "-L")) + || (arg_len >= 6 && startswith (argv[i], "-share"))) { /* Already handled. */ } - else if (strncmp (argv[i], "--opt=", 6) == 0) + else if (startswith (argv[i], "--opt=")) fprintf (optfile, "%s\n", argv[i] + 6); else if (arg_len > 1 && argv[i][0] == '@') { diff --git a/gcc/config/vms/vms.c b/gcc/config/vms/vms.c index 1ee1c86..bbf174e 100644 --- a/gcc/config/vms/vms.c +++ b/gcc/config/vms/vms.c @@ -302,7 +302,7 @@ vms_start_function (const char *fnname) #if VMS_DEBUGGING_INFO if (vms_debug_main && debug_info_level > DINFO_LEVEL_NONE - && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0) + && startswith (vms_debug_main, fnname)) { targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER); ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname); diff --git a/gcc/configure b/gcc/configure index f03fe88..039a86d 100755 --- a/gcc/configure +++ b/gcc/configure @@ -32205,7 +32205,8 @@ case $target in # cross build. are target headers available? # carefully coerce the build-system compiler to use target headers saved_CXXFLAGS="$CXXFLAGS" - CROSS_TEST_CXXFLAGS="-nostdinc ${XGCC_FLAGS_FOR_TARGET//-B/-idirafter/}" + fixed_XGCC_FLAGS_FOR_TARGET=`echo "$XGCC_FLAGS_FOR_TARGET" | sed 's/-B/-idirafter/g'` + CROSS_TEST_CXXFLAGS="-nostdinc $fixed_XGCC_FLAGS_FOR_TARGET" CXXFLAGS="$CROSS_TEST_CXXFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/gcc/configure.ac b/gcc/configure.ac index e9ba2af..4e78801 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -7499,7 +7499,8 @@ case $target in # cross build. are target headers available? # carefully coerce the build-system compiler to use target headers saved_CXXFLAGS="$CXXFLAGS" - CROSS_TEST_CXXFLAGS="-nostdinc ${XGCC_FLAGS_FOR_TARGET//-B/-idirafter/}" + fixed_XGCC_FLAGS_FOR_TARGET=`echo "$XGCC_FLAGS_FOR_TARGET" | sed 's/-B/-idirafter/g'` + CROSS_TEST_CXXFLAGS="-nostdinc $fixed_XGCC_FLAGS_FOR_TARGET" CXXFLAGS="$CROSS_TEST_CXXFLAGS" AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #include <math.h> diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 48425b9..45af840 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2021-05-17 Jonathan Wakely <jwakely@redhat.com> + + PR c++/100635 + * call.c (convert_like_internal): Print different diagnostic if + the lvalue reference is const. + 2021-05-14 Jason Merrill <jason@redhat.com> PR c++/95870 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f07e09a..1e2d1d4 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7900,9 +7900,13 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum, "type %qH to a value of type %qI", totype, next->type); } - else + else if (!CP_TYPE_CONST_P (TREE_TYPE (ref_type))) error_at (loc, "cannot bind non-const lvalue reference of " "type %qH to an rvalue of type %qI", totype, extype); + else // extype is volatile + error_at (loc, "cannot bind lvalue reference of type " + "%qH to an rvalue of type %qI", totype, + extype); } else if (!reference_compatible_p (TREE_TYPE (totype), extype)) { diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index f1687e8..7fa6e8d 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold, { if (TYPE_PRECISION (intype) == POINTER_SIZE) return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr, + expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), expr, complain); /* Modes may be different but sizes should be the same. There is supposed to be some integral type that is the same width diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7f148b4..35faeff 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1206,12 +1206,14 @@ vla_type_p (tree t) return false; } -/* Return a reference type node referring to TO_TYPE. If RVAL is + +/* Return a reference type node of MODE referring to TO_TYPE. If MODE + is VOIDmode the standard pointer mode will be picked. If RVAL is true, return an rvalue reference type, otherwise return an lvalue reference type. If a type node exists, reuse it, otherwise create a new one. */ tree -cp_build_reference_type (tree to_type, bool rval) +cp_build_reference_type_for_mode (tree to_type, machine_mode mode, bool rval) { tree lvalue_ref, t; @@ -1224,7 +1226,8 @@ cp_build_reference_type (tree to_type, bool rval) to_type = TREE_TYPE (to_type); } - lvalue_ref = build_reference_type (to_type); + lvalue_ref = build_reference_type_for_mode (to_type, mode, false); + if (!rval) return lvalue_ref; @@ -1250,7 +1253,7 @@ cp_build_reference_type (tree to_type, bool rval) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (to_type) != to_type) TYPE_CANONICAL (t) - = cp_build_reference_type (TYPE_CANONICAL (to_type), rval); + = cp_build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, rval); else TYPE_CANONICAL (t) = t; @@ -1260,6 +1263,16 @@ cp_build_reference_type (tree to_type, bool rval) } +/* Return a reference type node referring to TO_TYPE. If RVAL is + true, return an rvalue reference type, otherwise return an lvalue + reference type. If a type node exists, reuse it, otherwise create + a new one. */ +tree +cp_build_reference_type (tree to_type, bool rval) +{ + return cp_build_reference_type_for_mode (to_type, VOIDmode, rval); +} + /* Returns EXPR cast to rvalue reference type, like std::move. */ tree @@ -1561,11 +1574,11 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) { case POINTER_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = build_pointer_type (type); + result = build_pointer_type_for_mode (type, TYPE_MODE (t), false); break; case REFERENCE_TYPE: type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags); - result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t)); + result = cp_build_reference_type_for_mode (type, TYPE_MODE (t), TYPE_REF_IS_RVALUE (t)); break; case OFFSET_TYPE: t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes, flags); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index dc0bde8..a0c9bb2 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13143,7 +13143,7 @@ function prologue and epilogue. @item uninlined-function-time Extra time accounted by inliner for function overhead such as time needed to -execute function prologue and epilogue +execute function prologue and epilogue. @item inline-heuristics-hint-percent The scale (in percents) applied to @option{inline-insns-single}, @@ -13154,7 +13154,7 @@ very profitable (will enable later optimizations). @item uninlined-thunk-insns @item uninlined-thunk-time Same as @option{--param uninlined-function-insns} and -@option{--param uninlined-function-time} but applied to function thunks +@option{--param uninlined-function-time} but applied to function thunks. @item inline-min-speedup When estimated performance improvement of caller + callee runtime exceeds this diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 781dedd..54fa0ee 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2021-05-17 Harald Anlauf <anlauf@gmx.de> + + PR fortran/98411 + * trans-decl.c (gfc_finish_var_decl): Add check for explicit SAVE + attribute. + +2021-05-17 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/100633 + * resolve.c (gfc_resolve_code): Reject nonintrinsic assignments in + OMP WORKSHARE. + 2021-05-14 Tobias Burnus <tobias@codesourcery.com> * dump-parse-tree.c (show_omp_node, show_code_node): Handle diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index a170188..406b4ae 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -738,6 +738,7 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym) /* Keep variables larger than max-stack-var-size off stack. */ if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive) && !sym->attr.automatic + && sym->attr.save != SAVE_EXPLICIT && INTEGER_CST_P (DECL_SIZE_UNIT (decl)) && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)) /* Put variable length auto array pointers always into stack. */ diff --git a/gcc/function.c b/gcc/function.c index a3ed398..fc7b147 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4930,6 +4930,9 @@ push_dummy_function (bool with_decl) fn_result_decl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node); DECL_RESULT (fn_decl) = fn_result_decl; + DECL_ARTIFICIAL (fn_decl) = 1; + tree fn_name = get_identifier (" "); + SET_DECL_ASSEMBLER_NAME (fn_decl, fn_name); } else fn_decl = NULL_TREE; diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 60e5d66..2c922e3 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -703,8 +703,19 @@ ranger_cache::set_global_range (tree name, const irange &r) propagate_updated_value (name, bb); } - // Mark the value as up-to-date. - m_temporal->set_timestamp (name); + // Constants no longer need to tracked. Any further refinement has to be + // undefined. Propagation works better with constants. PR 100512. + // Pointers which resolve to non-zero also do not need + // tracking in the cache as they will never change. See PR 98866. + // Otherwise mark the value as up-to-date. + if (r.singleton_p () + || (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ())) + { + set_range_invariant (name); + m_temporal->set_always_current (name); + } + else + m_temporal->set_timestamp (name); } // Register a dependency on DEP to name. If the timestamp for DEP is ever diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 5b288d8..710bc7f 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1082,11 +1082,6 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name) r.intersect (tmp); m_cache.set_global_range (name, r); - // Pointers which resolve to non-zero at the defintion point do not need - // tracking in the cache as they will never change. See PR 98866. - if (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ()) - m_cache.set_range_invariant (name); - return true; } diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 7c271e2..44f6295 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -808,6 +808,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) /* Detect obviously dead sets (via REG_UNUSED notes) and remove them. */ if (set && !RTX_FRAME_RELATED_P (insn) + && NONJUMP_INSN_P (insn) && !may_trap_p (set) && find_reg_note (insn, REG_UNUSED, SET_DEST (set)) && !side_effects_p (SET_SRC (set)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 936f37a..9141534 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,96 @@ +2021-05-17 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/100512 + * gcc.dg/pr100512.c: New. + +2021-05-17 Jonathan Wakely <jwakely@redhat.com> + + * g++.dg/conversion/pr100635.C: New test. + +2021-05-17 Harald Anlauf <anlauf@gmx.de> + + PR fortran/98411 + * gfortran.dg/pr98411.f90: New test. + +2021-05-17 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/pr100349.c: New test. + +2021-05-17 Tamar Christina <tamar.christina@arm.com> + + * gcc.target/aarch64/cpunative/info_16: New test. + * gcc.target/aarch64/cpunative/info_17: New test. + * gcc.target/aarch64/cpunative/native_cpu_16.c: New test. + * gcc.target/aarch64/cpunative/native_cpu_17.c: New test. + +2021-05-17 Richard Biener <rguenther@suse.de> + + PR c/100625 + * gcc.dg/gimplefe-error-9.c: New testcase. + +2021-05-17 Richard Biener <rguenther@suse.de> + + PR middle-end/100582 + * gcc.target/i386/pr100582.c: New testcase. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-compare-3.c: New test with GCC vectors. + * gcc.target/arm/simd/mve-vcmp-f16.c: New test for + auto-vectorization. + * gcc.target/arm/armv8_2-fp16-arith-1.c: Adjust since we now + vectorize float16_t vectors. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-compare-1.c: New test with GCC vectors. + * gcc.target/arm/simd/mve-compare-2.c: New test with GCC vectors. + * gcc.target/arm/simd/mve-compare-scalar-1.c: New test with GCC + vectors. + * gcc.target/arm/simd/mve-vcmp-f32.c: New test for + auto-vectorization. + * gcc.target/arm/simd/mve-vcmp.c: New test for auto-vectorization. + +2021-05-17 liuhongt <hongtao.liu@intel.com> + + PR target/100549 + * gcc.target/i386/pr100549.c: New test. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-vadd-scalar-1.c: New. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-vadd-1.c: New. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-vsub_1.c: Factorize and add __fp16 test. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/simd/mve-vshr.c: Add more scan-assembler-times. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + * gcc.target/arm/acle/saturation.c: Use arm_sat_ok effective + target. + * lib/target-supports.exp + (check_effective_target_arm_qbit_ok_nocache): Rename into... + (check_effective_target_arm_sat_ok_nocache): ... this. Check + __ARM_FEATURE_SAT and use armv6. + +2021-05-17 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/100633 + * gfortran.dg/gomp/workshare-59.f90: New test. + +2021-05-17 Christophe Lyon <christophe.lyon@linaro.org> + + PR debug/100515 + * gcc.dg/debug/dwarf2/pr100515.c: Require openmp effective-target. + 2021-05-16 David Edelsohn <dje.gcc@gmail.com> * g++.dg/ext/attrib63.C: Add -Wno-psabi option. diff --git a/gcc/testsuite/g++.dg/conversion/pr100635.C b/gcc/testsuite/g++.dg/conversion/pr100635.C new file mode 100644 index 0000000..5841215 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/pr100635.C @@ -0,0 +1,12 @@ +// PR c++/100635 +// { dg-do compile } +// { dg-additional-options "-Wno-volatile" { target c++2a } } + +struct S { }; +volatile S v(); +const volatile S& svol = v(); // { dg-error "cannot bind lvalue reference of type 'const volatile S&' to an rvalue of type 'volatile S'" } + +#if __cplusplus >= 201103L +volatile int&& declvol(); +const volatile int& voli = declvol(); // { dg-error "cannot bind lvalue reference of type 'const volatile int&' to an rvalue of type 'volatile int'" "" { target c++11} } +#endif diff --git a/gcc/testsuite/g++.dg/opt/pr94589-2.C b/gcc/testsuite/g++.dg/opt/pr94589-2.C index dda947e..e9ef84b 100644 --- a/gcc/testsuite/g++.dg/opt/pr94589-2.C +++ b/gcc/testsuite/g++.dg/opt/pr94589-2.C @@ -1,8 +1,8 @@ // PR tree-optimization/94589 // { dg-do compile { target c++20 } } // { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } -// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } -// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 14 "optimized" } } +// { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) \[ij]_\[0-9]+\\(D\\)" 12 "optimized" } } +// { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 5\\.0" 12 "optimized" } } #include <compare> diff --git a/gcc/testsuite/g++.dg/other/pr100580.C b/gcc/testsuite/g++.dg/other/pr100580.C new file mode 100644 index 0000000..d6cc0a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr100580.C @@ -0,0 +1,8 @@ +// PR c++/100580 +// { dg-do compile } +// { dg-require-weak "" } +// { dg-options "-fdump-passes" } +// { dg-prune-output ".*" } + +int foo; +static __typeof(foo) bar __attribute__((__weakref__("foo"))); diff --git a/gcc/testsuite/g++.target/s390/pr100281-1.C b/gcc/testsuite/g++.target/s390/pr100281-1.C new file mode 100644 index 0000000..b82e27b --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr100281-1.C @@ -0,0 +1,10 @@ +// PR C++/100281 +// { dg-do compile } + +typedef void * __attribute__((mode (SI))) __ptr32_t; + +void foo () { + unsigned int b = 100; + __ptr32_t a; + a = b; /* { dg-error "invalid conversion from 'unsigned int' to '__ptr32_t'.*" } */ +} diff --git a/gcc/testsuite/g++.target/s390/pr100281-2.C b/gcc/testsuite/g++.target/s390/pr100281-2.C new file mode 100644 index 0000000..58552be --- /dev/null +++ b/gcc/testsuite/g++.target/s390/pr100281-2.C @@ -0,0 +1,9 @@ +// PR C++/100281 +// { dg-do compile } + +typedef int & __attribute__((mode (SI))) __ref32_t; + +void foo () { + unsigned int b = 100; + __ref32_t a = b; /* { dg-error "cannot bind non-const lvalue reference of type '__ref32_t'.*" } */ +} diff --git a/gcc/testsuite/gcc.dg/attr-vector_size.c b/gcc/testsuite/gcc.dg/attr-vector_size.c index 00be26a..3f2ce88 100644 --- a/gcc/testsuite/gcc.dg/attr-vector_size.c +++ b/gcc/testsuite/gcc.dg/attr-vector_size.c @@ -22,14 +22,6 @@ DEFVEC (extern, 30); #if __SIZEOF_SIZE_T__ > 4 -DEFVEC (extern, 31); -DEFVEC (extern, 32); -DEFVEC (extern, 33); -DEFVEC (extern, 34); -DEFVEC (extern, 60); -DEFVEC (extern, 61); -DEFVEC (extern, 62); - VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */ #else @@ -49,14 +41,6 @@ void test_local_scope (void) #if __SIZEOF_SIZE_T__ > 4 - DEFVEC (auto, 31); - DEFVEC (auto, 32); - DEFVEC (auto, 33); - DEFVEC (auto, 34); - DEFVEC (auto, 60); - DEFVEC (auto, 61); - DEFVEC (auto, 62); - VEC (POW2 (63)) char v63; /* { dg-error "'vector_size' attribute argument value '9223372036854775808' exceeds 9223372036854775807" "LP64" { target lp64 } } */ #else diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-10.c b/gcc/testsuite/gcc.dg/gimplefe-error-10.c new file mode 100644 index 0000000..13d86ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-10.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +__GIMPLE +void foo() { + int t1; + t1_1 = t1_1(); /* { dg-error "invalid call" } */ +} diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-9.c b/gcc/testsuite/gcc.dg/gimplefe-error-9.c new file mode 100644 index 0000000..87014c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-9.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +void __GIMPLE +foo() +{ +bb1: +bb1:; /* { dg-error "duplicate" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr100349.c b/gcc/testsuite/gcc.dg/pr100349.c new file mode 100644 index 0000000..dd7977a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100349.c @@ -0,0 +1,16 @@ +// { dg-do compile } +// { dg-options "-O2 -w" } + +#include <stdint.h> +uint8_t a; +b(int8_t c) { + int d; +e: + uint32_t f; + for (;;) + for (c = 10; c; c++) + if (0 > (a = c) ?: d) { + f = a; + goto e; + } +} diff --git a/gcc/testsuite/gcc.dg/pr100512.c b/gcc/testsuite/gcc.dg/pr100512.c new file mode 100644 index 0000000..70b90e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100512.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -w" } */ + +#include <stdint.h> +int a; +void b() { + int16_t *c; + uint16_t d = 2; + if (0 == d) { + uint64_t e; + uint64_t *f = &e; + for (;;) { + if (e += 0 >= 0) + for (;;) + ; + g: + for (; a;) { + int16_t i = &d; + *c = i && *f; + } + } + } + goto g; +} + diff --git a/gcc/testsuite/gcc.dg/pr100547.c b/gcc/testsuite/gcc.dg/pr100547.c new file mode 100644 index 0000000..2d3da4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100547.c @@ -0,0 +1,35 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O -g" } */ + +typedef int __attribute__((vector_size( + ((((((((((((((((((((((((((((((8 * sizeof(short)) * sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)) * + sizeof(short)))) V; /* { dg-error "number of vector components" } */ +void k() { V w = { 0 }; } diff --git a/gcc/testsuite/gcc.dg/pr100590.c b/gcc/testsuite/gcc.dg/pr100590.c new file mode 100644 index 0000000..5cd3687 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100590.c @@ -0,0 +1,13 @@ +/* PR rtl-optimization/100590 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-dce -w" } */ + +int +foo (void) +{ + int x; + asm goto ("" : "+r" (x) : : : lab); + return 0; + lab: + return 1; +} diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 new file mode 100644 index 0000000..b067957 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 @@ -0,0 +1,8 @@ +processor : 0 +BogoMIPS : 100.00 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 +CPU implementer : 0xff +CPU architecture: 8 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 2 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 new file mode 100644 index 0000000..b067957 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 @@ -0,0 +1,8 @@ +processor : 0 +BogoMIPS : 100.00 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 +CPU implementer : 0xff +CPU architecture: 8 +CPU variant : 0x0 +CPU part : 0xd08 +CPU revision : 2 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c new file mode 100644 index 0000000..a424e7c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */ +/* { dg-set-compiler-env-var GCC_CPUINFO "$srcdir/gcc.target/aarch64/cpunative/info_16" } */ +/* { dg-additional-options "-mcpu=native" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod\+sve2} } } */ + +/* Test a normal looking procinfo. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c new file mode 100644 index 0000000..c269c5f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { { aarch64*-*-linux*} && native } } } */ +/* { dg-set-compiler-env-var GCC_CPUINFO "$srcdir/gcc.target/aarch64/cpunative/info_17" } */ +/* { dg-additional-options "-march=native" } */ + +int main() +{ + return 0; +} + +/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod\+sve2} } } */ + +/* Test a normal looking procinfo. */ diff --git a/gcc/testsuite/gcc.target/i386/pr100582.c b/gcc/testsuite/gcc.target/i386/pr100582.c index 9520fe7..1a8e9eb 100644 --- a/gcc/testsuite/gcc.target/i386/pr100582.c +++ b/gcc/testsuite/gcc.target/i386/pr100582.c @@ -6,11 +6,11 @@ typedef unsigned char v32qi __attribute__((vector_size(32))); v32qi f2 (v32qi x, v32qi a, v32qi b) { - v32qi e; + v32qi e; for (int i = 0; i != 32; i++) - e[i] = x[i] ? a[i] : b[i]; + e[i] = x[i] ? a[i] : b[i]; return e; } -/* { dg-final { scan-assembler-times "pblendvb" 1 } } */ +/* { dg-final { scan-assembler-times "pblend" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/zvector/vec-_Bool.c b/gcc/testsuite/gcc.target/s390/zvector/vec-_Bool.c new file mode 100644 index 0000000..525b950 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/zvector/vec-_Bool.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=z13 -mzvector" } */ + +vector _Bool char bc; +vector _Bool short int bs; +vector _Bool int bi; +vector _Bool long long bll; diff --git a/gcc/testsuite/gfortran.dg/pr98411.f90 b/gcc/testsuite/gfortran.dg/pr98411.f90 new file mode 100644 index 0000000..249afae --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr98411.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-options "-Wall -fautomatic -fmax-stack-var-size=100" } +! PR fortran/98411 - Pointless warning for static variables + +module try + implicit none + integer, save :: a(1000) +contains + subroutine initmodule + real, save :: b(1000) + logical :: c(1000) ! { dg-warning "moved from stack to static storage" } + a(1) = 42 + b(2) = 3.14 + c(3) = .true. + end subroutine initmodule +end module try diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index e0a41d4..8e8a08b 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1887,8 +1887,9 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, edge e0, edge e1, gphi *phi, tree arg0, tree arg1) { - if (!INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (phi))) - || TYPE_UNSIGNED (TREE_TYPE (PHI_RESULT (phi))) + tree phires = PHI_RESULT (phi); + if (!INTEGRAL_TYPE_P (TREE_TYPE (phires)) + || TYPE_UNSIGNED (TREE_TYPE (phires)) || !tree_fits_shwi_p (arg0) || !tree_fits_shwi_p (arg1) || !IN_RANGE (tree_to_shwi (arg0), -1, 2) @@ -1902,12 +1903,32 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, use_operand_p use_p; gimple *use_stmt; - if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))) + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phires)) return false; - if (!single_imm_use (PHI_RESULT (phi), &use_p, &use_stmt)) + if (!single_imm_use (phires, &use_p, &use_stmt)) return false; enum tree_code cmp; tree lhs, rhs; + gimple *orig_use_stmt = use_stmt; + tree orig_use_lhs = NULL_TREE; + int prec = TYPE_PRECISION (TREE_TYPE (phires)); + if (is_gimple_assign (use_stmt) + && gimple_assign_rhs_code (use_stmt) == BIT_AND_EXPR + && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST + && (wi::to_wide (gimple_assign_rhs2 (use_stmt)) + == wi::shifted_mask (1, prec - 1, false, prec))) + { + /* For partial_ordering result operator>= with unspec as second + argument is (res & 1) == res, folded by match.pd into + (res & ~1) == 0. */ + orig_use_lhs = gimple_assign_lhs (use_stmt); + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs)) + return false; + if (EDGE_COUNT (phi_bb->preds) != 4) + return false; + if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt)) + return false; + } if (gimple_code (use_stmt) == GIMPLE_COND) { cmp = gimple_cond_code (use_stmt); @@ -1948,10 +1969,19 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, default: return false; } - if (lhs != PHI_RESULT (phi) + if (lhs != (orig_use_lhs ? orig_use_lhs : phires) || !tree_fits_shwi_p (rhs) || !IN_RANGE (tree_to_shwi (rhs), -1, 1)) return false; + if (orig_use_lhs) + { + if ((cmp != EQ_EXPR && cmp != NE_EXPR) || !integer_zerop (rhs)) + return false; + /* As for -ffast-math we assume the 2 return to be + impossible, canonicalize (res & ~1) == 0 into + res >= 0 and (res & ~1) != 0 as res < 0. */ + cmp = cmp == EQ_EXPR ? GE_EXPR : LT_EXPR; + } if (!empty_block_p (middle_bb)) return false; @@ -2092,7 +2122,7 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) == 0) return false; - /* lhs1 one_cmp rhs1 results in PHI_RESULT (phi) of 1. */ + /* lhs1 one_cmp rhs1 results in phires of 1. */ enum tree_code one_cmp; if ((cmp1 == LT_EXPR) ^ (!integer_onep ((e1->flags & EDGE_TRUE_VALUE) ? arg1 : arg0))) @@ -2185,13 +2215,29 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, use_operand_p use_p; imm_use_iterator iter; bool has_debug_uses = false; - FOR_EACH_IMM_USE_FAST (use_p, iter, PHI_RESULT (phi)) + FOR_EACH_IMM_USE_FAST (use_p, iter, phires) { gimple *use_stmt = USE_STMT (use_p); + if (orig_use_lhs && use_stmt == orig_use_stmt) + continue; gcc_assert (is_gimple_debug (use_stmt)); has_debug_uses = true; break; } + if (orig_use_lhs) + { + if (!has_debug_uses) + FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs) + { + gimple *use_stmt = USE_STMT (use_p); + gcc_assert (is_gimple_debug (use_stmt)); + has_debug_uses = true; + } + gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt); + tree zero = build_zero_cst (TREE_TYPE (orig_use_lhs)); + gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero); + update_stmt (orig_use_stmt); + } if (has_debug_uses) { @@ -2203,7 +2249,7 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, Ignore the value of 2, because if NaNs aren't expected, all floating point numbers should be comparable. */ gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi)); - tree type = TREE_TYPE (PHI_RESULT (phi)); + tree type = TREE_TYPE (phires); tree temp1 = make_node (DEBUG_EXPR_DECL); DECL_ARTIFICIAL (temp1) = 1; TREE_TYPE (temp1) = type; @@ -2221,10 +2267,18 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb, t = build3 (COND_EXPR, type, t, build_zero_cst (type), temp1); g = gimple_build_debug_bind (temp2, t, phi); gsi_insert_before (&gsi, g, GSI_SAME_STMT); - replace_uses_by (PHI_RESULT (phi), temp2); + replace_uses_by (phires, temp2); + if (orig_use_lhs) + replace_uses_by (orig_use_lhs, temp2); } } + if (orig_use_lhs) + { + gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt); + gsi_remove (&gsi, true); + } + gimple_stmt_iterator psi = gsi_for_stmt (phi); remove_phi_node (&psi, true); @@ -6792,9 +6792,10 @@ operation_no_trapping_overflow (tree type, enum tree_code code) constructed by language-dependent code, not here.) */ /* Construct, lay out and return the type of pointers to TO_TYPE with - mode MODE. If CAN_ALIAS_ALL is TRUE, indicate this type can - reference all of memory. If such a type has already been - constructed, reuse it. */ + mode MODE. If MODE is VOIDmode, a pointer mode for the address + space of TO_TYPE will be picked. If CAN_ALIAS_ALL is TRUE, + indicate this type can reference all of memory. If such a type has + already been constructed, reuse it. */ tree build_pointer_type_for_mode (tree to_type, machine_mode mode, @@ -6806,6 +6807,12 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode, if (to_type == error_mark_node) return error_mark_node; + if (mode == VOIDmode) + { + addr_space_t as = TYPE_ADDR_SPACE (to_type); + mode = targetm.addr_space.pointer_mode (as); + } + /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) @@ -6857,10 +6864,7 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode, tree build_pointer_type (tree to_type) { - addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC - : TYPE_ADDR_SPACE (to_type); - machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); - return build_pointer_type_for_mode (to_type, pointer_mode, false); + return build_pointer_type_for_mode (to_type, VOIDmode, false); } /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE. */ @@ -6875,6 +6879,12 @@ build_reference_type_for_mode (tree to_type, machine_mode mode, if (to_type == error_mark_node) return error_mark_node; + if (mode == VOIDmode) + { + addr_space_t as = TYPE_ADDR_SPACE (to_type); + mode = targetm.addr_space.pointer_mode (as); + } + /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) @@ -6926,10 +6936,7 @@ build_reference_type_for_mode (tree to_type, machine_mode mode, tree build_reference_type (tree to_type) { - addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC - : TYPE_ADDR_SPACE (to_type); - machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); - return build_reference_type_for_mode (to_type, pointer_mode, false); + return build_reference_type_for_mode (to_type, VOIDmode, false); } #define MAX_INT_CACHED_PREC \ diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 08b237b..b1bf53a 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1650,6 +1650,9 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, init = initial_condition_in_loop_num (chrec, loop->num); step = evolution_part_in_loop_num (chrec, loop->num); + if (!init || !step) + return false; + /* If INIT is an SSA with a singleton range, set INIT to said singleton, otherwise leave INIT alone. */ if (TREE_CODE (init) == SSA_NAME) diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 424c574..8caeda0 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,9 @@ +2021-05-17 Kwok Cheung Yeung <kcy@codesourcery.com> + + * task.c (omp_fulfill_event): Call gomp_team_barrier_set_task_pending + if new tasks generated. + * testsuite/libgomp.c-c++-common/task-detach-13.c: New. + 2021-05-14 Tobias Burnus <tobias@codesourcery.com> * testsuite/libgomp.fortran/parallel-master.f90: New test. diff --git a/libgomp/task.c b/libgomp/task.c index 1c73c75..feb4796 100644 --- a/libgomp/task.c +++ b/libgomp/task.c @@ -2460,6 +2460,7 @@ omp_fulfill_event (omp_event_handle_t event) if (new_tasks > 0) { /* Wake up threads to run new tasks. */ + gomp_team_barrier_set_task_pending (&team->barrier); do_wake = team->nthreads - team->task_running_count; if (do_wake > new_tasks) do_wake = new_tasks; diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c new file mode 100644 index 0000000..9622fd8 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c @@ -0,0 +1,59 @@ +/* { dg-do run { target *-*-linux* *-*-gnu* *-*-freebsd* } } */ +/* { dg-timeout 10 } */ + +/* Test that omp_fulfill_event works when called from an external + non-OpenMP thread. */ + +#include <omp.h> +#include <unistd.h> +#include <pthread.h> +#include <stdio.h> + +int finished = 0; +int event_pending = 0; +omp_event_handle_t detach_event; + +void * +fulfill_thread (void *) +{ + while (!__atomic_load_n (&finished, __ATOMIC_RELAXED)) + { + if (__atomic_load_n (&event_pending, __ATOMIC_ACQUIRE)) + { + omp_fulfill_event (detach_event); + __atomic_store_n (&event_pending, 0, __ATOMIC_RELEASE); + } + + sleep(1); + } + + return 0; +} + +int +main (void) +{ + pthread_t thr; + int dep; + pthread_create (&thr, NULL, fulfill_thread, 0); + + #pragma omp parallel + #pragma omp single + { + omp_event_handle_t ev; + + #pragma omp task depend (out: dep) detach (ev) + { + detach_event = ev; + __atomic_store_n (&event_pending, 1, __ATOMIC_RELEASE); + } + + #pragma omp task depend (in: dep) + { + __atomic_store_n (&finished, 1, __ATOMIC_RELAXED); + } + } + + pthread_join (thr, 0); + return 0; +} diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e48de21..91ba017 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,54 @@ +2021-05-17 Thomas Rodgers <rodgert@twrodgers.com> + + * include/bits/atomic_wait.h (__waiter::_M_do_wait_v): loop + until value change observed. + (__waiter_base::_M_laundered): New member. + (__waiter_base::_M_notify): Check _M_laundered to determine + whether to wake one or all. + (__detail::__atomic_compare): Return true if call to + __builtin_memcmp() == 0. + (__waiter_base::_S_do_spin_v): Adjust predicate. + * testsuite/29_atomics/atomic/wait_notify/100334.cc: New + test. + +2021-05-17 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/100630 + * include/experimental/bits/fs_path.h (__is_constructible_from): + Test construction from a const lvalue, not an rvalue. + * testsuite/27_io/filesystem/path/construct/100630.cc: New test. + * testsuite/experimental/filesystem/path/construct/100630.cc: + New test. + +2021-05-17 Antony Polukhin <antoshkka@gmail.com> + + PR libstdc++/89728 + * include/bits/locale_facets.h (ctype<basic_string<C,T,A>>): + Declare (but do not define) partial specialization. + * testsuite/22_locale/ctype/is/string/89728_neg.cc: New test. + +2021-05-17 Jonathan Wakely <jwakely@redhat.com> + + * include/std/thread (jthread::_S_create): Fix static assert + message. + * testsuite/30_threads/jthread/95989.cc: Re-enable test. + * testsuite/30_threads/jthread/jthread.cc: Do not require + pthread effective target. + * testsuite/30_threads/jthread/2.cc: Moved to... + * testsuite/30_threads/jthread/version.cc: ...here. + +2021-05-17 Jonathan Wakely <jwakely@redhat.com> + + * doc/Makefile.am: Simplify doxygen recipes and use --latex_cmd. + * doc/Makefile.in: Regenerate. + * doc/doxygen/user.cfg.in (LATEX_CMD_NAME): Add placeholder + value. + * scripts/run_doxygen (print_usage): Always print to stdout and + do not exit. + (fail): New function for exiting on error. + (parse_options): Handle --latex_cmd. Do not treat --help the + same as errors. Simplify handling of required arguments. + 2021-05-12 Jonathan Wakely <jwakely@redhat.com> * testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc: diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 984ed70..07bb744 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -181,11 +181,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } + // return true if equal template<typename _Tp> bool __atomic_compare(const _Tp& __a, const _Tp& __b) { // TODO make this do the correct padding bit ignoring comparison - return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) != 0; + return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0; } struct __waiter_pool_base @@ -300,14 +301,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION explicit __waiter_base(const _Up* __addr) noexcept : _M_w(_S_for(__addr)) , _M_addr(_S_wait_addr(__addr, &_M_w._M_ver)) - { - } + { } + + bool + _M_laundered() const + { return _M_addr == &_M_w._M_ver; } void _M_notify(bool __all, bool __bare = false) { - if (_M_addr == &_M_w._M_ver) - __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL); + if (_M_laundered()) + { + __atomic_fetch_add(_M_addr, 1, __ATOMIC_ACQ_REL); + __all = true; + } _M_w._M_notify(_M_addr, __all, __bare); } @@ -320,7 +327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Spin __spin = _Spin{ }) { auto const __pred = [=] - { return __detail::__atomic_compare(__old, __vfn()); }; + { return !__detail::__atomic_compare(__old, __vfn()); }; if constexpr (__platform_wait_uses_type<_Up>) { @@ -387,7 +394,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __platform_wait_t __val; if (__base_type::_M_do_spin_v(__old, __vfn, __val)) return; - __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val); + + do + { + __base_type::_M_w._M_do_wait(__base_type::_M_addr, __val); + } + while (__detail::__atomic_compare(__old, __vfn())); } template<typename _Pred> @@ -452,7 +464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __atomic_notify_address(const _Tp* __addr, bool __all) noexcept { __detail::__bare_wait __w(__addr); - __w._M_notify(__all, true); + __w._M_notify(__all); } // This call is to be used by atomic types which track contention externally diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 03724cf..5ca431e 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -671,6 +671,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _CharT> locale::id ctype<_CharT>::id; + // Incomplete to provide a compile time diagnostics for common misuse + // of [locale.convenience] functions with basic_string as a character type. + template<typename _CharT, typename _Traits, typename _Alloc> + class ctype<basic_string<_CharT, _Traits, _Alloc> >; + /** * @brief The ctype<char> specialization. * @ingroup locales diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 2df2bba..1ecf2f3 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -124,7 +124,7 @@ namespace __detail template<typename _Source> struct __constructible_from<_Source, void> - : decltype(__is_path_src(std::declval<_Source>(), 0)) + : decltype(__is_path_src(std::declval<const _Source&>(), 0)) { }; template<typename _Tp1, typename _Tp2 = void, diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 48100e9..ca62f73 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -163,7 +163,7 @@ namespace ranges constexpr explicit __box(in_place_t, _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>) - : _M_value{std::forward<_Args>(__args)...} + : _M_value(std::forward<_Args>(__args)...) { } constexpr bool @@ -180,11 +180,11 @@ namespace ranges constexpr _Tp* operator->() noexcept - { return &_M_value; } + { return std::__addressof(_M_value); } constexpr const _Tp* operator->() const noexcept - { return &_M_value; } + { return std::__addressof(_M_value); } }; } // namespace __detail @@ -3228,7 +3228,9 @@ namespace views::__adaptor { private: static constexpr bool _S_needs_cached_begin - = !common_range<_Vp> && !random_access_range<_Vp>; + = !common_range<_Vp> && !(random_access_range<_Vp> + && sized_sentinel_for<sentinel_t<_Vp>, + iterator_t<_Vp>>); [[no_unique_address]] __detail::__maybe_present_t<_S_needs_cached_begin, @@ -3634,16 +3636,22 @@ namespace views::__adaptor requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> { return __x._M_current - __y._M_current; } - friend _Sentinel<_Const>; + template <bool> friend struct _Sentinel; }; template<bool _Const> struct _Sentinel { private: - constexpr bool - _M_equal(const _Iterator<_Const>& __x) const - { return __x._M_current == _M_end; } + template<bool _Const2> + constexpr bool + _M_equal(const _Iterator<_Const2>& __x) const + { return __x._M_current == _M_end; } + + template<bool _Const2> + constexpr auto + _M_distance_from(const _Iterator<_Const2>& __i) const + { return _M_end - __i._M_current; } using _Base = elements_view::_Base<_Const>; sentinel_t<_Base> _M_end = sentinel_t<_Base>(); @@ -3684,9 +3692,9 @@ namespace views::__adaptor template<bool _Const2, typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> - friend constexpr range_difference_t<_Base> + friend constexpr range_difference_t<_Base2> operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y) - { return __x._M_end - __y._M_current; } + { return __x._M_distance_from(__y); } friend _Sentinel<!_Const>; }; diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 886994c..f51392a 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -219,7 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { static_assert(is_invocable_v<decay_t<_Callable>, decay_t<_Args>...>, - "std::thread arguments must be invocable after" + "std::jthread arguments must be invocable after" " conversion to rvalues"); return thread{std::forward<_Callable>(__f), std::forward<_Args>(__args)...}; diff --git a/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc b/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc new file mode 100644 index 0000000..9f15620 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc @@ -0,0 +1,73 @@ +// { dg-do compile } + +// Copyright (C) 2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-error "complete" "" { target *-*-* } 0 } + +#include <locale> + +template <class Char, int I> +struct trait: std::char_traits<Char> {}; + +template <class Char, int I> +std::basic_string<Char, trait<Char, I> > make_str() +{ + return std::basic_string<Char, trait<Char, I> >(); +} + +void test01() +{ + const std::locale& loc = std::locale::classic(); + + std::isspace(std::string(), loc); // { dg-error "required from here" } + std::isprint(make_str<char, 0>(), loc); // { dg-error "required from here" } + std::iscntrl(make_str<char, 1>(), loc); // { dg-error "required from here" } + std::isupper(make_str<char, 2>(), loc); // { dg-error "required from here" } + std::islower(make_str<char, 3>(), loc); // { dg-error "required from here" } + std::isalpha(make_str<char, 4>(), loc); // { dg-error "required from here" } + std::isdigit(make_str<char, 5>(), loc); // { dg-error "required from here" } + std::ispunct(make_str<char, 6>(), loc); // { dg-error "required from here" } + std::isxdigit(make_str<char, 7>(), loc); // { dg-error "required from here" } + std::isalnum(make_str<char, 8>(), loc); // { dg-error "required from here" } + std::isgraph(make_str<char, 9>(), loc); // { dg-error "required from here" } + std::isblank(make_str<char, 10>(), loc); // { dg-error "required from here" } + std::toupper(make_str<char, 11>(), loc); // { dg-error "required from here" } + std::tolower(make_str<char, 12>(), loc); // { dg-error "required from here" } +} + +#ifdef _GLIBCXX_USE_WCHAR_T +void test02() +{ + const std::locale& loc = std::locale::classic(); + + std::isspace(std::wstring(), loc); // { dg-error "required from here" } + std::isprint(make_str<wchar_t, 0>(), loc); // { dg-error "required from here" } + std::iscntrl(make_str<wchar_t, 1>(), loc); // { dg-error "required from here" } + std::isupper(make_str<wchar_t, 2>(), loc); // { dg-error "required from here" } + std::islower(make_str<wchar_t, 3>(), loc); // { dg-error "required from here" } + std::isalpha(make_str<wchar_t, 4>(), loc); // { dg-error "required from here" } + std::isdigit(make_str<wchar_t, 5>(), loc); // { dg-error "required from here" } + std::ispunct(make_str<wchar_t, 6>(), loc); // { dg-error "required from here" } + std::isxdigit(make_str<wchar_t, 7>(), loc); // { dg-error "required from here" } + std::isalnum(make_str<wchar_t, 8>(), loc); // { dg-error "required from here" } + std::isgraph(make_str<wchar_t, 9>(), loc); // { dg-error "required from here" } + std::isblank(make_str<wchar_t, 10>(), loc); // { dg-error "required from here" } + std::toupper(make_str<wchar_t, 11>(), loc); // { dg-error "required from here" } + std::tolower(make_str<wchar_t, 12>(), loc); // { dg-error "required from here" } +} +#endif diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/100630.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/100630.cc new file mode 100644 index 0000000..eb8473e --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/100630.cc @@ -0,0 +1,14 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include <filesystem> + +void f(bool) { } +void f(const std::filesystem::path&) { } + +void +test_100630() +{ + volatile bool b = true; + f(b); +} diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc new file mode 100644 index 0000000..fceb709 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/100334.cc @@ -0,0 +1,93 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } +// { dg-require-gthreads "" } +// { dg-additional-options "-pthread" { target pthread } } +// { dg-add-options libatomic } + +// Copyright (C) 2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <atomic> +#include <future> + +#include <testsuite_hooks.h> + +template <typename T> +struct atomics_sharing_same_waiter +{ + std::atomic<T> tmp[49 * 4] = {}; + std::atomic<T>* a[4] = { + { &tmp[0] }, + { &tmp[16 * 4] }, + { &tmp[32 * 4] }, + { &tmp[48 * 4] } + }; +}; + +constexpr unsigned key(void * a) +{ + constexpr uintptr_t ct = 16; + return (uintptr_t(a) >> 2) % ct; +} + +int +main() +{ + // all atomic share the same waiter +// atomics_sharing_same_waiter<char> atomics; + atomics_sharing_same_waiter<char> atomics; + for (auto& atom : atomics.a) + { + atom->store(0); + } + + auto a = &std::__detail::__waiter_pool_base::_S_for(reinterpret_cast<char *>(atomics.a[0])); + auto b = &std::__detail::__waiter_pool_base::_S_for(reinterpret_cast<char *>(atomics.a[1])); + VERIFY( a == b ); + + auto fut0 = std::async(std::launch::async, [&] { atomics.a[0]->wait(0); }); + auto fut1 = std::async(std::launch::async, [&] { atomics.a[1]->wait(0); }); + auto fut2 = std::async(std::launch::async, [&] { atomics.a[2]->wait(0); }); + auto fut3 = std::async(std::launch::async, [&] { atomics.a[3]->wait(0); }); + + // make sure the all threads already await + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + + atomics.a[2]->store(1); + atomics.a[2]->notify_one(); + + VERIFY(std::future_status::timeout == fut0.wait_for(std::chrono::milliseconds{100})); + VERIFY(atomics.a[0]->load() == 0); + + VERIFY(std::future_status::timeout == fut1.wait_for(std::chrono::milliseconds{100})); + VERIFY(atomics.a[1]->load() == 0); + + VERIFY(std::future_status::ready == fut2.wait_for(std::chrono::milliseconds{100})); + VERIFY(atomics.a[2]->load() == 1); + + VERIFY(std::future_status::timeout == fut3.wait_for(std::chrono::milliseconds{100})); + VERIFY(atomics.a[3]->load() == 0); + + atomics.a[0]->store(1); + atomics.a[0]->notify_one(); + atomics.a[1]->store(1); + atomics.a[1]->notify_one(); + atomics.a[3]->store(1); + atomics.a[3]->notify_one(); + + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc index 53f9082..fb3f43b 100644 --- a/libstdc++-v3/testsuite/30_threads/jthread/95989.cc +++ b/libstdc++-v3/testsuite/30_threads/jthread/95989.cc @@ -20,7 +20,6 @@ // { dg-require-gthreads {} } // { dg-additional-options "-pthread" { target pthread } } // { dg-additional-options "-static" { target static } } -// { dg-skip-if "broken" { *-*-* } } #include <thread> diff --git a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc index 6adc498..7997870 100644 --- a/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc +++ b/libstdc++-v3/testsuite/30_threads/jthread/jthread.cc @@ -16,9 +16,9 @@ // <http://www.gnu.org/licenses/>. // { dg-options "-std=gnu++2a -pthread" } -// { dg-add-options libatomic } // { dg-do run { target c++2a } } -// { dg-require-effective-target pthread } +// { dg-add-options libatomic } +// { dg-additional-options "-pthread" { target pthread } } // { dg-require-gthreads "" } #include <thread> diff --git a/libstdc++-v3/testsuite/30_threads/jthread/2.cc b/libstdc++-v3/testsuite/30_threads/jthread/version.cc index 8d250f0..8d250f0 100644 --- a/libstdc++-v3/testsuite/30_threads/jthread/2.cc +++ b/libstdc++-v3/testsuite/30_threads/jthread/version.cc diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/construct/100630.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/100630.cc new file mode 100644 index 0000000..b2428ff --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/100630.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++11 } } +// { dg-require-filesystem-ts "" } + +#include <experimental/filesystem> + +void f(bool) { } +void f(const std::experimental::filesystem::path&) { } + +void +test_100630() +{ + volatile bool b = true; + f(b); +} diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/detail/semiregular_box.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/detail/semiregular_box.cc index 65931de..ed694e0 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/detail/semiregular_box.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/detail/semiregular_box.cc @@ -81,3 +81,21 @@ test01() return true; } static_assert(test01()); + +template<bool make_semiregular> + struct A { + A() requires make_semiregular; + A(int, int); + A(std::initializer_list<int>) = delete; + }; + +void +test02() +{ + // PR libstdc++/100475 + static_assert(std::semiregular<A<true>>); + __box<A<true>> x2(std::in_place, 0, 0); + + static_assert(!std::semiregular<A<false>>); + __box<A<false>> x1(std::in_place, 0, 0); +} diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc index 134afd6..c6839e3 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc @@ -115,6 +115,35 @@ test05() VERIFY( r2[0] == 1 && r2[1] == 3 ); } +void +test06() +{ + // PR libstdc++/100631 + auto r = views::iota(0) + | views::filter([](int){ return true; }) + | views::take(42) + | views::reverse + | views::transform([](int) { return std::make_pair(42, "hello"); }) + | views::take(42) + | views::keys; + auto b = r.begin(); + auto e = r.end(); + e - b; +} + +void +test07() +{ + // PR libstdc++/100631 comment #2 + auto r = views::iota(0) + | views::transform([](int) { return std::make_pair(42, "hello"); }) + | views::keys; + auto b = ranges::cbegin(r); + auto e = ranges::end(r); + b.base() == e.base(); + b == e; +} + int main() { @@ -123,4 +152,6 @@ main() test03(); test04(); test05(); + test06(); + test07(); } diff --git a/libstdc++-v3/testsuite/std/ranges/single_view.cc b/libstdc++-v3/testsuite/std/ranges/single_view.cc index 97bc39b..f530cc0 100644 --- a/libstdc++-v3/testsuite/std/ranges/single_view.cc +++ b/libstdc++-v3/testsuite/std/ranges/single_view.cc @@ -58,9 +58,25 @@ test03() VERIFY(*std::ranges::begin(s3) == 'a'); } +void +test04() +{ + // PR libstdc++/100475 + struct A { + A() = default; + A(int, int) { } + A(std::initializer_list<int>) = delete; + void operator&() const = delete; + }; + std::ranges::single_view<A> s(std::in_place, 0, 0); + s.data(); + std::as_const(s).data(); +} + int main() { test01(); test02(); test03(); + test04(); } |