diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2017-07-07 16:01:24 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2017-07-07 16:01:24 +0200 |
commit | 6b949707cb585a4acced74a912739f26dea33820 (patch) | |
tree | f913afb9b3f6cd17f124d2e69f7e01d1273b3507 /gcc | |
parent | 0c7d6c4a218b7802e62cadce6e42f9c2544abd67 (diff) |
Merge branches/gcc-7-branch rev 250046.
Change-Id: Iab4acacc1408cb2f8e03dd1d07ec9241c762f83a
Diffstat (limited to 'gcc')
140 files changed, 3347 insertions, 552 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4af1ddd4fa..6c3a7dcd8ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,361 @@ +2017-07-05 Georg-Johann Lay <avr@gjlay.de> + + Backport from 2017-07-05 trunk r249995. + + PR target/81305 + * config/avr/avr.c (avr_out_movhi_mr_r_xmega) [CONSTANT_ADDRESS_P]: + Don't depend on "optimize > 0". + (out_movhi_r_mr, out_movqi_mr_r): Same. + (out_movhi_mr_r, out_movqi_r_mr): Same. + (avr_address_cost) [CONSTANT_ADDRESS_P]: Don't depend cost for + io_address_operand on "optimize > 0". + +2017-07-04 Uros Bizjak <ubizjak@gmail.com> + + PR target/81300 + * config/i386/i386.md (setcc + movzbl/and to xor + setcc peepholes): + Require dead FLAGS_REG at the beginning of a peephole. + +2017-07-04 Uros Bizjak <ubizjak@gmail.com> + + PR target/81294 + * config/i386/adxintrin.h (_subborrow_u32): Swap _X and _Y + arguments in the call to __builtin_ia32_sbb_u32. + (_subborrow_u64): Swap _X and _Y arguments in the call to + __builtin_ia32_sbb_u64. + +2017-07-03 Segher Boessenkool <segher@kernel.crashing.org> + + Backport from trunk: + + 2017-06-15 Segher Boessenkool <segher@kernel.crashing.org> + + * config/rs6000/rs6000.md (add<mode>3): Use reg_or_subregno instead + of REGNO. + +2017-07-03 Tom de Vries <tom@codesourcery.com> + + backport from mainline: + PR tree-optimization/81192 + 2017-07-03 Tom de Vries <tom@codesourcery.com> + + * tree-ssa-tail-merge.c (same_succ_flush_bb): Handle + BB_SAME_SUCC (bb) == NULL. + +2017-06-29 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport from mainline + 2017-06-23 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/80510 + * config/rs6000/rs6000.md (ALTIVEC_DFORM): Do not allow DImode in + 32-bit, since indexed is not valid for DImode. + (mov<mode>_hardfloat32): Reorder ISA 2.07 load/stores before ISA + 3.0 d-form load/stores to be the same as mov<mode>_hardfloat64. + (define_peephole2 for Altivec d-form load): Add 32-bit support. + (define_peephole2 for Altivec d-form store): Likewise. + + Backport from mainline + 2017-06-20 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/79799 + * config/rs6000/rs6000.c (rs6000_expand_vector_init): Add support + for doing vector set of SFmode on ISA 3.0. + * config/rs6000/vsx.md (vsx_set_v4sf_p9): Likewise. + (vsx_set_v4sf_p9_zero): Special case setting 0.0f to a V4SF + element. + (vsx_insert_extract_v4sf_p9): Add an optimization for inserting a + SFmode value into a V4SF variable that was extracted from another + V4SF variable without converting the element to double precision + and back to single precision vector format. + (vsx_insert_extract_v4sf_p9_2): Likewise. + +2017-06-29 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2017-06-19 Richard Biener <rguenther@suse.de> + + PR ipa/81112 + * ipa-prop.c (find_constructor_constant_at_offset): Handle + RANGE_EXPR conservatively. + +2017-06-28 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2017-06-09 Richard Biener <rguenther@suse.de> + + PR middle-end/81007 + * ipa-polymorphic-call.c + (ipa_polymorphic_call_context::restrict_to_inner_class): + Skip FIELD_DECLs with error_mark_node type. + * passes.def (all_lowering_passes): Run pass_build_cgraph_edges + last again. + + 2017-06-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/81083 + * tree-ssa-sccvn.c (vn_reference_lookup_3): Do not use abnormals + as values. + +2017-06-27 Segher Boessenkool <segher@kernel.crashing.org> + + Backports from trunk: + + 2017-05-17 Segher Boessenkool <segher@kernel.crashing.org> + PR middle-end/80692 + * real.c (do_compare): Give decimal_do_compare preference over + comparing just the signs. + + 2017-05-31 Segher Boessenkool <segher@kernel.crashing.org> + PR target/80618 + * config/rs6000/vector.md (*vector_uneq<mode>): Write the nor in the + splitter result in the canonical way. + + 2017-06-09 Segher Boessenkool <segher@kernel.crashing.org> + PR target/80966 + * config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that + gen_add3_insn did not fail. + * config/rs6000/rs6000.md (add<mode>3): If asked to add a constant to + r0, construct that number in a temporary reg and add that reg to r0. + If asked to put the result in r0 as well, fail. + + 2017-06-23 Segher Boessenkool <segher@kernel.crashing.org> + PR middle-end/80902 + * builtins.c (expand_builtin_atomic_fetch_op): If emitting code after + a call, force the call to not be a tail call. + +2017-06-27 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81209 + * ubsan.c (ubsan_encode_value): Initialize DECL_CONTEXT on var. + + PR middle-end/81207 + * gimple-fold.c (replace_call_with_call_and_fold): Handle + gimple_vuse copying separately from gimple_vdef copying. + +2017-06-24 Jim Wilson <jim.wilson@linaro.org> + + * config/aarch64/aarch64-cost-tables.h (qdf24xx_extra_costs): Move to + here. + * config/arm/aarch-cost-tables.h (qdf24xx_extra_costs): From here. + * config/arm/arm-cpu-cdata.h: Regenerate. + * config/arm/arm-cpu-data.h, config/arm/arm-cpu.h: Likewise. + * config/arm/arm-tables.opt, config/arm/arm-tune.md: Likewise. + * config/arm/arm-cpus.in: Delete falkor and qdf24xx entries. + * config/arm/arm.c (arm_qdf24xx_tune): Delete. + * config/arm/bpabi.h (BE8_LINK_SPEC): Delete falkor and qdf24xx + support. + * config/arm/t-aprofile (MULTILIB_MATCHES): Delete falkor and qdf24xx + support. + * config/arm/t-rmprofile: Likewise. + * doc/invoke.texi (ARM Options): Drop falkor and qdf24xx support. + +2017-06-24 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2017-05-04 Marek Polacek <polacek@redhat.com> + + PR tree-optimization/80612 + * calls.c (get_size_range): Check for INTEGRAL_TYPE_P. + +2017-06-23 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2017-05-04 Prakhar Bahuguna <prakhar.bahuguna@arm.com> + + * config/arm/arm-builtins.c (arm_init_builtins): Rename + __builtin_arm_ldfscr to __builtin_arm_get_fpscr, and rename + __builtin_arm_stfscr to __builtin_arm_set_fpscr. + +2017-06-23 Jonathan Wakely <jwakely@redhat.com> + + PR c++/81187 + * doc/invoke.texi (-Wnoexcept-type): Fix name of option, from + -Wnoexcept. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-06-19 Martin Liska <mliska@suse.cz> + + PR sanitizer/80879 + * gimplify.c (gimplify_switch_expr): + Initialize live_switch_vars for SWITCH_BODY == STATEMENT_LIST. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-31 Martin Liska <mliska@suse.cz> + + PR target/79155 + * config/i386/cpuid.h: Fix typo in a comment in cpuid.h. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-30 Martin Liska <mliska@suse.cz> + + PR other/80909 + * auto-profile.c (get_function_decl_from_block): Fix + parenthesis. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-26 Martin Liska <mliska@suse.cz> + + PR ipa/80663 + * params.def: Bound partial-inlining-entry-probability param. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-16 Martin Liska <mliska@suse.cz> + + PR ipa/79849. + PR ipa/79850. + * ipa-devirt.c (warn_types_mismatch): Fix typo. + (odr_types_equivalent_p): Likewise. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-15 Martin Liska <mliska@suse.cz> + + PR driver/31468 + * gcc.c (process_command): Do not allow empty argument of -o option. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-02 Martin Liska <mliska@suse.cz> + + * doc/gcov.texi: Add missing preposition. + * gcov.c (function_info::function_info): Properly fill up + all member variables. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-02 Martin Liska <mliska@suse.cz> + + PR other/80589 + * common.opt: Fix typo. + * doc/invoke.texi: Likewise. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-04-28 Martin Liska <mliska@suse.cz> + + * doc/gcov.texi: Enhance documentation of gcov. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-04-28 Martin Liska <mliska@suse.cz> + + * doc/gcov.texi: Sort options in alphabetic order. + * doc/gcov-dump.texi: Likewise. + * doc/gcov-tool.texi: Likewise. + * gcov.c (print_usage): Likewise. + * gcov-dump.c (print_usage): Likewise. + * gcov-tool.c (print_merge_usage_message): Likewise. + (print_rewrite_usage_message): Likewise. + (print_overlap_usage_message): Likewise. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-04-28 Martin Liska <mliska@suse.cz> + + PR gcov-profile/53915 + * gcov.c (format_gcov): Print 'NAN %' when top > bottom. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-04-28 Martin Liska <mliska@suse.cz> + + PR driver/56469 + * coverage.c (coverage_remove_note_file): New function. + * coverage.h: Declare the function. + * toplev.c (finalize): Clean if an error has been seen. + +2017-06-21 Jakub Jelinek <jakub@redhat.com> + + PR target/81151 + * config/i386/sse.md (round<mode>2): Renumber match_dup and + operands indexes to avoid gap between operands and match_dups. + + PR c++/81130 + * gimplify.c (omp_add_variable): Don't force GOVD_SEEN for types + with ctors/dtors if GOVD_SHARED is set. + + Backported from mainline + 2017-06-20 Jakub Jelinek <jakub@redhat.com> + + PR target/81121 + * config/i386/i386.md (TARGET_USE_VECTOR_CONVERTS float si->{sf,df} + splitter): Require TARGET_SSE2 in the condition. + + PR sanitizer/81125 + * ubsan.h (ubsan_encode_value): Workaround buggy clang++ parser + by removing enum keyword. + (ubsan_type_descriptor): Likewise. Formatting fix. + + 2017-06-19 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81125 + * ubsan.h (enum ubsan_encode_value_phase): New. + (ubsan_encode_value): Change second argument to + enum ubsan_encode_value_phase with default value of + UBSAN_ENCODE_VALUE_GENERIC. + * ubsan.c (ubsan_encode_value): Change second argument to + enum ubsan_encode_value_phase PHASE from bool IN_EXPAND_P, + adjust uses, for UBSAN_ENCODE_VALUE_GENERIC use just + create_tmp_var_raw instead of create_tmp_var and use a + TARGET_EXPR. + (ubsan_expand_bounds_ifn, ubsan_build_overflow_builtin, + instrument_bool_enum_load, ubsan_instrument_float_cast): Adjust + ubsan_encode_value callers. + + PR sanitizer/81111 + * ubsan.c (ubsan_encode_value): If current_function_decl is NULL, + use create_tmp_var_raw instead of create_tmp_var, mark it addressable + just by setting TREE_ADDRESSABLE on the result and use a TARGET_EXPR. + +2017-06-20 James Greenhalgh <james.greenhalgh@arm.com> + + Backport from Mainline + * config/aarch64/aarch64-option-extensions.def (fp16): Fix expected + feature string. + +2017-06-20 Andreas Schwab <schwab@suse.de> + + PR target/80970 + * config/m68k/m68k.md (bsetdreg, bchgdreg, bclrdreg): Use "=d" + instead of "+d". + +2017-06-19 James Greenhalgh <james.greenhalgh@arm.com> + + Backport from mainline + 2017-06-19 James Greenhalgh <james.greenhalgh@arm.com> + + PR target/71778 + * config/arm/arm-builtins.c (arm_expand_builtin_args): Return TARGET + if given a non-constant argument for an intrinsic which requires a + constant. + +2017-06-19 Alexander Monakov <amonakov@ispras.ru> + + * doc/invoke.texi (mcx16): Rewrite. + +2017-06-15 Eric Botcazou <ebotcazou@adacore.com> + + PR rtl-optimization/80474 + * reorg.c (update_block): Do not ignore instructions in a delay slot. + 2017-06-14 Eric Botcazou <ebotcazou@adacore.com> * config/sparc/sparc.h (MASK_ISA): Add MASK_LEON and MASK_LEON3. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 8df707d5252..ef40facd4a9 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20170614 +20170707 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 90cffd705ec..0eb93cbd5de 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2017-06-15 Nicolas Boulenguez <nicolas.boulenguez@free.fr> + + PR ada/81105 + * gcc-interface/Makefile.in (x86 kfreebsd): Adjust system.ads setting. + (i[3456]86-pc-gnu): Likewise. + (x86_64 kfreebsd): Likewise. + 2017-06-12 Eric Botcazou <ebotcazou@adacore.com> PR ada/81070 diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 95221cdbe73..3c42634f38a 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -1424,7 +1424,7 @@ ifeq ($(strip $(filter-out %86 kfreebsd%,$(target_cpu) $(target_os))),) s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ $(ATOMICS_TARGET_PAIRS) \ $(X86_TARGET_PAIRS) \ - system.ads<system-freebsd-x86.ads + system.ads<system-freebsd.ads TOOLS_TARGET_PAIRS = \ mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \ @@ -1454,7 +1454,7 @@ ifeq ($(strip $(filter-out %86 pc gnu,$(target_cpu) $(target_vendor) $(target_os s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ $(ATOMICS_TARGET_PAIRS) \ $(X86_TARGET_PAIRS) \ - system.ads<system-freebsd-x86.ads + system.ads<system-freebsd.ads TOOLS_TARGET_PAIRS = \ mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \ @@ -1482,7 +1482,7 @@ ifeq ($(strip $(filter-out x86_64 kfreebsd%,$(target_cpu) $(target_os))),) s-taprop.adb<s-taprop-posix.adb \ s-taspri.ads<s-taspri-posix.ads \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ - system.ads<system-freebsd-x86.ads + system.ads<system-freebsd.ads TOOLS_TARGET_PAIRS = \ mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \ diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c index 4e498dc6b0e..e353e04df76 100644 --- a/gcc/auto-profile.c +++ b/gcc/auto-profile.c @@ -355,7 +355,7 @@ get_function_decl_from_block (tree block) { tree decl; - if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block) == UNKNOWN_LOCATION)) + if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (block)) == UNKNOWN_LOCATION) return NULL_TREE; for (decl = BLOCK_ABSTRACT_ORIGIN (block); diff --git a/gcc/builtins.c b/gcc/builtins.c index f3bee5bfc1a..7034445a3b7 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5939,6 +5939,12 @@ expand_builtin_atomic_fetch_op (machine_mode mode, tree exp, rtx target, gcc_assert (TREE_OPERAND (addr, 0) == fndecl); TREE_OPERAND (addr, 0) = builtin_decl_explicit (ext_call); + /* If we will emit code after the call, the call can not be a tail call. + If it is emitted as a tail call, a barrier is emitted after it, and + then all trailing code is removed. */ + if (!ignore) + CALL_EXPR_TAILCALL (exp) = 0; + /* Expand the call here so we can emit trailing code. */ ret = expand_call (exp, target, ignore); diff --git a/gcc/calls.c b/gcc/calls.c index c92e35ea5a8..68721767429 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1270,7 +1270,7 @@ get_size_range (tree exp, tree range[2]) wide_int min, max; enum value_range_type range_type - = (TREE_CODE (exp) == SSA_NAME + = ((TREE_CODE (exp) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE (exp))) ? get_range_info (exp, &min, &max) : VR_VARYING); if (range_type == VR_VARYING) diff --git a/gcc/common.opt b/gcc/common.opt index 4021622cf5c..437db8e8615 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2492,7 +2492,7 @@ flow and turn the statement with erroneous or undefined behavior into a trap. fisolate-erroneous-paths-attribute Common Report Var(flag_isolate_erroneous_paths_attribute) Optimization -Detect paths that trigger erroneous or undefined behavior due a null value +Detect paths that trigger erroneous or undefined behavior due to a null value being used in a way forbidden by a returns_nonnull or nonnull attribute. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap. diff --git a/gcc/config/aarch64/aarch64-cost-tables.h b/gcc/config/aarch64/aarch64-cost-tables.h index bde1f10058b..070c083beb3 100644 --- a/gcc/config/aarch64/aarch64-cost-tables.h +++ b/gcc/config/aarch64/aarch64-cost-tables.h @@ -23,7 +23,111 @@ #include "config/arm/aarch-cost-tables.h" -/* ThunderX does not have implement AArch32. */ +/* QDF24xx does not implement AArch32. */ +const struct cpu_cost_table qdf24xx_extra_costs = +{ + /* ALU */ + { + 0, /* arith. */ + 0, /* logical. */ + 0, /* shift. */ + 0, /* shift_reg. */ + COSTS_N_INSNS (1), /* arith_shift. */ + COSTS_N_INSNS (1), /* arith_shift_reg. */ + 0, /* log_shift. */ + 0, /* log_shift_reg. */ + 0, /* extend. */ + 0, /* extend_arith. */ + 0, /* bfi. */ + 0, /* bfx. */ + 0, /* clz. */ + 0, /* rev. */ + 0, /* non_exec. */ + true /* non_exec_costs_exec. */ + }, + { + /* MULT SImode */ + { + COSTS_N_INSNS (2), /* simple. */ + COSTS_N_INSNS (2), /* flag_setting. */ + COSTS_N_INSNS (2), /* extend. */ + COSTS_N_INSNS (2), /* add. */ + COSTS_N_INSNS (2), /* extend_add. */ + COSTS_N_INSNS (4) /* idiv. */ + }, + /* MULT DImode */ + { + COSTS_N_INSNS (3), /* simple. */ + 0, /* flag_setting (N/A). */ + COSTS_N_INSNS (3), /* extend. */ + COSTS_N_INSNS (3), /* add. */ + COSTS_N_INSNS (3), /* extend_add. */ + COSTS_N_INSNS (9) /* idiv. */ + } + }, + /* LD/ST */ + { + COSTS_N_INSNS (2), /* load. */ + COSTS_N_INSNS (2), /* load_sign_extend. */ + COSTS_N_INSNS (2), /* ldrd. */ + COSTS_N_INSNS (2), /* ldm_1st. */ + 1, /* ldm_regs_per_insn_1st. */ + 2, /* ldm_regs_per_insn_subsequent. */ + COSTS_N_INSNS (2), /* loadf. */ + COSTS_N_INSNS (2), /* loadd. */ + COSTS_N_INSNS (3), /* load_unaligned. */ + 0, /* store. */ + 0, /* strd. */ + 0, /* stm_1st. */ + 1, /* stm_regs_per_insn_1st. */ + 2, /* stm_regs_per_insn_subsequent. */ + 0, /* storef. */ + 0, /* stored. */ + COSTS_N_INSNS (1), /* store_unaligned. */ + COSTS_N_INSNS (1), /* loadv. */ + COSTS_N_INSNS (1) /* storev. */ + }, + { + /* FP SFmode */ + { + COSTS_N_INSNS (6), /* div. */ + COSTS_N_INSNS (5), /* mult. */ + COSTS_N_INSNS (5), /* mult_addsub. */ + COSTS_N_INSNS (5), /* fma. */ + COSTS_N_INSNS (3), /* addsub. */ + COSTS_N_INSNS (1), /* fpconst. */ + COSTS_N_INSNS (1), /* neg. */ + COSTS_N_INSNS (2), /* compare. */ + COSTS_N_INSNS (4), /* widen. */ + COSTS_N_INSNS (4), /* narrow. */ + COSTS_N_INSNS (4), /* toint. */ + COSTS_N_INSNS (4), /* fromint. */ + COSTS_N_INSNS (2) /* roundint. */ + }, + /* FP DFmode */ + { + COSTS_N_INSNS (11), /* div. */ + COSTS_N_INSNS (6), /* mult. */ + COSTS_N_INSNS (6), /* mult_addsub. */ + COSTS_N_INSNS (6), /* fma. */ + COSTS_N_INSNS (3), /* addsub. */ + COSTS_N_INSNS (1), /* fpconst. */ + COSTS_N_INSNS (1), /* neg. */ + COSTS_N_INSNS (2), /* compare. */ + COSTS_N_INSNS (4), /* widen. */ + COSTS_N_INSNS (4), /* narrow. */ + COSTS_N_INSNS (4), /* toint. */ + COSTS_N_INSNS (4), /* fromint. */ + COSTS_N_INSNS (2) /* roundint. */ + } + }, + /* Vector */ + { + COSTS_N_INSNS (1) /* alu. */ + } +}; + +/* ThunderX does not implement AArch32. */ const struct cpu_cost_table thunderx_extra_costs = { /* ALU */ @@ -230,6 +334,4 @@ const struct cpu_cost_table thunderx2t99_extra_costs = } }; - #endif - diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index 36766d9c48f..b54de032ea7 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -58,6 +58,6 @@ AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, "atomics") /* Enabling "fp16" also enables "fp". Disabling "fp16" just disables "fp16". */ -AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, 0, "fp16") +AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, 0, "fphp asimdhp") #undef AARCH64_OPT_EXTENSION diff --git a/gcc/config/arm/aarch-cost-tables.h b/gcc/config/arm/aarch-cost-tables.h index 8cff517861a..dc67faf9ab4 100644 --- a/gcc/config/arm/aarch-cost-tables.h +++ b/gcc/config/arm/aarch-cost-tables.h @@ -537,107 +537,4 @@ const struct cpu_cost_table xgene1_extra_costs = } }; -const struct cpu_cost_table qdf24xx_extra_costs = -{ - /* ALU */ - { - 0, /* arith. */ - 0, /* logical. */ - 0, /* shift. */ - 0, /* shift_reg. */ - COSTS_N_INSNS (1), /* arith_shift. */ - COSTS_N_INSNS (1), /* arith_shift_reg. */ - 0, /* log_shift. */ - 0, /* log_shift_reg. */ - 0, /* extend. */ - 0, /* extend_arith. */ - 0, /* bfi. */ - 0, /* bfx. */ - 0, /* clz. */ - 0, /* rev. */ - 0, /* non_exec. */ - true /* non_exec_costs_exec. */ - }, - { - /* MULT SImode */ - { - COSTS_N_INSNS (2), /* simple. */ - COSTS_N_INSNS (2), /* flag_setting. */ - COSTS_N_INSNS (2), /* extend. */ - COSTS_N_INSNS (2), /* add. */ - COSTS_N_INSNS (2), /* extend_add. */ - COSTS_N_INSNS (4) /* idiv. */ - }, - /* MULT DImode */ - { - COSTS_N_INSNS (3), /* simple. */ - 0, /* flag_setting (N/A). */ - COSTS_N_INSNS (3), /* extend. */ - COSTS_N_INSNS (3), /* add. */ - COSTS_N_INSNS (3), /* extend_add. */ - COSTS_N_INSNS (9) /* idiv. */ - } - }, - /* LD/ST */ - { - COSTS_N_INSNS (2), /* load. */ - COSTS_N_INSNS (2), /* load_sign_extend. */ - COSTS_N_INSNS (2), /* ldrd. */ - COSTS_N_INSNS (2), /* ldm_1st. */ - 1, /* ldm_regs_per_insn_1st. */ - 2, /* ldm_regs_per_insn_subsequent. */ - COSTS_N_INSNS (2), /* loadf. */ - COSTS_N_INSNS (2), /* loadd. */ - COSTS_N_INSNS (3), /* load_unaligned. */ - 0, /* store. */ - 0, /* strd. */ - 0, /* stm_1st. */ - 1, /* stm_regs_per_insn_1st. */ - 2, /* stm_regs_per_insn_subsequent. */ - 0, /* storef. */ - 0, /* stored. */ - COSTS_N_INSNS (1), /* store_unaligned. */ - COSTS_N_INSNS (1), /* loadv. */ - COSTS_N_INSNS (1) /* storev. */ - }, - { - /* FP SFmode */ - { - COSTS_N_INSNS (6), /* div. */ - COSTS_N_INSNS (5), /* mult. */ - COSTS_N_INSNS (5), /* mult_addsub. */ - COSTS_N_INSNS (5), /* fma. */ - COSTS_N_INSNS (3), /* addsub. */ - COSTS_N_INSNS (1), /* fpconst. */ - COSTS_N_INSNS (1), /* neg. */ - COSTS_N_INSNS (2), /* compare. */ - COSTS_N_INSNS (4), /* widen. */ - COSTS_N_INSNS (4), /* narrow. */ - COSTS_N_INSNS (4), /* toint. */ - COSTS_N_INSNS (4), /* fromint. */ - COSTS_N_INSNS (2) /* roundint. */ - }, - /* FP DFmode */ - { - COSTS_N_INSNS (11), /* div. */ - COSTS_N_INSNS (6), /* mult. */ - COSTS_N_INSNS (6), /* mult_addsub. */ - COSTS_N_INSNS (6), /* fma. */ - COSTS_N_INSNS (3), /* addsub. */ - COSTS_N_INSNS (1), /* fpconst. */ - COSTS_N_INSNS (1), /* neg. */ - COSTS_N_INSNS (2), /* compare. */ - COSTS_N_INSNS (4), /* widen. */ - COSTS_N_INSNS (4), /* narrow. */ - COSTS_N_INSNS (4), /* toint. */ - COSTS_N_INSNS (4), /* fromint. */ - COSTS_N_INSNS (2) /* roundint. */ - } - }, - /* Vector */ - { - COSTS_N_INSNS (1) /* alu. */ - } -}; - #endif /* GCC_AARCH_COST_TABLES_H */ diff --git a/gcc/config/arm/arm-cpu-cdata.h b/gcc/config/arm/arm-cpu-cdata.h index b3888120daa..b00d83302f6 100644 --- a/gcc/config/arm/arm-cpu-cdata.h +++ b/gcc/config/arm/arm-cpu-cdata.h @@ -740,20 +740,6 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] = }, }, { - "falkor", - { - ISA_ARMv8a,isa_bit_crc32, - isa_nobit - }, - }, - { - "qdf24xx", - { - ISA_ARMv8a,isa_bit_crc32, - isa_nobit - }, - }, - { "xgene1", { ISA_ARMv8a, diff --git a/gcc/config/arm/arm-cpu-data.h b/gcc/config/arm/arm-cpu-data.h index 8d47e7c7492..78421adb9e5 100644 --- a/gcc/config/arm/arm-cpu-data.h +++ b/gcc/config/arm/arm-cpu-data.h @@ -1144,28 +1144,6 @@ static const struct processors all_cores[] = &arm_exynosm1_tune }, { - "falkor", - TARGET_CPU_cortexa57, - (TF_LDSCHED), - "8A", BASE_ARCH_8A, - { - ISA_ARMv8a,isa_bit_crc32, - isa_nobit - }, - &arm_qdf24xx_tune - }, - { - "qdf24xx", - TARGET_CPU_cortexa57, - (TF_LDSCHED), - "8A", BASE_ARCH_8A, - { - ISA_ARMv8a,isa_bit_crc32, - isa_nobit - }, - &arm_qdf24xx_tune - }, - { "xgene1", TARGET_CPU_xgene1, (TF_LDSCHED), diff --git a/gcc/config/arm/arm-cpu.h b/gcc/config/arm/arm-cpu.h index cd282db02f5..cc0cb0017eb 100644 --- a/gcc/config/arm/arm-cpu.h +++ b/gcc/config/arm/arm-cpu.h @@ -123,8 +123,6 @@ enum processor_type TARGET_CPU_cortexa72, TARGET_CPU_cortexa73, TARGET_CPU_exynosm1, - TARGET_CPU_falkor, - TARGET_CPU_qdf24xx, TARGET_CPU_xgene1, TARGET_CPU_cortexa57cortexa53, TARGET_CPU_cortexa72cortexa53, diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in index d116b09eabb..1100f3a5411 100644 --- a/gcc/config/arm/arm-cpus.in +++ b/gcc/config/arm/arm-cpus.in @@ -1020,20 +1020,6 @@ begin cpu exynos-m1 costs exynosm1 end cpu exynos-m1 -begin cpu falkor - tune for cortex-a57 - tune flags LDSCHED - architecture armv8-a+crc - costs qdf24xx -end cpu falkor - -begin cpu qdf24xx - tune for cortex-a57 - tune flags LDSCHED - architecture armv8-a+crc - costs qdf24xx -end cpu qdf24xx - begin cpu xgene1 tune flags LDSCHED architecture armv8-a diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt index cbcd85d9906..cb45e097c90 100644 --- a/gcc/config/arm/arm-tables.opt +++ b/gcc/config/arm/arm-tables.opt @@ -328,12 +328,6 @@ EnumValue Enum(processor_type) String(exynos-m1) Value( TARGET_CPU_exynosm1) EnumValue -Enum(processor_type) String(falkor) Value( TARGET_CPU_falkor) - -EnumValue -Enum(processor_type) String(qdf24xx) Value( TARGET_CPU_qdf24xx) - -EnumValue Enum(processor_type) String(xgene1) Value( TARGET_CPU_xgene1) EnumValue diff --git a/gcc/config/arm/arm-tune.md b/gcc/config/arm/arm-tune.md index 13db413459f..6252d42d4d8 100644 --- a/gcc/config/arm/arm-tune.md +++ b/gcc/config/arm/arm-tune.md @@ -54,8 +54,7 @@ cortexm3,marvell_pj4,cortexa15cortexa7, cortexa17cortexa7,cortexa32,cortexa35, cortexa53,cortexa57,cortexa72, - cortexa73,exynosm1,falkor, - qdf24xx,xgene1,cortexa57cortexa53, - cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53, - cortexm23,cortexm33" + cortexa73,exynosm1,xgene1, + cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35, + cortexa73cortexa53,cortexm23,cortexm33" (const (symbol_ref "((enum attr_tune) arm_tune)"))) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 692641120be..fda59b5b9b2 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2094,28 +2094,6 @@ const struct tune_params arm_xgene1_tune = tune_params::SCHED_AUTOPREF_OFF }; -const struct tune_params arm_qdf24xx_tune = -{ - &qdf24xx_extra_costs, - NULL, /* Scheduler cost adjustment. */ - arm_default_branch_cost, - &arm_default_vec_cost, /* Vectorizer costs. */ - 1, /* Constant limit. */ - 2, /* Max cond insns. */ - 8, /* Memset max inline. */ - 4, /* Issue rate. */ - ARM_PREFETCH_BENEFICIAL (0, -1, 64), - tune_params::PREF_CONST_POOL_FALSE, - tune_params::PREF_LDRD_TRUE, - tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* Thumb. */ - tune_params::LOG_OP_NON_SHORT_CIRCUIT_TRUE, /* ARM. */ - tune_params::DISPARAGE_FLAGS_ALL, - tune_params::PREF_NEON_64_FALSE, - tune_params::PREF_NEON_STRINGOPS_TRUE, - FUSE_OPS (tune_params::FUSE_MOVW_MOVT), - tune_params::SCHED_AUTOPREF_FULL -}; - /* Branches can be dual-issued on Cortex-A5, so conditional execution is less appealing. Set max_insns_skipped to a low value. */ diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h index 56a4a475042..f9f9a9248d4 100644 --- a/gcc/config/arm/bpabi.h +++ b/gcc/config/arm/bpabi.h @@ -79,8 +79,6 @@ |mcpu=cortex-a73.cortex-a35 \ |mcpu=cortex-a73.cortex-a53 \ |mcpu=exynos-m1 \ - |mcpu=falkor \ - |mcpu=qdf24xx \ |mcpu=xgene1 \ |mcpu=cortex-m1.small-multiply \ |mcpu=cortex-m0.small-multiply \ @@ -118,8 +116,6 @@ |mcpu=cortex-a73.cortex-a35 \ |mcpu=cortex-a73.cortex-a53 \ |mcpu=exynos-m1 \ - |mcpu=falkor \ - |mcpu=qdf24xx \ |mcpu=xgene1 \ |mcpu=cortex-m1.small-multiply \ |mcpu=cortex-m0.small-multiply \ diff --git a/gcc/config/arm/t-aprofile b/gcc/config/arm/t-aprofile index b71cbda3e81..10e2d34062d 100644 --- a/gcc/config/arm/t-aprofile +++ b/gcc/config/arm/t-aprofile @@ -79,8 +79,6 @@ MULTILIB_MATCHES += march?armv8-a=mcpu?cortex-a73 MULTILIB_MATCHES += march?armv8-a=mcpu?cortex-a73.cortex-a35 MULTILIB_MATCHES += march?armv8-a=mcpu?cortex-a73.cortex-a53 MULTILIB_MATCHES += march?armv8-a=mcpu?exynos-m1 -MULTILIB_MATCHES += march?armv8-a=mcpu?falkor -MULTILIB_MATCHES += march?armv8-a=mcpu?qdf24xx MULTILIB_MATCHES += march?armv8-a=mcpu?xgene1 # Arch Matches diff --git a/gcc/config/arm/t-rmprofile b/gcc/config/arm/t-rmprofile index 8cd735110b6..ee869b761f7 100644 --- a/gcc/config/arm/t-rmprofile +++ b/gcc/config/arm/t-rmprofile @@ -112,7 +112,6 @@ MULTILIB_MATCHES += march?armv7=mcpu?cortex-a73 MULTILIB_MATCHES += march?armv7=mcpu?cortex-a73.cortex-a35 MULTILIB_MATCHES += march?armv7=mcpu?cortex-a73.cortex-a53 MULTILIB_MATCHES += march?armv7=mcpu?exynos-m1 -MULTILIB_MATCHES += march?armv7=mcpu?qdf24xx MULTILIB_MATCHES += march?armv7=mcpu?xgene1 # Arch Matches diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 648a1256f80..aa35dafc4b8 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -3820,7 +3820,7 @@ out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (x)) { int n_words = AVR_TINY ? 1 : 2; - return optimize > 0 && io_address_operand (x, QImode) + return io_address_operand (x, QImode) ? avr_asm_len ("in %0,%i1", op, plen, -1) : avr_asm_len ("lds %0,%m1", op, plen, -n_words); } @@ -4088,7 +4088,7 @@ out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen) else if (CONSTANT_ADDRESS_P (base)) { int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("in %A0,%i1" CR_TAB "in %B0,%i1+1", op, plen, -2) @@ -5215,7 +5215,7 @@ out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (x)) { int n_words = AVR_TINY ? 1 : 2; - return optimize > 0 && io_address_operand (x, QImode) + return io_address_operand (x, QImode) ? avr_asm_len ("out %i0,%1", op, plen, -1) : avr_asm_len ("sts %m0,%1", op, plen, -n_words); } @@ -5291,13 +5291,12 @@ avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (base)) { - int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("out %i0,%A1" CR_TAB "out %i0+1,%B1", op, plen, -2) : avr_asm_len ("sts %m0,%A1" CR_TAB - "sts %m0+1,%B1", op, plen, -n_words); + "sts %m0+1,%B1", op, plen, -4); } if (reg_base > 0) @@ -5477,7 +5476,7 @@ out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen) if (CONSTANT_ADDRESS_P (base)) { int n_words = AVR_TINY ? 2 : 4; - return optimize > 0 && io_address_operand (base, HImode) + return io_address_operand (base, HImode) ? avr_asm_len ("out %i0+1,%B1" CR_TAB "out %i0,%A1", op, plen, -2) @@ -11361,8 +11360,7 @@ avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, } else if (CONSTANT_ADDRESS_P (x)) { - if (optimize > 0 - && io_address_operand (x, QImode)) + if (io_address_operand (x, QImode)) cost = 2; if (AVR_TINY diff --git a/gcc/config/i386/adxintrin.h b/gcc/config/i386/adxintrin.h index 9c4152b9f36..7acdaf4ab6f 100644 --- a/gcc/config/i386/adxintrin.h +++ b/gcc/config/i386/adxintrin.h @@ -33,7 +33,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _subborrow_u32 (unsigned char __CF, unsigned int __X, unsigned int __Y, unsigned int *__P) { - return __builtin_ia32_sbb_u32 (__CF, __Y, __X, __P); + return __builtin_ia32_sbb_u32 (__CF, __X, __Y, __P); } extern __inline unsigned char @@ -58,7 +58,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _subborrow_u64 (unsigned char __CF, unsigned long long __X, unsigned long long __Y, unsigned long long *__P) { - return __builtin_ia32_sbb_u64 (__CF, __Y, __X, __P); + return __builtin_ia32_sbb_u64 (__CF, __X, __Y, __P); } extern __inline unsigned char diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index f915d2dbd5a..b3b0f912c98 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -179,7 +179,7 @@ /* Return highest supported input value for cpuid instruction. ext can - be either 0x0 or 0x8000000 to return highest supported value for + be either 0x0 or 0x80000000 to return highest supported value for basic or extended cpuid information. Function returns 0 if cpuid is not supported or whatever cpuid returns in eax register. If sig pointer is non-null, then first four bytes of the signature diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 161b36786db..55fc640cf25 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5218,7 +5218,8 @@ (define_split [(set (match_operand:MODEF 0 "sse_reg_operand") (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))] - "TARGET_USE_VECTOR_CONVERTS + "TARGET_SSE2 + && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) && reload_completed && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC) @@ -11681,7 +11682,8 @@ (zero_extend (match_dup 1)))] "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && peep2_regno_dead_p (0, FLAGS_REG)" [(set (match_dup 4) (match_dup 0)) (set (strict_low_part (match_dup 5)) (match_dup 2))] @@ -11702,7 +11704,8 @@ "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) && ! reg_overlap_mentioned_p (operands[3], operands[0]) - && ! reg_set_p (operands[3], operands[4])" + && ! reg_set_p (operands[3], operands[4]) + && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) @@ -11724,7 +11727,8 @@ (and:SI (match_dup 3) (const_int 255))) (clobber (reg:CC FLAGS_REG))])] "REGNO (operands[1]) == REGNO (operands[3]) - && ! reg_overlap_mentioned_p (operands[3], operands[0])" + && ! reg_overlap_mentioned_p (operands[3], operands[0]) + && peep2_regno_dead_p (0, FLAGS_REG)" [(set (match_dup 4) (match_dup 0)) (set (strict_low_part (match_dup 5)) (match_dup 2))] @@ -11746,7 +11750,8 @@ "(peep2_reg_dead_p (3, operands[1]) || operands_match_p (operands[1], operands[3])) && ! reg_overlap_mentioned_p (operands[3], operands[0]) - && ! reg_set_p (operands[3], operands[4])" + && ! reg_set_p (operands[3], operands[4]) + && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 5) (match_dup 0)) (match_dup 4)]) (set (strict_low_part (match_dup 6)) diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 91dcf1eec99..3ae014c1ccb 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -15617,13 +15617,13 @@ (set_attr "mode" "<MODE>")]) (define_expand "round<mode>2" - [(set (match_dup 4) + [(set (match_dup 3) (plus:VF (match_operand:VF 1 "register_operand") - (match_dup 3))) + (match_dup 2))) (set (match_operand:VF 0 "register_operand") (unspec:VF - [(match_dup 4) (match_dup 5)] + [(match_dup 3) (match_dup 4)] UNSPEC_ROUND))] "TARGET_ROUND && !flag_trapping_math" { @@ -15643,11 +15643,11 @@ vec_half = ix86_build_const_vector (<MODE>mode, true, half); vec_half = force_reg (<MODE>mode, vec_half); - operands[3] = gen_reg_rtx (<MODE>mode); - emit_insn (gen_copysign<mode>3 (operands[3], vec_half, operands[1])); + operands[2] = gen_reg_rtx (<MODE>mode); + emit_insn (gen_copysign<mode>3 (operands[2], vec_half, operands[1])); - operands[4] = gen_reg_rtx (<MODE>mode); - operands[5] = GEN_INT (ROUND_TRUNC); + operands[3] = gen_reg_rtx (<MODE>mode); + operands[4] = GEN_INT (ROUND_TRUNC); }) (define_expand "round<mode>2_sfix" diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 5bf6c92d3d5..7933f8eb253 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -5337,7 +5337,7 @@ [(set_attr "type" "bitrw")]) (define_insn "*bsetdreg" - [(set (match_operand:SI 0 "register_operand" "+d") + [(set (match_operand:SI 0 "register_operand" "=d") (ior:SI (ashift:SI (const_int 1) (and:SI (match_operand:SI 1 "register_operand" "d") (const_int 31))) @@ -5350,7 +5350,7 @@ [(set_attr "type" "bitrw")]) (define_insn "*bchgdreg" - [(set (match_operand:SI 0 "register_operand" "+d") + [(set (match_operand:SI 0 "register_operand" "=d") (xor:SI (ashift:SI (const_int 1) (and:SI (match_operand:SI 1 "register_operand" "d") (const_int 31))) @@ -5363,7 +5363,7 @@ [(set_attr "type" "bitrw")]) (define_insn "*bclrdreg" - [(set (match_operand:SI 0 "register_operand" "+d") + [(set (match_operand:SI 0 "register_operand" "=d") (and:SI (rotate:SI (const_int -2) (and:SI (match_operand:SI 1 "register_operand" "d") (const_int 31))) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d1aff871d1e..801ea965580 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7481,6 +7481,8 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt) insn = gen_vsx_set_v8hi_p9 (target, target, val, elt_rtx); else if (mode == V16QImode) insn = gen_vsx_set_v16qi_p9 (target, target, val, elt_rtx); + else if (mode == V4SFmode) + insn = gen_vsx_set_v4sf_p9 (target, target, val, elt_rtx); } if (insn) @@ -28134,9 +28136,11 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) && REGNO (stack_limit_rtx) > 1 && REGNO (stack_limit_rtx) <= 31) { - emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size))); - emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, - const0_rtx)); + rtx_insn *insn + = gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)); + gcc_assert (insn); + emit_insn (insn); + emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, const0_rtx)); } else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF && TARGET_32BIT diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 24d0af97bdc..8176dd758a3 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -704,7 +704,9 @@ ;; Iterator to optimize the following cases: ;; D-form load to FPR register & move to Altivec register ;; Move Altivec register to FPR register and store -(define_mode_iterator ALTIVEC_DFORM [DI DF SF]) +(define_mode_iterator ALTIVEC_DFORM [DF + SF + (DI "TARGET_POWERPC64")]) ;; Start with fixed-point load and store insns. Here we put only the more @@ -1650,6 +1652,17 @@ || rtx_equal_p (operands[0], operands[1])) ? operands[0] : gen_reg_rtx (<MODE>mode)); + /* Adding a constant to r0 is not a valid insn, so use a different + strategy in that case. */ + if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0) + { + if (operands[0] == operands[1]) + FAIL; + rs6000_emit_move (operands[0], operands[2], <MODE>mode); + emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0])); + DONE; + } + HOST_WIDE_INT val = INTVAL (operands[2]); HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); @@ -7467,8 +7480,8 @@ ;; except for 0.0 which can be created on VSX with an xor instruction. (define_insn "*mov<mode>_hardfloat32" - [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") - (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] + [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") + (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" @@ -7476,10 +7489,10 @@ stfd%U0%X0 %1,%0 lfd%U1%X1 %0,%1 fmr %0,%1 - lxsd%U1x %x0,%y1 - stxsd%U0x %x1,%y0 lxsd %0,%1 stxsd %1,%0 + lxsd%U1x %x0,%y1 + stxsd%U0x %x1,%y0 xxlor %x0,%x1,%x1 xxlxor %x0,%x0,%x0 # @@ -14088,13 +14101,13 @@ ;; move fpr->altivec (define_peephole2 - [(match_scratch:DI 0 "b") + [(match_scratch:P 0 "b") (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") (match_dup 1))] - "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE> - && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])" + "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR + && peep2_reg_dead_p (2, operands[1])" [(set (match_dup 0) (match_dup 4)) (set (match_dup 3) @@ -14109,7 +14122,7 @@ add_op0 = XEXP (addr, 0); add_op1 = XEXP (addr, 1); gcc_assert (REG_P (add_op0)); - new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg); + new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); operands[4] = add_op1; operands[5] = change_address (mem, <MODE>mode, new_addr); @@ -14121,13 +14134,13 @@ ;; store fpr (define_peephole2 - [(match_scratch:DI 0 "b") + [(match_scratch:P 0 "b") (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") (match_dup 1))] - "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE> - && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])" + "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR + && peep2_reg_dead_p (2, operands[1])" [(set (match_dup 0) (match_dup 4)) (set (match_dup 5) @@ -14142,7 +14155,7 @@ add_op0 = XEXP (addr, 0); add_op1 = XEXP (addr, 1); gcc_assert (REG_P (add_op0)); - new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg); + new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); operands[4] = add_op1; operands[5] = change_address (mem, <MODE>mode, new_addr); diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index e6489a861cd..ea8169fabe0 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -582,13 +582,12 @@ (gt:VEC_F (match_dup 2) (match_dup 1))) (set (match_dup 0) - (not:VEC_F (ior:VEC_F (match_dup 3) - (match_dup 4))))] - " + (and:VEC_F (not:VEC_F (match_dup 3)) + (not:VEC_F (match_dup 4))))] { operands[3] = gen_reg_rtx (<MODE>mode); operands[4] = gen_reg_rtx (<MODE>mode); -}") +}) (define_insn_and_split "*vector_ltgt<mode>" [(set (match_operand:VEC_F 0 "vfloat_operand" "") diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index c6be17fd8e4..71b897bd97f 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -3012,6 +3012,134 @@ } [(set_attr "type" "vecperm")]) +(define_insn_and_split "vsx_set_v4sf_p9" + [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa") + (unspec:V4SF + [(match_operand:V4SF 1 "gpc_reg_operand" "0") + (match_operand:SF 2 "gpc_reg_operand" "ww") + (match_operand:QI 3 "const_0_to_3_operand" "n")] + UNSPEC_VSX_SET)) + (clobber (match_scratch:SI 4 "=&wJwK"))] + "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 5) + (unspec:V4SF [(match_dup 2)] + UNSPEC_VSX_CVDPSPN)) + (parallel [(set (match_dup 4) + (vec_select:SI (match_dup 6) + (parallel [(match_dup 7)]))) + (clobber (scratch:SI))]) + (set (match_dup 8) + (unspec:V4SI [(match_dup 8) + (match_dup 4) + (match_dup 3)] + UNSPEC_VSX_SET))] +{ + unsigned int tmp_regno = reg_or_subregno (operands[4]); + + operands[5] = gen_rtx_REG (V4SFmode, tmp_regno); + operands[6] = gen_rtx_REG (V4SImode, tmp_regno); + operands[7] = GEN_INT (VECTOR_ELT_ORDER_BIG ? 1 : 2); + operands[8] = gen_rtx_REG (V4SImode, reg_or_subregno (operands[0])); +} + [(set_attr "type" "vecperm") + (set_attr "length" "12")]) + +;; Special case setting 0.0f to a V4SF element +(define_insn_and_split "*vsx_set_v4sf_p9_zero" + [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa") + (unspec:V4SF + [(match_operand:V4SF 1 "gpc_reg_operand" "0") + (match_operand:SF 2 "zero_fp_constant" "j") + (match_operand:QI 3 "const_0_to_3_operand" "n")] + UNSPEC_VSX_SET)) + (clobber (match_scratch:SI 4 "=&wJwK"))] + "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64" + "#" + "&& reload_completed" + [(set (match_dup 4) + (const_int 0)) + (set (match_dup 5) + (unspec:V4SI [(match_dup 5) + (match_dup 4) + (match_dup 3)] + UNSPEC_VSX_SET))] +{ + operands[5] = gen_rtx_REG (V4SImode, reg_or_subregno (operands[0])); +} + [(set_attr "type" "vecperm") + (set_attr "length" "8")]) + +;; Optimize x = vec_insert (vec_extract (v2, n), v1, m) if n is the element +;; that is in the default scalar position (1 for big endian, 2 for little +;; endian). We just need to do an xxinsertw since the element is in the +;; correct location. + +(define_insn "*vsx_insert_extract_v4sf_p9" + [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa") + (unspec:V4SF + [(match_operand:V4SF 1 "gpc_reg_operand" "0") + (vec_select:SF (match_operand:V4SF 2 "gpc_reg_operand" "wa") + (parallel + [(match_operand:QI 3 "const_0_to_3_operand" "n")])) + (match_operand:QI 4 "const_0_to_3_operand" "n")] + UNSPEC_VSX_SET))] + "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64 + && (INTVAL (operands[3]) == (VECTOR_ELT_ORDER_BIG ? 1 : 2))" +{ + int ele = INTVAL (operands[4]); + + if (!VECTOR_ELT_ORDER_BIG) + ele = GET_MODE_NUNITS (V4SFmode) - 1 - ele; + + operands[4] = GEN_INT (GET_MODE_SIZE (SFmode) * ele); + return "xxinsertw %x0,%x2,%4"; +} + [(set_attr "type" "vecperm")]) + +;; Optimize x = vec_insert (vec_extract (v2, n), v1, m) if n is not the element +;; that is in the default scalar position (1 for big endian, 2 for little +;; endian). Convert the insert/extract to int and avoid doing the conversion. + +(define_insn_and_split "*vsx_insert_extract_v4sf_p9_2" + [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa") + (unspec:V4SF + [(match_operand:V4SF 1 "gpc_reg_operand" "0") + (vec_select:SF (match_operand:V4SF 2 "gpc_reg_operand" "wa") + (parallel + [(match_operand:QI 3 "const_0_to_3_operand" "n")])) + (match_operand:QI 4 "const_0_to_3_operand" "n")] + UNSPEC_VSX_SET)) + (clobber (match_scratch:SI 5 "=&wJwK"))] + "VECTOR_MEM_VSX_P (V4SFmode) && VECTOR_MEM_VSX_P (V4SImode) + && TARGET_P9_VECTOR && TARGET_VSX_SMALL_INTEGER + && TARGET_UPPER_REGS_DI && TARGET_POWERPC64 + && (INTVAL (operands[3]) != (VECTOR_ELT_ORDER_BIG ? 1 : 2))" + "#" + "&& 1" + [(parallel [(set (match_dup 5) + (vec_select:SI (match_dup 6) + (parallel [(match_dup 3)]))) + (clobber (scratch:SI))]) + (set (match_dup 7) + (unspec:V4SI [(match_dup 8) + (match_dup 5) + (match_dup 4)] + UNSPEC_VSX_SET))] +{ + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (SImode); + + operands[6] = gen_lowpart (V4SImode, operands[2]); + operands[7] = gen_lowpart (V4SImode, operands[0]); + operands[8] = gen_lowpart (V4SImode, operands[1]); +} + [(set_attr "type" "vecperm")]) + ;; Expanders for builtins (define_expand "vsx_mergel_<mode>" [(use (match_operand:VSX_D 0 "vsx_register_operand" "")) diff --git a/gcc/coverage.c b/gcc/coverage.c index 0a949c3a9f7..53e379b3295 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -731,6 +731,18 @@ coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum) } } +/* Remove coverage file if opened. */ + +void +coverage_remove_note_file (void) +{ + if (bbg_file_name) + { + gcov_close (); + unlink (bbg_file_name); + } +} + /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER >= 0 it is a counter array, otherwise it is the function structure. */ diff --git a/gcc/coverage.h b/gcc/coverage.h index cde6aef1d76..90454c0ecba 100644 --- a/gcc/coverage.h +++ b/gcc/coverage.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see extern void coverage_init (const char *); extern void coverage_finish (void); +extern void coverage_remove_note_file (void); /* Start outputting coverage information for the current function. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f090ae3f52d..cf289ce0db2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,143 @@ +2017-07-06 Jason Merrill <jason@redhat.com> + + PR c++/81204 - parse error with dependent template-name + * parser.c (cp_parser_lookup_name): Revert previous change. + +2017-06-30 Jason Merrill <jason@redhat.com> + + PR c++/54769 - wrong lookup of dependent template-name. + PR c++/81257 - ICE with invalid ::template. + * parser.c (cp_parser_template_name): Handle dependent object type. + (cp_parser_nested_name_specifier_opt): Make template_keyword_p a + parameter. + (cp_parser_id_expression): Pass it. + +2017-06-29 Jason Merrill <jason@redhat.com> + + PR c++/81180 - ICE with C++17 deduction of member class template. + * pt.c (build_deduction_guide): Correct member template handling. + + PR c++/81188 - matching decltype of member function call. + * tree.c (cp_tree_equal): Remove COMPONENT_REF special case. + + PR c++/81164 - ICE with invalid inherited constructor. + * search.c (binfo_direct_p): New. + * name-lookup.c (do_class_using_decl): Use it. + +2017-06-28 Jason Merrill <jason@redhat.com> + + PR c++/61022 - error with variadic template template parm + * pt.c (convert_template_argument): Keep the TYPE_PACK_EXPANSION. + + PR c++/72801 - ICE with variadic partial specialization + * pt.c (unify_pack_expansion): Use PACK_EXPANSION_EXTRA_ARGS. + + PR c++/81204 - parse error with dependent template-name + * parser.c (cp_parser_lookup_name): Disqualify function templates + after lookup. + +2017-06-26 Jason Merrill <jason@redhat.com> + + PR c++/81215 + * pt.c (unify_bound_ttp_args): Restore old logic for C++14 and down. + +2017-06-23 Jason Merrill <jason@redhat.com> + + PR c++/79056 - C++17 ICE with invalid template syntax. + * parser.c (cp_parser_simple_type_specifier): Don't assume that type + is a TYPE_DECL. + (cp_parser_check_for_invalid_template_id): Handle TYPE_DECL. + * pt.c (template_placeholder_p): New. + * cp-tree.h: Declare it. + +2017-06-21 Jakub Jelinek <jakub@redhat.com> + + PR c++/81154 + * semantics.c (handle_omp_array_sections_1, finish_omp_clauses): + Complain about t not being a variable if t is OVERLOAD even + when processing_template_decl. + + Backported from mainline + 2017-06-13 Jakub Jelinek <jakub@redhat.com> + + PR c++/80973 + * cp-gimplify.c (cp_genericize_r): Don't instrument MEM_REF second + argument even if it has REFERENCE_TYPE. + + PR c++/80984 + * cp-gimplify.c (cp_genericize): Only look for VAR_DECLs in + BLOCK_VARS (outer) chain. + (cxx_omp_const_qual_no_mutable): Likewise. + +2017-06-20 Jason Merrill <jason@redhat.com> + + PR c++/80972 - C++17 ICE with attribute packed. + * call.c (build_over_call): Allow a TARGET_EXPR from reference + binding. + +2017-06-19 Jason Merrill <jason@redhat.com> + + PR c++/80562 - ICE with constexpr if. + * semantics.c (finish_if_stmt_cond): Call + instantiate_non_dependent_expr. + + PR c++/80829 - ICE with constexpr copy of base subobject. + * constexpr.c (clear_no_implicit_zero): New. + (cxx_eval_call_expression): Call it. + + PR c++/81073 - constexpr and static var in statement-expression. + * constexpr.c (cxx_eval_constant_expression) [DECL_EXPR]: Check + potential_constant_expression. + +2017-06-17 Jason Merrill <jason@redhat.com> + + PR c++/60063 - -Wunused-local-typedefs and templates. + * decl2.c (is_late_template_attribute): Return false for "used". + + PR c++/70844 - -Wuseless-cast and inheriting constructor. + * method.c (forward_parm): Suppress warn_useless_cast. + +2017-06-16 Jason Merrill <jason@redhat.com> + + PR c++/81045 - Wrong type-dependence with auto return type. + * pt.c (type_dependent_expression_p): An undeduced auto outside the + template isn't dependent. + * call.c (build_over_call): Instantiate undeduced auto even in a + template. + + PR c++/81102 - Wrong error with partial specialization. + * pt.c (unify) [TEMPLATE_PARM_INDEX]: Strip reference when comparing + types. Do type deduction later. + + PR c++/81074 - ICE with partial specialization of member template. + PR c++/71747 + * pt.c (get_partial_spec_bindings): Only coerce innermost args. + + PR c++/80831 - ICE with -fsyntax-only. + * decl2.c (c_parse_final_cleanups): Use cgraph_node::get_create. + + PR c++/80639 - ICE with invalid PMF initialization. + PR c++/80043 - ICE with -fpermissive + * typeck.c (convert_for_assignment): Recurse when instantiate_type + returns without an error. + + PR c++/80465 - ICE with generic lambda with noexcept-specifier. + * lambda.c (maybe_add_lambda_conv_op): Keep processing_template_decl + set longer for a generic lambda. + + PR c++/80614 - Wrong mangling for C++17 noexcept type + * mangle.c (write_type): Put the eh spec back on the function type. + + PR c++/80384 - ICE with dependent noexcept-specifier + * pt.c (dependent_type_p_r) [FUNCTION_TYPE]: Check for dependent + noexcept-specifier. + + * parser.c (cp_parser_constant_expression): Check + potential_rvalue_constant_expression after decay_conversion. + * pt.c (convert_nontype_argument): Don't require linkage in C++17. + + * constexpr.c (potential_constant_expression_1): Allow 'this' capture. + 2017-06-08 Jakub Jelinek <jakub@redhat.com> PR c/81006 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c15b8e46f34..c0c76aa7303 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7552,6 +7552,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) const tree *argarray; unsigned int nargs; + if (undeduced_auto_decl (fn)) + mark_used (fn, complain); + return_type = TREE_TYPE (TREE_TYPE (fn)); nargs = vec_safe_length (args); if (first_arg == NULL_TREE) @@ -7990,6 +7993,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) subobject. */ if (CHECKING_P && cxx_dialect >= cxx1z) gcc_assert (TREE_CODE (arg) != TARGET_EXPR + /* It's from binding the ref parm to a packed field. */ + || convs[0]->need_temporary_p || seen_error () /* See unsafe_copy_elision_p. */ || DECL_BASE_CONSTRUCTOR_P (fn)); diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 9cb769df592..41734c402ee 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -1393,6 +1393,21 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t, return t; } +/* Clean CONSTRUCTOR_NO_IMPLICIT_ZERO from CTOR and its sub-aggregates. */ + +static void +clear_no_implicit_zero (tree ctor) +{ + if (CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor)) + { + CONSTRUCTOR_NO_IMPLICIT_ZERO (ctor) = false; + tree elt; unsigned HOST_WIDE_INT idx; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), idx, elt) + if (TREE_CODE (elt) == CONSTRUCTOR) + clear_no_implicit_zero (elt); + } +} + /* Subroutine of cxx_eval_constant_expression. Evaluate the call expression tree T in the context of OLD_CALL expression evaluation. */ @@ -1696,7 +1711,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, /* The result of a constexpr function must be completely initialized. */ if (TREE_CODE (result) == CONSTRUCTOR) - CONSTRUCTOR_NO_IMPLICIT_ZERO (result) = false; + clear_no_implicit_zero (result); pop_cx_call_context (); return unshare_constructor (result); @@ -4021,6 +4036,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case DECL_EXPR: + if (!potential_constant_expression (t)) + { + if (!ctx->quiet) + require_potential_constant_expression (t); + *non_constant_p = true; + break; + } { r = DECL_EXPR_DECL (t); if (AGGREGATE_TYPE_P (TREE_TYPE (r)) @@ -5293,7 +5315,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, { tree x = TREE_OPERAND (t, 0); STRIP_NOPS (x); - if (is_this_parameter (x)) + if (is_this_parameter (x) && !is_capture_proxy (x)) { if (DECL_CONTEXT (x) && !DECL_DECLARED_CONSTEXPR_P (DECL_CONTEXT (x))) diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 2ded007e5ec..0ff1dd439d1 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1482,6 +1482,16 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) *stmt_p = cplus_expand_constant (stmt); *walk_subtrees = 0; } + else if (TREE_CODE (stmt) == MEM_REF) + { + /* For MEM_REF, make sure not to sanitize the second operand even + if it has reference type. It is just an offset with a type + holding other information. There is no other processing we + need to do for INTEGER_CSTs, so just ignore the second argument + unconditionally. */ + cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL); + *walk_subtrees = 0; + } else if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) && !wtd->no_sanitize_p) @@ -1622,7 +1632,8 @@ cp_genericize (tree fndecl) if (outer) for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) - if (DECL_NAME (t) == DECL_NAME (var) + if (VAR_P (var) + && DECL_NAME (t) == DECL_NAME (var) && DECL_HAS_VALUE_EXPR_P (var) && DECL_VALUE_EXPR (var) == t) { @@ -1869,7 +1880,8 @@ cxx_omp_const_qual_no_mutable (tree decl) if (outer) for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) - if (DECL_NAME (decl) == DECL_NAME (var) + if (VAR_P (var) + && DECL_NAME (decl) == DECL_NAME (var) && (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) { diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d8a80ead95c..9481160e576 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6147,6 +6147,7 @@ extern void check_template_variable (tree); extern tree make_auto (void); extern tree make_decltype_auto (void); extern tree make_template_placeholder (tree); +extern bool template_placeholder_p (tree); extern tree do_auto_deduction (tree, tree, tree); extern tree do_auto_deduction (tree, tree, tree, tsubst_flags_t, @@ -6343,6 +6344,7 @@ extern tree dfs_walk_all (tree, tree (*) (tree, void *), extern tree dfs_walk_once (tree, tree (*) (tree, void *), tree (*) (tree, void *), void *); extern tree binfo_via_virtual (tree, tree); +extern bool binfo_direct_p (tree); extern tree build_baselink (tree, tree, tree, tree); extern tree adjust_result_of_qualified_name_lookup (tree, tree, tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 9c351fda44d..fd5622b8cad 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1094,9 +1094,10 @@ is_late_template_attribute (tree attr, tree decl) if (is_attribute_p ("weak", name)) return true; - /* Attribute unused is applied directly, as it appertains to + /* Attributes used and unused are applied directly, as they appertain to decls. */ - if (is_attribute_p ("unused", name)) + if (is_attribute_p ("unused", name) + || is_attribute_p ("used", name)) return false; /* Attribute tls_model wants to modify the symtab. */ @@ -4661,6 +4662,8 @@ c_parse_final_cleanups (void) if (!DECL_SAVED_TREE (decl)) continue; + cgraph_node *node = cgraph_node::get_create (decl); + /* We lie to the back end, pretending that some functions are not defined when they really are. This keeps these functions from being put out unnecessarily. But, we must @@ -4681,9 +4684,6 @@ c_parse_final_cleanups (void) && DECL_INITIAL (decl) && decl_needed_p (decl)) { - struct cgraph_node *node, *next; - - node = cgraph_node::get (decl); if (node->cpp_implicit_alias) node = node->get_alias_target (); @@ -4693,7 +4693,8 @@ c_parse_final_cleanups (void) group, we need to mark all symbols in the same comdat group that way. */ if (node->same_comdat_group) - for (next = dyn_cast<cgraph_node *> (node->same_comdat_group); + for (cgraph_node *next + = dyn_cast<cgraph_node *> (node->same_comdat_group); next != node; next = dyn_cast<cgraph_node *> (next->same_comdat_group)) next->call_for_symbol_thunks_and_aliases (clear_decl_external, @@ -4707,7 +4708,7 @@ c_parse_final_cleanups (void) if (!DECL_EXTERNAL (decl) && decl_needed_p (decl) && !TREE_ASM_WRITTEN (decl) - && !cgraph_node::get (decl)->definition) + && !node->definition) { /* We will output the function; no longer consider it in this loop. */ diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 46ab30f0a76..431823f7501 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -999,6 +999,8 @@ maybe_add_lambda_conv_op (tree type) null_pointer_node); if (generic_lambda_p) { + ++processing_template_decl; + /* Prepare the dependent member call for the static member function '_FUN' and, potentially, prepare another call to be used in a decltype return expression for a deduced return call op to allow for simple @@ -1048,9 +1050,7 @@ maybe_add_lambda_conv_op (tree type) if (generic_lambda_p) { - ++processing_template_decl; tree a = forward_parm (tgt); - --processing_template_decl; CALL_EXPR_ARG (call, ix) = a; if (decltype_call) @@ -1074,11 +1074,9 @@ maybe_add_lambda_conv_op (tree type) { if (decltype_call) { - ++processing_template_decl; fn_result = finish_decltype_type (decltype_call, /*id_expression_or_member_access_p=*/false, tf_warning_or_error); - --processing_template_decl; } } else @@ -1096,6 +1094,9 @@ maybe_add_lambda_conv_op (tree type) && TYPE_NOTHROW_P (TREE_TYPE (callop))) stattype = build_exception_variant (stattype, noexcept_true_spec); + if (generic_lambda_p) + --processing_template_decl; + /* First build up the conversion op. */ tree rettype = build_pointer_type (stattype); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 6f7e21c28a8..c669cc4366a 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2100,6 +2100,11 @@ write_type (tree type) || TREE_CODE (t) == METHOD_TYPE) { t = build_ref_qualified_type (t, type_memfn_rqual (type)); + if (flag_noexcept_type) + { + tree r = TYPE_RAISES_EXCEPTIONS (type); + t = build_exception_variant (t, r); + } if (abi_version_at_least (8) || type == TYPE_MAIN_VARIANT (type)) /* Avoid adding the unqualified function type as a substitution. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index b4c1f60da03..a01f66f2e90 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -486,6 +486,7 @@ forward_parm (tree parm) type = PACK_EXPANSION_PATTERN (type); if (TREE_CODE (type) != REFERENCE_TYPE) type = cp_build_reference_type (type, /*rval=*/true); + warning_sentinel w (warn_useless_cast); exp = build_static_cast (type, exp, tf_warning_or_error); if (DECL_PACK_P (parm)) exp = make_pack_expansion (exp); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 9dedad4e181..dc8e82c2fe2 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3453,8 +3453,7 @@ do_class_using_decl (tree scope, tree name) return NULL_TREE; } } - else if (name == ctor_identifier - && BINFO_INHERITANCE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo))) + else if (name == ctor_identifier && !binfo_direct_p (binfo)) { error ("cannot inherit constructors from indirect base %qT", scope); return NULL_TREE; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 60188dfec86..239dfb10d97 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2039,7 +2039,7 @@ static cp_expr cp_parser_id_expression static cp_expr cp_parser_unqualified_id (cp_parser *, bool, bool, bool, bool); static tree cp_parser_nested_name_specifier_opt - (cp_parser *, bool, bool, bool, bool); + (cp_parser *, bool, bool, bool, bool, bool = false); static tree cp_parser_nested_name_specifier (cp_parser *, bool, bool, bool, bool); static tree cp_parser_qualifying_entity @@ -2983,7 +2983,9 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) { - if (TYPE_P (type)) + if (TREE_CODE (type) == TYPE_DECL) + type = TREE_TYPE (type); + if (TYPE_P (type) && !template_placeholder_p (type)) error_at (location, "%qT is not a template", type); else if (identifier_p (type)) { @@ -5406,16 +5408,21 @@ cp_parser_id_expression (cp_parser *parser, /* Look for the optional `::' operator. */ global_scope_p - = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false) - != NULL_TREE); + = (!template_keyword_p + && (cp_parser_global_scope_opt (parser, + /*current_scope_valid_p=*/false) + != NULL_TREE)); + /* Look for the optional nested-name-specifier. */ nested_name_specifier_p = (cp_parser_nested_name_specifier_opt (parser, /*typename_keyword_p=*/false, check_dependency_p, /*type_p=*/false, - declarator_p) + declarator_p, + template_keyword_p) != NULL_TREE); + /* If there is a nested-name-specifier, then we are looking at the first qualified-id production. */ if (nested_name_specifier_p) @@ -5860,7 +5867,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, bool typename_keyword_p, bool check_dependency_p, bool type_p, - bool is_declaration) + bool is_declaration, + bool template_keyword_p /* = false */) { bool success = false; cp_token_position start = 0; @@ -5878,7 +5886,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, tree new_scope; tree old_scope; tree saved_qualifying_scope; - bool template_keyword_p; /* Spot cases that cannot be the beginning of a nested-name-specifier. */ @@ -5950,8 +5957,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, first time through the loop. */ if (success) template_keyword_p = cp_parser_optional_template_keyword (parser); - else - template_keyword_p = false; /* Save the old scope since the name lookup we are about to do might destroy it. */ @@ -9447,10 +9452,14 @@ cp_parser_constant_expression (cp_parser* parser, /* Require an rvalue constant expression here; that's what our callers expect. Reference constant expressions are handled separately in e.g. cp_parser_template_argument. */ - bool is_const = potential_rvalue_constant_expression (expression); + tree decay = expression; + if (TREE_TYPE (expression) + && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE) + decay = build_address (expression); + bool is_const = potential_rvalue_constant_expression (decay); parser->non_integral_constant_expression_p = !is_const; if (!is_const && !allow_non_constant_p) - require_potential_rvalue_constant_expression (expression); + require_potential_rvalue_constant_expression (decay); } if (allow_non_constant_p) *non_constant_p = parser->non_integral_constant_expression_p; @@ -15710,15 +15719,19 @@ cp_parser_template_name (cp_parser* parser, no point in doing name-lookup, so we just return IDENTIFIER. But, if the qualifying scope is non-dependent then we can (and must) do name-lookup normally. */ - if (template_keyword_p - && (!parser->scope - || (TYPE_P (parser->scope) - && dependent_type_p (parser->scope)))) + if (template_keyword_p) { - /* We're optimizing away the call to cp_parser_lookup_name, but we - still need to do this. */ - parser->context->object_type = NULL_TREE; - return identifier; + tree scope = (parser->scope ? parser->scope + : parser->context->object_type); + if (scope && TYPE_P (scope) + && (!CLASS_TYPE_P (scope) + || (check_dependency_p && dependent_type_p (scope)))) + { + /* We're optimizing away the call to cp_parser_lookup_name, but + we still need to do this. */ + parser->context->object_type = NULL_TREE; + return identifier; + } } } @@ -16942,7 +16955,7 @@ cp_parser_simple_type_specifier (cp_parser* parser, /* There is no valid C++ program where a non-template type is followed by a "<". That usually indicates that the user thought that the type was a template. */ - cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type), + cp_parser_check_for_invalid_template_id (parser, type, none_type, token->location); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c257d6095de..d1c846ecf44 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6603,13 +6603,46 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) expr, type, decl); return NULL_TREE; } - else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none) + else if ((cxx_dialect >= cxx11 && cxx_dialect < cxx1z) + && decl_linkage (decl) == lk_none) { if (complain & tf_error) error ("%qE is not a valid template argument of type %qT " "because %qD has no linkage", expr, type, decl); return NULL_TREE; } + /* C++17: For a non-type template-parameter of reference or pointer + type, the value of the constant expression shall not refer to (or + for a pointer type, shall not be the address of): + * a subobject (4.5), + * a temporary object (15.2), + * a string literal (5.13.5), + * the result of a typeid expression (8.2.8), or + * a predefined __func__ variable (11.4.1). */ + else if (DECL_ARTIFICIAL (decl)) + { + if (complain & tf_error) + error ("the address of %qD is not a valid template argument", + decl); + return NULL_TREE; + } + else if (!same_type_ignoring_top_level_qualifiers_p + (strip_array_types (TREE_TYPE (type)), + strip_array_types (TREE_TYPE (decl)))) + { + if (complain & tf_error) + error ("the address of the %qT subobject of %qD is not a " + "valid template argument", TREE_TYPE (type), decl); + return NULL_TREE; + } + else if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) + { + if (complain & tf_error) + error ("the address of %qD is not a valid template argument " + "because it does not have static storage duration", + decl); + return NULL_TREE; + } } expr = decay_conversion (expr, complain); @@ -7077,26 +7110,68 @@ unify_bound_ttp_args (tree tparms, tree targs, tree parm, tree& arg, parmvec = expand_template_argument_pack (parmvec); argvec = expand_template_argument_pack (argvec); - tree nparmvec = parmvec; if (flag_new_ttp) { /* In keeping with P0522R0, adjust P's template arguments to apply to A's template; then flatten it again. */ + tree nparmvec = parmvec; nparmvec = coerce_ttp_args_for_tta (arg, parmvec, tf_none); nparmvec = expand_template_argument_pack (nparmvec); - } - if (unify (tparms, targs, nparmvec, argvec, - UNIFY_ALLOW_NONE, explain_p)) - return 1; + if (unify (tparms, targs, nparmvec, argvec, + UNIFY_ALLOW_NONE, explain_p)) + return 1; - /* If the P0522 adjustment eliminated a pack expansion, deduce - empty packs. */ - if (flag_new_ttp - && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec) - && unify_pack_expansion (tparms, targs, parmvec, argvec, - DEDUCE_EXACT, /*sub*/true, explain_p)) - return 1; + /* If the P0522 adjustment eliminated a pack expansion, deduce + empty packs. */ + if (flag_new_ttp + && TREE_VEC_LENGTH (nparmvec) < TREE_VEC_LENGTH (parmvec) + && unify_pack_expansion (tparms, targs, parmvec, argvec, + DEDUCE_EXACT, /*sub*/true, explain_p)) + return 1; + } + else + { + /* Deduce arguments T, i from TT<T> or TT<i>. + We check each element of PARMVEC and ARGVEC individually + rather than the whole TREE_VEC since they can have + different number of elements, which is allowed under N2555. */ + + int len = TREE_VEC_LENGTH (parmvec); + + /* Check if the parameters end in a pack, making them + variadic. */ + int parm_variadic_p = 0; + if (len > 0 + && PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, len - 1))) + parm_variadic_p = 1; + + for (int i = 0; i < len - parm_variadic_p; ++i) + /* If the template argument list of P contains a pack + expansion that is not the last template argument, the + entire template argument list is a non-deduced + context. */ + if (PACK_EXPANSION_P (TREE_VEC_ELT (parmvec, i))) + return unify_success (explain_p); + + if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p) + return unify_too_few_arguments (explain_p, + TREE_VEC_LENGTH (argvec), len); + + for (int i = 0; i < len - parm_variadic_p; ++i) + if (unify (tparms, targs, + TREE_VEC_ELT (parmvec, i), + TREE_VEC_ELT (argvec, i), + UNIFY_ALLOW_NONE, explain_p)) + return 1; + + if (parm_variadic_p + && unify_pack_expansion (tparms, targs, + parmvec, argvec, + DEDUCE_EXACT, + /*subr=*/true, explain_p)) + return 1; + } return 0; } @@ -7559,7 +7634,7 @@ convert_template_argument (tree parm, else if (TREE_CODE (TREE_TYPE (arg)) == UNBOUND_CLASS_TEMPLATE) /* The number of argument required is not known yet. Just accept it for now. */ - val = TREE_TYPE (arg); + val = orig_arg; else { tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm); @@ -19961,6 +20036,9 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, tree pack, packs = NULL_TREE; int i, start = TREE_VEC_LENGTH (packed_parms) - 1; + /* Add in any args remembered from an earlier partial instantiation. */ + targs = add_to_template_args (PACK_EXPANSION_EXTRA_ARGS (parm), targs); + packed_args = expand_template_argument_pack (packed_args); int len = TREE_VEC_LENGTH (packed_args); @@ -20570,18 +20648,6 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, return x; } - if (cxx_dialect >= cxx1z - /* We deduce from array bounds in try_array_deduction. */ - && !(strict & UNIFY_ALLOW_INTEGER) - && uses_template_parms (TREE_TYPE (parm)) - && !type_uses_auto (TREE_TYPE (parm))) - { - tree atype = TREE_TYPE (arg); - RECUR_AND_CHECK_FAILURE (tparms, targs, - TREE_TYPE (parm), atype, - UNIFY_ALLOW_NONE, explain_p); - } - /* [temp.deduct.type] If, in the declaration of a function template with a non-type template-parameter, the non-type template-parameter is used in an expression in the function @@ -20602,7 +20668,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, /* Template-parameter dependent expression. Just accept it for now. It will later be processed in convert_template_argument. */ ; - else if (same_type_p (TREE_TYPE (arg), tparm)) + else if (same_type_p (non_reference (TREE_TYPE (arg)), + non_reference (tparm))) /* OK */; else if ((strict & UNIFY_ALLOW_INTEGER) && CP_INTEGRAL_TYPE_P (tparm)) @@ -20611,9 +20678,22 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, corresponding parameter. */ arg = fold (build_nop (tparm, arg)); else if (uses_template_parms (tparm)) - /* We haven't deduced the type of this parameter yet. Try again - later. */ - return unify_success (explain_p); + { + /* We haven't deduced the type of this parameter yet. */ + if (cxx_dialect >= cxx1z + /* We deduce from array bounds in try_array_deduction. */ + && !(strict & UNIFY_ALLOW_INTEGER)) + { + /* Deduce it from the non-type argument. */ + tree atype = TREE_TYPE (arg); + RECUR_AND_CHECK_FAILURE (tparms, targs, + tparm, atype, + UNIFY_ALLOW_NONE, explain_p); + } + else + /* Try again later. */ + return unify_success (explain_p); + } else return unify_type_mismatch (explain_p, tparm, TREE_TYPE (arg)); @@ -21605,9 +21685,11 @@ get_partial_spec_bindings (tree tmpl, tree spec_tmpl, tree args) `T' is `A' but unify () does not check whether `typename T::X' is `int'. */ spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE); - spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - spec_args, tmpl, - tf_none, false, false); + + if (spec_args != error_mark_node) + spec_args = coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), + INNERMOST_TEMPLATE_ARGS (spec_args), + tmpl, tf_none, false, false); pop_tinst_level (); @@ -23379,6 +23461,14 @@ dependent_type_p_r (tree type) arg_type = TREE_CHAIN (arg_type)) if (dependent_type_p (TREE_VALUE (arg_type))) return true; + if (cxx_dialect >= cxx1z) + { + /* A value-dependent noexcept-specifier makes the type dependent. */ + tree spec = TYPE_RAISES_EXCEPTIONS (type); + if (spec && TREE_PURPOSE (spec) + && value_dependent_expression_p (TREE_PURPOSE (spec))) + return true; + } return false; } /* -- an array type constructed from any dependent type or whose @@ -23927,17 +24017,34 @@ type_dependent_expression_p (tree expression) return true; /* A function or variable template-id is type-dependent if it has any - dependent template arguments. Note that we only consider the innermost - template arguments here, since those are the ones that come from the - template-id; the template arguments for the enclosing class do not make it - type-dependent, they only make a member function value-dependent. */ + dependent template arguments. */ if (VAR_OR_FUNCTION_DECL_P (expression) && DECL_LANG_SPECIFIC (expression) - && DECL_TEMPLATE_INFO (expression) - && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression)) - && (any_dependent_template_arguments_p - (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) - return true; + && DECL_TEMPLATE_INFO (expression)) + { + /* Consider the innermost template arguments, since those are the ones + that come from the template-id; the template arguments for the + enclosing class do not make it type-dependent unless they are used in + the type of the decl. */ + if (PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression)) + && (any_dependent_template_arguments_p + (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression))))) + return true; + + /* Otherwise, if the decl isn't from a dependent scope, it can't be + type-dependent. Checking this is important for functions with auto + return type, which looks like a dependent type. */ + if (TREE_CODE (expression) == FUNCTION_DECL + && undeduced_auto_decl (expression) + && (!DECL_CLASS_SCOPE_P (expression) + || !dependent_type_p (DECL_CONTEXT (expression))) + && (!DECL_FRIEND_CONTEXT (expression) + || !dependent_type_p (DECL_FRIEND_CONTEXT (expression))) + && !DECL_LOCAL_FUNCTION_P (expression)) + { + return false; + } + } /* Always dependent, on the number of arguments if nothing else. */ if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) @@ -24704,6 +24811,14 @@ make_template_placeholder (tree tmpl) return t; } +/* True iff T is a C++17 class template deduction placeholder. */ + +bool +template_placeholder_p (tree t) +{ + return is_auto (t) && CLASS_PLACEHOLDER_TEMPLATE (t); +} + /* Make a "constrained auto" type-specifier. This is an auto type with constraints that must be associated after deduction. The constraint is formed from the given @@ -25061,17 +25176,16 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) } else { + ++processing_template_decl; + + tree fn_tmpl + = (TREE_CODE (ctor) == TEMPLATE_DECL ? ctor + : DECL_TI_TEMPLATE (ctor)); if (outer_args) - ctor = tsubst (ctor, outer_args, complain, ctor); + fn_tmpl = tsubst (fn_tmpl, outer_args, complain, ctor); + ctor = DECL_TEMPLATE_RESULT (fn_tmpl); + type = DECL_CONTEXT (ctor); - tree fn_tmpl; - if (TREE_CODE (ctor) == TEMPLATE_DECL) - { - fn_tmpl = ctor; - ctor = DECL_TEMPLATE_RESULT (fn_tmpl); - } - else - fn_tmpl = DECL_TI_TEMPLATE (ctor); tparms = DECL_TEMPLATE_PARMS (fn_tmpl); /* If type is a member class template, DECL_TI_ARGS (ctor) will have @@ -25093,7 +25207,6 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) /* For a member template constructor, we need to flatten the two template parameter lists into one, and then adjust the function signature accordingly. This gets...complicated. */ - ++processing_template_decl; tree save_parms = current_template_parms; /* For a member template we should have two levels of parms/args, one @@ -25154,8 +25267,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) ci = tsubst_constraint_info (ci, tsubst_args, complain, ctor); current_template_parms = save_parms; - --processing_template_decl; } + --processing_template_decl; } if (!memtmpl) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 09c1b4e6456..f9d770ad8ee 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2754,6 +2754,28 @@ binfo_via_virtual (tree binfo, tree limit) return NULL_TREE; } +/* BINFO is for a base class in some hierarchy. Return true iff it is a + direct base. */ + +bool +binfo_direct_p (tree binfo) +{ + tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo); + if (BINFO_INHERITANCE_CHAIN (d_binfo)) + /* A second inheritance chain means indirect. */ + return false; + if (!BINFO_VIRTUAL_P (binfo)) + /* Non-virtual, so only one inheritance chain means direct. */ + return true; + /* A virtual base looks like a direct base, so we need to look through the + direct bases to see if it's there. */ + tree b_binfo; + for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i) + if (b_binfo == binfo) + return true; + return false; +} + /* BINFO is a base binfo in the complete type BINFO_TYPE (HERE). Find the equivalent binfo within whatever graph HERE is located. This is the inverse of original_binfo. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ad6900258d4..ecfa4e25765 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -731,7 +731,10 @@ finish_if_stmt_cond (tree cond, tree if_stmt) if (IF_STMT_CONSTEXPR_P (if_stmt) && require_potential_rvalue_constant_expression (cond) && !value_dependent_expression_p (cond)) - cond = cxx_constant_value (cond, NULL_TREE); + { + cond = instantiate_non_dependent_expr (cond); + cond = cxx_constant_value (cond, NULL_TREE); + } finish_cond (&IF_COND (if_stmt), cond); add_stmt (if_stmt); THEN_CLAUSE (if_stmt) = push_stmt_list (); @@ -4562,7 +4565,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) return NULL_TREE; if (DECL_P (t)) error_at (OMP_CLAUSE_LOCATION (c), @@ -6076,7 +6079,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL && (!field_ok || TREE_CODE (t) != FIELD_DECL)) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (DECL_P (t)) error ("%qD is not a variable in clause %qs", t, @@ -6148,7 +6151,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP || TREE_CODE (t) != FIELD_DECL)) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (DECL_P (t)) error ("%qD is not a variable in clause %<firstprivate%>", t); @@ -6191,7 +6194,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP || TREE_CODE (t) != FIELD_DECL)) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (DECL_P (t)) error ("%qD is not a variable in clause %<lastprivate%>", t); @@ -6554,7 +6557,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (DECL_P (t)) error ("%qD is not a variable in %<aligned%> clause", t); @@ -6636,7 +6639,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (DECL_P (t)) error ("%qD is not a variable in %<depend%> clause", t); @@ -6767,7 +6770,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) { - if (processing_template_decl) + if (processing_template_decl && TREE_CODE (t) != OVERLOAD) break; if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 15b3ad93b2c..7d525ad443d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -3272,11 +3272,6 @@ cp_tree_equal (tree t1, tree t2) return false; return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1)); - case COMPONENT_REF: - if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1)) - return false; - return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - case PARM_DECL: /* For comparing uses of parameters in late-specified return types with an out-of-class definition of the function, but can also come diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7aee0d6f0ac..0bcf6d0ac97 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8499,9 +8499,10 @@ convert_for_assignment (tree type, tree rhs, if (rhstype == unknown_type_node) { tree r = instantiate_type (type, rhs, tf_warning_or_error); - /* -fpermissive might allow this. */ + /* -fpermissive might allow this; recurse. */ if (!seen_error ()) - return r; + return convert_for_assignment (type, r, errtype, fndecl, + parmnum, complain, flags); } else if (fndecl) error ("cannot convert %qT to %qT for argument %qP to %qD", diff --git a/gcc/doc/gcov-dump.texi b/gcc/doc/gcov-dump.texi index d7931fd3a19..26653d28def 100644 --- a/gcc/doc/gcov-dump.texi +++ b/gcc/doc/gcov-dump.texi @@ -72,11 +72,6 @@ gcov-dump [@option{-v}|@option{--version}] Display help about using @command{gcov-dump} (on the standard output), and exit without doing any further processing. -@item -v -@itemx --version -Display the @command{gcov-dump} version number (on the standard output), -and exit without doing any further processing. - @item -l @itemx --long Dump content of records. @@ -85,6 +80,11 @@ Dump content of records. @itemx --positions Dump positions of records. +@item -v +@itemx --version +Display the @command{gcov-dump} version number (on the standard output), +and exit without doing any further processing. + @item -w @itemx --working-sets Dump working set computed from summary. diff --git a/gcc/doc/gcov-tool.texi b/gcc/doc/gcov-tool.texi index 86044fc1c0b..79f6d96f5ce 100644 --- a/gcc/doc/gcov-tool.texi +++ b/gcc/doc/gcov-tool.texi @@ -113,23 +113,23 @@ gcov-tool @r{[}@var{global-options}@r{]} SUB_COMMAND @r{[}@var{sub_command-optio gcov-tool [@option{-v}|@option{--version}] [@option{-h}|@option{--help}] gcov-tool merge [merge-options] @var{directory1} @var{directory2} + [@option{-o}|@option{--output} @var{directory}] [@option{-v}|@option{--verbose}] - [@option{-o}|@option{ --output} @var{directory}] [@option{-w}|@option{--weight} @var{w1,w2}] gcov-tool rewrite [rewrite-options] @var{directory} - [@option{-v}|@option{--verbose}] + [@option{-n}|@option{--normalize} @var{long_long_value}] [@option{-o}|@option{--output} @var{directory}] [@option{-s}|@option{--scale} @var{float_or_simple-frac_value}] - [@option{-n}|@option{--normalize} @var{long_long_value}] + [@option{-v}|@option{--verbose}] gcov-tool overlap [overlap-options] @var{directory1} @var{directory2} - [@option{-v}|@option{--verbose}] - [@option{-h}|@option{--hotonly}] [@option{-f}|@option{--function}] [@option{-F}|@option{--fullname}] + [@option{-h}|@option{--hotonly}] [@option{-o}|@option{--object}] [@option{-t}|@option{--hot_threshold}] @var{float} + [@option{-v}|@option{--verbose}] @c man end @c man begin SEEALSO @@ -152,17 +152,17 @@ and exit without doing any further processing. @item merge Merge two profile directories. - @table @gcctabopt -@item -v -@itemx --verbose -Set the verbose mode. @item -o @var{directory} @itemx --output @var{directory} Set the output profile directory. Default output directory name is @var{merged_profile}. +@item -v +@itemx --verbose +Set the verbose mode. + @item -w @var{w1},@var{w2} @itemx --weight @var{w1},@var{w2} Set the merge weights of the @var{directory1} and @var{directory2}, @@ -171,11 +171,12 @@ respectively. The default weights are 1 for both. @item rewrite Read the specified profile directory and rewrite to a new directory. - @table @gcctabopt -@item -v -@itemx --verbose -Set the verbose mode. + +@item -n @var{long_long_value} +@itemx --normalize <long_long_value> +Normalize the profile. The specified value is the max counter value +in the new profile. @item -o @var{directory} @itemx --output @var{directory} @@ -186,10 +187,9 @@ Set the output profile directory. Default output name is @var{rewrite_profile}. Scale the profile counters. The specified value can be in floating point value, or simple fraction value form, such 1, 2, 2/3, and 5/3. -@item -n @var{long_long_value} -@itemx --normalize <long_long_value> -Normalize the profile. The specified value is the max counter value -in the new profile. +@item -v +@itemx --verbose +Set the verbose mode. @end table @item overlap @@ -201,14 +201,6 @@ matched counters and p1_sum_all and p2_sum_all are the sum of counter values in profile 1 and profile 2, respectively. @table @gcctabopt -@item -v -@itemx --verbose -Set the verbose mode. - -@item -h -@itemx --hotonly -Only print info for hot objects/functions. - @item -f @itemx --function Print function level overlap score. @@ -217,6 +209,10 @@ Print function level overlap score. @itemx --fullname Print full gcda filename. +@item -h +@itemx --hotonly +Only print info for hot objects/functions. + @item -o @itemx --object Print object level overlap score. @@ -224,6 +220,10 @@ Print object level overlap score. @item -t @var{float} @itemx --hot_threshold <float> Set the threshold for hot counter value. + +@item -v +@itemx --verbose +Set the verbose mode. @end table @end table diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index d728444e1e7..706aa6cf0b0 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -143,15 +143,6 @@ gpl(7), gfdl(7), fsf-funding(7), gcc(1) and the Info entry for @file{gcc}. @c man begin OPTIONS @table @gcctabopt -@item -h -@itemx --help -Display help about using @command{gcov} (on the standard output), and -exit without doing any further processing. - -@item -v -@itemx --version -Display the @command{gcov} version number (on the standard output), -and exit without doing any further processing. @item -a @itemx --all-blocks @@ -172,68 +163,18 @@ be shown, unless the @option{-u} option is given. Write branch frequencies as the number of branches taken, rather than the percentage of branches taken. -@item -n -@itemx --no-output -Do not create the @command{gcov} output file. - -@item -l -@itemx --long-file-names -Create long file names for included source files. For example, if the -header file @file{x.h} contains code, and was included in the file -@file{a.c}, then running @command{gcov} on the file @file{a.c} will -produce an output file called @file{a.c##x.h.gcov} instead of -@file{x.h.gcov}. This can be useful if @file{x.h} is included in -multiple source files and you want to see the individual -contributions. If you use the @samp{-p} option, both the including -and included file names will be complete path names. - -@item -p -@itemx --preserve-paths -Preserve complete path information in the names of generated -@file{.gcov} files. Without this option, just the filename component is -used. With this option, all directories are used, with @samp{/} characters -translated to @samp{#} characters, @file{.} directory components -removed and unremoveable @file{..} -components renamed to @samp{^}. This is useful if sourcefiles are in several -different directories. - -@item -r -@itemx --relative-only -Only output information about source files with a relative pathname -(after source prefix elision). Absolute paths are usually system -header files and coverage of any inline functions therein is normally -uninteresting. +@item -d +@itemx --display-progress +Display the progress on the standard output. @item -f @itemx --function-summaries Output summaries for each function in addition to the file level summary. -@item -o @var{directory|file} -@itemx --object-directory @var{directory} -@itemx --object-file @var{file} -Specify either the directory containing the gcov data files, or the -object path name. The @file{.gcno}, and -@file{.gcda} data files are searched for using this option. If a directory -is specified, the data files are in that directory and named after the -input file name, without its extension. If a file is specified here, -the data files are named after that file, without its extension. - -@item -s @var{directory} -@itemx --source-prefix @var{directory} -A prefix for source file names to remove when generating the output -coverage files. This option is useful when building in a separate -directory, and the pathname to the source directory is not wanted when -determining the output file names. Note that this prefix detection is -applied before determining whether the source file is absolute. - -@item -u -@itemx --unconditional-branches -When branch probabilities are given, include those of unconditional branches. -Unconditional branches are normally not interesting. - -@item -d -@itemx --display-progress -Display the progress on the standard output. +@item -h +@itemx --help +Display help about using @command{gcov} (on the standard output), and +exit without doing any further processing. @item -i @itemx --intermediate-format @@ -274,11 +215,75 @@ lcount:26,1 branch:28,nottaken @end smallexample +@item -l +@itemx --long-file-names +Create long file names for included source files. For example, if the +header file @file{x.h} contains code, and was included in the file +@file{a.c}, then running @command{gcov} on the file @file{a.c} will +produce an output file called @file{a.c##x.h.gcov} instead of +@file{x.h.gcov}. This can be useful if @file{x.h} is included in +multiple source files and you want to see the individual +contributions. If you use the @samp{-p} option, both the including +and included file names will be complete path names. + @item -m @itemx --demangled-names Display demangled function names in output. The default is to show mangled function names. +@item -n +@itemx --no-output +Do not create the @command{gcov} output file. + +@item -o @var{directory|file} +@itemx --object-directory @var{directory} +@itemx --object-file @var{file} +Specify either the directory containing the gcov data files, or the +object path name. The @file{.gcno}, and +@file{.gcda} data files are searched for using this option. If a directory +is specified, the data files are in that directory and named after the +input file name, without its extension. If a file is specified here, +the data files are named after that file, without its extension. + +@item -p +@itemx --preserve-paths +Preserve complete path information in the names of generated +@file{.gcov} files. Without this option, just the filename component is +used. With this option, all directories are used, with @samp{/} characters +translated to @samp{#} characters, @file{.} directory components +removed and unremoveable @file{..} +components renamed to @samp{^}. This is useful if sourcefiles are in several +different directories. + +@item -r +@itemx --relative-only +Only output information about source files with a relative pathname +(after source prefix elision). Absolute paths are usually system +header files and coverage of any inline functions therein is normally +uninteresting. + +@item -s @var{directory} +@itemx --source-prefix @var{directory} +A prefix for source file names to remove when generating the output +coverage files. This option is useful when building in a separate +directory, and the pathname to the source directory is not wanted when +determining the output file names. Note that this prefix detection is +applied before determining whether the source file is absolute. + +@item -u +@itemx --unconditional-branches +When branch probabilities are given, include those of unconditional branches. +Unconditional branches are normally not interesting. + +@item -v +@itemx --version +Display the @command{gcov} version number (on the standard output), +and exit without doing any further processing. + +@item -w +@itemx --verbose +Print verbose informations related to basic blocks and arcs. + @item -x @itemx --hash-filenames By default, gcov uses the full pathname of the source files to to create @@ -319,7 +324,9 @@ command line option. The @var{execution_count} is @samp{-} for lines containing no code. Unexecuted lines are marked @samp{#####} or @samp{====}, depending on whether they are reachable by non-exceptional paths or only exceptional paths such as C++ exception -handlers, respectively. +handlers, respectively. Given @samp{-a} option, unexecuted blocks are +marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block +is reachable via non-exceptional or exceptional paths. Some lines of information at the start have @var{line_number} of zero. These preamble lines are of the form @@ -670,5 +677,5 @@ it. This can be overcome by, for example, setting the environment as setting will name the data file @file{/target/run/build/foo.gcda}. You must move the data files to the expected directory tree in order to -use them for profile directed optimizations (@option{--use-profile}), or to +use them for profile directed optimizations (@option{-fprofile-use}), or to use the @command{gcov} tool. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 42c8dae4a25..896bbbcd30f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2898,7 +2898,7 @@ to a function that does not have a non-throwing exception specification (i.e. @code{throw()} or @code{noexcept}) but is known by the compiler to never throw an exception. -@item -Wnoexcept @r{(C++ and Objective-C++ only)} +@item -Wnoexcept-type @r{(C++ and Objective-C++ only)} @opindex Wnoexcept-type @opindex Wno-noexcept-type Warn if the C++1z feature making @code{noexcept} part of a function @@ -9902,7 +9902,7 @@ The maximum number of insns of an unswitched loop. The maximum number of branches unswitched in a single loop. @item max-loop-headers-insns -The maximum number of insns in loop header duplicated by he copy loop headers +The maximum number of insns in loop header duplicated by the copy loop headers pass. @item lim-expensive @@ -15133,8 +15133,6 @@ Permissible names are: @samp{arm2}, @samp{arm250}, @samp{cortex-m0.small-multiply}, @samp{cortex-m0plus.small-multiply}, @samp{exynos-m1}, -@samp{falkor}, -@samp{qdf24xx}, @samp{marvell-pj4}, @samp{xscale}, @samp{iwmmxt}, @samp{iwmmxt2}, @samp{ep9312}, @samp{fa526}, @samp{fa626}, @@ -25172,13 +25170,12 @@ This option instructs GCC to use 128-bit AVX instructions instead of @item -mcx16 @opindex mcx16 -This option enables GCC to generate @code{CMPXCHG16B} instructions. -@code{CMPXCHG16B} allows for atomic operations on 128-bit double quadword -(or oword) data types. -This is useful for high-resolution counters that can be updated -by multiple processors (or cores). This instruction is generated as part of -atomic built-in functions: see @ref{__sync Builtins} or -@ref{__atomic Builtins} for details. +This option enables GCC to generate @code{CMPXCHG16B} instructions in 64-bit +code to implement compare-and-exchange operations on 16-byte aligned 128-bit +objects. This is useful for atomic updates of data structures exceeding one +machine word in size. The compiler uses this instruction to implement +@ref{__sync Builtins}. However, for @ref{__atomic Builtins} operating on +128-bit integers, a library call is always used. @item -msahf @opindex msahf diff --git a/gcc/gcc.c b/gcc/gcc.c index 826b012cd77..9721f94b4f6 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -4472,6 +4472,9 @@ process_command (unsigned int decoded_options_count, output_file); } + if (output_file != NULL && output_file[0] == '\0') + fatal_error (input_location, "output filename may not be empty"); + /* If -save-temps=obj and -o name, create the prefix to use for %b. Otherwise just make -save-temps=obj the same as -save-temps=cwd. */ if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL) diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c index 91c48668c82..3bf16ab2c53 100644 --- a/gcc/gcov-dump.c +++ b/gcc/gcov-dump.c @@ -132,9 +132,9 @@ print_usage (void) printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); printf ("Print coverage file contents\n"); printf (" -h, --help Print this help\n"); - printf (" -v, --version Print version number\n"); printf (" -l, --long Dump record contents too\n"); printf (" -p, --positions Dump record positions\n"); + printf (" -v, --version Print version number\n"); printf (" -w, --working-sets Dump working set computed from summary\n"); printf ("\nFor bug reporting instructions, please see:\n%s.\n", bug_report_url); diff --git a/gcc/gcov-tool.c b/gcc/gcov-tool.c index 80c08354857..74e77b90d72 100644 --- a/gcc/gcov-tool.c +++ b/gcc/gcov-tool.c @@ -173,8 +173,8 @@ print_merge_usage_message (int error_p) FILE *file = error_p ? stderr : stdout; fnotice (file, " merge [options] <dir1> <dir2> Merge coverage file contents\n"); - fnotice (file, " -v, --verbose Verbose mode\n"); fnotice (file, " -o, --output <dir> Output directory\n"); + fnotice (file, " -v, --verbose Verbose mode\n"); fnotice (file, " -w, --weight <w1,w2> Set weights (float point values)\n"); } @@ -267,10 +267,10 @@ print_rewrite_usage_message (int error_p) FILE *file = error_p ? stderr : stdout; fnotice (file, " rewrite [options] <dir> Rewrite coverage file contents\n"); - fnotice (file, " -v, --verbose Verbose mode\n"); + fnotice (file, " -n, --normalize <int64_t> Normalize the profile\n"); fnotice (file, " -o, --output <dir> Output directory\n"); fnotice (file, " -s, --scale <float or simple-frac> Scale the profile counters\n"); - fnotice (file, " -n, --normalize <int64_t> Normalize the profile\n"); + fnotice (file, " -v, --verbose Verbose mode\n"); } static const struct option rewrite_options[] = @@ -417,12 +417,12 @@ print_overlap_usage_message (int error_p) FILE *file = error_p ? stderr : stdout; fnotice (file, " overlap [options] <dir1> <dir2> Compute the overlap of two profiles\n"); - fnotice (file, " -v, --verbose Verbose mode\n"); - fnotice (file, " -h, --hotonly Only print info for hot objects/functions\n"); fnotice (file, " -f, --function Print function level info\n"); fnotice (file, " -F, --fullname Print full filename\n"); + fnotice (file, " -h, --hotonly Only print info for hot objects/functions\n"); fnotice (file, " -o, --object Print object level info\n"); fnotice (file, " -t <float>, --hot_threshold <float> Set the threshold for hotness\n"); + fnotice (file, " -v, --verbose Verbose mode\n"); } diff --git a/gcc/gcov.c b/gcc/gcov.c index bb26a1a9787..1fb505898a3 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -655,13 +655,13 @@ print_usage (int error_p) fnotice (file, "Usage: gcov [OPTION...] SOURCE|OBJ...\n\n"); fnotice (file, "Print code coverage information.\n\n"); - fnotice (file, " -h, --help Print this help, then exit\n"); fnotice (file, " -a, --all-blocks Show information for every basic block\n"); fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n"); fnotice (file, " -c, --branch-counts Output counts of branches taken\n\ rather than percentages\n"); fnotice (file, " -d, --display-progress Display progress information\n"); fnotice (file, " -f, --function-summaries Output summaries for each function\n"); + fnotice (file, " -h, --help Print this help, then exit\n"); fnotice (file, " -i, --intermediate-format Output .gcov file in intermediate text format\n"); fnotice (file, " -l, --long-file-names Use long output file names for included\n\ source files\n"); @@ -1959,6 +1959,13 @@ format_gcov (gcov_type top, gcov_type bottom, int dp) { static char buffer[20]; + /* Handle invalid values that would result in a misleading value. */ + if (bottom != 0 && top > bottom && dp >= 0) + { + sprintf (buffer, "NAN %%"); + return buffer; + } + if (dp >= 0) { float ratio = bottom ? (float)top / bottom : 0; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 5ebdcdfd796..20c1add3002 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -606,9 +606,10 @@ replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME) { gimple_set_vdef (repl, gimple_vdef (stmt)); - gimple_set_vuse (repl, gimple_vuse (stmt)); SSA_NAME_DEF_STMT (gimple_vdef (repl)) = repl; } + if (gimple_vuse (stmt)) + gimple_set_vuse (repl, gimple_vuse (stmt)); gsi_replace (gsi, repl, false); fold_stmt (gsi); } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index f98a2836489..201ffc1dbac 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2276,7 +2276,8 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p) /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR. */ saved_live_switch_vars = gimplify_ctxp->live_switch_vars; - if (TREE_CODE (SWITCH_BODY (switch_expr)) == BIND_EXPR) + tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr)); + if (body_type == BIND_EXPR || body_type == STATEMENT_LIST) gimplify_ctxp->live_switch_vars = new hash_set<tree> (4); else gimplify_ctxp->live_switch_vars = NULL; @@ -6608,9 +6609,11 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags) return; /* Never elide decls whose type has TREE_ADDRESSABLE set. This means - there are constructors involved somewhere. */ - if (TREE_ADDRESSABLE (TREE_TYPE (decl)) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) + there are constructors involved somewhere. Exception is a shared clause, + there is nothing privatized in that case. */ + if ((flags & GOVD_SHARED) == 0 + && (TREE_ADDRESSABLE (TREE_TYPE (decl)) + || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))) flags |= GOVD_SEEN; n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl); diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index e013a26a4a0..0d214170c24 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1226,7 +1226,7 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2) if (types_odr_comparable (t1, t2, true) && types_same_for_odr (t1, t2, true)) inform (loc_t1, - "type %qT itself violate the C++ One Definition Rule", t1); + "type %qT itself violates the C++ One Definition Rule", t1); /* Prevent pointless warnings like "struct aa" should match "struct aa". */ else if (TYPE_NAME (t1) == TYPE_NAME (t2) && TREE_CODE (t1) == TREE_CODE (t2) && !loc_t2_useful) @@ -1573,7 +1573,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, if (DECL_ARTIFICIAL (f1)) break; warn_odr (t1, t2, f1, f2, warn, warned, - G_("fields has different layout " + G_("fields have different layout " "in another translation unit")); return false; } diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c index c8bab92b7bb..afffb17462e 100644 --- a/gcc/ipa-polymorphic-call.c +++ b/gcc/ipa-polymorphic-call.c @@ -267,7 +267,8 @@ ipa_polymorphic_call_context::restrict_to_inner_class (tree otr_type, { for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld)) { - if (TREE_CODE (fld) != FIELD_DECL) + if (TREE_CODE (fld) != FIELD_DECL + || TREE_TYPE (fld) == error_mark_node) continue; pos = int_bit_position (fld); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index b3d51595d3f..9cc19cec204 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3030,7 +3030,10 @@ find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset) if (index) { - off = wi::to_offset (index); + if (TREE_CODE (index) == RANGE_EXPR) + off = wi::to_offset (TREE_OPERAND (index, 0)); + else + off = wi::to_offset (index); if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type))) { tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type)); @@ -3039,6 +3042,8 @@ find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset) TYPE_PRECISION (TREE_TYPE (index))); } off *= wi::to_offset (unit_size); + /* ??? Handle more than just the first index of a + RANGE_EXPR. */ } else off = wi::to_offset (unit_size) * ix; diff --git a/gcc/params.def b/gcc/params.def index 1b058e49860..6b07518a34b 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -126,7 +126,7 @@ DEFPARAM (PARAM_COMDAT_SHARING_PROBABILITY, DEFPARAM (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY, "partial-inlining-entry-probability", "Maximum probability of the entry BB of split region (in percent relative to entry BB of the function) to make partial inlining happen.", - 70, 0, 0) + 70, 0, 100) /* Limit the number of expansions created by the variable expansion optimization to avoid register pressure. */ diff --git a/gcc/passes.def b/gcc/passes.def index 6b0f05b07bd..e2610a38f41 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -42,9 +42,9 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_build_cfg); NEXT_PASS (pass_warn_function_return); NEXT_PASS (pass_expand_omp); - NEXT_PASS (pass_build_cgraph_edges); NEXT_PASS (pass_sprintf_length, false); NEXT_PASS (pass_walloca, /*strict_mode_p=*/true); + NEXT_PASS (pass_build_cgraph_edges); TERMINATE_PASS_LIST (all_lowering_passes) /* Interprocedural optimization passes. */ diff --git a/gcc/real.c b/gcc/real.c index 97452a9701e..a5671b2865b 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -960,12 +960,12 @@ do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b, gcc_unreachable (); } - if (a->sign != b->sign) - return -a->sign - -b->sign; - if (a->decimal || b->decimal) return decimal_do_compare (a, b, nan_result); + if (a->sign != b->sign) + return -a->sign - -b->sign; + if (REAL_EXP (a) > REAL_EXP (b)) ret = 1; else if (REAL_EXP (a) < REAL_EXP (b)) diff --git a/gcc/reorg.c b/gcc/reorg.c index 85ef7d6880c..19bb65bcfb1 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -1694,9 +1694,8 @@ own_thread_p (rtx thread, rtx label, int allow_fallthrough) } /* Called when INSN is being moved from a location near the target of a jump. - We leave a marker of the form (use (INSN)) immediately in front - of WHERE for mark_target_live_regs. These markers will be deleted when - reorg finishes. + We leave a marker of the form (use (INSN)) immediately in front of WHERE + for mark_target_live_regs. These markers will be deleted at the end. We used to try to update the live status of registers if WHERE is at the start of a basic block, but that can't work since we may remove a @@ -1705,16 +1704,10 @@ own_thread_p (rtx thread, rtx label, int allow_fallthrough) static void update_block (rtx_insn *insn, rtx_insn *where) { - /* Ignore if this was in a delay slot and it came from the target of - a branch. */ - if (INSN_FROM_TARGET_P (insn)) - return; - emit_insn_before (gen_rtx_USE (VOIDmode, insn), where); /* INSN might be making a value live in a block where it didn't use to be. So recompute liveness information for this block. */ - incr_ticks_for_insn (insn); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d0f4468d8a..dbc3a0320ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,188 @@ +2017-07-05 Georg-Johann Lay <avr@gjlay.de> + + Backport from 2017-07-05 trunk r249995, r249996. + + PR target/81305 + * gcc.target/avr/isr-test.h: New file. + * gcc.target/avr/torture/isr-01-simple.c: New test. + * gcc.target/avr/torture/isr-02-call.c: New test. + * gcc.target/avr/torture/isr-03-fixed.c: New test. + +2017-07-04 Uros Bizjak <ubizjak@gmail.com> + + PR target/81300 + * gcc.target/i386/pr81300.c: New test. + +2017-07-04 Uros Bizjak <ubizjak@gmail.com> + + PR target/81294 + * gcc.target/i386/adx-addcarryx32-2.c (adx_test): Swap + x and y arguments in the call to _subborrow_u32. + * gcc.target/i386/adx-addcarryx64-2.c (adx_test): Swap + x and y arguments in the call to _subborrow_u64. + * gcc.target/i386/pr81294-1.c: New test. + * gcc.target/i386/pr81294-2.c: Ditto. + +2017-07-03 Tom de Vries <tom@codesourcery.com> + + backport from mainline: + PR tree-optimization/81192 + 2017-07-03 Tom de Vries <tom@codesourcery.com> + + * gcc.dg/pr81192.c: New test. + +2017-06-29 Michael Meissner <meissner@linux.vnet.ibm.com> + + Backport from mainline + 2017-06-23 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/80510 + * gcc.target/powerpc/pr80510-1.c: Allow test to run on 32-bit. + * gcc.target/powerpc/pr80510-2.c: Likewise. + + Backport from mainline + 2017-06-20 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/79799 + * gcc.target/powerpc/pr79799-1.c: New test. + * gcc.target/powerpc/pr79799-2.c: Likewise. + * gcc.target/powerpc/pr79799-3.c: Likewise. + * gcc.target/powerpc/pr79799-4.c: Likewise. + * gcc.target/powerpc/pr79799-5.c: Likewise. + +2017-06-29 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2017-06-19 Richard Biener <rguenther@suse.de> + + PR ipa/81112 + * g++.dg/torture/pr81112.C: New testcase. + +2017-06-28 Richard Biener <rguenther@suse.de> + + Backport from mainline + 2017-06-09 Richard Biener <rguenther@suse.de> + + PR middle-end/81007 + * g++.dg/pr81007.C: New testcase. + + 2017-06-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/81083 + * gcc.dg/torture/pr81083.c: New testcase. + +2017-06-28 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/tree-prof/val-profiler-threads-1.c (main): Fix 2nd argument + passed to pthread_join. + +2017-06-27 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + Backport from trunk: + PR libgfortran/53029 + * gfortran.dg/read_5.f90: New test. + +2017-06-27 Segher Boessenkool <segher@kernel.crashing.org> + + Backports from trunk: + + 2017-05-17 Segher Boessenkool <segher@kernel.crashing.org> + PR middle-end/80692 + * gcc.c-torture/execute/pr80692.c: New testcase. + + 2017-06-09 Segher Boessenkool <segher@kernel.crashing.org> + PR target/80966 + * gcc.target/powerpc/stack-limit.c: New testcase. + +2017-06-27 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81209 + * g++.dg/ubsan/pr81209.C: New test. + + PR middle-end/81207 + * gcc.c-torture/compile/pr81207.c: New test. + +2017-06-26 Eric Botcazou <ebotcazou@adacore.com> + + * c-c++-common/ubsan/sanitize-recover-7.c (dg-options): Add -w. + +2017-06-24 Marek Polacek <polacek@redhat.com> + + Backport from mainline + 2017-05-04 Marek Polacek <polacek@redhat.com> + + PR tree-optimization/80612 + * gcc.dg/torture/pr80612.c: New test. + +2017-06-23 Thomas Preud'homme <thomas.preudhomme@arm.com> + + Backport from mainline + 2017-05-04 Prakhar Bahuguna <prakhar.bahuguna@arm.com> + + * gcc.target/arm/fpscr.c: New file. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-06-19 Martin Liska <mliska@suse.cz> + + PR sanitizer/80879 + * gcc.dg/asan/use-after-scope-switch-4.c: New test. + +2017-06-22 Martin Liska <mliska@suse.cz> + + Backport from mainline + 2017-05-26 Martin Liska <mliska@suse.cz> + + PR ipa/80663 + * g++.dg/ipa/pr80212.C: Remove the test as it does not longer + split at the problematic spot. + * gcc.dg/ipa/pr48195.c: Change 101 to 100 as 101 is no longer + a valid value of the param. + +2017-06-21 Michael Meissner <meissner@linux.vnet.ibm.com> + + Back port from mainline + PR target/80510 + * gcc.target/powerpc/pr80510-1.c: Restrict test to 64-bit until + 32-bit support is added. Change ITYPE size to 64-bit integer. + * gcc.target/powerpc/pr80510-2.c: Likewise. + +2017-06-21 Jakub Jelinek <jakub@redhat.com> + + PR c++/81154 + * g++.dg/gomp/pr81154.C: New test. + + Backported from mainline + 2017-06-20 Jakub Jelinek <jakub@redhat.com> + + PR target/81121 + * gcc.target/i386/pr81121.c: New test. + + 2017-06-19 Jakub Jelinek <jakub@redhat.com> + + PR sanitizer/81125 + * g++.dg/ubsan/pr81125.C: New test. + + PR sanitizer/81111 + * g++.dg/ubsan/pr81111.C: New test. + + 2017-06-13 Jakub Jelinek <jakub@redhat.com> + + PR c++/80973 + * g++.dg/ubsan/pr80973.C: New test. + + PR c++/80984 + * g++.dg/opt/nrv18.C: New test. + +2017-06-19 James Greenhalgh <james.greenhalgh@arm.com> + + Backport from mainline + 2017-06-19 James Greenhalgh <james.greenhalgh@arm.com> + + PR target/71778 + * gcc.target/arm/pr71778.c: New. + 2017-06-14 Eric Botcazou <ebotcazou@adacore.com> * gcc.target/sparc/overflow-4.c: Add -mno-vis3. diff --git a/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c b/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c index 2e6599fe312..26403ce2488 100644 --- a/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c +++ b/gcc/testsuite/c-c++-common/ubsan/sanitize-recover-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fsanitize=address -fsanitize=thread" } */ +/* { dg-options "-fsanitize=address -fsanitize=thread -w" } */ int i; diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-base5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-base5.C new file mode 100644 index 00000000000..84700bccff7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-base5.C @@ -0,0 +1,15 @@ +// PR c++/80829 +// { dg-do compile { target c++11 } } + +struct A { + constexpr A(int a) : _a(a) {} + int _a; +}; + +struct B : public A { + constexpr B(int a) : A(a) {} +}; + +int main() { + constexpr A a = B(10); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call4.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call4.C new file mode 100644 index 00000000000..d504954bc63 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call4.C @@ -0,0 +1,13 @@ +// PR c++/81188 +// { dg-do compile { target c++11 } } + +template <class F> +struct C { + F fast(long i) const; + auto operator[](long i) const -> decltype(this->fast(i)); +}; + +template <class F> +auto C<F>::operator[](long i) const -> decltype(this->fast(i)) { + return fast(i); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor27.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor27.C new file mode 100644 index 00000000000..ef2ada17d51 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor27.C @@ -0,0 +1,13 @@ +// PR c++/70844 +// { dg-options -Wuseless-cast } +// { dg-do compile { target c++11 } } + +struct base { + base (int const &); +}; + +struct derived : public base { + using base::base; +}; + +derived d(0); diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C new file mode 100644 index 00000000000..90a06c610f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C @@ -0,0 +1,7 @@ +// PR c++/81164 +// { dg-do compile { target c++11 } } + +struct A {}; +struct B : virtual A {}; +struct C : virtual A {}; +struct D : B,C { using A::A; }; // { dg-error "indirect" } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn2.C new file mode 100644 index 00000000000..4a02ab22990 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mem_fn2.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } + +template <class A0, class... As> struct tuple +{ + tuple<As...> tail; + template <int Offset, class... More> int apply(const More&... more) { + return tail.apply<1>(more...); // { dg-error "" } needs .template + } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C new file mode 100644 index 00000000000..6f8df3e1aaf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-partial1.C @@ -0,0 +1,22 @@ +// PR c++/72801 +// { dg-do compile { target c++11 } } + +template < typename, typename > struct A {}; + +template < typename ... T > struct B +{ + template < typename > struct C + { + static const int a = 0; + }; + + template < typename R, typename ... S > + struct C < R (A < T, S > ...) > + { + static const int a = 1; + }; +}; + +#define SA(X) static_assert ((X), #X) +SA(B <>::C<int()>::a == 1); + diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C new file mode 100644 index 00000000000..0dbe904601d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp7.C @@ -0,0 +1,16 @@ +// PR c++/81215 +// { dg-do compile { target c++11 } } + +template<typename U> struct X { }; +template<typename T, typename U = void> struct set { }; + +template <typename V, template <typename...> class C> +void bar (const X<C<V>>&) +{ +} + +void +foo (X<set<int>>& x) +{ + bar (x); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C new file mode 100644 index 00000000000..f3e576ae988 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp8.C @@ -0,0 +1,27 @@ +// PR c++/69111 +// { dg-do compile { target c++11 } } + +template <template <typename> class ...> +struct template_list {}; + +template <typename T> +struct A +{}; + +template <typename> +struct B +{ + template <typename T> + using type = A<T>; +}; + +template <typename ... Types> +struct C +{ + using type = template_list<B<Types>::template type...>; +}; + +int main() +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C index b114df2fdd5..c019d9ef583 100644 --- a/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn27.C @@ -31,7 +31,7 @@ F<T>::bar (const G &) { auto s = I; typedef decltype (s) L; - auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:'void t' has incomplete type" } + auto u =[&](L) { auto t = foo (J::K (), 0); }; // { dg-error "25:declared void" } } struct B { typedef int G; diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn39.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn39.C new file mode 100644 index 00000000000..b4ba29eb200 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn39.C @@ -0,0 +1,48 @@ +// PR c++/81045 +// { dg-do compile { target c++14 } } + +template<typename T> class vectorIterator; + +template<typename T> class vector { + public: + auto get(unsigned int i) { return data[i]; } + + auto begin() { return vectorIterator<T>{*this, 0}; } + auto end() { return vectorIterator<T>{*this, 10}; } + + private: + T data[10] = {}; +}; + +template<typename T> class vectorIterator { + public: + vectorIterator(vector<T>& self, unsigned int offset) : self(self), offset(offset) {} + + auto operator*() -> T& { return self.get(offset); } + auto operator!=(const vectorIterator& source) -> bool { return offset != source.offset; } + auto operator++() -> vectorIterator& { ++offset; return *this; } + + private: + vector<T>& self; + unsigned int offset; +}; + +class Object { + public: + template<typename T> auto cast() -> T { + return T(); + } +}; + +class Group : public Object { + public: + template<typename T = Object> auto objects() const -> void { + vector<Object> easyObjects; + for(auto obj : easyObjects) { + auto casted = obj.cast<T>(); + } + } +}; + +int main() { return 0; } + diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C new file mode 100644 index 00000000000..eeffa69adf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction40.C @@ -0,0 +1,19 @@ +// PR c++/81180 +// { dg-options -std=c++1z } + +template < int I > struct int_{}; + +template < typename T > +struct A{ + template < typename U, int I > + struct B{ + B(U u, int_< I >){} + }; +}; + + +int main(){ + A< int >::B v(0, int_< 0 >()); + (void)v; +} + diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C new file mode 100644 index 00000000000..1ed2c30c5c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C @@ -0,0 +1,14 @@ +// PR c++/80562 +// { dg-options -std=c++1z } + +struct T { + constexpr auto foo() { return false; } +}; + +template <class MustBeTemplate> +constexpr auto bf(T t) { + if constexpr(t.foo()) { + return false; + } + return true; +} diff --git a/gcc/testsuite/g++.dg/cpp1z/lambda-this3.C b/gcc/testsuite/g++.dg/cpp1z/lambda-this3.C new file mode 100644 index 00000000000..b5a1fc63a53 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/lambda-this3.C @@ -0,0 +1,10 @@ +// { dg-options -std=c++1z } + +struct S { + int i; + constexpr S() : i(5) { + ([*this] () { return i + 10; }()); + } + constexpr operator int() const { return i; } +}; +constexpr int x = S(); diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type15.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type15.C new file mode 100644 index 00000000000..cc5a3edf1e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type15.C @@ -0,0 +1,11 @@ +// PR c++/80384 +// { dg-options -std=c++17 } + +template<class> struct foo; +template<bool B> +struct foo<int() noexcept(B)> { + static const bool value = B; +}; + +static_assert(!foo<int()>::value); +static_assert(foo<int() noexcept>::value); diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type16.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type16.C new file mode 100644 index 00000000000..8c763a536a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type16.C @@ -0,0 +1,11 @@ +// PR c++/80614 +// { dg-options -std=c++1z } + +template <typename T> void fn() {} + +int main() { + // { dg-final { scan-assembler "_Z2fnIKFvvEEvv" } } + fn<void() const>(); + // { dg-final { scan-assembler "_Z2fnIKDoFvvEEvv" } } + fn<void() const noexcept>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type17.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type17.C new file mode 100644 index 00000000000..46aefddedf8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type17.C @@ -0,0 +1,7 @@ +// PR c++/80465 +// { dg-options -std=c++1z } + +int foo(...); +int main() { + [](auto a) noexcept(noexcept(foo(a))){}(42); +} diff --git a/gcc/testsuite/g++.dg/ext/packed12.C b/gcc/testsuite/g++.dg/ext/packed12.C new file mode 100644 index 00000000000..2ad14de102d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed12.C @@ -0,0 +1,6 @@ +// PR c++/80972 + +struct A { int i; }; +struct B { A a; } __attribute__((packed)); + +A a = B().a; diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr19.C b/gcc/testsuite/g++.dg/ext/stmtexpr19.C new file mode 100644 index 00000000000..0c19a210f70 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr19.C @@ -0,0 +1,17 @@ +// PR c++/81073 +// { dg-options "" } +// { dg-do compile { target c++11 } } + +struct test { const int *addr; }; + +const test* setup() +{ + static constexpr test atest = + { + ({ static const int inner = 123; &inner; }) // { dg-error "static" } + }; + + return &atest; +} + +int main(){} diff --git a/gcc/testsuite/g++.dg/gomp/pr81154.C b/gcc/testsuite/g++.dg/gomp/pr81154.C new file mode 100644 index 00000000000..dc0aec33e14 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr81154.C @@ -0,0 +1,57 @@ +// PR c++/81154 +// { dg-do compile } + +template <typename T> +struct C +{ + int foo (T n) const + { +#pragma omp parallel shared (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel private (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel firstprivate (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel for lastprivate (foo) // { dg-error "is not a variable in clause" } + for (T i = 0; i < n; i++) + ; +#pragma omp parallel for linear (foo) // { dg-error "is not a variable in clause" } + for (T i = 0; i < n; i++) + ; +#pragma omp parallel reduction (+:foo) // { dg-error "is not a variable in clause" } + ; + return 0; + } + int foo (int x, int y) { return x; } +}; + +struct D +{ + typedef int T; + int foo (T n) const + { +#pragma omp parallel shared (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel private (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel firstprivate (foo) // { dg-error "is not a variable in clause" } + ; +#pragma omp parallel for lastprivate (foo) // { dg-error "is not a variable in clause" } + for (T i = 0; i < n; i++) + ; +#pragma omp parallel for linear (foo) // { dg-error "is not a variable in clause" } + for (T i = 0; i < n; i++) + ; +#pragma omp parallel reduction (+:foo) // { dg-error "is not a variable in clause" } + ; + return 0; + } + int foo (int x, int y) { return x; } +}; + +int +main () +{ + C<int> ().foo (1); + D ().foo (1); +} diff --git a/gcc/testsuite/g++.dg/ipa/pr80212.C b/gcc/testsuite/g++.dg/ipa/pr80212.C deleted file mode 100644 index 60d3b613035..00000000000 --- a/gcc/testsuite/g++.dg/ipa/pr80212.C +++ /dev/null @@ -1,18 +0,0 @@ -// PR ipa/80212 -// { dg-options "-O2 --param partial-inlining-entry-probability=403796683 -fno-early-inlining" } - -struct b -{ - virtual b *c () const; -}; -struct d : virtual b -{ -}; -struct e : d -{ - e * - c () const - { - } -}; -main () { e a; } diff --git a/gcc/testsuite/g++.dg/opt/nrv18.C b/gcc/testsuite/g++.dg/opt/nrv18.C new file mode 100644 index 00000000000..92e9bdf3dbc --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv18.C @@ -0,0 +1,12 @@ +// PR c++/80984 +// { dg-do compile } + +struct A { ~A (); }; + +A +foo () +{ + A a; +a: + return a; +} diff --git a/gcc/testsuite/g++.dg/other/fsyntax-only1.C b/gcc/testsuite/g++.dg/other/fsyntax-only1.C new file mode 100644 index 00000000000..19adb7e6129 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/fsyntax-only1.C @@ -0,0 +1,45 @@ +// PR c++/80831 +// { dg-options -fsyntax-only } +// { dg-do compile { target c++11 } } + +class A +{ +public: + virtual ~A() { } +}; + +class B { }; + +class C : public A { }; + +template<class J> +class D : public C +{ +public: + D() { } + ~D() { } +}; + +class E +{ +public: + static E& p(); + B q(); + template<class J> + B q(void (J::*r)()) + { + new D<J>(); + return q(); + } +}; + +void t() +{ + class F + { + public: + virtual void s() { } + }; + E& x = E::p(); + B y = x.q(&F::s); +} diff --git a/gcc/testsuite/g++.dg/parse/template-keyword1.C b/gcc/testsuite/g++.dg/parse/template-keyword1.C new file mode 100644 index 00000000000..0a1298e75f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template-keyword1.C @@ -0,0 +1,3 @@ +// PR c++/81257 + +template < typename ::template A < int > >; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/parse/template28.C b/gcc/testsuite/g++.dg/parse/template28.C new file mode 100644 index 00000000000..6868bc85285 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template28.C @@ -0,0 +1,10 @@ +// PR c++/79056 + +template<class> struct A {}; + +template<class T> void foo(A<T>=A<T>()) {} // { dg-error "" } + +void bar() +{ + foo(A<int>()); // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/pr81007.C b/gcc/testsuite/g++.dg/pr81007.C new file mode 100644 index 00000000000..87d7d40b913 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr81007.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-options "-O2" } + +struct A +{ + A p; // { dg-error "incomplete" } + virtual void foo(); +}; + +struct B : A {}; + +void bar(B& b) +{ + b.foo(); +} diff --git a/gcc/testsuite/g++.dg/template/function1.C b/gcc/testsuite/g++.dg/template/function1.C index f2345855ed9..4bab2e4e9bf 100644 --- a/gcc/testsuite/g++.dg/template/function1.C +++ b/gcc/testsuite/g++.dg/template/function1.C @@ -1,10 +1,8 @@ // PR c++/38647 -// { dg-do compile { target { ! c++1z } } } -// { dg-prune-output "note" } template<const char *, int> struct A {}; const char func[] = "abc"; -template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid|not a valid|constant expression" } +template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid|not a valid|constant expression" "" { target c++98_only } } char a1[1]; A<a1, 0> a; diff --git a/gcc/testsuite/g++.dg/template/lookup10.C b/gcc/testsuite/g++.dg/template/lookup10.C new file mode 100644 index 00000000000..fa90af46c7c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup10.C @@ -0,0 +1,12 @@ +// PR c++/81204 + +namespace std { + template<typename, typename> struct set { }; +} +using namespace std; + +template <int I, typename Result> +inline void set(Result & res) +{ + res.template set<I>(); +} diff --git a/gcc/testsuite/g++.dg/template/lookup11.C b/gcc/testsuite/g++.dg/template/lookup11.C new file mode 100644 index 00000000000..203460eda73 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup11.C @@ -0,0 +1,11 @@ +// PR c++/81026 + +namespace std { + template<class> struct extent; +} +using namespace std; + +template <class T> +struct S { + void f() { T().template extent<42>(); } +}; diff --git a/gcc/testsuite/g++.dg/template/nontype-array1.C b/gcc/testsuite/g++.dg/template/nontype-array1.C new file mode 100644 index 00000000000..cf21908481b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype-array1.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++11 } } + +template <char const* STR> +class Message { +}; + +extern char const s1[] = "hi"; +char const s2[] = "hi"; +constexpr char const s3[] = "hi"; // OK since C++11 + +constexpr char const * f() { return s3; } + +int main() +{ + Message<s1> m1; // OK (all versions) + Message<s2> m2; // OK for clang since C++14, for gcc since C++17 + Message<s3> m3; // OK for clang/gcc since C++11 + + static char const s4[] = "hi"; + static constexpr char const s5[] = "hi"; // OK since C++11 + Message<s4> m4; // { dg-error "no linkage" "" { target c++14_down } } + Message<s5> m5; // { dg-error "no linkage" "" { target c++14_down } } + Message<f()> m6; // { dg-error "" "" { target c++14_down } } + + char const s8[] = "hi"; + Message<s8> m8; // { dg-error "" } +} diff --git a/gcc/testsuite/g++.dg/template/partial-specialization6.C b/gcc/testsuite/g++.dg/template/partial-specialization6.C new file mode 100644 index 00000000000..51a15905839 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization6.C @@ -0,0 +1,28 @@ +// PR c++/80174 + +typedef unsigned char uint8_t; + +template <typename T> +struct HighestMaxFieldIdx { + static const uint8_t maxFieldIdx = T::fieldIdx; +}; + +template <typename This> +struct Outer { + + template <uint8_t _fieldIdx, typename T, T This::*field> + struct Varint {}; + + + template <uint8_t _fieldIdx, uint8_t This::*field> + struct Varint<_fieldIdx, uint8_t, field> { + static const uint8_t fieldIdx = _fieldIdx; + }; +}; + +struct Msg { + uint8_t a; + + static const uint8_t t + = HighestMaxFieldIdx<Outer<Msg>::Varint<1, uint8_t, &Msg::a> >::maxFieldIdx; +}; diff --git a/gcc/testsuite/g++.dg/template/partial-specialization7.C b/gcc/testsuite/g++.dg/template/partial-specialization7.C new file mode 100644 index 00000000000..aa42191e178 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization7.C @@ -0,0 +1,40 @@ +// PR c++/81102 + +template <typename FuncSig, FuncSig f> +struct HelperWrapper; + +// [...] + +template <typename Ret, Ret (&Func)()> +struct HelperWrapper<Ret (&)(), Func> +{ + static inline int WrapFuncT(const int) + { + return 0; // Changed + } +}; + +// Unary +template <typename Ret, typename Arg1, Ret (&Func)(Arg1)> +struct HelperWrapper<Ret (&)(Arg1), Func> +{ + static inline int WrapFuncT(const int) + { + return 1; // Changed + } +}; + +// Binary +template <typename Ret, typename Arg1, typename Arg2, Ret (&Func)(Arg1, Arg2)> +struct HelperWrapper<Ret (&)(Arg1, Arg2), Func> +{ + static inline int WrapFuncT(const int) + { + return 2; // Changed + } +}; + +int main() +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C index 1b56fb39fa1..ee45a936a0c 100644 --- a/gcc/testsuite/g++.dg/template/partial5.C +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -14,7 +14,7 @@ template<typename T, typename T::foo V> struct Y { }; template<typename T, typename U, U v> -struct Y<T, v> { }; // { dg-error "" } +struct Y<T, v> { }; // { dg-error "" "" { target { ! c++1z } } } template<typename T, T V> diff --git a/gcc/testsuite/g++.dg/template/ptrmem31.C b/gcc/testsuite/g++.dg/template/ptrmem31.C new file mode 100644 index 00000000000..5c66b72cb8f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ptrmem31.C @@ -0,0 +1,23 @@ +// PR c++/80639 +// { dg-do compile { target c++14 } } + +template < typename > struct A; + +struct B +{ + template < int > void m (); + template < int > struct K { static void n (); }; + void p () { K < 0 >::n (); } +}; + +template <> struct A < B > +{ + using T = void (A::*)(); + template < int u > static constexpr T h = &B::m < u >; // { dg-error "cannot convert" } +}; + +template < int v > void B::K < v >::n () +{ + using S = A < B >; + S::h < 0 >; +} diff --git a/gcc/testsuite/g++.dg/torture/pr81112.C b/gcc/testsuite/g++.dg/torture/pr81112.C new file mode 100644 index 00000000000..e9ef2a84cbf --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr81112.C @@ -0,0 +1,68 @@ +// { dg-do compile } +// { dg-additional-options "-Wno-psabi" } + +class AssertionResult { + bool success_; +}; + +AssertionResult AssertionSuccess(); + +template <typename T1> +AssertionResult EXPECT_EQ(const T1& expected, const T1& actual) { + if (expected == actual) { + return AssertionSuccess(); + } + return AssertionSuccess(); +} + +struct uuid +{ + unsigned char data[16]; +}; + +bool operator== (uuid const& lhs, uuid const& rhs); + +typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef int __v4si __attribute__ ((__vector_size__ (16))); +typedef char __v16qi __attribute__ ((__vector_size__ (16))); +typedef long long __m128i_u __attribute__ ((__vector_size__ (16), __may_alias__, __aligned__ (1))); + +int foo (__v16qi); + +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + _mm_loadu_si128 (__m128i_u const *__P) +{ + return *__P; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + _mm_cmpeq_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) ((__v4si)__A == (__v4si)__B); +} +extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + _mm_movemask_epi8 (__m128i __A) +{ + return foo ((__v16qi)__A); +} + + +__m128i load_unaligned_si128(const unsigned char* p) +{ + return _mm_loadu_si128(reinterpret_cast< const __m128i* >(p)); +} + +inline bool operator== (uuid const& lhs, uuid const& rhs) +{ + __m128i mm_left = load_unaligned_si128(lhs.data); + __m128i mm_right = load_unaligned_si128(rhs.data); + + __m128i mm_cmp = _mm_cmpeq_epi32(mm_left, mm_right); + + return _mm_movemask_epi8(mm_cmp) == 0xFFFF; +} + +void crash_gcc7() +{ + static const uuid u = uuid(); + EXPECT_EQ(u, u); +} diff --git a/gcc/testsuite/g++.dg/ubsan/pr80973.C b/gcc/testsuite/g++.dg/ubsan/pr80973.C new file mode 100644 index 00000000000..b534fdbab6f --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr80973.C @@ -0,0 +1,16 @@ +// PR c++/80973 +// { dg-do compile } +// { dg-options "-fsanitize=undefined -std=c++14" } + +struct A { + A(); + A(const A &); +}; +struct B { + B(); + template <typename... Args> auto g(Args &&... p1) { + return [=] { f(p1...); }; + } + void f(A, const char *); +}; +B::B() { g(A(), ""); } diff --git a/gcc/testsuite/g++.dg/ubsan/pr81111.C b/gcc/testsuite/g++.dg/ubsan/pr81111.C new file mode 100644 index 00000000000..6d54a2fdf91 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr81111.C @@ -0,0 +1,45 @@ +// PR sanitizer/81111 +// { dg-do compile } +// { dg-options "-fsanitize=shift" } + +template <typename V> +struct N +{ + static const V m = (((V)(-1) < 0) + ? (V)1 << (sizeof(V) * __CHAR_BIT__ - ((V)(-1) < 0)) + : (V) 0); +}; + +template<typename V> +const V N<V>::m; + +template <typename V> +struct O +{ + static const V m = (V)1 << sizeof(V) * __CHAR_BIT__; +}; + +template<typename V> +const V O<V>::m; + +void +foo () +{ + N<long long>::m; + N<unsigned long long>::m; +#ifdef __SIZEOF_INT128__ + N<__int128>::m; + N<unsigned __int128>::m; +#endif +} + +void +bar () +{ + O<long long>::m; + O<unsigned long long>::m; +#ifdef __SIZEOF_INT128__ + O<__int128>::m; + O<unsigned __int128>::m; +#endif +} diff --git a/gcc/testsuite/g++.dg/ubsan/pr81125.C b/gcc/testsuite/g++.dg/ubsan/pr81125.C new file mode 100644 index 00000000000..c91ddc7db0e --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr81125.C @@ -0,0 +1,20 @@ +// PR sanitizer/81125 +// { dg-do compile } +// { dg-options "-fsanitize=undefined" } + +#ifdef __SIZEOF_INT128__ +typedef __int128 T; +#else +typedef long long int T; +#endif + +struct A +{ + A (long); + T a; +}; + +A::A (long c) +{ + long b = a % c; +} diff --git a/gcc/testsuite/g++.dg/ubsan/pr81209.C b/gcc/testsuite/g++.dg/ubsan/pr81209.C new file mode 100644 index 00000000000..3f2a5768907 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr81209.C @@ -0,0 +1,21 @@ +// PR sanitizer/81209 +// { dg-do compile } +// { dg-options "-fsanitize=undefined -fno-declone-ctor-dtor" } + +#ifdef __SIZEOF_INT128__ +typedef __int128 T; +#else +typedef long long int T; +#endif + +struct B {}; +struct A : virtual public B +{ + A (long); + T a; +}; + +A::A (long c) +{ + long b = a % c; +} diff --git a/gcc/testsuite/g++.dg/warn/Wunused-local-typedefs-4.C b/gcc/testsuite/g++.dg/warn/Wunused-local-typedefs-4.C new file mode 100644 index 00000000000..7efe1125477 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-local-typedefs-4.C @@ -0,0 +1,13 @@ +// PR c++/60063 +// { dg-options -Wunused-local-typedefs } + +template <class> struct S; + +void foo (int i) { + typedef __attribute__ ((used)) S<int> X; +} + +template <class T> +void bar (T i) { + typedef __attribute__ ((used)) S<T> Y; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr81207.c b/gcc/testsuite/gcc.c-torture/compile/pr81207.c new file mode 100644 index 00000000000..f0faa8c0a22 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr81207.c @@ -0,0 +1,13 @@ +/* PR middle-end/81207 */ + +static const char *b[2] = { "'", "" }; + +int +foo (const char *d) +{ + int e; + for (e = 0; b[e]; e++) + if (__builtin_strstr (d, b[e])) + return 1; + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr80692.c b/gcc/testsuite/gcc.c-torture/execute/pr80692.c new file mode 100644 index 00000000000..e653c71c913 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr80692.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target dfp } */ + +int main () { + _Decimal64 d64 = -0.DD; + + if (d64 != 0.DD) + __builtin_abort (); + + if (d64 != -0.DD) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-4.c b/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-4.c new file mode 100644 index 00000000000..babffcc1cbe --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-4.c @@ -0,0 +1,35 @@ +// { dg-do run } +// { dg-additional-options "-fdump-tree-gimple" } + +int *ptr; + +struct a +{ + int c; +}; + +int main(int argc, char **argv) +{ + struct a e; + e.c = 2; + int x = 0; + + for (;;) + switch (e.c) + case 3: + { + int resxxx; + case 2: + ptr = &resxxx; + *ptr = 123; + + if (x) + return 0; + else + x = 1; + } + + return 1; +} + +/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(UNPOISON, &resxxx, \[0-9\]\\);" 2 "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/pr48195.c b/gcc/testsuite/gcc.dg/ipa/pr48195.c index 2e38452d598..25e80bab8f8 100644 --- a/gcc/testsuite/gcc.dg/ipa/pr48195.c +++ b/gcc/testsuite/gcc.dg/ipa/pr48195.c @@ -1,5 +1,5 @@ /* { dg-do link } */ -/* { dg-options "-O2 -flto --param partial-inlining-entry-probability=101" } */ +/* { dg-options "-O2 -flto --param partial-inlining-entry-probability=100" } */ /* { dg-require-effective-target lto } */ extern void abort(void); diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c new file mode 100644 index 00000000000..57eb4781d4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr81192.c @@ -0,0 +1,22 @@ +/* { dg-options "-Os -fdump-tree-pre-details" } */ + +unsigned a; +int b, c; + +static int +fn1 (int p1, int p2) +{ + return p1 > 2147483647 - p2 ? p1 : p1 + p2; +} + +void +fn2 (void) +{ + int j; + a = 30; + for (; a;) + for (; c; b = fn1 (j, 1)) + ; +} + +/* { dg-final { scan-tree-dump-times "(?n)find_duplicates: <bb .*> duplicate of <bb .*>" 1 "pre" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr80612.c b/gcc/testsuite/gcc.dg/torture/pr80612.c new file mode 100644 index 00000000000..225b81127a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr80612.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/80612 */ +/* { dg-do compile } */ + +struct obstack *a; +struct obstack { + union { + void *plain; + void (*extra)(); + } chunkfun; +} fn1(void p4()) { + a->chunkfun.plain = p4; + a->chunkfun.extra(a); +} +void fn2(int) __attribute__((__alloc_size__(1))); +void fn3() { fn1(fn2); } diff --git a/gcc/testsuite/gcc.dg/torture/pr80970.c b/gcc/testsuite/gcc.dg/torture/pr80970.c new file mode 100644 index 00000000000..3b96b581e33 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr80970.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +int a, b, c, d, e; +void f () +{ + long g, h; + if (c) + e = d; + g = d & 31; + h = 1 << g; + a = e | h; + b = a; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr81083.c b/gcc/testsuite/gcc.dg/torture/pr81083.c new file mode 100644 index 00000000000..53f96a3835a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr81083.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +void setjmp(); +void func(); +void a(int arg) +{ + extern struct { int x; } obj; + setjmp(); + obj.x = arg; + arg = arg; + if (obj.x) + func(); + if (obj.x) + func(); +} diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c index 95d6ee3b4a3..830232a7ffa 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c @@ -35,9 +35,9 @@ int main(int argc, char *argv[]) } } - int retval; + void *retval; for(t=0;t<NUM_THREADS;t++) - pthread_join (threads[t], (void**)&retval); + pthread_join (threads[t], &retval); return buffer[10]; } diff --git a/gcc/testsuite/gcc.target/avr/isr-test.h b/gcc/testsuite/gcc.target/avr/isr-test.h new file mode 100644 index 00000000000..2d2babe2150 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/isr-test.h @@ -0,0 +1,282 @@ +#ifndef ISR_TEST_H +#define ISR_TEST_H + +#include <string.h> + +#define ISR(N,...) \ +__attribute__ ((used, externally_visible , ## __VA_ARGS__)) \ + void __vector_##N (void); \ + void __vector_##N (void) + +#define SFR(ADDR) (*(unsigned char volatile*) (__AVR_SFR_OFFSET__ + (ADDR))) +#define CORE_SFRS SFR (0x38) +#define SREG SFR (0x3F) +#define SPL SFR (0x3D) +#define EIND SFR (0x3C) +#define RAMPZ SFR (0x3B) +#define RAMPY SFR (0x3A) +#define RAMPX SFR (0x39) +#define RAMPD SFR (0x38) + +#ifdef __AVR_HAVE_JMP_CALL__ +#define VEC_SIZE 4 +#else +#define VEC_SIZE 2 +#endif + +#ifdef __AVR_TINY__ +#define FIRST_REG 16 +#else +#define FIRST_REG 0 +#endif + +#define CR "\n\t" + +typedef struct +{ + unsigned char sfrs[8]; + unsigned char gprs[32 - FIRST_REG]; +} regs_t; + +regs_t reginfo1, reginfo2; + +__attribute__((noinline)) +static void clear_reginfo (void) +{ + memset (reginfo1.sfrs, 0, sizeof (reginfo1.sfrs)); + memset (reginfo2.sfrs, 0, sizeof (reginfo2.sfrs)); +} + +__attribute__((noinline)) +static void compare_reginfo (unsigned long gpr_ignore) +{ + signed char regno; + const unsigned char *preg1 = ®info1.gprs[0]; + const unsigned char *preg2 = ®info2.gprs[0]; + + if (memcmp (®info1, ®info2, 8)) + __builtin_abort(); + + gpr_ignore >>= FIRST_REG; + + for (regno = FIRST_REG; regno < 32; + regno++, preg1++, preg2++, gpr_ignore >>= 1) + { + if (gpr_ignore & 1) + continue; + + if (*preg1 != *preg2) + { + static signed char volatile failed_regno; + failed_regno = regno; + __builtin_abort(); + } + } +} + +/* STore GPR */ +#define ST(regno,M) \ + CR "sts %[" #M "]+8-%[first]+" #regno ", r" #regno + +/* STore SFR */ +#define ST_SFR(sfr, n_sfr, M) \ + CR "in __tmp_reg__,%i[s_" #sfr "]" \ + CR "sts %[" #M "]+" #n_sfr ", __tmp_reg__" + +/* Named asm OPerand for SFR */ +#define OP_SFR(sfr) \ + , [s_ ## sfr] "n" (&(sfr)) + +/* Write funny value to SFR */ +#define XX_SFR(sfr) \ + CR "dec r31 $ out %i[s_" #sfr "], r31" + +/* Write 0 to SFR */ +#define OO_SFR(sfr) \ + CR "out %i[s_" #sfr "], __zero_reg__" + +/* Macros for SREG */ +#define ST_SREG(M) ST_SFR (SREG,0,M) +#define OP_SREG OP_SFR (SREG) +#define XX_SREG XX_SFR (SREG) + +/* Macros for EIND */ +#if defined __AVR_HAVE_EIJMP_EICALL__ +#define ST_EIND(M) ST_SFR (EIND,1,M) +#define OP_EIND OP_SFR (EIND) +#else +#define ST_EIND(M) /* empty */ +#define OP_EIND /* empty */ +#endif + +/* Macros for RAMPX */ +#if defined (__AVR_HAVE_RAMPX__) +#define ST_RAMPX(M) ST_SFR (RAMPX,2,M) +#define OP_RAMPX OP_SFR (RAMPX) +#define XX_RAMPX XX_SFR (RAMPX) +#define OO_RAMPX OO_SFR (RAMPX) +#else +#define ST_RAMPX(M) /* empty */ +#define OP_RAMPX /* empty */ +#define XX_RAMPX /* empty */ +#define OO_RAMPX /* empty */ +#endif + +/* Macros for RAMPY */ +#if defined (__AVR_HAVE_RAMPY__) +#define ST_RAMPY(M) ST_SFR (RAMPY,3,M) +#define OP_RAMPY OP_SFR (RAMPY) +#define XX_RAMPY XX_SFR (RAMPY) +#define OO_RAMPY OO_SFR (RAMPY) +#else +#define ST_RAMPY(M) /* empty */ +#define OP_RAMPY /* empty */ +#define XX_RAMPY /* empty */ +#define OO_RAMPY /* empty */ +#endif + +/* Macros for RAMPZ */ +#if defined (__AVR_HAVE_RAMPZ__) +#define ST_RAMPZ(M) ST_SFR (RAMPZ,4,M) +#define OP_RAMPZ OP_SFR (RAMPZ) +#define XX_RAMPZ XX_SFR (RAMPZ) +#define OO_RAMPZ OO_SFR (RAMPZ) +#else +#define ST_RAMPZ(M) /* empty */ +#define OP_RAMPZ /* empty */ +#define XX_RAMPZ /* empty */ +#define OO_RAMPZ /* empty */ +#endif + +/* Macros for RAMPD */ +#if defined (__AVR_HAVE_RAMPD__) +#define ST_RAMPD(M) ST_SFR (RAMPD,5,M) +#define OP_RAMPD OP_SFR (RAMPD) +#else +#define ST_RAMPD(M) /* empty */ +#define OP_RAMPD /* empty */ +#endif + +/* Macros for all GPRs */ +#if defined __AVR_TINY__ +#define ST_REGS_LO(M) /* empty */ +#else +#define ST_REGS_LO(M) \ + ST(0,M) ST(1,M) ST(2,M) ST(3,M) \ + ST(4,M) ST(5,M) ST(6,M) ST(7,M) \ + ST(8,M) ST(9,M) ST(10,M) ST(11,M) \ + ST(12,M) ST(13,M) ST(14,M) ST(15,M) +#endif /* AVR_TINY */ + +#define ST_REGS_HI(M) \ + ST(16,M) ST(17,M) ST(18,M) ST(19,M) \ + ST(20,M) ST(21,M) ST(22,M) ST(23,M) \ + ST(24,M) ST(25,M) ST(26,M) ST(27,M) \ + ST(28,M) ST(29,M) ST(30,M) ST(31,M) + +__attribute__((used,naked,noinline,noclone)) +static void host_store1 (void) +{ + __asm __volatile__ + ("nop" + CR ".global do_stores_before" + CR ".type do_stores_before,@function" + CR "do_stores_before:" + /* Funny values to some SFRs */ + CR "ldi r31, 1 + 'Z'" + XX_RAMPZ + XX_RAMPY + XX_RAMPX + CR "dec __zero_reg__" + CR "clr r31" + XX_SREG + /* Must set I-flag due to RETI of ISR */ + CR "sei" + /* Store core regs before ISR */ + ST_RAMPX (mem1) + ST_RAMPY (mem1) + ST_RAMPZ (mem1) + ST_RAMPD (mem1) + ST_EIND (mem1) + ST_SREG (mem1) + CR "ldi r31, 0xaa" + CR "mov __tmp_reg__, r31" + CR "ldi r31, 31" + ST_REGS_LO (mem1) + ST_REGS_HI (mem1) + CR "ret" + : /* No outputs */ + : [mem1] "i" (®info1), [first] "n" (FIRST_REG) + OP_RAMPX + OP_RAMPY + OP_RAMPZ + OP_RAMPD + OP_EIND + OP_SREG + : "memory", "r31"); +} + +__attribute__((used,naked,noinline,noclone)) +static void host_store2 (void) +{ + __asm __volatile__ + ("nop" + CR ".global do_stores_after" + CR ".type do_stores_after,@function" + CR "do_stores_after:" + /* Store core regs after ISR */ + ST_REGS_LO (mem2) + ST_REGS_HI (mem2) + ST_RAMPX (mem2) + ST_RAMPY (mem2) + ST_RAMPZ (mem2) + ST_RAMPD (mem2) + ST_EIND (mem2) + ST_SREG (mem2) + /* Undo funny values */ + CR "clr __zero_reg__" + OO_RAMPX + OO_RAMPY + OO_RAMPZ + CR "ret" + : /* No outputs */ + : [mem2] "i" (®info2), [first] "n" (FIRST_REG) + OP_RAMPX + OP_RAMPY + OP_RAMPZ + OP_RAMPD + OP_EIND + OP_SREG + : "memory"); +} + +#define MK_CALL_ISR(vecno) \ + __asm __volatile__ \ + (/* Funny values to some SFRs */ \ + /* Must set I-flag due to RETI of ISR */ \ + /* Store core regs before ISR */ \ + CR "%~call do_stores_before" \ + /* Execute ISR */ \ + CR "%~call __vectors + %[vect]" \ + /* Store core regs after ISR */ \ + /* Undo funny values */ \ + CR "%~call do_stores_after" \ + : /* No outputs */ \ + : [vect] "i" (VEC_SIZE * (vecno)) \ + , "i" (host_store1) \ + , "i" (host_store2) \ + : "memory", "r31") + + +#define MK_RUN_ISR(N, IGMSK) \ + \ +__attribute__((noinline,noclone)) \ +void run_isr_ ## N (void) \ +{ \ + clear_reginfo(); \ + MK_CALL_ISR (N); \ + compare_reginfo (IGMSK); \ +} + +#endif /* ISR_TEST_H */ + diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c b/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c new file mode 100644 index 00000000000..271d0cf47e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-01-simple.c @@ -0,0 +1,98 @@ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +#include "../isr-test.h" + +int volatile v; + +/**********************************************************************/ + +ISR (1, signal) +{ +} + +MK_RUN_ISR (1, 0) + +void test1 (void) +{ + run_isr_1(); +} + +/**********************************************************************/ + +ISR (2, signal) +{ + v++; +} + +MK_RUN_ISR (2, 0) + +void test2 (void) +{ + v = 0; + run_isr_2(); + if (v != 1) + __builtin_abort(); +} + + +/**********************************************************************/ + +ISR (3, signal) +{ + __asm __volatile__ ("$ lds r27, v" + "$ swap r27" + "$ sts v, r27" + ::: "memory", "r27"); +} + +MK_RUN_ISR (3, 0) + +void test3 (void) +{ + run_isr_3(); + if (v != 0x10) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (4, signal) +{ + __asm __volatile__ ("sts v,__zero_reg__" ::: "memory"); +} + +MK_RUN_ISR (4, 0) + +void test4 (void) +{ + run_isr_4(); + if (v != 0) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (5, signal) +{ + __asm __volatile__ ("clt"); +} + +MK_RUN_ISR (5, 0) + +void test5 (void) +{ + run_isr_5(); +} + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c b/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c new file mode 100644 index 00000000000..be4f22ebb35 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-02-call.c @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-options "-std=c99" } */ + +#include "../isr-test.h" + +int volatile v; + +__attribute__((noinline,noclone)) +void inc_v (void) +{ + v++; +} + +/**********************************************************************/ + +ISR (1, signal) +{ + inc_v(); +} + +MK_RUN_ISR (1, 0) + +void test1 (void) +{ + run_isr_1(); + if (v != 1) + __builtin_abort(); +} + +/**********************************************************************/ + +ISR (2, signal) +{ + if (v == 1) + inc_v(); + else + v += 2; +} + +MK_RUN_ISR (2, 0) + +void test2 (void) +{ + run_isr_2(); + if (v != 2) + __builtin_abort(); + run_isr_2(); + if (v != 4) + __builtin_abort(); +} + + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c b/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c new file mode 100644 index 00000000000..5606225aebc --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/isr-03-fixed.c @@ -0,0 +1,146 @@ +/* { dg-do run } */ +/* { dg-options "-std=gnu99 -fno-lto -fno-toplevel-reorder" } */ + +// No LTO for now due to PR lto/68384. + +#ifdef __AVR_TINY__ +unsigned char reg2; +#else +register unsigned char reg2 __asm("r2"); +#endif + +#include "../isr-test.h" + +#define SET_REG(reg,val) \ + do { \ + reg = (val); \ + __asm __volatile__("" : "+r" (reg)); \ + } while (0) \ + +#define GET_REG(reg) \ + ({ \ + __asm __volatile__("" : "+r" (reg)); \ + reg; \ + }) + +/**********************************************************************/ + +ISR (1, signal) +{ + reg2++; +} + +MK_RUN_ISR (1, 1ul << 2) + +void test1 (void) +{ + SET_REG (reg2, 0); + run_isr_1(); + if (GET_REG (reg2) != 1) + __builtin_abort(); +} + +/**********************************************************************/ + +__attribute__((noinline,noclone)) +void inc_r2 (void) +{ + reg2++; +} + +ISR (2, signal) +{ + inc_r2 (); +} + +MK_RUN_ISR (2, 1ul << 2) + +void test2 (void) +{ + run_isr_2(); + if (GET_REG (reg2) != 2) + __builtin_abort(); +} + + +/**********************************************************************/ + +ISR (3, signal) +{ +#ifndef __AVR_TINY__ + register char r4 __asm ("r4"); + __asm __volatile ("inc %0" : "+r" (r4)); + __asm __volatile ("inc r5" ::: "r5"); +#endif +} + +MK_RUN_ISR (3, 0) + +void test3 (void) +{ + run_isr_3(); +} + + +/**********************************************************************/ + +#define CLOBB(reg) \ + do { \ + __asm __volatile__ ("inc " #reg ::: #reg); \ + } while (0) + +ISR (4, signal) +{ + char volatile v; + v = 1; + +#ifndef __AVR_TINY__ + CLOBB (r3); + CLOBB (r4); + CLOBB (r5); + CLOBB (r6); + CLOBB (r7); + CLOBB (r8); + CLOBB (r9); + CLOBB (r10); + CLOBB (r11); + CLOBB (r12); + CLOBB (r13); + CLOBB (r14); + CLOBB (r15); + CLOBB (r16); + CLOBB (r17); +#endif + + CLOBB (r18); + CLOBB (r19); + CLOBB (r20); + CLOBB (r21); + CLOBB (r22); + CLOBB (r23); + CLOBB (r24); + CLOBB (r25); + CLOBB (r26); + CLOBB (r27); + CLOBB (r30); + CLOBB (r31); +} + +MK_RUN_ISR (4, 0) + +void test4 (void) +{ + run_isr_4(); +} + + +/**********************************************************************/ + +int main (void) +{ + test1(); + test2(); + test3(); + test4(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c index b1da555bc31..ddee754c962 100644 --- a/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c +++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx32-2.c @@ -44,9 +44,9 @@ adx_test (void) sum_ref = 0x0; /* X = 0x00000001, Y = 0x00000000, C = 0. */ - c = _subborrow_u32 (c, x, y, &x); + c = _subborrow_u32 (c, y, x, &x); /* X = 0xFFFFFFFF, Y = 0x00000000, C = 1. */ - c = _subborrow_u32 (c, x, y, &x); + c = _subborrow_u32 (c, y, x, &x); /* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 1. */ if (x != sum_ref) diff --git a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c index b326291bb35..287e263a9dd 100644 --- a/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c +++ b/gcc/testsuite/gcc.target/i386/adx-addcarryx64-2.c @@ -44,9 +44,9 @@ adx_test (void) sum_ref = 0x0LL; /* X = 0x0000000000000001, Y = 0x0000000000000000, C = 0. */ - c = _subborrow_u64 (c, x, y, &x); + c = _subborrow_u64 (c, y, x, &x); /* X = 0xFFFFFFFFFFFFFFFF, Y = 0x0000000000000000, C = 1. */ - c = _subborrow_u64 (c, x, y, &x); + c = _subborrow_u64 (c, y, x, &x); /* X = 0x0000000000000000, Y = 0x0000000000000000, C = 1. */ if (x != sum_ref) diff --git a/gcc/testsuite/gcc.target/i386/pr81121.c b/gcc/testsuite/gcc.target/i386/pr81121.c new file mode 100644 index 00000000000..aca74e95b46 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81121.c @@ -0,0 +1,10 @@ +/* PR target/81121 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -march=amdfam10 -mno-sse2" } */ + +void +foo (short *x, short *y) +{ + float a = 0; + y[0] = x[0] * a; +} diff --git a/gcc/testsuite/gcc.target/i386/pr81294-1.c b/gcc/testsuite/gcc.target/i386/pr81294-1.c new file mode 100644 index 00000000000..6a15ed0a410 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81294-1.c @@ -0,0 +1,29 @@ +/* PR target/81294 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include <x86intrin.h> + +int +main () +{ + volatile unsigned char c; + unsigned int x; + volatile unsigned int y, sum_ref; + + c = 0; + x = 1; + y = 0; + sum_ref = 0x0; + + /* X = 0x00000001, Y = 0x00000000, C = 0. */ + c = _subborrow_u32 (c, y, x, &x); + /* X = 0xFFFFFFFF, Y = 0x00000000, C = 1. */ + c = _subborrow_u32 (c, y, x, &x); + /* X = 0xFFFFFFFF, Y = 0xFFFFFFFF, C = 1. */ + + if (x != sum_ref) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr81294-2.c b/gcc/testsuite/gcc.target/i386/pr81294-2.c new file mode 100644 index 00000000000..3e3bdb44139 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81294-2.c @@ -0,0 +1,28 @@ +/* PR target/81294 */ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +#include <x86intrin.h> + +int main () +{ + volatile unsigned char c; + unsigned long long x; + volatile unsigned long long y, sum_ref; + + c = 0; + x = 1LL; + y = 0LL; + sum_ref = 0x0LL; + + /* X = 0x0000000000000001, Y = 0x0000000000000000, C = 0. */ + c = _subborrow_u64 (c, y, x, &x); + /* X = 0xFFFFFFFFFFFFFFFF, Y = 0x0000000000000000, C = 1. */ + c = _subborrow_u64 (c, y, x, &x); + /* X = 0x0000000000000000, Y = 0x0000000000000000, C = 1. */ + + if (x != sum_ref) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr81300.c b/gcc/testsuite/gcc.target/i386/pr81300.c new file mode 100644 index 00000000000..11eb55fed8d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81300.c @@ -0,0 +1,30 @@ +/* PR target/81300 */ +/* { dg-do run { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ + +int +__attribute__((noinline, noclone)) +foo (void) +{ + unsigned long long _discard = 0, zero = 0, maxull = 0; + unsigned char zero1 = __builtin_ia32_addcarryx_u64 (0, 0, 0, &_discard); + unsigned char zero2 = __builtin_ia32_addcarryx_u64 (zero1, 0, 0, &zero); + __builtin_ia32_sbb_u64 (0x0, 2, -1, &_discard); + unsigned char one = __builtin_ia32_sbb_u64 (0, zero, 1, &maxull); + unsigned long long x = __builtin_ia32_sbb_u64 (one, zero2, 0, &_discard); + + unsigned long long z1 = 0; + __asm__ ("mov{q}\t{%1, %0|%0, %1}" : "+r" (z1) : "r" (x)); + unsigned long long z2 = 3; + __asm__ ("mov{q}\t{%1, %0|%0, %1}" : "+r" (z2) : "r" (x)); + + return 1 - (z1 | z2); +} + +int main () +{ + if (foo ()) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-1.c b/gcc/testsuite/gcc.target/powerpc/pr79799-1.c new file mode 100644 index 00000000000..87a9e49b889 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-1.c @@ -0,0 +1,43 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include <altivec.h> + +/* GCC 7.1 did not have a specialized method for inserting 32-bit floating + point on ISA 3.0 (power9) systems. */ + +vector float +insert_arg_0 (vector float vf, float f) +{ + return vec_insert (f, vf, 0); +} + +vector float +insert_arg_1 (vector float vf, float f) +{ + return vec_insert (f, vf, 1); +} + +vector float +insert_arg_2 (vector float vf, float f) +{ + return vec_insert (f, vf, 2); +} + +vector float +insert_arg_3 (vector float vf, float f) +{ + return vec_insert (f, vf, 3); +} + +/* { dg-final { scan-assembler {\mxscvdpspn\M} } } */ +/* { dg-final { scan-assembler {\mxxinsertw\M} } } */ +/* { dg-final { scan-assembler-not {\mlvewx\M} } } */ +/* { dg-final { scan-assembler-not {\mlvx\M} } } */ +/* { dg-final { scan-assembler-not {\mvperm\M} } } */ +/* { dg-final { scan-assembler-not {\mvpermr\M} } } */ +/* { dg-final { scan-assembler-not {\mstfs\M} } } */ +/* { dg-final { scan-assembler-not {\mstxssp\M} } } */ +/* { dg-final { scan-assembler-not {\mstxsspx\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-2.c b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c new file mode 100644 index 00000000000..793e3b9b66c --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c @@ -0,0 +1,31 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include <altivec.h> + +/* Optimize x = vec_insert (vec_extract (v2, N), v1, M) for SFmode if N is the default + scalar position. */ + +#if __ORDER_LITTLE_ENDIAN__ +#define ELE 2 +#else +#define ELE 1 +#endif + +vector float +foo (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, ELE), v1, 0); +} + +/* { dg-final { scan-assembler {\mxxinsertw\M} } } */ +/* { dg-final { scan-assembler-not {\mxxextractuw\M} } } */ +/* { dg-final { scan-assembler-not {\mlvewx\M} } } */ +/* { dg-final { scan-assembler-not {\mlvx\M} } } */ +/* { dg-final { scan-assembler-not {\mvperm\M} } } */ +/* { dg-final { scan-assembler-not {\mvpermr\M} } } */ +/* { dg-final { scan-assembler-not {\mstfs\M} } } */ +/* { dg-final { scan-assembler-not {\mstxssp\M} } } */ +/* { dg-final { scan-assembler-not {\mstxsspx\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-3.c b/gcc/testsuite/gcc.target/powerpc/pr79799-3.c new file mode 100644 index 00000000000..72550421859 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-3.c @@ -0,0 +1,24 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include <altivec.h> + +/* Optimize x = vec_insert (vec_extract (v2, N), v1, M) for SFmode. */ + +vector float +foo (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, 4), v1, 0); +} + +/* { dg-final { scan-assembler {\mxxinsertw\M} } } */ +/* { dg-final { scan-assembler {\mxxextractuw\M} } } */ +/* { dg-final { scan-assembler-not {\mlvewx\M} } } */ +/* { dg-final { scan-assembler-not {\mlvx\M} } } */ +/* { dg-final { scan-assembler-not {\mvperm\M} } } */ +/* { dg-final { scan-assembler-not {\mvpermr\M} } } */ +/* { dg-final { scan-assembler-not {\mstfs\M} } } */ +/* { dg-final { scan-assembler-not {\mstxssp\M} } } */ +/* { dg-final { scan-assembler-not {\mstxsspx\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-4.c b/gcc/testsuite/gcc.target/powerpc/pr79799-4.c new file mode 100644 index 00000000000..056a005be25 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-4.c @@ -0,0 +1,105 @@ +/* { dg-do run { target { powerpc*-*-linux* } } } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include <altivec.h> +#include <stdlib.h> + +__attribute__ ((__noinline__)) +vector float +insert_0 (vector float v, float f) +{ + return vec_insert (f, v, 0); +} + +__attribute__ ((__noinline__)) +vector float +insert_1 (vector float v, float f) +{ + return vec_insert (f, v, 1); +} + +__attribute__ ((__noinline__)) +vector float +insert_2 (vector float v, float f) +{ + return vec_insert (f, v, 2); +} + +__attribute__ ((__noinline__)) +vector float +insert_3 (vector float v, float f) +{ + return vec_insert (f, v, 3); +} + +__attribute__ ((__noinline__)) +void +test_insert (void) +{ + vector float v1 = { 1.0f, 2.0f, 3.0f, 4.0f }; + vector float v2 = { 5.0f, 6.0f, 7.0f, 8.0f }; + + v1 = insert_0 (v1, 5.0f); + v1 = insert_1 (v1, 6.0f); + v1 = insert_2 (v1, 7.0f); + v1 = insert_3 (v1, 8.0f); + + if (vec_any_ne (v1, v2)) + abort (); +} + +__attribute__ ((__noinline__)) +vector float +insert_extract_0_3 (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, 3), v1, 0); +} + +__attribute__ ((__noinline__)) +vector float +insert_extract_1_2 (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, 2), v1, 1); +} + +__attribute__ ((__noinline__)) +vector float +insert_extract_2_1 (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, 1), v1, 2); +} + +__attribute__ ((__noinline__)) +vector float +insert_extract_3_0 (vector float v1, vector float v2) +{ + return vec_insert (vec_extract (v2, 0), v1, 3); +} + +__attribute__ ((__noinline__)) +void +test_insert_extract (void) +{ + vector float v1 = { 1.0f, 2.0f, 3.0f, 4.0f }; + vector float v2 = { 5.0f, 6.0f, 7.0f, 8.0f }; + vector float v3 = { 8.0f, 7.0f, 6.0f, 5.0f }; + + v1 = insert_extract_0_3 (v1, v2); + v1 = insert_extract_1_2 (v1, v2); + v1 = insert_extract_2_1 (v1, v2); + v1 = insert_extract_3_0 (v1, v2); + + if (vec_any_ne (v1, v3)) + abort (); +} + +int +main (void) +{ + test_insert (); + test_insert_extract (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-5.c b/gcc/testsuite/gcc.target/powerpc/pr79799-5.c new file mode 100644 index 00000000000..fcd92ffd60a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-5.c @@ -0,0 +1,25 @@ +/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mcpu=power9 -O2" } */ + +#include <altivec.h> + +/* Insure setting 0.0f to a V4SFmode element does not do a FP conversion. */ + +vector float +insert_arg_0 (vector float vf) +{ + return vec_insert (0.0f, vf, 0); +} + +/* { dg-final { scan-assembler {\mxxinsertw\M} } } */ +/* { dg-final { scan-assembler-not {\mlvewx\M} } } */ +/* { dg-final { scan-assembler-not {\mlvx\M} } } */ +/* { dg-final { scan-assembler-not {\mvperm\M} } } */ +/* { dg-final { scan-assembler-not {\mvpermr\M} } } */ +/* { dg-final { scan-assembler-not {\mstfs\M} } } */ +/* { dg-final { scan-assembler-not {\mstxssp\M} } } */ +/* { dg-final { scan-assembler-not {\mstxsspx\M} } } */ +/* { dg-final { scan-assembler-not {\mxscvdpspn\M} } } */ +/* { dg-final { scan-assembler-not {\mxxextractuw\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr80510-1.c b/gcc/testsuite/gcc.target/powerpc/pr80510-1.c index 8bff3ce15c3..deb51ac9916 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr80510-1.c +++ b/gcc/testsuite/gcc.target/powerpc/pr80510-1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { powerpc*-*-* } } } */ -/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target powerpc_vsx_ok } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ /* { dg-options "-mcpu=power7 -O2" } */ @@ -21,7 +21,7 @@ #endif #ifndef ITYPE -#define ITYPE long +#define ITYPE __INT64_TYPE__ #endif #ifdef DO_CALL diff --git a/gcc/testsuite/gcc.target/powerpc/pr80510-2.c b/gcc/testsuite/gcc.target/powerpc/pr80510-2.c index 2f7107b8782..b4d2491551b 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr80510-2.c +++ b/gcc/testsuite/gcc.target/powerpc/pr80510-2.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { powerpc*-*-* } } } */ -/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target powerpc_p8vector_ok } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ /* { dg-options "-mcpu=power8 -O2" } */ @@ -21,7 +21,7 @@ #endif #ifndef ITYPE -#define ITYPE long +#define ITYPE __INT64_TYPE__ #endif #ifdef DO_CALL diff --git a/gcc/testsuite/gcc.target/powerpc/stack-limit.c b/gcc/testsuite/gcc.target/powerpc/stack-limit.c new file mode 100644 index 00000000000..e676c96eb8e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/stack-limit.c @@ -0,0 +1,10 @@ +/* { dg-options "-O0 -fstack-limit-register=r14" } */ + +// PR80966 + +int foo (int i) +{ + char arr[135000]; + + arr[i] = 0; +} diff --git a/gcc/testsuite/gfortran.dg/read_5.f90 b/gcc/testsuite/gfortran.dg/read_5.f90 new file mode 100644 index 00000000000..81f1f11cf28 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/read_5.f90 @@ -0,0 +1,21 @@ +! { dg-do run } +! PR53029 Missed optimization, this test case took several seconds to + program internalread + implicit none + integer m + parameter(m=1000000) + character value*10 + character(80) :: result + integer i,j,intvalues(m) + real :: start, finish + intvalues = 33 + call cpu_time(start) + do j=1,100 + write(value,'(i3,a5)') j," 5 69" + read(value,*,end=20) intvalues + 20 write(result,*) (intvalues(i),i=2,4) + if (result.ne.(' 5 69 33')) call abort + call cpu_time(finish) + if ((finish-start).gt. 0.5) call abort + enddo + end program internalread diff --git a/gcc/toplev.c b/gcc/toplev.c index 54a4f05c9a1..f1384fc2fda 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1915,6 +1915,9 @@ finalize (bool no_backend) stack_usage_file = NULL; } + if (seen_error ()) + coverage_remove_note_file (); + if (!no_backend) { statistics_fini (); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 36386cf3e60..ac3bfd2cb03 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2035,7 +2035,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, ops[1] = bitsize_int (ref->size); ops[2] = bitsize_int (offset - offset2); tree val = vn_nary_build_or_lookup (rcode, vr->type, ops); - if (val) + if (val + && (TREE_CODE (val) != SSA_NAME + || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) { vn_reference_t res = vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index 71f874d3123..01c25d43e0d 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -808,6 +808,9 @@ static void same_succ_flush_bb (basic_block bb) { same_succ *same = BB_SAME_SUCC (bb); + if (! same) + return; + BB_SAME_SUCC (bb) = NULL; if (bitmap_single_bit_set_p (same->bbs)) same_succ_htab->remove_elt_with_hash (same, same->hashval); diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 4159cc5f6f9..fa58589b7d8 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -114,10 +114,10 @@ decl_for_type_insert (tree type, tree decl) /* Helper routine, which encodes a value in the pointer_sized_int_node. Arguments with precision <= POINTER_SIZE are passed directly, the rest is passed by reference. T is a value we are to encode. - IN_EXPAND_P is true if this function is called during expansion. */ + PHASE determines when this function is called. */ tree -ubsan_encode_value (tree t, bool in_expand_p) +ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase) { tree type = TREE_TYPE (t); const unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type)); @@ -143,10 +143,19 @@ ubsan_encode_value (tree t, bool in_expand_p) { /* The reason for this is that we don't want to pessimize code by making vars unnecessarily addressable. */ - tree var = create_tmp_var (type); - tree tem = build2 (MODIFY_EXPR, void_type_node, var, t); - mark_addressable (var); - if (in_expand_p) + tree var; + if (phase != UBSAN_ENCODE_VALUE_GENERIC) + { + var = create_tmp_var (type); + mark_addressable (var); + } + else + { + var = create_tmp_var_raw (type); + TREE_ADDRESSABLE (var) = 1; + DECL_CONTEXT (var) = current_function_decl; + } + if (phase == UBSAN_ENCODE_VALUE_RTL) { rtx mem = assign_stack_temp_for_type (TYPE_MODE (type), @@ -156,8 +165,17 @@ ubsan_encode_value (tree t, bool in_expand_p) expand_assignment (var, t, false); return build_fold_addr_expr (var); } - t = build_fold_addr_expr (var); - return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t); + if (phase != UBSAN_ENCODE_VALUE_GENERIC) + { + tree tem = build2 (MODIFY_EXPR, void_type_node, var, t); + t = build_fold_addr_expr (var); + return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t); + } + else + { + var = build4 (TARGET_EXPR, type, var, t, NULL_TREE, NULL_TREE); + return build_fold_addr_expr (var); + } } else return build_fold_addr_expr (t); @@ -708,9 +726,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi) ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT; tree fn = builtin_decl_explicit (bcode); - tree val - = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true, - NULL_TREE, true, GSI_SAME_STMT); + tree val = ubsan_encode_value (orig_index, UBSAN_ENCODE_VALUE_GIMPLE); + val = force_gimple_operand_gsi (gsi, val, true, NULL_TREE, true, + GSI_SAME_STMT); g = gimple_build_call (fn, 2, data, val); } gimple_set_location (g, loc); @@ -1266,9 +1284,11 @@ ubsan_build_overflow_builtin (tree_code code, location_t loc, tree lhstype, tree fn = builtin_decl_explicit (fn_code); return build_call_expr_loc (loc, fn, 2 + (code != NEGATE_EXPR), build_fold_addr_expr_loc (loc, data), - ubsan_encode_value (op0, true), - op1 ? ubsan_encode_value (op1, true) - : NULL_TREE); + ubsan_encode_value (op0, UBSAN_ENCODE_VALUE_RTL), + op1 + ? ubsan_encode_value (op1, + UBSAN_ENCODE_VALUE_RTL) + : NULL_TREE); } /* Perform the signed integer instrumentation. GSI is the iterator @@ -1458,9 +1478,9 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi) : BUILT_IN_UBSAN_HANDLE_LOAD_INVALID_VALUE_ABORT; tree fn = builtin_decl_explicit (bcode); - tree val = force_gimple_operand_gsi (&gsi2, ubsan_encode_value (urhs), - true, NULL_TREE, true, - GSI_SAME_STMT); + tree val = ubsan_encode_value (urhs, UBSAN_ENCODE_VALUE_GIMPLE); + val = force_gimple_operand_gsi (&gsi2, val, true, NULL_TREE, true, + GSI_SAME_STMT); g = gimple_build_call (fn, 2, data, val); } gimple_set_location (g, loc); @@ -1624,7 +1644,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr) fn = builtin_decl_explicit (bcode); fn = build_call_expr_loc (loc, fn, 2, build_fold_addr_expr_loc (loc, data), - ubsan_encode_value (expr, false)); + ubsan_encode_value (expr)); } return fold_build3 (COND_EXPR, void_type_node, t, fn, integer_zero_node); diff --git a/gcc/ubsan.h b/gcc/ubsan.h index f04929d6678..56c41361cb4 100644 --- a/gcc/ubsan.h +++ b/gcc/ubsan.h @@ -42,6 +42,13 @@ enum ubsan_print_style { UBSAN_PRINT_ARRAY }; +/* This controls ubsan_encode_value behavior. */ +enum ubsan_encode_value_phase { + UBSAN_ENCODE_VALUE_GENERIC, + UBSAN_ENCODE_VALUE_GIMPLE, + UBSAN_ENCODE_VALUE_RTL +}; + extern bool do_ubsan_in_current_function (void); extern bool ubsan_expand_bounds_ifn (gimple_stmt_iterator *); extern bool ubsan_expand_null_ifn (gimple_stmt_iterator *); @@ -49,8 +56,10 @@ extern bool ubsan_expand_objsize_ifn (gimple_stmt_iterator *); extern bool ubsan_expand_vptr_ifn (gimple_stmt_iterator *); extern bool ubsan_instrument_unreachable (gimple_stmt_iterator *); extern tree ubsan_create_data (const char *, int, const location_t *, ...); -extern tree ubsan_type_descriptor (tree, enum ubsan_print_style = UBSAN_PRINT_NORMAL); -extern tree ubsan_encode_value (tree, bool = false); +extern tree ubsan_type_descriptor (tree, ubsan_print_style + = UBSAN_PRINT_NORMAL); +extern tree ubsan_encode_value (tree, ubsan_encode_value_phase + = UBSAN_ENCODE_VALUE_GENERIC); extern bool is_ubsan_builtin_p (tree); extern tree ubsan_build_overflow_builtin (tree_code, location_t, tree, tree, tree, tree *); |