diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 13:19:46 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 13:19:46 +0000 |
commit | b4f314ea97f04620d290f3ae25d831f46692864f (patch) | |
tree | e99df6f0f35dce95dacd7a91b0242e81462a0860 | |
parent | 644412e1c29a2984b1b37656c18fe9f33791eff1 (diff) | |
parent | 7de380af566c189319d706d3b4ab04e32ecc5d90 (diff) | |
download | gcc-b4f314ea97f04620d290f3ae25d831f46692864f.tar.gz |
Merge from trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/wide-int@209485 138bc75d-0d04-0410-961f-82ee72b054a4
459 files changed, 12553 insertions, 5384 deletions
diff --git a/ChangeLog b/ChangeLog index 587843f29c7..5ddacbe6994 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-04-04 Eric Botcazou <ebotcazou@adacore.com> + + PR bootstrap/60620 + * Makefile.def (dependencies): Make gnattools depend on libstdc++-v3. + * Makefile.in: Regenerate. + 2014-03-28 Yaakov Selkowitz <yselkowitz@users.sourceforge.net> * Makefile.def (dependencies): Make all-ld depend on all-binutils diff --git a/Makefile.def b/Makefile.def index cfb81d3621b..ec2b0f27810 100644 --- a/Makefile.def +++ b/Makefile.def @@ -336,6 +336,7 @@ dependencies = { module=all-libcpp; on=all-intl; }; dependencies = { module=all-fixincludes; on=all-libiberty; }; dependencies = { module=all-gnattools; on=all-target-libada; }; +dependencies = { module=all-gnattools; on=all-target-libstdc++-v3; }; dependencies = { module=all-lto-plugin; on=all-libiberty; }; diff --git a/Makefile.in b/Makefile.in index f90e34a0368..bf06dce8a2e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -47249,6 +47249,7 @@ all-stage4-fixincludes: maybe-all-stage4-libiberty all-stageprofile-fixincludes: maybe-all-stageprofile-libiberty all-stagefeedback-fixincludes: maybe-all-stagefeedback-libiberty all-gnattools: maybe-all-target-libada +all-gnattools: maybe-all-target-libstdc++-v3 all-lto-plugin: maybe-all-libiberty all-stage1-lto-plugin: maybe-all-stage1-libiberty diff --git a/gcc/BASE-VER b/gcc/BASE-VER index 6ed7776bf32..2da4316236a 100644 --- a/gcc/BASE-VER +++ b/gcc/BASE-VER @@ -1 +1 @@ -4.9.0 +4.10.0 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 31ff90d0aae..1d89cebbae7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,878 @@ +2014-03-20 Mark Wielaard <mjw@redhat.com> + + * dwarf2out.c (add_bound_info): If HOST_WIDE_INT is big enough, + then represent the bound as normal constant value. + +2014-04-17 Jakub Jelinek <jakub@redhat.com> + + PR target/60847 + Forward port from 4.8 branch + 2013-07-19 Kirill Yukhin <kirill.yukhin@intel.com> + + * config/i386/bmiintrin.h (_blsi_u32): New. + (_blsi_u64): Ditto. + (_blsr_u32): Ditto. + (_blsr_u64): Ditto. + (_blsmsk_u32): Ditto. + (_blsmsk_u64): Ditto. + (_tzcnt_u32): Ditto. + (_tzcnt_u64): Ditto. + +2014-04-17 Kito Cheng <kito@0xlab.org> + + * gcc.c (used_arg): Prevent out of bound access for multilib_options. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR middle-end/60849 + * tree-ssa-propagate.c (valid_gimple_rhs_p): Only allow effective + boolean results for comparisons. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60836 + * tree-vect-loop.c (vect_create_epilog_for_reduction): Force + initial PHI args to be gimple values. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60841 + * tree-vect-data-refs.c (vect_analyze_data_refs): Count stmts. + * tree-vect-loop.c (vect_analyze_loop_2): Pass down number + of stmts to SLP build. + * tree-vect-slp.c (vect_slp_analyze_bb_1): Likewise. + (vect_analyze_slp): Likewise. + (vect_analyze_slp_instance): Likewise. + (vect_build_slp_tree): Limit overall SLP tree growth. + * tree-vectorizer.h (vect_analyze_data_refs, + vect_analyze_slp): Adjust prototypes. + +2014-04-17 Evgeny Stupachenko <evstupac@gmail.com> + + * config/i386/i386.c (x86_add_stmt_cost): Fix vector cost model for + Silvermont. + +2014-04-17 Evgeny Stupachenko <evstupac@gmail.com> + + * config/i386/x86-tune.def (TARGET_SLOW_PSHUFB): New tune definition. + * config/i386/i386.h (TARGET_SLOW_PSHUFB): New tune flag. + * config/i386/i386.c (expand_vec_perm_even_odd_1): Avoid byte shuffles + for TARGET_SLOW_PSHUFB + +2014-04-17 Evgeny Stupachenko <evstupac@gmail.com> + + * config/i386/i386.c (slm_cost): Adjust vec_to_scalar_cost. + * config/i386/i386.c (intel_cost): Ditto. + +2014-04-17 Joey Ye <joey.ye@arm.com> + + * opts.c (OPT_fif_conversion, OPT_fif_conversion2): Disable for Og. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + * opts.c (common_handle_option): Disable -fipa-reference coorectly + with -fuse-profile. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + * ipa-devirt.c (odr_type_d): Add field all_derivations_known. + (type_all_derivations_known_p): New predicate. + (type_all_ctors_visible_p): New predicate. + (type_possibly_instantiated_p): New predicate. + (get_odr_type): Compute all_derivations_known. + (dump_odr_type): Dump the flag. + (maybe_record_type): Cleanup. + (record_target_from_binfo): Add bases_to_consider array; + record bases for types w/o instances and skip CXX destructor. + (possible_polymorphic_call_targets_1): Add bases_to_consider + and consider_construction parameters; check if type may + have instance. + (get_polymorphic_call_info): Set maybe_in_construction to true + when we know nothing. + (record_targets_from_bases): Skip CXX destructors; they are + never called for types in construction. + (possible_polymorphic_call_targets): Do not record target when + type may not have instance. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/60854 + * ipa.c (symtab_remove_unreachable_nodes): Mark targets of + external aliases alive, too. + +2014-04-16 Andrew Pinski <apinski@cavium.com> + + * config/host-linux.c (TRY_EMPTY_VM_SPACE): Change aarch64 ilp32 + definition. + +2014-04-16 Eric Botcazou <ebotcazou@adacore.com> + + * final.c (compute_alignments): Do not apply loop alignment to a block + falling through to the exit. + +2014-04-16 Catherine Moore <clm@codesourcery.com> + + * mips.md (*mov<mode>_internal, *movhi_internal, *movqi_internal): + Adjust constraints for microMIPS store patterns. + +2014-04-16 Pitchumani Sivanupandi <Pitchumani.S@atmel.com> + + * config/avr/avr-mcus.def: Correct typo for atxmega256a3bu macro. + +2014-04-16 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-operands.c (create_vop_var): Set DECL_IGNORED_P. + (append_use): Run at -O0. + (append_vdef): Likewise. + * tree-ssa-ter.c (ter_is_replaceable_p): Do not special-case -O0. + * tree-ssa-uninit.c (warn_uninitialized_vars): Remove obsolete comment. + +2014-04-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/60844 + * tree-ssa-reassoc.c (reassoc_remove_stmt): New function. + (propagate_op_to_single_use, remove_visited_stmt_chain, + linearize_expr, repropagate_negates, reassociate_bb): Use it + instead of gsi_remove. + +2014-04-16 Martin Jambor <mjambor@suse.cz> + + * cgraphclones.c (cgraph_create_virtual_clone): Duplicate + ipa_transforms_to_apply. + (cgraph_function_versioning): Assert that old_node has empty + ipa_transforms_to_apply. + * trans-mem.c (ipa_tm_create_version): Likewise. + * tree-inline.c (tree_function_versioning): Do not duplicate + ipa_transforms_to_apply. + +2014-04-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR target/60817 + * configure.ac (set_have_as_tls): Merge i[34567]86-*-* and + x86_64-*-* cases. + Pass necessary as flags on 64-bit Solaris/x86. + Use lowercase relocs for x86_64-*-*. + * configure: Regenerate. + +2014-04-15 Jan Hubicka <jh@suse.cz> + + * ipa-devirt.c (referenced_from_vtable_p): New predicate. + (maybe_record_node, likely_target_p): Use it. + +2014-04-15 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR target/60839 + Revert following patch + + 2014-04-02 Michael Meissner <meissner@linux.vnet.ibm.com> + + PR target/60735 + * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): If we have + software floating point or no floating point registers, do not + allow any type in the FPRs. Eliminate a test for SPE SIMD types + in GPRs that occurs after we tested for GPRs that would never be + true. + + * config/rs6000/rs6000.md (mov<mode>_softfloat32, FMOVE64): + Rewrite tests to use TARGET_DOUBLE_FLOAT and TARGET_E500_DOUBLE, + since the FMOVE64 type is DFmode/DDmode. If TARGET_E500_DOUBLE, + specifically allow DDmode, since that does not use the SPE SIMD + instructions. + +2014-03-21 Mark Wielaard <mjw@redhat.com> + + * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_const_value + as unsigned or int depending on type and value used. + +2014-04-15 Richard Biener <rguenther@suse.de> + + PR rtl-optimization/56965 + * alias.c (ncr_compar, nonoverlapping_component_refs_p): Move ... + * tree-ssa-alias.c (ncr_compar, nonoverlapping_component_refs_p): + ... here. + * alias.c (true_dependence_1): Do not call + nonoverlapping_component_refs_p. + * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Call + nonoverlapping_component_refs_p. + (indirect_refs_may_alias_p): Likewise. + +2014-04-15 Teresa Johnson <tejohnson@google.com> + + * cfg.c (dump_bb_info): Fix flags check. + * tree-cfg.c (remove_bb): Only dump TDF_BLOCKS when removing. + +2014-04-15 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR rtl-optimization/60663 + * config/arm/arm.c (arm_new_rtx_costs): Improve ASM_OPERANDS case, + avoid 0 cost. + +2014-04-15 Richard Biener <rguenther@suse.de> + + * lto-streamer.h (LTO_major_version): Bump to 4. + +2014-04-15 Richard Biener <rguenther@suse.de> + + * common.opt (lto_partition_model): New enum. + (flto-partition=): Merge separate options with a single with argument, + add -flto-partition=one support. + * flag-types.h (enum lto_partition_model): Declare. + * opts.c (finish_options): Remove duplicate -flto-partition= + option check. + * lto-wrapper.c (run_gcc): Adjust. + +2014-04-15 Richard Biener <rguenther@suse.de> + + * alias.c (ncr_compar): New function. + (nonoverlapping_component_refs_p): Re-implement in O (n log n). + +2014-04-15 Richard Biener <rguenther@suse.de> + + * alias.c (record_component_aliases): Do not walk BINFOs. + +2014-04-15 Richard Biener <rguenther@suse.de> + + * tree-ssa-structalias.c (find_func_aliases_for_builtin_call): + Add struct function argument and adjust. + (find_func_aliases_for_call): Likewise. + (find_func_aliases): Likewise. + (find_func_clobbers): Likewise. + (intra_create_variable_infos): Likewise. + (compute_points_to_sets): Likewise. + (ipa_pta_execute): Adjust. Do not push/pop cfun. + +2014-04-15 Richard Biener <rguenther@suse.de> + + * tree.c (iterative_hash_expr): Use enum tree_code_class + to store TREE_CODE_CLASS. + (tree_block): Likewise. + (tree_set_block): Likewise. + * tree.h (fold_build_pointer_plus_loc): Use + convert_to_ptrofftype_loc. + +2014-04-15 Jakub Jelinek <jakub@redhat.com> + + PR plugins/59335 + * Makefile.in (PLUGIN_HEADERS): Add various headers that have been + added in 4.9. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * cfgloop.h (struct loop): Move force_vectorize down. + * gimplify.c (gimple_boolify) <ANNOTATE_EXPR>: Handle new kinds. + (gimplify_expr) <ANNOTATE_EXPR>: Minor tweak. + * lto-streamer-in.c (input_cfg): Read dont_vectorize field. + * lto-streamer-out.c (output_cfg): Write dont_vectorize field. + * tree-cfg.c (replace_loop_annotate): Revamp and handle new kinds. + * tree-core.h (enum annot_expr_kind): Add new kind values. + * tree-inline.c (copy_loops): Copy dont_vectorize field and reorder. + * tree-pretty-print.c (dump_generic_node) <ANNOTATE_EXPR>: Handle new + kinds. + * tree.def (ANNOTATE_EXPR): Tweak comment. + +2014-04-14 Jan Hubicka <hubicka@ucw.cz> + + * ipa-devirt.c (maybe_record_node): Ignore all non-methods (including + cxa_pure_virtual). + +2014-04-14 Paolo Carlini <paolo.carlini@oracle.com> + + * tree.h (TYPE_IDENTIFIER): Declare. + * tree.c (subrange_type_for_debug_p): Use it. + * godump.c (go_format_type): Likewise. + * dwarf2out.c (is_cxx_auto, modified_type_die, + gen_type_die_with_usage, gen_type_die_with_usage): Likewise. + * dbxout.c (dbxout_type, dbxout_symbol): Likewise. + +2014-04-14 Jan Hubicka <hubicka@ucw.cz> + + PR lto/60820 + * varpool.c (varpool_remove_node): Do not alter decls when streaming. + +2014-04-14 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.c (examine_argument): Return bool. Return true if + parameter should be passed in memory. + <case X86_64_COMPLEX_X87_CLASS>: Adjust. + (construct_container): Update calls to examine_argument. + (function_arg_advance_64): Ditto. + (return_in_memory_32): Merge with ix86_return_in_memory. + (return_in_memory_64): Ditto. + (return_in_memory_ms_64): Ditto. + +2014-04-14 Jan Hubicka <hubicka@ucw.cz> + + * ipa-utils.c (ipa_merge_profiles): Merge profile_id. + * coverage.c (coverage_compute_profile_id): Handle externally visible + symbols. + +2014-04-14 Martin Jambor <mjambor@suse.cz> + + * tree-sra.c (ipa_sra_preliminary_function_checks): Skip + DECL_DISREGARD_INLINE_LIMITS functions. + +2014-04-14 H.J. Lu <hongjiu.lu@intel.com> + + PR target/60827 + * config/i386/i386.md (*fixuns_trunc<mode>_1): Revert the last change. + +2014-04-14 H.J. Lu <hongjiu.lu@intel.com> + + PR target/60827 + * config/i386/i386.md (*fixuns_trunc<mode>_1): Check + optimize_insn_for_speed_p instead of + optimize_function_for_speed_p. + +2014-04-14 Yufeng Zhang <yufeng.zhang@arm.com> + + * doc/invoke.texi (free): Document AArch64. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60042 + * tree-ssa-pre.c (inhibit_phi_insertion): Remove. + (insert_into_preds_of_block): Do not prevent PHI insertion + for REFERENCE exprs here ... + (eliminate_dom_walker::before_dom_children): ... but prevent + their use here under similar conditions when applied to the + IL after PRE optimizations. + +2014-04-14 Richard Biener <rguenther@suse.de> + + * passes.def: Move early points-to after early SRA. + +2014-04-14 Richard Biener <rguenther@suse.de> + + * tree-ssa-forwprop.c (simplify_gimple_switch): Enhance + check for which sign-changes we allow when forwarding + a converted value into a switch. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + + * stor-layout.c (place_field): Finalize non-constant offset for the + field, if any. + +2014-04-14 Richard Biener <rguenther@suse.de> + + * tree-switch-conversion.c (lshift_cheap_p): Get speed_p + as argument. + (expand_switch_using_bit_tests_p): Likewise. + (process_switch): Compute and pass on speed_p based on the + switch stmt. + * tree-ssa-math-opts.c (gimple_expand_builtin_pow): Use + optimize_bb_for_speed_p. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + + * cfgloop.h (struct loop): Rename force_vect into force_vectorize. + * function.h (struct function): Rename has_force_vect_loops into + has_force_vectorize_loops. + * lto-streamer-in.c (input_cfg): Adjust for renaming. + (input_struct_function_base): Likewise. + * lto-streamer-out.c (output_cfg): Likewise. + (output_struct_function_base): Likewise. + * omp-low.c (expand_omp_simd): Likewise. + * tree-cfg.c (move_sese_region_to_fn): Likewise. + * tree-if-conv.c (ifcvt_can_use_mask_load_store): Likewise. + (version_loop_for_if_conversion): Likewise. + (tree_if_conversion): Likewise. + (main_tree_if_conversion): Likewise. + (gate_tree_if_conversion): Likewise. + * tree-inline.c (copy_loops): Likewise. + * tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely_1): Likewise. + * tree-ssa-loop.c (tree_loop_vectorize): Likewise. + * tree-ssa-phiopt.c (tree_ssa_phiopt_worker): Likewise. + * tree-vect-loop.c (vect_estimate_min_profitable_iters): Likewise. + * tree-vectorizer.c (vectorize_loops): Likewise. + * tree-vectorizer.h (unlimited_cost_model): Likewise. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR lto/60720 + * lto-streamer-out.c (wrap_refs): New function. + (lto_output): Wrap symbol references in global initializes in + type-preserving MEM_REFs. + +2014-04-14 Christian Bruel <christian.bruel@st.com> + + * config/sh/sh-mem.cc (sh_expand_strlen): Unroll last word. + +2014-04-14 Christian Bruel <christian.bruel@st.com> + + * config/sh/sh.md (setmemqi): New expand pattern. + * config/sh/sh.h (CLEAR_RATIO): Define. + * config/sh/sh-mem.cc (sh_expand_setmem): Define. + * config/sh/sh-protos.h (sh_expand_setmem): Declare. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR middle-end/55022 + * fold-const.c (negate_expr_p): Don't negate directional rounding + division. + (fold_negate_expr): Likewise. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59817 + PR tree-optimization/60453 + * graphite-scop-detection.c (graphite_can_represent_scev): Complete + recursion to catch all CHRECs in the scalar evolution and restrict + the predicate for the remains appropriately. + +2014-04-12 Catherine Moore <clm@codesourcery.com> + + * config/mips/constraints.md: Add new register constraint "kb". + * config/mips/mips.md (*mov<mode>_internal): Use constraint "kb". + (*movhi_internal): Likewise. + (*movqi_internal): Likewise. + * config/mips/mips.h (M16_STORE_REGS): New register class. + (REG_CLASS_NAMES): Add M16_STORE_REGS. + (REG_CLASS_CONTENTS): Likewise. + * config/mips/mips.c (mips_regno_to_class): Add M16_STORE_REGS. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR c/60194 + * doc/invoke.texi (-Wformat-signedness): Document it. + (Wformat=2): Mention that this enables -Wformat-signedness. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + * common/config/epiphany/epiphany-common.c + (epiphany_option_optimization_table): Enable section anchors by + default at -O1 or higher. + * config/epiphany/epiphany.c (TARGET_MAX_ANCHOR_OFFSET): Define. + (TARGET_MIN_ANCHOR_OFFSET): Likewise. + (epiphany_rtx_costs) <SET>: For binary operators, the set as such + carries no extra cost. + (epiphany_legitimate_address_p): For BLKmode, apply SImode check. + * config/epiphany/epiphany.h (ASM_OUTPUT_DEF): Define. + * config/epiphany/predicates.md (memclob_operand): New predicate. + * config/epiphany/epiphany.md (stack_adjust_add, stack_adjust_str): + Use memclob_operand predicate and X constraint for operand 3. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + * config/epiphany/epiphany.c (epiphany_rtx_cost): Compare + with CC_N_NE / CC_C_LTU / CC_C_GTU carries no extra cost for + its operands. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + PR rtl-optimization/60651 + * mode-switching.c (optimize_mode_switching): Make sure to emit + sets of a lower numbered entity before sets of a higher numbered + entity to a mode of the same or lower priority. + When creating a seginfo for a basic block that starts with a code + label, move the insertion point past the code label. + (new_seginfo): Document and enforce requirement that + NOTE_INSN_BASIC_BLOCK only appears for empty blocks. + * doc/tm.texi.in: Document ordering constraint for emitted mode sets. + * doc/tm.texi: Regenerate. + +2014-01-11 Joern Rennecke <joern.rennecke@embecosm.com> + + PR target/60811 + * config/arc/arc.c (arc_save_restore): Fix assert typo. + +2013-04-11 Jakub Jelinek <jakub@redhat.com> + + * BASE-VER: Set to 4.10.0. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR other/59055 + * doc/bugreport.texi (Bugs): Remove nodes pointing to the nirvana. + * doc/gcc.texi (Service): Update description in the @menu + * doc/invoke.texi (Option Summary): Remove misplaced and + duplicated @menu. + +2014-04-11 Steve Ellcey <sellcey@mips.com> + Jakub Jelinek <jakub@redhat.com> + + PR middle-end/60556 + * expr.c (convert_move): Use emit_store_flag_force instead of + emit_store_flag. Pass lowpart_mode instead of VOIDmode as 5th + argument to it. + +2014-04-11 Richard Biener <rguenther@suse.de> + + PR middle-end/60797 + * varasm.c (assemble_alias): Avoid endless error reporting + recursion by setting TREE_ASM_WRITTEN. + +2014-04-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.md: Add a splitter for NOT rtx. + +2014-04-11 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/60663 + * cse.c (cse_insn): Set src_volatile on ASM_OPERANDS in PARALLEL. + +2014-04-10 Jan Hubicka <hubicka@ucw.cz> + Jakub Jelinek <jakub@redhat.com> + + PR lto/60567 + * ipa.c (function_and_variable_visibility): Copy forced_by_abi + flag from decl_node to node. + +2014-04-10 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR debug/60655 + * config/arm/arm.c (TARGET_CONST_NOT_OK_FOR_DEBUG_P): Define + (arm_const_not_ok_for_debug_p): Reject MINUS with SYM_REF's + ameliorating the cases where it can be. + +2014-04-09 David Edelsohn <dje.gcc@gmail.com> + + Revert + 2014-04-08 Pat Haugen <pthaugen@us.ibm.com> + + * config/rs6000/sync.md (AINT mode_iterator): Move definition. + (loadsync_<mode>): Change mode. + (load_quadpti, store_quadpti): New. + (atomic_load<mode>, atomic_store<mode>): Add support for TI mode. + * config/rs6000/rs6000.md (unspec enum): Add UNSPEC_LSQ. + * config/rs6000/predicates.md (quad_memory_operand): !TARGET_SYNC_TI. + +2014-04-09 Cong Hou <congh@google.com> + + PR testsuite/60773 + * doc/sourcebuild.texi (vect_widen_mult_si_to_di_pattern): Add + documentation. + +2014-04-08 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + * config/rs6000/rs6000.c (rs6000_expand_vector_set): Use vnand + instead of vnor to exploit possible fusion opportunity in the + future. + (altivec_expand_vec_perm_const_le): Likewise. + +2014-04-08 Pat Haugen <pthaugen@us.ibm.com> + + * config/rs6000/sync.md (AINT mode_iterator): Move definition. + (loadsync_<mode>): Change mode. + (load_quadpti, store_quadpti): New. + (atomic_load<mode>, atomic_store<mode>): Add support for TI mode. + * config/rs6000/rs6000.md (unspec enum): Add UNSPEC_LSQ. + +2014-04-08 Richard Sandiford <rdsandiford@googlemail.com> + + PR target/60763 + * config/rs6000/vsx.md (vsx_xscvdpspn_scalar): Change input to DImode. + * config/rs6000/rs6000.md (reload_vsx_from_gprsf): Update accordingly. + Use gen_rtx_REG rather than simplify_gen_subreg for op0_di. + +2014-04-08 Richard Biener <rguenther@suse.de> + + PR middle-end/60706 + * tree-pretty-print.c (pp_double_int): For HWI32 hosts with + a 64bit widest int print double-int similar to on HWI64 hosts. + +2014-04-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60785 + * graphite-sese-to-poly.c (rewrite_phi_out_of_ssa): Treat + default defs properly. + +2014-04-08 Nathan Sidwell <nathan@codesourcery.com> + + * doc/invoke (Wnon-virtual-dtor): Update to match implementation. + (Weffc++): Likewise. + +2014-04-07 Jan Hubicka <hubcika@ucw.cz> + + * ipa-devirt.c (maybe_record_node): When node is not recorded, + set completep to false rather than true. + +2014-04-07 Douglas B Rupp <rupp@adacore.com> + + PR target/60504 + * config/arm/arm.h (ASM_PREFERRED_EH_DATA_FORMAT): Expose from + ARM_TARGET2_DWARF_FORMAT. + +2014-04-07 Charles Baylis <charles.baylis@linaro.org> + + PR target/60609 + * config/arm/arm.h (ASM_OUTPUT_CASE_END): Remove. + (LABEL_ALIGN_AFTER_BARRIER): Align barriers which occur after + ADDR_DIFF_VEC. + +2014-04-07 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60766 + * tree-ssa-loop-ivopts.c (cand_value_at): Compute in an unsigned type. + (may_eliminate_iv): Convert cand_value_at result to desired type. + +2014-04-07 Jason Merrill <jason@redhat.com> + + PR c++/60731 + * common.opt (-fno-gnu-unique): Add. + * config/elfos.h (USE_GNU_UNIQUE_OBJECT): Check it. + +2014-04-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * haifa-sched.c: Fix outdated function reference and minor + grammar errors in introductory comment. + +2014-04-07 Richard Biener <rguenther@suse.de> + + PR middle-end/60750 + * tree-ssa-operands.c (maybe_add_call_vops): Also add VDEFs + for noreturn calls. + * tree-cfgcleanup.c (fixup_noreturn_call): Do not remove VDEFs. + +2014-04-06 John David Anglin <danglin@gcc.gnu.org> + + PR debug/55794 + * config/pa/pa.c (pa_output_function_epilogue): Skip address and code + size accounting for thunks. + (pa_asm_output_mi_thunk): Use final_start_function() and + final_end_function() to output function start and end directives. + +2014-04-05 Pitchumani Sivanupandi <Pitchumani.S@atmel.com> + + * config/avr/avr-arch.h (avr_mcu_t): Add dev_attribute field to have + device specific ISA/ feature information. Remove short_sp and + errata_skip ds. Add avr_device_specific_features enum to have device + specific info. + * config/avr/avr-c.c (avr_cpu_cpp_builtins): use dev_attribute to check + errata_skip. Add __AVR_ISA_RMW__ builtin macro if RMW ISA available. + * config/avr/avr-devices.c (avr_mcu_types): Update AVR_MCU macro for + updated device specific info. + * config/avr/avr-mcus.def: Merge device specific details to + dev_attribute field. + * config/avr/avr.c (avr_2word_insn_p): use dev_attribute field to check + errata_skip. + * config/avr/avr.h (AVR_HAVE_8BIT_SP): same for short sp info. + * config/avr/driver-avr.c (avr_device_to_as): Pass -mrmw option to + assembler if RMW isa supported by current device. + * config/avr/genmultilib.awk: Update as device info structure changed. + * doc/invoke.texi: Add info for __AVR_ISA_RMW__ builtin macro + +2014-04-04 Cong Hou <congh@google.com> + + PR tree-optimization/60656 + * tree-vect-stmts.c (supportable_widening_operation): + Fix a bug that elements in a vector with vect_used_by_reduction + property are incorrectly reordered when the operation on it is not + consistant with the one in reduction operation. + +2014-04-04 John David Anglin <danglin@gcc.gnu.org> + + PR rtl-optimization/60155 + * gcse.c (record_set_data): New function. + (single_set_gcse): New function. + (gcse_emit_move_after): Use single_set_gcse instead of single_set. + (hoist_code): Likewise. + (get_pressure_class_and_nregs): Likewise. + +2014-04-04 Eric Botcazou <ebotcazou@adacore.com> + + * explow.c (probe_stack_range): Emit a final optimization blockage. + +2014-04-04 Anthony Green <green@moxielogic.com> + + * config/moxie/moxie.md (zero_extendqisi2, zero_extendhisi2): Fix + typos. + +2014-04-04 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/59626 + * lto-cgraph.c (input_overwrite_node): Check that partitioning + flags are set only during streaming. + * ipa.c (process_references, walk_polymorphic_call_targets, + symtab_remove_unreachable_nodes): Drop bodies of always inline + after early inlining. + (symtab_remove_unreachable_nodes): Remove always_inline attribute. + +2014-04-04 Jakub Jelinek <jakub@redhat.com> + Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR debug/60655 + * dwarf2out.c (const_ok_for_output_1): Reject expressions + containing a NOT. + +2014-04-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + PR bootstrap/60743 + * config/arm/cortex-a53.md (cortex_a53_fdivs): Reduce reservation + duration. + (cortex_a53_fdivd): Likewise. + +2014-04-04 Martin Jambor <mjambor@suse.cz> + + PR ipa/60640 + * cgraph.h (cgraph_clone_node): New parameter added to declaration. + Adjust all callers. + * cgraph.c (clone_of_p): Also return true if thunks match. + (verify_edge_corresponds_to_fndecl): Removed extraneous call to + cgraph_function_or_thunk_node and an obsolete comment. + * cgraphclones.c (build_function_type_skip_args): Moved upwards in the + file. + (build_function_decl_skip_args): Likewise. + (set_new_clone_decl_and_node_flags): New function. + (duplicate_thunk_for_node): Likewise. + (redirect_edge_duplicating_thunks): Likewise. + (cgraph_clone_node): New parameter args_to_skip, pass it to + redirect_edge_duplicating_thunks which is called instead of + cgraph_redirect_edge_callee. + (cgraph_create_virtual_clone): Pass args_to_skip to cgraph_clone_node, + moved setting of a lot of flags to set_new_clone_decl_and_node_flags. + +2014-04-04 Jeff Law <law@redhat.com> + + PR target/60657 + * config/arm/predicates.md (const_int_I_operand): New predicate. + (const_int_M_operand): Similarly. + * config/arm/arm.md (insv_zero): Use const_int_M_operand instead of + const_int_operand. + (insv_t2, extv_reg, extzv_t2): Likewise. + (load_multiple_with_writeback): Similarly for const_int_I_operand. + (pop_multiple_with_writeback_and_return): Likewise. + (vfp_pop_multiple_with_writeback): Likewise + +2014-04-04 Richard Biener <rguenther@suse.de> + + PR ipa/60746 + * tree-ssanames.c (make_ssa_name_fn): Fix assert. + * gimple.c (gimple_set_bb): Avoid ICEing for NULL cfun for + non-GIMPLE_LABELs. + * gimplify.h (gimple_add_tmp_var_fn): Declare. + * gimplify.c (gimple_add_tmp_var_fn): New function. + * gimple-expr.h (create_tmp_reg_fn): Declare. + * gimple-expr.c (create_tmp_reg_fn): New function. + * gimple-low.c (record_vars_into): Don't change cfun. + * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Fix + code generation without cfun. + +2014-04-04 Thomas Schwinge <thomas@codesourcery.com> + + PR bootstrap/60719 + * Makefile.in (install-driver): Fix shell scripting. + +2014-04-03 Cong Hou <congh@google.com> + + PR tree-optimization/60505 + * tree-vectorizer.h (struct _stmt_vec_info): Add th field as the + threshold of number of iterations below which no vectorization + will be done. + * tree-vect-loop.c (new_loop_vec_info): + Initialize LOOP_VINFO_COST_MODEL_THRESHOLD. + * tree-vect-loop.c (vect_analyze_loop_operations): + Set LOOP_VINFO_COST_MODEL_THRESHOLD. + * tree-vect-loop.c (vect_transform_loop): + Use LOOP_VINFO_COST_MODEL_THRESHOLD. + * tree-vect-loop.c (vect_analyze_loop_2): Check the maximum number + of iterations of the loop and see if we should build the epilogue. + +2014-04-03 Richard Biener <rguenther@suse.de> + + * tree-streamer.h (struct streamer_tree_cache_d): Add next_idx member. + (streamer_tree_cache_create): Adjust. + * tree-streamer.c (streamer_tree_cache_add_to_node_array): Adjust + to allow optional nodes array. + (streamer_tree_cache_insert_1): Use next_idx to assign idx. + (streamer_tree_cache_append): Likewise. + (streamer_tree_cache_create): Create nodes array optionally + as specified by parameter. + * lto-streamer-out.c (create_output_block): Avoid maintaining + the node array in the writer cache. + (DFS_write_tree): Remove assertion. + (produce_asm_for_decls): Free the out decl state hash table early. + * lto-streamer-in.c (lto_data_in_create): Adjust for + streamer_tree_cache_create prototype change. + +2014-04-03 Richard Biener <rguenther@suse.de> + + * tree-streamer-out.c (streamer_write_chain): Do not temporarily + set TREE_CHAIN to NULL_TREE. + +2014-04-03 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60740 + * graphite-scop-detection.c (stmt_simple_for_scop_p): Iterate + over all GIMPLE_COND operands. + +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * doc/invoke.texi (Wnon-virtual-dtor): Adjust documentation. + (Weffc++): Remove Scott's numbering, merge lists and reference + Wnon-virtual-dtor. + + c-family/ + + cp/ + * class.c (accessible_nvdtor_p): New. + (check_bases): Don't check base destructor here ... + (check_bases_and_members): ... check them here. Trigger on + Wnon-virtual-dtor flag. + (finish_struct_1): Use accessible_nvdtor_p. + + testsuite/ + * g++.dg/warn/Wnvdtor.C: Add non-polymorphic case. + * g++.dg/warn/Wnvdtor-2.C: New. + * g++.dg/warn/Wnvdtor-3.C: New. + * g++.dg/warn/Wnvdtor-4.C: New. + * g++.dg/warn/Weff1.C: Delete. + * g++.old-deja/g++.benjamin/15309-1.C: Delete. + * g++.old-deja/g++.benjamin/15309-2.C: Delete. + +2014-04-03 Nick Clifton <nickc@redhat.com> + + * config/rl78/rl78-expand.md (movqi): Handle (SUBREG (SYMBOL_REF)) + properly. + +2014-04-03 Martin Jambor <mjambor@suse.cz> + + * ipa-cp.c (ipcp_verify_propagated_values): Also dump symtab and + mention gcc_unreachable before failing. + * ipa.c (symtab_remove_unreachable_nodes): Also print order of + removed symbols. + +2014-04-02 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/60659 + * ipa-devirt.c (get_polymorphic_call_info): Do not ICE on type + inconsistent code and instead mark the context inconsistent. + (possible_polymorphic_call_targets): For inconsistent contexts + return empty complete list. + +2014-04-02 Anthony Green <green@moxielogic.com> + + * config/moxie/moxie.md (zero_extendqisi2, zero_extendhisi2) + (extendqisi2, extendhisi2): Define. + * config/moxie/moxie.h (DEFAULT_SIGNED_CHAR): Change to 0. + (WCHAR_TYPE): Change to unsigned int. + +2014-04-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR tree-optimization/60733 + * gimple-ssa-strength-reduction.c (ncd_with_phi): Change required + insertion point for PHI candidates to be the end of the feeding + block for the PHI argument. + +2014-04-02 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/60650 + * lra-constraints.c (process_alt_operands): Decrease reject for + earlyclobber matching. + +2014-04-02 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * config/s390/s390.c (s390_expand_insv): Use GET_MODE_BITSIZE. + +2014-04-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.c (pad_bb): Do not crash when the last + insn is CODE_FOR_blockage. + +2014-04-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.md ("insv"): Fail if bitoffset+bitsize + lies outside the target mode. + 2014-04-02 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/60735 @@ -64,8 +939,7 @@ 2014-04-01 Richard Biener <rguenther@suse.de> - * gimple.h (struct gimple_statement_base): Align subcode to - 16 bits. + * gimple.h (struct gimple_statement_base): Align subcode to 16 bits. 2014-04-01 Sebastian Huber <sebastian.huber@embedded-brains.de> @@ -266,7 +1140,7 @@ 2014-03-27 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/60650 - * lra-asign.c (find_hard_regno_for, spill_for): Add parameter + * lra-assign.c (find_hard_regno_for, spill_for): Add parameter first_p. Use it. (find_spills_for): New. (assign_by_spills): Pass the new parameter to find_hard_regno_for. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 9b2bb2031b3..493fa0a805c 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20140402 +20140417 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d6af1f3c1f0..108388c71bb 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3127,7 +3127,14 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ version.h stringpool.h gimplify.h gimple-iterator.h gimple-ssa.h \ fold-const.h tree-cfg.h tree-into-ssa.h tree-ssanames.h print-tree.h \ varasm.h context.h tree-phinodes.h stor-layout.h ssa-iterators.h \ - $(RESOURCE_H) tree-cfgcleanup.h + $(RESOURCE_H) tree-cfgcleanup.h attribs.h calls.h cfgexpand.h \ + diagnostic-color.h gcc-symtab.h gimple-builder.h gimple-low.h \ + gimple-walk.h gimplify-me.h pass_manager.h print-rtl.h stmt.h \ + tree-dfa.h tree-hasher.h tree-nested.h tree-object-size.h tree-outof-ssa.h \ + tree-parloops.h tree-ssa-address.h tree-ssa-coalesce.h tree-ssa-dom.h \ + tree-ssa-loop.h tree-ssa-loop-ivopts.h tree-ssa-loop-manip.h \ + tree-ssa-loop-niter.h tree-ssa-ter.h tree-ssa-threadedge.h \ + tree-ssa-threadupdate.h # generate the 'build fragment' b-header-vars s-header-vars: Makefile @@ -3208,9 +3215,9 @@ install-driver: installdirs xgcc$(exeext) -rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) -$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext) -if [ "$(GCC_INSTALL_NAME)" != "$(target_noncanonical)-gcc-$(version)" ]; then \ - -rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)$(exeext) \ - -( cd $(DESTDIR)$(bindir) && \ - $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version)$(exeext) ) \ + rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)$(exeext); \ + ( cd $(DESTDIR)$(bindir) && \ + $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version)$(exeext) ); \ fi -if [ ! -f gcc-cross$(exeext) ] \ && [ "$(GCC_INSTALL_NAME)" != "$(GCC_TARGET_INSTALL_NAME)" ]; then \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index de71b062f4b..2e3dc5058f3 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,128 @@ +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + Pierre-Marie de Rodat <derodat@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Create a mere + scalar constant instead of a reference for renaming of scalar literal. + Do not create a new object for constant renaming except for a function + call. Make sure a VAR_DECL is created for the renaming pointer. + * gcc-interface/trans.c (constant_decl_with_initializer_p): New. + (fold_constant_decl_in_expr): New function. + (Identifier_to_gnu): Use constant_decl_with_initializer_p. + For a constant renaming, try to fold a constant DECL in the result. + (lvalue_required_p) <N_Object_Renaming_Declaration>: Always return 1. + (Identifier_to_gnu): Reference the renamed object of constant renaming + pointers directly. + * gcc-interface/utils.c (invalidate_global_renaming_pointers): Do not + invalidate constant renaming pointers. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils.c (type_for_vector_element_p): New predicate. + (build_vector_type_for_size): New function. + (build_vector_type_for_array): Likewise. + (unchecked_convert): Build an intermediate vector type to convert + from a generic array type to a vector type. + (handle_vector_size_attribute): Reimplement. + (handle_vector_type_attribute): Likewise. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (prepend_one_attribute_pragma): Call + Is_OK_Static_Expression in lieu of Is_Static_Expression to + detect valid arguments. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c (gnat_gimplify_stmt): Propagate loop hints. + +2014-04-14 Paolo Carlini <paolo.carlini@oracle.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity): Use TYPE_IDENTIFIER. + (components_to_record): Likewise. + * gcc-interface/utils.c (make_aligning_type): Likewise. + (maybe_pad_type): Likewise. + (finish_record_type): Likewise. + (rest_of_record_type_compilation): Likewise. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + + * snames.ads-tmpl (Name_Ivdep): New pragma-related name. + * sem_prag.adb (Analyze_Pragma) <Pragma_Loop_Optimize>: Add support + for Ivdep hint. + * gnat_rm.texi (Implementation Defined Pragmas): Document new Ivdep + hint for Loop_Optimize. + * gnat_ugn.texi (Vectorization of loops): Mention new Ivdep hint. + * gcc-interface/trans.c (Pragma_to_gnu) <Pragma_Loop_Optimize>: Deal + with new Ivdep hint. + * gcc-interface/ada-tree.h (LOOP_STMT_IVDEP): New macro. + * gcc-interface/trans.c (Pragma_to_gnu) <Pragma_Loop_Optimize>: Deal + with new Ivdep hint. + (gnat_gimplify_stmt) <LOOP_STMT>: Propagate loop hints. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + Robert Dewar <dewar@adacore.com> + + * opt.ads (Suppress_Back_Annotation): Remove as unused. + * fe.h (Back_Annotate_Rep_Info): Likewise. + (Global_Discard_Names): Likewise. + (List_Representation_Info): Declare. + * types.h (Uint_Minus_1): Likewise. + * repinfo.ads: Document back-annotation change. + * gcc-interface/gigi.h (init_gnat_decl): Declare. + (destroy_gnat_decl): Likewise. + * gcc-interface/decl.c (annotate_value): Do not create the cache of + annotated values here but... + <CALL_EXPR>: Only inline the call if -gnatR3 is specified or we are + in ASIS mode. + (init_gnat_decl): ...here instead. New function. + (destroy_gnat_decl): Likewise. + * gcc-interface/trans.c (gigi): Call {init|destroy}_gnat_decl. + * gcc-interface/utils.c (init_gnat_utils): Minor reformatting. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (create_field_decl_from): Finalize non-constant + offset for the field, if any. + +2014-04-09 Eric Botcazou <ebotcazou@adacore.com> + Svante Signell <svante.signell@gmail.com> + + PR ada/54040 + PR ada/59346 + * s-osinte-x32.adb: New file. + * s-linux.ads (Time): New section. + * s-linux-alpha.ads (Time): Likewise. + * s-linux-android.ads (Time: Likewise. + * s-linux-hppa.ads (Time): Likewise. + * s-linux-mipsel.ads (Time): Likewise. + * s-linux-sparc.ads (Time): Likewise. + * s-linux-x32.ads (Time): Likewise. + * s-osprim-x32.ads (timespec): Adjust. + (Clock): Likewise. + (To_Timespec): Likewise. + * s-osinte-linux.ads (Time): Define local subtypes for those defined + in System.Linux. + * s-taprop-linux.adb (Monotonic_Clock): Do not define timeval. + * s-osinte-hpux.ads (timespec): Revert POSIX breakage. + * s-osinte-kfreebsd-gnu.ads (timespec): Likewise. + * s-osinte-solaris-posix.ads (timespec): Likewise. + * s-osinte-posix.adb (To_Timespec): Likewise. + * gcc-interface/Makefile.in (x32/Linux): Use s-osinte-x32.adb. + +2014-04-08 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/60411 + * gcc-interface/Makefile.in (arm% linux-android): Switch to EHABI. + * s-linux-android.ads: New file. + * s-intman-android.adb: Likewise. + * s-osinte-android.ads: Adjust. + * sigtramp-armdroid.c: Likewise. + * sigtramp.h: Add Android support. + +2014-04-07 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/Makefile.in (alpha-vms): Add missing line. + 2014-03-30 Eric Botcazou <ebotcazou@adacore.com> PR ada/60703 diff --git a/gcc/ada/fe.h b/gcc/ada/fe.h index 9b38903f9a5..d9fe48b5baa 100644 --- a/gcc/ada/fe.h +++ b/gcc/ada/fe.h @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 1992-2013, Free Software Foundation, Inc. * + * Copyright (C) 1992-2014, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -178,23 +178,21 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id); /* opt: */ -#define Back_Annotate_Rep_Info opt__back_annotate_rep_info #define Exception_Extra_Info opt__exception_extra_info #define Exception_Locations_Suppressed opt__exception_locations_suppressed #define Exception_Mechanism opt__exception_mechanism #define Generate_SCO_Instance_Table opt__generate_sco_instance_table -#define Global_Discard_Names opt__global_discard_names #define Float_Format opt__float_format +#define List_Representation_Info opt__list_representation_info typedef enum {Setjmp_Longjmp, Back_End_Exceptions} Exception_Mechanism_Type; -extern Boolean Back_Annotate_Rep_Info; extern Boolean Exception_Extra_Info; extern Boolean Exception_Locations_Suppressed; extern Exception_Mechanism_Type Exception_Mechanism; extern Boolean Generate_SCO_Instance_Table; -extern Boolean Global_Discard_Names; extern Char Float_Format; +extern Int List_Representation_Info; /* restrict: */ diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 352d6550cdc..9af1967ce9f 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -536,7 +536,7 @@ ifeq ($(strip $(filter-out powerpc% wrs vxworks,$(target_cpu) $(target_vendor) $ # System.Stack_Checking.Operations is not needed on VxWorks 6 as it leads to # an undefined symbol when building a dynamic shared library. To alleviate # this problem and distinguish this case, we use the THREAD_KIND and include - # the package only in kernel mode. + # the package only in default mode. ifeq ($(strip $(filter-out default,$(THREAD_KIND))),) LIBGNAT_TARGET_PAIRS += \ @@ -1045,15 +1045,17 @@ ifeq ($(strip $(filter-out arm% linux-androideabi,$(target_cpu) $(target_os))),) LIBGNAT_TARGET_PAIRS = \ a-intnam.ads<a-intnam-linux.ads \ s-inmaop.adb<s-inmaop-posix.adb \ - s-intman.adb<s-intman-posix.adb \ - s-linux.ads<s-linux.ads \ + s-intman.adb<s-intman-android.adb \ + s-linux.ads<s-linux-android.ads \ s-osinte.adb<s-osinte-android.adb \ s-osinte.ads<s-osinte-android.ads \ s-osprim.adb<s-osprim-posix.adb \ s-taprop.adb<s-taprop-posix.adb \ - s-taspri.ads<s-taspri-posix-noaltstack.ads \ + s-taspri.ads<s-taspri-posix.ads \ s-tpopsp.adb<s-tpopsp-posix-foreign.adb \ system.ads<system-linux-armel.ads \ + a-exexpr.adb<a-exexpr-gcc.adb \ + s-excmac.ads<s-excmac-arm.ads \ $(DUMMY_SOCKETS_TARGET_PAIRS) TOOLS_TARGET_PAIRS = \ @@ -1062,7 +1064,9 @@ ifeq ($(strip $(filter-out arm% linux-androideabi,$(target_cpu) $(target_os))),) GNATRTL_SOCKETS_OBJS = EXTRA_GNATRTL_TASKING_OBJS=s-linux.o - EH_MECHANISM= + EXTRA_LIBGNAT_OBJS+=raise-gcc.o sigtramp-armdroid.o + EXTRA_GNATRTL_NONTASKING_OBJS+=g-cppexc.o s-excmac.o + EH_MECHANISM=-arm THREADSLIB = GNATLIB_SHARED = gnatlib-shared-dual LIBRARY_VERSION := $(LIB_VERSION) @@ -1615,6 +1619,7 @@ ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(target_ $(ATOMICS_BUILTINS_TARGET_PAIRS) EXTRA_LIBGNAT_SRCS+=tb-alvms.c + override GNATRTL_ALTIVEC_OBJS= TOOLS_TARGET_PAIRS= \ mlib-tgt-specific.adb<mlib-tgt-specific-vms-alpha.adb \ @@ -2234,7 +2239,7 @@ ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),) s-linux.ads<s-linux-x32.ads \ s-mudido.adb<s-mudido-affinity.adb \ s-osinte.ads<s-osinte-linux.ads \ - s-osinte.adb<s-osinte-posix.adb \ + s-osinte.adb<s-osinte-x32.adb \ s-osprim.adb<s-osprim-x32.adb \ s-taprop.adb<s-taprop-linux.adb \ s-tasinf.ads<s-tasinf-linux.ads \ @@ -3063,6 +3068,7 @@ mkdir.o : mkdir.c socket.o : socket.c gsocket.h sysdep.o : sysdep.c raise.o : raise.c raise.h +sigtramp-armdroid.o : sigtramp-armdroid.c sigtramp.h sigtramp-armvxw.o : sigtramp-armvxw.c sigtramp.h sigtramp-ppcvxw.o : sigtramp-ppcvxw.c sigtramp.h terminals.o : terminals.c diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index c1b45effcdb..5ea386f860c 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 1992-2013, Free Software Foundation, Inc. * + * Copyright (C) 1992-2014, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -504,10 +504,11 @@ do { \ #define LOOP_STMT_TOP_UPDATE_P(NODE) TREE_LANG_FLAG_1 (LOOP_STMT_CHECK (NODE)) /* Optimization hints on loops. */ -#define LOOP_STMT_NO_UNROLL(NODE) TREE_LANG_FLAG_2 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_UNROLL(NODE) TREE_LANG_FLAG_3 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_NO_VECTOR(NODE) TREE_LANG_FLAG_4 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_VECTOR(NODE) TREE_LANG_FLAG_5 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_IVDEP(NODE) TREE_LANG_FLAG_2 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_NO_UNROLL(NODE) TREE_LANG_FLAG_3 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_UNROLL(NODE) TREE_LANG_FLAG_4 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_NO_VECTOR(NODE) TREE_LANG_FLAG_5 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_VECTOR(NODE) TREE_LANG_FLAG_6 (LOOP_STMT_CHECK (NODE)) #define EXIT_STMT_COND(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_STMT, 0) #define EXIT_STMT_LABEL(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_STMT, 1) diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 3bab482c705..ac2af06c45c 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -960,18 +960,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnu_type = TREE_TYPE (gnu_expr); /* Case 1: If this is a constant renaming stemming from a function - call, treat it as a normal object whose initial value is what - is being renamed. RM 3.3 says that the result of evaluating a - function call is a constant object. As a consequence, it can - be the inner object of a constant renaming. In this case, the - renaming must be fully instantiated, i.e. it cannot be a mere - reference to (part of) an existing object. */ + call, treat it as a normal object whose initial value is what is + being renamed. RM 3.3 says that the result of evaluating a + function call is a constant object. Treat constant literals + the same way. As a consequence, it can be the inner object of + a constant renaming. In this case, the renaming must be fully + instantiated, i.e. it cannot be a mere reference to (part of) an + existing object. */ if (const_flag) { tree inner_object = gnu_expr; while (handled_component_p (inner_object)) inner_object = TREE_OPERAND (inner_object, 0); - if (TREE_CODE (inner_object) == CALL_EXPR) + if (TREE_CODE (inner_object) == CALL_EXPR + || CONSTANT_CLASS_P (inner_object)) create_normal_object = true; } @@ -1030,15 +1032,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) about that failure. */ } - /* Case 3: If this is a constant renaming and creating a - new object is allowed and cheap, treat it as a normal - object whose initial value is what is being renamed. */ - if (const_flag - && !Is_Composite_Type - (Underlying_Type (Etype (gnat_entity)))) - ; - - /* Case 4: Make this into a constant pointer to the object we + /* Case 3: Make this into a constant pointer to the object we are to rename and attach the object to the pointer if it is something we can stabilize. @@ -1050,68 +1044,59 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) The pointer is called a "renaming" pointer in this case. In the rare cases where we cannot stabilize the renamed - object, we just make a "bare" pointer, and the renamed - entity is always accessed indirectly through it. */ - else - { - /* We need to preserve the volatileness of the renamed - object through the indirection. */ - if (TREE_THIS_VOLATILE (gnu_expr) - && !TYPE_VOLATILE (gnu_type)) - gnu_type - = build_qualified_type (gnu_type, - (TYPE_QUALS (gnu_type) - | TYPE_QUAL_VOLATILE)); - gnu_type = build_reference_type (gnu_type); - inner_const_flag = TREE_READONLY (gnu_expr); - const_flag = true; - - /* If the previous attempt at stabilizing failed, there - is no point in trying again and we reuse the result - without attaching it to the pointer. In this case it - will only be used as the initializing expression of - the pointer and thus needs no special treatment with - regard to multiple evaluations. */ - if (maybe_stable_expr) - ; - - /* Otherwise, try to stabilize and attach the expression - to the pointer if the stabilization succeeds. - - Note that this might introduce SAVE_EXPRs and we don't - check whether we're at the global level or not. This - is fine since we are building a pointer initializer and - neither the pointer nor the initializing expression can - be accessed before the pointer elaboration has taken - place in a correct program. - - These SAVE_EXPRs will be evaluated at the right place - by either the evaluation of the initializer for the - non-global case or the elaboration code for the global - case, and will be attached to the elaboration procedure - in the latter case. */ - else - { - maybe_stable_expr - = gnat_stabilize_reference (gnu_expr, true, &stable); + object, we just make a "bare" pointer and the renamed + object will always be accessed indirectly through it. + + Note that we need to preserve the volatility of the renamed + object through the indirection. */ + if (TREE_THIS_VOLATILE (gnu_expr) && !TYPE_VOLATILE (gnu_type)) + gnu_type = build_qualified_type (gnu_type, + (TYPE_QUALS (gnu_type) + | TYPE_QUAL_VOLATILE)); + gnu_type = build_reference_type (gnu_type); + inner_const_flag = TREE_READONLY (gnu_expr); + const_flag = true; - if (stable) - renamed_obj = maybe_stable_expr; + /* If the previous attempt at stabilizing failed, there is + no point in trying again and we reuse the result without + attaching it to the pointer. In this case it will only + be used as the initializing expression of the pointer and + thus needs no special treatment with regard to multiple + evaluations. + + Otherwise, try to stabilize and attach the expression to + the pointer if the stabilization succeeds. + + Note that this might introduce SAVE_EXPRs and we don't + check whether we are at the global level or not. This + is fine since we are building a pointer initializer and + neither the pointer nor the initializing expression can + be accessed before the pointer elaboration has taken + place in a correct program. + + These SAVE_EXPRs will be evaluated at the right place + by either the evaluation of the initializer for the + non-global case or the elaboration code for the global + case, and will be attached to the elaboration procedure + in the latter case. */ + if (!maybe_stable_expr) + { + maybe_stable_expr + = gnat_stabilize_reference (gnu_expr, true, &stable); - /* Attaching is actually performed downstream, as soon - as we have a VAR_DECL for the pointer we make. */ - } + if (stable) + renamed_obj = maybe_stable_expr; + } - if (type_annotate_only - && TREE_CODE (maybe_stable_expr) == ERROR_MARK) - gnu_expr = NULL_TREE; - else - gnu_expr = build_unary_op (ADDR_EXPR, gnu_type, - maybe_stable_expr); + if (type_annotate_only + && TREE_CODE (maybe_stable_expr) == ERROR_MARK) + gnu_expr = NULL_TREE; + else + gnu_expr + = build_unary_op (ADDR_EXPR, gnu_type, maybe_stable_expr); - gnu_size = NULL_TREE; - used_by_ref = true; - } + gnu_size = NULL_TREE; + used_by_ref = true; } } @@ -1483,10 +1468,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* Now create the variable or the constant and set various flags. */ gnu_decl - = create_var_decl (gnu_entity_name, gnu_ext_name, gnu_type, - gnu_expr, const_flag, Is_Public (gnat_entity), - imported_p || !definition, static_p, attr_list, - gnat_entity); + = create_var_decl_1 (gnu_entity_name, gnu_ext_name, gnu_type, + gnu_expr, const_flag, Is_Public (gnat_entity), + imported_p || !definition, static_p, + !renamed_obj, attr_list, gnat_entity); DECL_BY_REF_P (gnu_decl) = used_by_ref; DECL_POINTS_TO_READONLY_P (gnu_decl) = used_by_ref && inner_const_flag; DECL_CAN_NEVER_BE_NULL_P (gnu_decl) = Can_Never_Be_Null (gnat_entity); @@ -1517,7 +1502,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* If this is a renaming pointer, attach the renamed object to it and register it if we are at the global level. Note that an external constant is at the global level. */ - if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj) + if (renamed_obj) { SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj); if ((!definition && kind == E_Constant) || global_bindings_p ()) @@ -2671,10 +2656,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) for (index = ndim - 1; index >= 0; index--) { tree gnu_index = TYPE_INDEX_TYPE (gnu_index_types[index]); - tree gnu_index_name = TYPE_NAME (gnu_index); - - if (TREE_CODE (gnu_index_name) == TYPE_DECL) - gnu_index_name = DECL_NAME (gnu_index_name); + tree gnu_index_name = TYPE_IDENTIFIER (gnu_index); /* Make sure to reference the types themselves, and not just their names, as the debugger may fall back on them. */ @@ -3652,12 +3634,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) if (debug_info_p) { tree gnu_subtype_marker = make_node (RECORD_TYPE); - tree gnu_unpad_base_name = TYPE_NAME (gnu_unpad_base_type); + tree gnu_unpad_base_name + = TYPE_IDENTIFIER (gnu_unpad_base_type); tree gnu_size_unit = TYPE_SIZE_UNIT (gnu_type); - if (TREE_CODE (gnu_unpad_base_name) == TYPE_DECL) - gnu_unpad_base_name = DECL_NAME (gnu_unpad_base_name); - TYPE_NAME (gnu_subtype_marker) = create_concat_name (gnat_entity, "XVS"); finish_record_type (gnu_subtype_marker, @@ -4976,11 +4956,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) false, !gnu_decl, definition, false); if (TYPE_IS_PADDING_P (gnu_type)) - { - gnu_entity_name = TYPE_NAME (gnu_type); - if (TREE_CODE (gnu_entity_name) == TYPE_DECL) - gnu_entity_name = DECL_NAME (gnu_entity_name); - } + gnu_entity_name = TYPE_IDENTIFIER (gnu_type); /* Now set the RM size of the type. We cannot do it before padding because we need to accept arbitrary RM sizes on integral types. */ @@ -6160,7 +6136,8 @@ prepend_one_attribute_pragma (struct attrib **attr_list, Node_Id gnat_pragma) Node_Id gnat_arg0 = Next (First (gnat_arg)); Node_Id gnat_arg1 = Empty; - if (Present (gnat_arg0) && Is_Static_Expression (Expression (gnat_arg0))) + if (Present (gnat_arg0) + && Is_OK_Static_Expression (Expression (gnat_arg0))) { gnu_arg0 = gnat_to_gnu (Expression (gnat_arg0)); @@ -6174,7 +6151,8 @@ prepend_one_attribute_pragma (struct attrib **attr_list, Node_Id gnat_pragma) gnat_arg1 = Next (gnat_arg0); } - if (Present (gnat_arg1) && Is_Static_Expression (Expression (gnat_arg1))) + if (Present (gnat_arg1) + && Is_OK_Static_Expression (Expression (gnat_arg1))) { gnu_arg1 = gnat_to_gnu (Expression (gnat_arg1)); @@ -7035,7 +7013,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, { Node_Id gnat_discr = Name (variant_part), variant; tree gnu_discr = gnat_to_gnu (gnat_discr); - tree gnu_name = TYPE_NAME (gnu_record_type); + tree gnu_name = TYPE_IDENTIFIER (gnu_record_type); tree gnu_var_name = concat_name (get_identifier (Get_Name_String (Chars (gnat_discr))), "XVN"); @@ -7047,9 +7025,6 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list, unsigned int variants_align = 0; unsigned int i; - if (TREE_CODE (gnu_name) == TYPE_DECL) - gnu_name = DECL_NAME (gnu_name); - gnu_union_name = concat_name (gnu_name, IDENTIFIER_POINTER (gnu_var_name)); @@ -7467,12 +7442,8 @@ annotate_value (tree gnu_size) { struct tree_int_map *e; - if (!annotate_value_cache) - annotate_value_cache = htab_create_ggc (512, tree_int_map_hash, - tree_int_map_eq, 0); in.base.from = gnu_size; - e = (struct tree_int_map *) - htab_find (annotate_value_cache, &in); + e = (struct tree_int_map *) htab_find (annotate_value_cache, &in); if (e) return (Node_Ref_Or_Val) e->to; @@ -7557,11 +7528,17 @@ annotate_value (tree gnu_size) break; case CALL_EXPR: - { - tree t = maybe_inline_call_in_expr (gnu_size); - if (t) - return annotate_value (t); - } + /* In regular mode, inline back only if symbolic annotation is requested + in order to avoid memory explosion on big discriminated record types. + But not in ASIS mode, as symbolic annotation is required for DDA. */ + if (List_Representation_Info == 3 || type_annotate_only) + { + tree t = maybe_inline_call_in_expr (gnu_size); + if (t) + return annotate_value (t); + } + else + return Uint_Minus_1; /* Fall through... */ @@ -7590,11 +7567,10 @@ annotate_value (tree gnu_size) if (in.base.from) { struct tree_int_map **h; - /* We can't assume the hash table data hasn't moved since the - initial look up, so we have to search again. Allocating and - inserting an entry at that point would be an alternative, but - then we'd better discard the entry if we decided not to cache - it. */ + /* We can't assume the hash table data hasn't moved since the initial + look up, so we have to search again. Allocating and inserting an + entry at that point would be an alternative, but then we'd better + discard the entry if we decided not to cache it. */ h = (struct tree_int_map **) htab_find_slot (annotate_value_cache, &in, INSERT); gcc_assert (!*h); @@ -8441,7 +8417,8 @@ create_field_decl_from (tree old_field, tree field_type, tree record_type, if (!new_pos) { normalize_offset (&pos, &bitpos, offset_align); - DECL_FIELD_OFFSET (new_field) = pos; + /* Finalize the position. */ + DECL_FIELD_OFFSET (new_field) = variable_size (pos); DECL_FIELD_BIT_OFFSET (new_field) = bitpos; SET_DECL_OFFSET_ALIGN (new_field, offset_align); DECL_SIZE (new_field) = size; @@ -8919,4 +8896,24 @@ concat_name (tree gnu_name, const char *suffix) return get_identifier_with_length (new_name, len); } +/* Initialize data structures of the decl.c module. */ + +void +init_gnat_decl (void) +{ + /* Initialize the cache of annotated values. */ + annotate_value_cache + = htab_create_ggc (512, tree_int_map_hash, tree_int_map_eq, 0); +} + +/* Destroy data structures of the decl.c module. */ + +void +destroy_gnat_decl (void) +{ + /* Destroy the cache of annotated values. */ + htab_delete (annotate_value_cache); + annotate_value_cache = NULL; +} + #include "gt-ada-decl.h" diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h index b7092735c89..76fa2abde9f 100644 --- a/gcc/ada/gcc-interface/gigi.h +++ b/gcc/ada/gcc-interface/gigi.h @@ -210,6 +210,12 @@ extern tree create_concat_name (Entity_Id gnat_entity, const char *suffix); the name followed by "___" and the specified suffix. */ extern tree concat_name (tree gnu_name, const char *suffix); +/* Initialize data structures of the decl.c module. */ +extern void init_gnat_decl (void); + +/* Destroy data structures of the decl.c module. */ +extern void destroy_gnat_decl (void); + /* Highest number in the front-end node table. */ extern int max_gnat_nodes; diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 4a4d0faa9f6..3482d2ce39b 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -353,6 +353,7 @@ gigi (Node_Id gnat_root, /* Initialize ourselves. */ init_code_table (); + init_gnat_decl (); init_gnat_utils (); /* If we are just annotating types, give VOID_TYPE zero sizes to avoid @@ -727,6 +728,7 @@ gigi (Node_Id gnat_root, } /* Destroy ourselves. */ + destroy_gnat_decl (); destroy_gnat_utils (); /* We cannot track the location of errors past this point. */ @@ -896,17 +898,8 @@ lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant, address_of_constant, aliased); case N_Object_Renaming_Declaration: - /* We need to make a real renaming only if the constant object is - aliased or if we may use a renaming pointer; otherwise we can - optimize and return the rvalue. We make an exception if the object - is an identifier since in this case the rvalue can be propagated - attached to the CONST_DECL. */ - return (!constant - || aliased - /* This should match the constant case of the renaming code. */ - || Is_Composite_Type - (Underlying_Type (Etype (Name (gnat_parent)))) - || Nkind (Name (gnat_parent)) == N_Identifier); + /* We need to preserve addresses through a renaming. */ + return 1; case N_Object_Declaration: /* We cannot use a constructor if this is an atomic object because @@ -966,6 +959,77 @@ lvalue_required_p (Node_Id gnat_node, tree gnu_type, bool constant, gcc_unreachable (); } +/* Return true if T is a constant DECL node that can be safely replaced + by its initializer. */ + +static bool +constant_decl_with_initializer_p (tree t) +{ + if (!TREE_CONSTANT (t) || !DECL_P (t) || !DECL_INITIAL (t)) + return false; + + /* Return false for aggregate types that contain a placeholder since + their initializers cannot be manipulated easily. */ + if (AGGREGATE_TYPE_P (TREE_TYPE (t)) + && !TYPE_IS_FAT_POINTER_P (TREE_TYPE (t)) + && type_contains_placeholder_p (TREE_TYPE (t))) + return false; + + return true; +} + +/* Return an expression equivalent to EXP but where constant DECL nodes + have been replaced by their initializer. */ + +static tree +fold_constant_decl_in_expr (tree exp) +{ + enum tree_code code = TREE_CODE (exp); + tree op0; + + switch (code) + { + case CONST_DECL: + case VAR_DECL: + if (!constant_decl_with_initializer_p (exp)) + return exp; + + return DECL_INITIAL (exp); + + case BIT_FIELD_REF: + case COMPONENT_REF: + op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0)); + if (op0 == TREE_OPERAND (exp, 0)) + return exp; + + return fold_build3 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1), + TREE_OPERAND (exp, 2)); + + case ARRAY_REF: + case ARRAY_RANGE_REF: + op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0)); + if (op0 == TREE_OPERAND (exp, 0)) + return exp; + + return fold (build4 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1), + TREE_OPERAND (exp, 2), TREE_OPERAND (exp, 3))); + + case VIEW_CONVERT_EXPR: + case REALPART_EXPR: + case IMAGPART_EXPR: + op0 = fold_constant_decl_in_expr (TREE_OPERAND (exp, 0)); + if (op0 == TREE_OPERAND (exp, 0)) + return exp; + + return fold_build1 (code, TREE_TYPE (exp), op0); + + default: + return exp; + } + + gcc_unreachable (); +} + /* Subroutine of gnat_to_gnu to translate gnat_node, an N_Identifier, to a GCC tree, which is returned. GNU_RESULT_TYPE_P is a pointer to where we should place the result type. */ @@ -1110,13 +1174,16 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) true, false))) gnu_result = DECL_INITIAL (gnu_result); - /* If it's a renaming pointer and we are at the right binding level, - we can reference the renamed object directly, since the renamed - expression has been protected against multiple evaluations. */ + /* If it's a renaming pointer and, either the renamed object is constant + or we are at the right binding level, we can reference the renamed + object directly, since it is constant or has been protected against + multiple evaluations. */ if (TREE_CODE (gnu_result) == VAR_DECL && !DECL_LOOP_PARM_P (gnu_result) && DECL_RENAMED_OBJECT (gnu_result) - && (!DECL_RENAMING_GLOBAL_P (gnu_result) || global_bindings_p ())) + && (TREE_CONSTANT (DECL_RENAMED_OBJECT (gnu_result)) + || !DECL_RENAMING_GLOBAL_P (gnu_result) + || global_bindings_p ())) gnu_result = DECL_RENAMED_OBJECT (gnu_result); /* Otherwise, do the final dereference. */ @@ -1136,15 +1203,8 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) /* If we have a constant declaration and its initializer, try to return the latter to avoid the need to call fold in lots of places and the need for - elaboration code if this identifier is used as an initializer itself. - Don't do it for aggregate types that contain a placeholder since their - initializers cannot be manipulated easily. */ - if (TREE_CONSTANT (gnu_result) - && DECL_P (gnu_result) - && DECL_INITIAL (gnu_result) - && !(AGGREGATE_TYPE_P (TREE_TYPE (gnu_result)) - && !TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_result)) - && type_contains_placeholder_p (TREE_TYPE (gnu_result)))) + elaboration code if this identifier is used as an initializer itself. */ + if (constant_decl_with_initializer_p (gnu_result)) { bool constant_only = (TREE_CODE (gnu_result) == CONST_DECL && !DECL_CONST_CORRESPONDING_VAR (gnu_result)); @@ -1164,6 +1224,21 @@ Identifier_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) gnu_result = DECL_INITIAL (gnu_result); } + /* But for a constant renaming we couldn't do that incrementally for its + definition because of the need to return an lvalue so, if the present + context doesn't itself require an lvalue, we try again here. */ + else if (Ekind (gnat_temp) == E_Constant + && Is_Elementary_Type (gnat_temp_type) + && Present (Renamed_Object (gnat_temp))) + { + if (require_lvalue < 0) + require_lvalue + = lvalue_required_p (gnat_node, gnu_result_type, true, false, + Is_Aliased (gnat_temp)); + if (!require_lvalue) + gnu_result = fold_constant_decl_in_expr (gnu_result); + } + /* The GNAT tree has the type of a function set to its result type, so we adjust here. Also use the type of the result if the Etype is a subtype that is nominally unconstrained. Likewise if this is a deferred constant @@ -1266,10 +1341,14 @@ Pragma_to_gnu (Node_Id gnat_node) Present (gnat_temp); gnat_temp = Next (gnat_temp)) { - tree gnu_loop_stmt = gnu_loop_stack ->last ()->stmt; + tree gnu_loop_stmt = gnu_loop_stack->last ()->stmt; switch (Chars (Expression (gnat_temp))) { + case Name_Ivdep: + LOOP_STMT_IVDEP (gnu_loop_stmt) = 1; + break; + case Name_No_Unroll: LOOP_STMT_NO_UNROLL (gnu_loop_stmt) = 1; break; @@ -7745,13 +7824,29 @@ gnat_gimplify_stmt (tree *stmt_p) tree gnu_cond = LOOP_STMT_COND (stmt); tree gnu_update = LOOP_STMT_UPDATE (stmt); tree gnu_end_label = LOOP_STMT_LABEL (stmt); - tree t; /* Build the condition expression from the test, if any. */ if (gnu_cond) - gnu_cond - = build3 (COND_EXPR, void_type_node, gnu_cond, alloc_stmt_list (), - build1 (GOTO_EXPR, void_type_node, gnu_end_label)); + { + /* Deal with the optimization hints. */ + if (LOOP_STMT_IVDEP (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_ivdep_kind)); + + if (LOOP_STMT_NO_VECTOR (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_no_vector_kind)); + if (LOOP_STMT_VECTOR (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_vector_kind)); + + gnu_cond + = build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE, + build1 (GOTO_EXPR, void_type_node, gnu_end_label)); + } /* Set to emit the statements of the loop. */ *stmt_p = NULL_TREE; @@ -7780,7 +7875,7 @@ gnat_gimplify_stmt (tree *stmt_p) if (gnu_update && !LOOP_STMT_TOP_UPDATE_P (stmt)) append_to_statement_list (gnu_update, stmt_p); - t = build1 (GOTO_EXPR, void_type_node, gnu_start_label); + tree t = build1 (GOTO_EXPR, void_type_node, gnu_start_label); SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label)); append_to_statement_list (t, stmt_p); diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index a728e8c487e..9d7438c4c0b 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -251,8 +251,8 @@ init_gnat_utils (void) dummy_node_table = ggc_alloc_cleared_vec_tree (max_gnat_nodes); /* Initialize the hash table of padded types. */ - pad_type_hash_table = htab_create_ggc (512, pad_type_hash_hash, - pad_type_hash_eq, 0); + pad_type_hash_table + = htab_create_ggc (512, pad_type_hash_hash, pad_type_hash_eq, 0); } /* Destroy data structures of the utils.c module. */ @@ -706,10 +706,8 @@ make_aligning_type (tree type, unsigned int align, tree size, tree vblock_addr_st = size_binop (PLUS_EXPR, record_addr_st, room_st); tree voffset_st, pos, field; - tree name = TYPE_NAME (type); + tree name = TYPE_IDENTIFIER (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); name = concat_name (name, "ALIGN"); TYPE_NAME (record_type) = name; @@ -1203,14 +1201,8 @@ maybe_pad_type (tree type, tree size, unsigned int align, && DECL_IGNORED_P (TYPE_NAME (type)))) { tree marker = make_node (RECORD_TYPE); - tree name = TYPE_NAME (record); - tree orig_name = TYPE_NAME (type); - - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - if (TREE_CODE (orig_name) == TYPE_DECL) - orig_name = DECL_NAME (orig_name); + tree name = TYPE_IDENTIFIER (record); + tree orig_name = TYPE_IDENTIFIER (type); TYPE_NAME (marker) = concat_name (name, "XVS"); finish_record_type (marker, @@ -1419,7 +1411,7 @@ finish_record_type (tree record_type, tree field_list, int rep_level, bool debug_info_p) { enum tree_code code = TREE_CODE (record_type); - tree name = TYPE_NAME (record_type); + tree name = TYPE_IDENTIFIER (record_type); tree ada_size = bitsize_zero_node; tree size = bitsize_zero_node; bool had_size = TYPE_SIZE (record_type) != 0; @@ -1431,8 +1423,6 @@ finish_record_type (tree record_type, tree field_list, int rep_level, /* Always attach the TYPE_STUB_DECL for a record type. It is required to generate debug info and have a parallel type. */ - if (name && TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); TYPE_STUB_DECL (record_type) = create_type_stub_decl (name, record_type); /* Globally initialize the record first. If this is a rep'ed record, @@ -1692,13 +1682,10 @@ rest_of_record_type_compilation (tree record_type) tree new_record_type = make_node (TREE_CODE (record_type) == QUAL_UNION_TYPE ? UNION_TYPE : TREE_CODE (record_type)); - tree orig_name = TYPE_NAME (record_type), new_name; + tree orig_name = TYPE_IDENTIFIER (record_type), new_name; tree last_pos = bitsize_zero_node; tree old_field, prev_old_field = NULL_TREE; - if (TREE_CODE (orig_name) == TYPE_DECL) - orig_name = DECL_NAME (orig_name); - new_name = concat_name (orig_name, TREE_CODE (record_type) == QUAL_UNION_TYPE ? "XVU" : "XVE"); @@ -2527,7 +2514,10 @@ record_global_renaming_pointer (tree decl) vec_safe_push (global_renaming_pointers, decl); } -/* Invalidate the global renaming pointers. */ +/* Invalidate the global renaming pointers that are not constant, lest their + renamed object contains SAVE_EXPRs tied to an elaboration routine. Note + that we should not blindly invalidate everything here because of the need + to propagate constant values through renaming. */ void invalidate_global_renaming_pointers (void) @@ -2539,7 +2529,8 @@ invalidate_global_renaming_pointers (void) return; FOR_EACH_VEC_ELT (*global_renaming_pointers, i, iter) - SET_DECL_RENAMED_OBJECT (iter, NULL_TREE); + if (!TREE_CONSTANT (DECL_RENAMED_OBJECT (iter))) + SET_DECL_RENAMED_OBJECT (iter, NULL_TREE); vec_free (global_renaming_pointers); } @@ -3207,6 +3198,96 @@ build_template (tree template_type, tree array_type, tree expr) return gnat_build_constructor (template_type, template_elts); } +/* Return true if TYPE is suitable for the element type of a vector. */ + +static bool +type_for_vector_element_p (tree type) +{ + enum machine_mode mode; + + if (!INTEGRAL_TYPE_P (type) + && !SCALAR_FLOAT_TYPE_P (type) + && !FIXED_POINT_TYPE_P (type)) + return false; + + mode = TYPE_MODE (type); + if (GET_MODE_CLASS (mode) != MODE_INT + && !SCALAR_FLOAT_MODE_P (mode) + && !ALL_SCALAR_FIXED_POINT_MODE_P (mode)) + return false; + + return true; +} + +/* Return a vector type given the SIZE and the INNER_TYPE, or NULL_TREE if + this is not possible. If ATTRIBUTE is non-zero, we are processing the + attribute declaration and want to issue error messages on failure. */ + +static tree +build_vector_type_for_size (tree inner_type, tree size, tree attribute) +{ + unsigned HOST_WIDE_INT size_int, inner_size_int; + int nunits; + + /* Silently punt on variable sizes. We can't make vector types for them, + need to ignore them on front-end generated subtypes of unconstrained + base types, and this attribute is for binding implementors, not end + users, so we should never get there from legitimate explicit uses. */ + if (!tree_fits_uhwi_p (size)) + return NULL_TREE; + size_int = tree_to_uhwi (size); + + if (!type_for_vector_element_p (inner_type)) + { + if (attribute) + error ("invalid element type for attribute %qs", + IDENTIFIER_POINTER (attribute)); + return NULL_TREE; + } + inner_size_int = tree_to_uhwi (TYPE_SIZE_UNIT (inner_type)); + + if (size_int % inner_size_int) + { + if (attribute) + error ("vector size not an integral multiple of component size"); + return NULL_TREE; + } + + if (size_int == 0) + { + if (attribute) + error ("zero vector size"); + return NULL_TREE; + } + + nunits = size_int / inner_size_int; + if (nunits & (nunits - 1)) + { + if (attribute) + error ("number of components of vector not a power of two"); + return NULL_TREE; + } + + return build_vector_type (inner_type, nunits); +} + +/* Return a vector type whose representative array type is ARRAY_TYPE, or + NULL_TREE if this is not possible. If ATTRIBUTE is non-zero, we are + processing the attribute and want to issue error messages on failure. */ + +static tree +build_vector_type_for_array (tree array_type, tree attribute) +{ + tree vector_type = build_vector_type_for_size (TREE_TYPE (array_type), + TYPE_SIZE_UNIT (array_type), + attribute); + if (!vector_type) + return NULL_TREE; + + TYPE_REPRESENTATIVE_ARRAY (vector_type) = array_type; + return vector_type; +} + /* Helper routine to make a descriptor field. FIELD_LIST is the list of decls being built; the new decl is chained on to the front of the list. */ @@ -5281,6 +5362,7 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) tree etype = TREE_TYPE (expr); enum tree_code ecode = TREE_CODE (etype); enum tree_code code = TREE_CODE (type); + tree tem; int c; /* If the expression is already of the right type, we are done. */ @@ -5427,6 +5509,18 @@ unchecked_convert (tree type, tree expr, bool notrunc_p) etype)) expr = convert (type, expr); + /* And, if the array type is not the representative, we try to build an + intermediate vector type of which the array type is the representative + and to do the unchecked conversion between the vector types, in order + to enable further simplifications in the middle-end. */ + else if (code == VECTOR_TYPE + && ecode == ARRAY_TYPE + && (tem = build_vector_type_for_array (etype, NULL_TREE))) + { + expr = convert (tem, expr); + return unchecked_convert (type, expr, notrunc_p); + } + /* If we are converting a CONSTRUCTOR to a more aligned RECORD_TYPE, bump the alignment of the CONSTRUCTOR to speed up the copy operation. */ else if (TREE_CODE (expr) == CONSTRUCTOR @@ -6322,27 +6416,13 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), static tree handle_vector_size_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *no_add_attrs) + int ARG_UNUSED (flags), bool *no_add_attrs) { - unsigned HOST_WIDE_INT vecsize, nunits; - enum machine_mode orig_mode; - tree type = *node, new_type, size; + tree type = *node; + tree vector_type; *no_add_attrs = true; - size = TREE_VALUE (args); - - if (!tree_fits_uhwi_p (size)) - { - warning (OPT_Wattributes, "%qs attribute ignored", - IDENTIFIER_POINTER (name)); - return NULL_TREE; - } - - /* Get the vector size (in bytes). */ - vecsize = tree_to_uhwi (size); - /* We need to provide for vector pointers, vector arrays, and functions returning vectors. For example: @@ -6350,53 +6430,17 @@ handle_vector_size_attribute (tree *node, tree name, tree args, In this case, the mode is SI, but the type being modified is HI, so we need to look further. */ - while (POINTER_TYPE_P (type) || TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); - /* Get the mode of the type being modified. */ - orig_mode = TYPE_MODE (type); - - if ((!INTEGRAL_TYPE_P (type) - && !SCALAR_FLOAT_TYPE_P (type) - && !FIXED_POINT_TYPE_P (type)) - || (!SCALAR_FLOAT_MODE_P (orig_mode) - && GET_MODE_CLASS (orig_mode) != MODE_INT - && !ALL_SCALAR_FIXED_POINT_MODE_P (orig_mode)) - || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)) - || TREE_CODE (type) == BOOLEAN_TYPE) - { - error ("invalid vector type for attribute %qs", - IDENTIFIER_POINTER (name)); - return NULL_TREE; - } - - if (vecsize % tree_to_uhwi (TYPE_SIZE_UNIT (type))) - { - error ("vector size not an integral multiple of component size"); - return NULL; - } - - if (vecsize == 0) - { - error ("zero vector size"); - return NULL; - } - - /* Calculate how many units fit in the vector. */ - nunits = vecsize / tree_to_uhwi (TYPE_SIZE_UNIT (type)); - if (nunits & (nunits - 1)) - { - error ("number of components of the vector not a power of two"); - return NULL_TREE; - } - - new_type = build_vector_type (type, nunits); + vector_type = build_vector_type_for_size (type, TREE_VALUE (args), name); + if (!vector_type) + return NULL_TREE; /* Build back pointers if needed. */ - *node = reconstruct_complex_type (*node, new_type); + *node = reconstruct_complex_type (*node, vector_type); return NULL_TREE; } @@ -6406,83 +6450,26 @@ handle_vector_size_attribute (tree *node, tree name, tree args, static tree handle_vector_type_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) + int ARG_UNUSED (flags), bool *no_add_attrs) { - /* Vector representative type and size. */ - tree rep_type = *node; - tree rep_size = TYPE_SIZE_UNIT (rep_type); - - /* Vector size in bytes and number of units. */ - unsigned HOST_WIDE_INT vec_bytes, vec_units; - - /* Vector element type and mode. */ - tree elem_type; - enum machine_mode elem_mode; + tree type = *node; + tree vector_type; *no_add_attrs = true; - if (TREE_CODE (rep_type) != ARRAY_TYPE) + if (TREE_CODE (type) != ARRAY_TYPE) { error ("attribute %qs applies to array types only", IDENTIFIER_POINTER (name)); return NULL_TREE; } - /* Silently punt on variable sizes. We can't make vector types for them, - need to ignore them on front-end generated subtypes of unconstrained - bases, and this attribute is for binding implementors, not end-users, so - we should never get there from legitimate explicit uses. */ - - if (!tree_fits_uhwi_p (rep_size)) + vector_type = build_vector_type_for_array (type, name); + if (!vector_type) return NULL_TREE; - /* Get the element type/mode and check this is something we know - how to make vectors of. */ - - elem_type = TREE_TYPE (rep_type); - elem_mode = TYPE_MODE (elem_type); - - if ((!INTEGRAL_TYPE_P (elem_type) - && !SCALAR_FLOAT_TYPE_P (elem_type) - && !FIXED_POINT_TYPE_P (elem_type)) - || (!SCALAR_FLOAT_MODE_P (elem_mode) - && GET_MODE_CLASS (elem_mode) != MODE_INT - && !ALL_SCALAR_FIXED_POINT_MODE_P (elem_mode)) - || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (elem_type))) - { - error ("invalid element type for attribute %qs", - IDENTIFIER_POINTER (name)); - return NULL_TREE; - } - - /* Sanity check the vector size and element type consistency. */ - - vec_bytes = tree_to_uhwi (rep_size); - - if (vec_bytes % tree_to_uhwi (TYPE_SIZE_UNIT (elem_type))) - { - error ("vector size not an integral multiple of component size"); - return NULL; - } - - if (vec_bytes == 0) - { - error ("zero vector size"); - return NULL; - } - - vec_units = vec_bytes / tree_to_uhwi (TYPE_SIZE_UNIT (elem_type)); - if (vec_units & (vec_units - 1)) - { - error ("number of components of the vector not a power of two"); - return NULL_TREE; - } - - /* Build the vector type and replace. */ - - *node = build_vector_type (elem_type, vec_units); - TYPE_REPRESENTATIVE_ARRAY (*node) = rep_type; + TYPE_REPRESENTATIVE_ARRAY (vector_type) = type; + *node = vector_type; return NULL_TREE; } diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 138551df327..34ac0e17aa9 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -4417,7 +4417,7 @@ Syntax: @smallexample @c ada pragma Loop_Optimize (OPTIMIZATION_HINT @{, OPTIMIZATION_HINT@}); -OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector +OPTIMIZATION_HINT ::= Ivdep | No_Unroll | Unroll | No_Vector | Vector @end smallexample @noindent @@ -4426,8 +4426,13 @@ programmer to specify optimization hints for the enclosing loop. The hints are not mutually exclusive and can be freely mixed, but not all combinations will yield a sensible outcome. -There are four supported optimization hints for a loop: +There are five supported optimization hints for a loop: + @itemize @bullet +@item Ivdep + +The programmer asserts that there are no loop-carried dependencies which would prevent consecutive iterations of the loop from being executed simultaneously. + @item No_Unroll The loop must not be unrolled. This is a strong hint: the compiler will not diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index b484665eab4..2d9c61865d9 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -10780,6 +10780,38 @@ preferably to other optimizations by means of pragma @code{Loop_Optimize}: placed immediately within the loop will convey the appropriate hint to the compiler for this loop. +It is also possible to help the compiler generate better vectorized code +for a given loop by asserting that there are no loop-carried dependencies +in the loop. Consider for example the procedure: + +@smallexample @c ada + type Arr is array (1 .. 4) of Long_Float; + + procedure Add (X, Y : not null access Arr; R : not null access Arr) is + begin + for I in Arr'Range loop + R(I) := X(I) + Y(I); + end loop; + end; +@end smallexample + +@noindent +By default, the compiler cannot unconditionally vectorize the loop because +assigning to a component of the array designated by R in one iteration could +change the value read from the components of the arrays designated by X or Y +in a later iteration. As a result, the compiler will generate two versions +of the loop in the object code, one vectorized and the other not vectorized, +as well as a test to select the appropriate version at run time. This can +be overcome by another hint: + +@smallexample @c ada + pragma Loop_Optimize (Ivdep); +@end smallexample + +@noindent +placed immediately within the loop will tell the compiler that it can safely +omit the non-vectorized version of the loop as well as the run-time test. + @node Other Optimization Switches @subsection Other Optimization Switches @cindex Optimization Switches diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads index 90bf403c5bf..ecefdadc6df 100644 --- a/gcc/ada/opt.ads +++ b/gcc/ada/opt.ads @@ -1371,12 +1371,6 @@ package Opt is -- initialized by Osint.Initialize, and further initialized by the -- Adjust_Global_Switches flag in Gnat1drv. - Suppress_Back_Annotation : Boolean := False; - -- GNAT - -- This flag is set True if back annotation of representation information - -- is to be suppressed. This is set if neither -gnatt or -gnatR0-3 is set. - -- This avoids unnecessary time being spent on back annotation. - Table_Factor : Int := 1; -- GNAT -- Factor by which all initial table sizes set in Alloc are multiplied. diff --git a/gcc/ada/repinfo.ads b/gcc/ada/repinfo.ads index 99fccc34d4a..7896439a0b5 100644 --- a/gcc/ada/repinfo.ads +++ b/gcc/ada/repinfo.ads @@ -108,6 +108,14 @@ package Repinfo is -- represent the value of such an expression, as explained in -- the following section. + -- Note: the extended back-annotation for the dynamic case is needed only + -- for -gnatR3 output, and for proper operation of the ASIS DDA. Since it + -- can be expensive to do this back annotation (for discriminated records + -- with many variable length arrays), we only do the full back annotation + -- in -gnatR3 mode, or ASIS mode. In any other mode, the back-end just sets + -- the value to Uint_Minus_1, indicating that the value of the attribute + -- depends on discriminant information, but not giving further details. + -- GCC expressions are represented with a Uint value that is negative. -- See the body of this package for details on the representation used. @@ -117,7 +125,9 @@ package Repinfo is -- as a negative Uint value, provides an expression which, when evaluated -- with a given set of discriminant values, indicates whether the variant -- is present for that set of values (result is True, i.e. non-zero) or - -- not present (result is False, i.e. zero). + -- not present (result is False, i.e. zero). Again, the full annotation of + -- this field is done only in -gnatR3 mode or in ASIS mode, and in other + -- modes, the value is set to Uint_Minus_1. subtype Node_Ref is Uint; -- Subtype used for negative Uint values used to represent nodes diff --git a/gcc/ada/s-intman-android.adb b/gcc/ada/s-intman-android.adb new file mode 100644 index 00000000000..30a980e3e3b --- /dev/null +++ b/gcc/ada/s-intman-android.adb @@ -0,0 +1,331 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- +-- -- +-- S Y S T E M . I N T E R R U P T _ M A N A G E M E N T -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2014, Free Software Foundation, Inc. -- +-- -- +-- GNARL is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- In particular, you can freely distribute your programs built with the -- +-- GNAT Pro compiler, including any required library run-time units, using -- +-- any licensing terms of your choosing. See the AdaCore Software License -- +-- for full details. -- +-- -- +-- GNARL was developed by the GNARL team at Florida State University. -- +-- Extensive contributions were provided by Ada Core Technologies, Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This is the Android version of this package + +-- Make a careful study of all signals available under the OS, to see which +-- need to be reserved, kept always unmasked, or kept always unmasked. Be on +-- the lookout for special signals that may be used by the thread library. + +-- Since this is a multi target file, the signal <-> exception mapping +-- is simple minded. If you need a more precise and target specific +-- signal handling, create a new s-intman.adb that will fit your needs. + +-- This file assumes that: + +-- SIGFPE, SIGILL, SIGSEGV and SIGBUS exist. They are mapped as follows: +-- SIGPFE => Constraint_Error +-- SIGILL => Program_Error +-- SIGSEGV => Storage_Error +-- SIGBUS => Storage_Error + +-- SIGINT exists and will be kept unmasked unless the pragma +-- Unreserve_All_Interrupts is specified anywhere in the application. + +-- System.OS_Interface contains the following: +-- SIGADAABORT: the signal that will be used to abort tasks. +-- Unmasked: the OS specific set of signals that should be unmasked in +-- all the threads. SIGADAABORT is unmasked by +-- default +-- Reserved: the OS specific set of signals that are reserved. + +with System.Task_Primitives; + +package body System.Interrupt_Management is + + use Interfaces.C; + use System.OS_Interface; + + type Interrupt_List is array (Interrupt_ID range <>) of Interrupt_ID; + Exception_Interrupts : constant Interrupt_List := + (SIGFPE, SIGILL, SIGSEGV, SIGBUS); + + Unreserve_All_Interrupts : Interfaces.C.int; + pragma Import + (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts"); + + ----------------------- + -- Local Subprograms -- + ----------------------- + + procedure Signal_Trampoline + (signo : Signal; + siginfo : System.Address; + ucontext : System.Address; + handler : System.Address); + pragma Import (C, Signal_Trampoline, "__gnat_sigtramp"); + -- Pass the real handler to a speical function that handles unwinding by + -- skipping over the kernel signal frame (which doesn't contain any unwind + -- information). + + function State (Int : Interrupt_ID) return Character; + pragma Import (C, State, "__gnat_get_interrupt_state"); + -- Get interrupt state. Defined in init.c The input argument is the + -- interrupt number, and the result is one of the following: + + procedure Map_Signal + (signo : Signal; + siginfo : System.Address; + ucontext : System.Address); + -- This function identifies the Ada exception to be raised using the + -- information when the system received a synchronous signal. + +---------------- +-- Map_Signal -- +---------------- + + procedure Map_Signal + (signo : Signal; + siginfo : System.Address; + ucontext : System.Address) + is + pragma Unreferenced (siginfo); + pragma Unreferenced (ucontext); + + begin + + -- Check that treatment of exception propagation here is consistent with + -- treatment of the abort signal in System.Task_Primitives.Operations. + + case signo is + when SIGFPE => + raise Constraint_Error; + when SIGILL => + raise Program_Error; + when SIGSEGV => + raise Storage_Error; + when SIGBUS => + raise Storage_Error; + when others => + null; + end case; + end Map_Signal; + +---------------------- +-- Notify_Exception -- +---------------------- + + User : constant Character := 'u'; + Runtime : constant Character := 'r'; + Default : constant Character := 's'; + -- 'n' this interrupt not set by any Interrupt_State pragma + -- 'u' Interrupt_State pragma set state to User + -- 'r' Interrupt_State pragma set state to Runtime + -- 's' Interrupt_State pragma set state to System (use "default" + -- system handler) + + procedure Notify_Exception + (signo : Signal; + siginfo : System.Address; + ucontext : System.Address); + -- This function is the signal handler and calls a trampoline subprogram + -- that adjusts the unwind information so the ARM unwinder can find it's + -- way back to the context of the originating subprogram. Compare with + -- __gnat_error_handler for non-tasking programs. + + ---------------------- + -- Notify_Exception -- + ---------------------- + + Signal_Mask : aliased sigset_t; + -- The set of signals handled by Notify_Exception + + procedure Notify_Exception + (signo : Signal; + siginfo : System.Address; + ucontext : System.Address) + is + Result : Interfaces.C.int; + + begin + -- With the __builtin_longjmp, the signal mask is not restored, so we + -- need to restore it explicitly. ??? We don't use __builtin_longjmp + -- anymore, so do we still need this? */ + + Result := pthread_sigmask (SIG_UNBLOCK, Signal_Mask'Access, null); + pragma Assert (Result = 0); + + -- Perform the necessary context adjustments prior to calling the + -- trampoline subprogram with the "real" signal handler. + + Adjust_Context_For_Raise (signo, ucontext); + + Signal_Trampoline (signo, siginfo, ucontext, Map_Signal'Address); + end Notify_Exception; + + ---------------- + -- Initialize -- + ---------------- + + Initialized : Boolean := False; + + procedure Initialize is + act : aliased struct_sigaction; + old_act : aliased struct_sigaction; + Result : System.OS_Interface.int; + + Use_Alternate_Stack : constant Boolean := + System.Task_Primitives.Alternate_Stack_Size /= 0; + -- Whether to use an alternate signal stack for stack overflows + + begin + if Initialized then + return; + end if; + + Initialized := True; + + -- Need to call pthread_init very early because it is doing signal + -- initializations. + + pthread_init; + + Abort_Task_Interrupt := SIGADAABORT; + + act.sa_handler := Notify_Exception'Address; + + -- Setting SA_SIGINFO asks the kernel to pass more than just the signal + -- number argument to the handler when it is called. The set of extra + -- parameters includes a pointer to the interrupted context, which the + -- ZCX propagation scheme needs. + + -- Most man pages for sigaction mention that sa_sigaction should be set + -- instead of sa_handler when SA_SIGINFO is on. In practice, the two + -- fields are actually union'ed and located at the same offset. + + -- On some targets, we set sa_flags to SA_NODEFER so that during the + -- handler execution we do not change the Signal_Mask to be masked for + -- the Signal. + + -- This is a temporary fix to the problem that the Signal_Mask is not + -- restored after the exception (longjmp) from the handler. The right + -- fix should be made in sigsetjmp so that we save the Signal_Set and + -- restore it after a longjmp. + + -- We set SA_NODEFER to be compatible with what is done in + -- __gnat_error_handler. + + Result := sigemptyset (Signal_Mask'Access); + pragma Assert (Result = 0); + + -- Add signals that map to Ada exceptions to the mask + + for J in Exception_Interrupts'Range loop + if State (Exception_Interrupts (J)) /= Default then + Result := + sigaddset + (Signal_Mask'Access, Signal (Exception_Interrupts (J))); + pragma Assert (Result = 0); + end if; + end loop; + + act.sa_mask := Signal_Mask; + + pragma Assert (Keep_Unmasked = (Interrupt_ID'Range => False)); + pragma Assert (Reserve = (Interrupt_ID'Range => False)); + + -- Process state of exception signals + + for J in Exception_Interrupts'Range loop + if State (Exception_Interrupts (J)) /= User then + Keep_Unmasked (Exception_Interrupts (J)) := True; + Reserve (Exception_Interrupts (J)) := True; + + if State (Exception_Interrupts (J)) /= Default then + act.sa_flags := SA_NODEFER + SA_RESTART + SA_SIGINFO; + + if Use_Alternate_Stack + and then Exception_Interrupts (J) = SIGSEGV + then + act.sa_flags := act.sa_flags + SA_ONSTACK; + end if; + + Result := + sigaction + (Signal (Exception_Interrupts (J)), act'Unchecked_Access, + old_act'Unchecked_Access); + pragma Assert (Result = 0); + end if; + end if; + end loop; + + if State (Abort_Task_Interrupt) /= User then + Keep_Unmasked (Abort_Task_Interrupt) := True; + Reserve (Abort_Task_Interrupt) := True; + end if; + + -- Set SIGINT to unmasked state as long as it is not in "User" state. + -- Check for Unreserve_All_Interrupts last. + + if State (SIGINT) /= User then + Keep_Unmasked (SIGINT) := True; + Reserve (SIGINT) := True; + end if; + + -- Check all signals for state that requires keeping them unmasked and + -- reserved. + + for J in Interrupt_ID'Range loop + if State (J) = Default or else State (J) = Runtime then + Keep_Unmasked (J) := True; + Reserve (J) := True; + end if; + end loop; + + -- Add the set of signals that must always be unmasked for this target + + for J in Unmasked'Range loop + Keep_Unmasked (Interrupt_ID (Unmasked (J))) := True; + Reserve (Interrupt_ID (Unmasked (J))) := True; + end loop; + + -- Add target-specific reserved signals + + for J in Reserved'Range loop + Reserve (Interrupt_ID (Reserved (J))) := True; + end loop; + + -- Process pragma Unreserve_All_Interrupts. This overrides any settings + -- due to pragma Interrupt_State: + + if Unreserve_All_Interrupts /= 0 then + Keep_Unmasked (SIGINT) := False; + Reserve (SIGINT) := False; + end if; + + -- We do not really have Signal 0. We just use this value to identify + -- non-existent signals (see s-intnam.ads). Therefore, Signal should not + -- be used in all signal related operations hence mark it as reserved. + + Reserve (0) := True; + end Initialize; + +end System.Interrupt_Management; diff --git a/gcc/ada/s-linux-alpha.ads b/gcc/ada/s-linux-alpha.ads index 1a9f37acd7d..e1c97ad9a33 100644 --- a/gcc/ada/s-linux-alpha.ads +++ b/gcc/ada/s-linux-alpha.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2009-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -35,14 +35,30 @@ -- PLEASE DO NOT add any with-clauses to this package or remove the pragma -- Preelaborate. This package is designed to be a bottom-level (leaf) package. +with Interfaces.C; + package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ - - type time_t is new Long_Integer; + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); + + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); ----------- -- Errno -- diff --git a/gcc/ada/s-linux-android.ads b/gcc/ada/s-linux-android.ads new file mode 100644 index 00000000000..85c421039b1 --- /dev/null +++ b/gcc/ada/s-linux-android.ads @@ -0,0 +1,128 @@ +------------------------------------------------------------------------------ +-- -- +-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS -- +-- -- +-- S Y S T E M . L I N U X -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2014, Free Software Foundation, Inc. -- +-- -- +-- GNARL is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- In particular, you can freely distribute your programs built with the -- +-- GNAT Pro compiler, including any required library run-time units, using -- +-- any licensing terms of your choosing. See the AdaCore Software License -- +-- for full details. -- +-- -- +-- -- +------------------------------------------------------------------------------ + +-- This is the Android version of this package + +-- This package encapsulates cpu specific differences between implementations +-- of GNU/Linux, in order to share s-osinte-linux.ads. + +-- PLEASE DO NOT add any with-clauses to this package or remove the pragma +-- Preelaborate. This package is designed to be a bottom-level (leaf) package + +with Interfaces.C; + +package System.Linux is + pragma Preelaborate; + + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); + + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); + + ----------- + -- Errno -- + ----------- + + EAGAIN : constant := 11; + EINTR : constant := 4; + EINVAL : constant := 22; + ENOMEM : constant := 12; + EPERM : constant := 1; + ETIMEDOUT : constant := 110; + + ------------- + -- Signals -- + ------------- + + SIGHUP : constant := 1; -- hangup + SIGINT : constant := 2; -- interrupt (rubout) + SIGQUIT : constant := 3; -- quit (ASCD FS) + SIGILL : constant := 4; -- illegal instruction (not reset) + SIGTRAP : constant := 5; -- trace trap (not reset) + SIGIOT : constant := 6; -- IOT instruction + SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future + SIGFPE : constant := 8; -- floating point exception + SIGKILL : constant := 9; -- kill (cannot be caught or ignored) + SIGBUS : constant := 7; -- bus error + SIGSEGV : constant := 11; -- segmentation violation + SIGPIPE : constant := 13; -- write on a pipe with no one to read it + SIGALRM : constant := 14; -- alarm clock + SIGTERM : constant := 15; -- software termination signal from kill + SIGUSR1 : constant := 10; -- user defined signal 1 + SIGUSR2 : constant := 12; -- user defined signal 2 + SIGCLD : constant := 17; -- alias for SIGCHLD + SIGCHLD : constant := 17; -- child status change + SIGPWR : constant := 30; -- power-fail restart + SIGWINCH : constant := 28; -- window size change + SIGURG : constant := 23; -- urgent condition on IO channel + SIGPOLL : constant := 29; -- pollable event occurred + SIGIO : constant := 29; -- I/O now possible (4.2 BSD) + SIGLOST : constant := 29; -- File lock lost + SIGSTOP : constant := 19; -- stop (cannot be caught or ignored) + SIGTSTP : constant := 20; -- user stop requested from tty + SIGCONT : constant := 18; -- stopped process has been continued + SIGTTIN : constant := 21; -- background tty read attempted + SIGTTOU : constant := 22; -- background tty write attempted + SIGVTALRM : constant := 26; -- virtual timer expired + SIGPROF : constant := 27; -- profiling timer expired + SIGXCPU : constant := 24; -- CPU time limit exceeded + SIGXFSZ : constant := 25; -- filesize limit exceeded + SIGUNUSED : constant := 31; -- unused signal (GNU/Linux) + SIGSTKFLT : constant := 16; -- coprocessor stack fault (Linux) + SIGLTHRRES : constant := 32; -- GNU/LinuxThreads restart signal + SIGLTHRCAN : constant := 33; -- GNU/LinuxThreads cancel signal + SIGLTHRDBG : constant := 34; -- GNU/LinuxThreads debugger signal + + -- struct_sigaction offsets + + sa_handler_pos : constant := 0; + sa_mask_pos : constant := Standard'Address_Size / 8; + sa_flags_pos : constant := 4 + sa_mask_pos; + + SA_SIGINFO : constant := 16#00000004#; + SA_ONSTACK : constant := 16#08000000#; + SA_RESTART : constant := 16#10000000#; + SA_NODEFER : constant := 16#40000000#; + +end System.Linux; diff --git a/gcc/ada/s-linux-hppa.ads b/gcc/ada/s-linux-hppa.ads index 90461504945..8f7d8117576 100644 --- a/gcc/ada/s-linux-hppa.ads +++ b/gcc/ada/s-linux-hppa.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2008-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2008-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -35,14 +35,30 @@ -- PLEASE DO NOT add any with-clauses to this package or remove the pragma -- Preelaborate. This package is designed to be a bottom-level (leaf) package. +with Interfaces.C; + package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); - type time_t is new Long_Integer; + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); ----------- -- Errno -- diff --git a/gcc/ada/s-linux-mipsel.ads b/gcc/ada/s-linux-mipsel.ads index 028ea7c0b60..1799a557ac6 100644 --- a/gcc/ada/s-linux-mipsel.ads +++ b/gcc/ada/s-linux-mipsel.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2009-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -34,14 +34,30 @@ -- PLEASE DO NOT add any with-clauses to this package or remove the pragma -- Preelaborate. This package is designed to be a bottom-level (leaf) package +with Interfaces.C; + package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); - type time_t is new Long_Integer; + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); ----------- -- Errno -- diff --git a/gcc/ada/s-linux-sparc.ads b/gcc/ada/s-linux-sparc.ads index db3b4ea794c..ae813e6b3b4 100644 --- a/gcc/ada/s-linux-sparc.ads +++ b/gcc/ada/s-linux-sparc.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2009-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2009-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -35,14 +35,30 @@ -- PLEASE DO NOT add any with-clauses to this package or remove the pragma -- Preelaborate. This package is designed to be a bottom-level (leaf) package +with Interfaces.C; + package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ - - type time_t is new Long_Integer; + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); + + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); ----------- -- Errno -- diff --git a/gcc/ada/s-linux-x32.ads b/gcc/ada/s-linux-x32.ads index 9dc0e830d94..1b2d46eddd2 100644 --- a/gcc/ada/s-linux-x32.ads +++ b/gcc/ada/s-linux-x32.ads @@ -6,7 +6,8 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2013-2014, Free Software Foundation, Inc. -- +-- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -38,12 +39,24 @@ package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ + ---------- + -- Time -- + ---------- type time_t is new Long_Long_Integer; + type timespec is record + tv_sec : time_t; + tv_nsec : Long_Long_Integer; + end record; + pragma Convention (C, timespec); + + type timeval is record + tv_sec : time_t; + tv_usec : Long_Long_Integer; + end record; + pragma Convention (C, timeval); + ----------- -- Errno -- ----------- diff --git a/gcc/ada/s-linux.ads b/gcc/ada/s-linux.ads index 2339e29e04b..8a49e8c891e 100644 --- a/gcc/ada/s-linux.ads +++ b/gcc/ada/s-linux.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 2008-2011, Free Software Foundation, Inc. -- +-- Copyright (C) 2008-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -35,14 +35,30 @@ -- PLEASE DO NOT add any with-clauses to this package or remove the pragma -- Preelaborate. This package is designed to be a bottom-level (leaf) package +with Interfaces.C; + package System.Linux is pragma Preelaborate; - ------------ - -- time_t -- - ------------ + ---------- + -- Time -- + ---------- + + subtype long is Interfaces.C.long; + subtype suseconds_t is Interfaces.C.long; + subtype time_t is Interfaces.C.long; + + type timespec is record + tv_sec : time_t; + tv_nsec : long; + end record; + pragma Convention (C, timespec); - type time_t is new Long_Integer; + type timeval is record + tv_sec : time_t; + tv_usec : suseconds_t; + end record; + pragma Convention (C, timeval); ----------- -- Errno -- diff --git a/gcc/ada/s-osinte-android.ads b/gcc/ada/s-osinte-android.ads index 2b94f3f05a1..310c598d77e 100644 --- a/gcc/ada/s-osinte-android.ads +++ b/gcc/ada/s-osinte-android.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1995-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -75,7 +75,7 @@ package System.OS_Interface is -- Signals -- ------------- - Max_Interrupt : constant := 63; + Max_Interrupt : constant := 31; type Signal is new int range 0 .. Max_Interrupt; for Signal'Size use int'Size; @@ -114,9 +114,6 @@ package System.OS_Interface is SIGXFSZ : constant := System.Linux.SIGXFSZ; SIGUNUSED : constant := System.Linux.SIGUNUSED; SIGSTKFLT : constant := System.Linux.SIGSTKFLT; - SIGLTHRRES : constant := System.Linux.SIGLTHRRES; - SIGLTHRCAN : constant := System.Linux.SIGLTHRCAN; - SIGLTHRDBG : constant := System.Linux.SIGLTHRDBG; SIGADAABORT : constant := SIGABRT; -- Change this to use another signal for task abort. SIGTERM might be a @@ -138,13 +135,9 @@ package System.OS_Interface is SIGPROF, -- To avoid confusing the profiler - SIGKILL, SIGSTOP, + SIGKILL, SIGSTOP); -- These two signals actually can't be masked (POSIX won't allow it) - SIGLTHRRES, SIGLTHRCAN, SIGLTHRDBG); - -- These three signals are used by GNU/LinuxThreads starting from glibc - -- 2.1 (future 2.2). - Reserved : constant Signal_Set := (SIGVTALRM, SIGUNUSED); -- Not clear why these two signals are reserved. Perhaps they are not -- supported by this version of GNU/Linux ??? @@ -187,6 +180,8 @@ package System.OS_Interface is SA_SIGINFO : constant := System.Linux.SA_SIGINFO; SA_ONSTACK : constant := System.Linux.SA_ONSTACK; + SA_NODEFER : constant := System.Linux.SA_NODEFER; + SA_RESTART : constant := System.Linux.SA_RESTART; SIG_BLOCK : constant := 0; SIG_UNBLOCK : constant := 1; @@ -580,17 +575,16 @@ package System.OS_Interface is private - type sigset_t is - -- array (0 .. OS_Constants.SIZEOF_sigset - 1) of unsigned_char; - array (1 .. 127) of unsigned_char; + type sigset_t is new Interfaces.C.unsigned_long; pragma Convention (C, sigset_t); for sigset_t'Alignment use Interfaces.C.unsigned_long'Alignment; pragma Warnings (Off); for struct_sigaction use record sa_handler at Linux.sa_handler_pos range 0 .. Standard'Address_Size - 1; - sa_mask at Linux.sa_mask_pos range 0 .. 1023; - sa_flags at Linux.sa_flags_pos range 0 .. Standard'Address_Size - 1; + sa_mask at Linux.sa_mask_pos range 0 .. sigset_t'Size - 1; + sa_flags at Linux.sa_flags_pos + range 0 .. Interfaces.C.unsigned_long'Size - 1; end record; -- We intentionally leave sa_restorer unspecified and let the compiler -- append it after the last field, so disable corresponding warning. diff --git a/gcc/ada/s-osinte-hpux.ads b/gcc/ada/s-osinte-hpux.ads index 396844c68a3..6beb0501899 100644 --- a/gcc/ada/s-osinte-hpux.ads +++ b/gcc/ada/s-osinte-hpux.ads @@ -7,7 +7,7 @@ -- S p e c -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -522,7 +522,7 @@ private type timespec is record tv_sec : time_t; - tv_nsec : time_t; + tv_nsec : long; end record; pragma Convention (C, timespec); diff --git a/gcc/ada/s-osinte-kfreebsd-gnu.ads b/gcc/ada/s-osinte-kfreebsd-gnu.ads index f57fe9fea07..be46c2e531e 100644 --- a/gcc/ada/s-osinte-kfreebsd-gnu.ads +++ b/gcc/ada/s-osinte-kfreebsd-gnu.ads @@ -7,7 +7,7 @@ -- S p e c -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -492,7 +492,7 @@ private type timespec is record tv_sec : time_t; - tv_nsec : time_t; + tv_nsec : long; end record; pragma Convention (C, timespec); diff --git a/gcc/ada/s-osinte-linux.ads b/gcc/ada/s-osinte-linux.ads index 3f8df80c072..15a351ac1c0 100644 --- a/gcc/ada/s-osinte-linux.ads +++ b/gcc/ada/s-osinte-linux.ads @@ -7,7 +7,7 @@ -- S p e c -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -217,8 +217,9 @@ package System.OS_Interface is -- Time -- ---------- - type timespec is private; - type time_t is private; + subtype time_t is System.Linux.time_t; + subtype timespec is System.Linux.timespec; + subtype timeval is System.Linux.timeval; function To_Duration (TS : timespec) return Duration; pragma Inline (To_Duration); @@ -598,14 +599,6 @@ private type pid_t is new int; - type time_t is new System.Linux.time_t; - - type timespec is record - tv_sec : time_t; - tv_nsec : time_t; - end record; - pragma Convention (C, timespec); - type unsigned_long_long_t is mod 2 ** 64; -- Local type only used to get the alignment of this type below diff --git a/gcc/ada/s-osinte-posix.adb b/gcc/ada/s-osinte-posix.adb index 402ddcb6190..6bcc7223564 100644 --- a/gcc/ada/s-osinte-posix.adb +++ b/gcc/ada/s-osinte-posix.adb @@ -7,7 +7,7 @@ -- B o d y -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2010, AdaCore -- +-- Copyright (C) 1995-2014, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -30,8 +30,7 @@ -- -- ------------------------------------------------------------------------------ --- This is a GNU/LinuxThreads, Solaris pthread and HP-UX pthread version --- of this package. +-- This version is for POSIX-like operating systems pragma Polling (Off); -- Turn off polling, we do not want ATC polling to take place during @@ -104,7 +103,7 @@ package body System.OS_Interface is end if; return timespec'(tv_sec => S, - tv_nsec => time_t (Long_Long_Integer (F * 10#1#E9))); + tv_nsec => long (Long_Long_Integer (F * 10#1#E9))); end To_Timespec; end System.OS_Interface; diff --git a/gcc/ada/s-osinte-solaris-posix.ads b/gcc/ada/s-osinte-solaris-posix.ads index 7aa20f11598..0859b8d7b82 100644 --- a/gcc/ada/s-osinte-solaris-posix.ads +++ b/gcc/ada/s-osinte-solaris-posix.ads @@ -7,7 +7,7 @@ -- S p e c -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2013, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2014, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -513,7 +513,7 @@ private type timespec is record tv_sec : time_t; - tv_nsec : time_t; + tv_nsec : long; end record; pragma Convention (C, timespec); diff --git a/gcc/ada/s-osinte-x32.adb b/gcc/ada/s-osinte-x32.adb new file mode 100644 index 00000000000..467970b963d --- /dev/null +++ b/gcc/ada/s-osinte-x32.adb @@ -0,0 +1,110 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- +-- -- +-- S Y S T E M . O S _ I N T E R F A C E -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 1991-1994, Florida State University -- +-- Copyright (C) 1995-2014, AdaCore -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- <http://www.gnu.org/licenses/>. -- +-- -- +-- GNARL was developed by the GNARL team at Florida State University. -- +-- Extensive contributions were provided by Ada Core Technologies, Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This version is for Linux/x32 + +pragma Polling (Off); +-- Turn off polling, we do not want ATC polling to take place during +-- tasking operations. It causes infinite loops and other problems. + +-- This package encapsulates all direct interfaces to OS services +-- that are needed by children of System. + +with Interfaces.C; use Interfaces.C; +package body System.OS_Interface is + + -------------------- + -- Get_Stack_Base -- + -------------------- + + function Get_Stack_Base (thread : pthread_t) return Address is + pragma Warnings (Off, thread); + + begin + return Null_Address; + end Get_Stack_Base; + + ------------------ + -- pthread_init -- + ------------------ + + procedure pthread_init is + begin + null; + end pthread_init; + + ----------------- + -- To_Duration -- + ----------------- + + function To_Duration (TS : timespec) return Duration is + begin + return Duration (TS.tv_sec) + Duration (TS.tv_nsec) / 10#1#E9; + end To_Duration; + + ------------------------ + -- To_Target_Priority -- + ------------------------ + + function To_Target_Priority + (Prio : System.Any_Priority) return Interfaces.C.int + is + begin + return Interfaces.C.int (Prio); + end To_Target_Priority; + + ----------------- + -- To_Timespec -- + ----------------- + + function To_Timespec (D : Duration) return timespec is + S : time_t; + F : Duration; + + use type System.Linux.time_t; + begin + S := time_t (Long_Long_Integer (D)); + F := D - Duration (S); + + -- If F has negative value due to a round-up, adjust for positive F + -- value. + + if F < 0.0 then + S := S - 1; + F := F + 1.0; + end if; + + return timespec'(tv_sec => S, + tv_nsec => Long_Long_Integer (F * 10#1#E9)); + end To_Timespec; + +end System.OS_Interface; diff --git a/gcc/ada/s-osprim-x32.adb b/gcc/ada/s-osprim-x32.adb index 5d4964a2776..e0c020c78f9 100644 --- a/gcc/ada/s-osprim-x32.adb +++ b/gcc/ada/s-osprim-x32.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2013, Free Software Foundation, Inc. -- +-- Copyright (C) 2013-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -42,7 +42,7 @@ package body System.OS_Primitives is type timespec is record tv_sec : time_t; - tv_nsec : time_t; + tv_nsec : Long_Long_Integer; end record; pragma Convention (C, timespec); @@ -54,7 +54,7 @@ package body System.OS_Primitives is ----------- function Clock return Duration is - type timeval is array (1 .. 2) of time_t; + type timeval is array (1 .. 2) of Long_Long_Integer; procedure timeval_to_duration (T : not null access timeval; @@ -118,7 +118,7 @@ package body System.OS_Primitives is return timespec'(tv_sec => S, - tv_nsec => time_t (Long_Long_Integer (F * 10#1#E9))); + tv_nsec => Long_Long_Integer (F * 10#1#E9)); end To_Timespec; ----------------- diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb index 515850a6838..5aa384ba126 100644 --- a/gcc/ada/s-taprop-linux.adb +++ b/gcc/ada/s-taprop-linux.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1992-2012, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-2014, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -627,8 +627,6 @@ package body System.Task_Primitives.Operations is function Monotonic_Clock return Duration is use Interfaces; - type timeval is array (1 .. 2) of System.OS_Interface.time_t; - procedure timeval_to_duration (T : not null access timeval; sec : not null access C.long; diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index b3590040109..42f080de4da 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -16560,7 +16560,8 @@ package body Sem_Prag is -- pragma Loop_Optimize ( OPTIMIZATION_HINT {, OPTIMIZATION_HINT } ); - -- OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector + -- OPTIMIZATION_HINT ::= + -- Ivdep | No_Unroll | Unroll | No_Vector | Vector when Pragma_Loop_Optimize => Loop_Optimize : declare Hint : Node_Id; @@ -16572,7 +16573,7 @@ package body Sem_Prag is Hint := First (Pragma_Argument_Associations (N)); while Present (Hint) loop - Check_Arg_Is_One_Of (Hint, + Check_Arg_Is_One_Of (Hint, Name_Ivdep, Name_No_Unroll, Name_Unroll, Name_No_Vector, Name_Vector); Next (Hint); end loop; diff --git a/gcc/ada/sigtramp-armdroid.c b/gcc/ada/sigtramp-armdroid.c new file mode 100644 index 00000000000..fb522dfcd99 --- /dev/null +++ b/gcc/ada/sigtramp-armdroid.c @@ -0,0 +1,161 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * S I G T R A M P * + * * + * Asm Implementation File * + * * + * Copyright (C) 2014, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 3, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. * + * * + * As a special exception under Section 7 of GPL version 3, you are granted * + * additional permissions described in the GCC Runtime Library Exception, * + * version 3.1, as published by the Free Software Foundation. * + * * + * In particular, you can freely distribute your programs built with the * + * GNAT Pro compiler, including any required library run-time units, using * + * any licensing terms of your choosing. See the AdaCore Software License * + * for full details. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * Extensive contributions were provided by Ada Core Technologies Inc. * + * * + ****************************************************************************/ + +/****************************************************** + * ARM-Android version of the __gnat_sigtramp service * + ******************************************************/ + +#include "sigtramp.h" +/* See sigtramp.h for a general explanation of functionality. */ + +/* ---------------------- + -- General comments -- + ---------------------- + + Stubs are generated from toplevel asms, + The general idea is to establish CFA as the sigcontext + and state where to find the registers as offsets from there. + + We support stubs for VxWorks and Android, providing unwind info for + common registers. We might need variants with support for floating + point or altivec registers as well at some point. + + For Android it would be simpler to write this in Asm since there's only + one variant, but to keep it looking like the VxWorks stubs, + C is the choice for our toplevel interface. + + Note that the registers we "restore" here are those to which we have + direct access through the system sigcontext structure, which includes + only a partial set of the non-volatiles ABI-wise. */ + +/* ----------------------------------------- + -- Protypes for our internal asm stubs -- + ----------------------------------------- + + The registers are expected to be at SIGCONTEXT + 12 (reference the + sicontext structure in asm/sigcontext.h which describes the first + 3 * 4byte fields.) Even though our symbols will remain local, the + prototype claims "extern" and not "static" to prevent compiler complaints + about a symbol used but never defined. */ + +/* sigtramp stub providing unwind info for common registers. */ + +extern void __gnat_sigtramp_common + (int signo, void *siginfo, void *sigcontext, + __sigtramphandler_t * handler); + +void __gnat_sigtramp (int signo, void *si, void *sc, + __sigtramphandler_t * handler) + __attribute__((optimize(2))); + +void __gnat_sigtramp (int signo, void *si, void *ucontext, + __sigtramphandler_t * handler) +{ + struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext; + + __gnat_sigtramp_common (signo, si, mcontext, handler); +} + +/* asm string construction helpers. */ + +#define STR(TEXT) #TEXT +/* stringify expanded TEXT, surrounding it with double quotes. */ + +#define S(E) STR(E) +/* stringify E, which will resolve as text but may contain macros + still to be expanded. */ + +/* asm (TEXT) outputs <tab>TEXT. These facilitate the output of + multiline contents: */ +#define TAB(S) "\t" S +#define CR(S) S "\n" + +#undef TCR +#define TCR(S) TAB(CR(S)) + +/* Trampoline body block + --------------------- */ + +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate frame and also save r2 which is the argument register") \ +TCR("# containing the sigcontext, so that we can restore it during") \ +TCR("# unwinding and thereby load the rest of the desired context.") \ +TCR("stmfd sp!, {r2, r3, lr}") \ +TCR("# The unwinder undo's these operations in reverse order so starting") \ +TCR("# from bottom, restore r2 from the current vsp location, move r2 into") \ +TCR("# the vsp, add 12 bytes to get the start of the register save area") \ +TCR("# then restore the 15 general purpose registers of the frame which") \ +TCR("# raised the signal.") \ +TCR(".save {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}") \ +TCR(".pad #12") \ +TCR(".movsp r2") \ +TCR(".save {r2}") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received in r0, r1 and r2.") \ +TCR("blx r3") \ +TCR("# Restore our callee-saved items, release our frame and return") \ +TCR("# (should never get here!).") \ +TCR("ldmfd sp, {r2, r3, pc}") + +/* Symbol definition block + ----------------------- */ + +#define SIGTRAMP_START(SYM) \ +CR("# " S(SYM) " unwind trampoline") \ +TCR(".type " S(SYM) ", %function") \ +CR("") \ +CR(S(SYM) ":") \ +TCR(".fnstart") + +/* Symbol termination block + ------------------------ */ + +#define SIGTRAMP_END(SYM) \ +CR(".fnend") \ +TCR(".size " S(SYM) ", .-" S(SYM)) + +/*---------------------------- + -- And now, the real code -- + ---------------------------- */ + +/* Text section start. The compiler isn't aware of that switch. */ + +asm (".text\n" + TCR(".align 2")); + +/* sigtramp stub for common registers. */ + +#define TRAMP_COMMON __gnat_sigtramp_common + +asm (SIGTRAMP_START(TRAMP_COMMON)); +asm (SIGTRAMP_BODY); +asm (SIGTRAMP_END(TRAMP_COMMON)); diff --git a/gcc/ada/sigtramp.h b/gcc/ada/sigtramp.h index cf5f4707ee3..7419e172510 100644 --- a/gcc/ada/sigtramp.h +++ b/gcc/ada/sigtramp.h @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 2011-2013, Free Software Foundation, Inc. * + * Copyright (C) 2011-2014, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -41,10 +41,29 @@ extern "C" { #endif - typedef void sighandler_t (int signo, void *siginfo, void *sigcontext); +#ifdef __ANDROID__ +#include <stdlib.h> +#include <asm/signal.h> +#include <asm/sigcontext.h> + +/* Android SDK doesn't define these structs */ +typedef struct sigcontext mcontext_t; + +typedef struct ucontext + { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; +} ucontext_t; +#endif + + /* This typedef signature sometimes conflicts with the sighandler_t from + system headers so call it something unique. */ + typedef void __sigtramphandler_t (int signo, void *siginfo, void *sigcontext); void __gnat_sigtramp (int signo, void *siginfo, void *sigcontext, - sighandler_t * handler); + __sigtramphandler_t * handler); /* To be called from an established signal handler. Setup the DWARF CFI bits letting unwinders walk through the signal frame up into the diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl index c8831b3f212..b4fcb54ccb2 100644 --- a/gcc/ada/snames.ads-tmpl +++ b/gcc/ada/snames.ads-tmpl @@ -730,6 +730,7 @@ package Snames is Name_Increases : constant Name_Id := N + $; Name_Info : constant Name_Id := N + $; Name_Internal : constant Name_Id := N + $; + Name_Ivdep : constant Name_Id := N + $; Name_Link_Name : constant Name_Id := N + $; Name_Lowercase : constant Name_Id := N + $; Name_Max_Entry_Queue_Depth : constant Name_Id := N + $; diff --git a/gcc/ada/types.h b/gcc/ada/types.h index 7d1e69624c5..dd049db908a 100644 --- a/gcc/ada/types.h +++ b/gcc/ada/types.h @@ -272,6 +272,8 @@ SUBTYPE (Uint_Direct, Uint, Uint_Direct_First, Uint_Direct_Last) #define Uint_10 (Uint_Direct_Bias + 10) #define Uint_16 (Uint_Direct_Bias + 16) +#define Uint_Minus_1 (Uint_Direct_Bias - 1) + /* Types for Ureal_Support Package: */ /* Type used for representation of universal reals. */ diff --git a/gcc/alias.c b/gcc/alias.c index daa9e837090..5f50fc245c9 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -157,7 +157,6 @@ static rtx find_base_value (rtx); static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx); static int insert_subset_children (splay_tree_node, void*); static alias_set_entry get_alias_set_entry (alias_set_type); -static bool nonoverlapping_component_refs_p (const_rtx, const_rtx); static tree decl_for_component_ref (tree); static int write_dependence_p (const_rtx, const_rtx, enum machine_mode, rtx, @@ -996,17 +995,6 @@ record_component_aliases (tree type) case RECORD_TYPE: case UNION_TYPE: case QUAL_UNION_TYPE: - /* Recursively record aliases for the base classes, if there are any. */ - if (TYPE_BINFO (type)) - { - int i; - tree binfo, base_binfo; - - for (binfo = TYPE_BINFO (type), i = 0; - BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - record_alias_subset (superset, - get_alias_set (BINFO_TYPE (base_binfo))); - } for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) record_alias_subset (superset, get_alias_set (TREE_TYPE (field))); @@ -2258,68 +2246,6 @@ read_dependence (const_rtx mem, const_rtx x) return false; } -/* Return true if we can determine that the fields referenced cannot - overlap for any pair of objects. */ - -static bool -nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly) -{ - const_tree x = MEM_EXPR (rtlx), y = MEM_EXPR (rtly); - const_tree fieldx, fieldy, typex, typey, orig_y; - - if (!flag_strict_aliasing - || !x || !y - || TREE_CODE (x) != COMPONENT_REF - || TREE_CODE (y) != COMPONENT_REF) - return false; - - do - { - /* The comparison has to be done at a common type, since we don't - know how the inheritance hierarchy works. */ - orig_y = y; - do - { - fieldx = TREE_OPERAND (x, 1); - typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx)); - - y = orig_y; - do - { - fieldy = TREE_OPERAND (y, 1); - typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy)); - - if (typex == typey) - goto found; - - y = TREE_OPERAND (y, 0); - } - while (y && TREE_CODE (y) == COMPONENT_REF); - - x = TREE_OPERAND (x, 0); - } - while (x && TREE_CODE (x) == COMPONENT_REF); - /* Never found a common type. */ - return false; - - found: - /* If we're left with accessing different fields of a structure, then no - possible overlap, unless they are both bitfields. */ - if (TREE_CODE (typex) == RECORD_TYPE && fieldx != fieldy) - return !(DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)); - - /* The comparison on the current field failed. If we're accessing - a very nested structure, look at the next outer level. */ - x = TREE_OPERAND (x, 0); - y = TREE_OPERAND (y, 0); - } - while (x && y - && TREE_CODE (x) == COMPONENT_REF - && TREE_CODE (y) == COMPONENT_REF); - - return false; -} - /* Look at the bottom of the COMPONENT_REF list for a DECL, and return it. */ static tree @@ -2602,9 +2528,6 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr, if (nonoverlapping_memrefs_p (mem, x, false)) return 0; - if (nonoverlapping_component_refs_p (mem, x)) - return 0; - return rtx_refs_may_alias_p (x, mem, true); } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c83bf5497da..206b47b1369 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,38 @@ +2014-04-14 Richard Biener <rguenther@suse.de> + Marc Glisse <marc.glisse@inria.fr> + + PR c/60819 + * c-common.c (convert_vector_to_pointer_for_subscript): Properly + apply may-alias the scalar pointer type when applicable. + +2014-04-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/60467 + * cilk.c (cilk_set_spawn_marker): Remove FUNCTION_DECL + as possible argument for Cilk_spawn. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR c/60194 + * c.opt (Wformat-signedness): Add + * c-format.c(check_format_types): Use it. + +2014-04-11 Jason Merrill <jason@redhat.com> + + PR c++/57926 + * c-common.c (sync_resolve_size, get_atomic_generic_size): Call + default_conversion for an array argument. + +2014-04-08 Marek Polacek <polacek@redhat.com> + + PR sanitizer/60745 + * c-ubsan.c: Include asan.h. + (ubsan_instrument_return): Call initialize_sanitizer_builtins. + +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * c.opt (Wnon-virtual-dtor): Auto set when Weffc++. + 2014-04-02 Marek Polacek <polacek@redhat.com> * c-common.h (c_expand_expr): Remove declaration. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 48561828532..34273fbcb10 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -10188,6 +10188,13 @@ sync_resolve_size (tree function, vec<tree, va_gc> *params) } type = TREE_TYPE ((*params)[0]); + if (TREE_CODE (type) == ARRAY_TYPE) + { + /* Force array-to-pointer decay for C++. */ + gcc_assert (c_dialect_cxx()); + (*params)[0] = default_conversion ((*params)[0]); + type = TREE_TYPE ((*params)[0]); + } if (TREE_CODE (type) != POINTER_TYPE) goto incompatible; @@ -10339,6 +10346,13 @@ get_atomic_generic_size (location_t loc, tree function, /* Get type of first parameter, and determine its size. */ type_0 = TREE_TYPE ((*params)[0]); + if (TREE_CODE (type_0) == ARRAY_TYPE) + { + /* Force array-to-pointer decay for C++. */ + gcc_assert (c_dialect_cxx()); + (*params)[0] = default_conversion ((*params)[0]); + type_0 = TREE_TYPE ((*params)[0]); + } if (TREE_CODE (type_0) != POINTER_TYPE || VOID_TYPE_P (TREE_TYPE (type_0))) { error_at (loc, "argument 1 of %qE must be a non-void pointer type", @@ -11756,8 +11770,21 @@ convert_vector_to_pointer_for_subscript (location_t loc, c_common_mark_addressable_vec (*vecp); type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type)); - type = build_pointer_type (type); type1 = build_pointer_type (TREE_TYPE (*vecp)); + bool ref_all = TYPE_REF_CAN_ALIAS_ALL (type1); + if (!ref_all + && !DECL_P (*vecp)) + { + /* If the original vector isn't declared may_alias and it + isn't a bare vector look if the subscripting would + alias the vector we subscript, and if not, force ref-all. */ + alias_set_type vecset = get_alias_set (*vecp); + alias_set_type sset = get_alias_set (type); + if (!alias_sets_must_conflict_p (sset, vecset) + && !alias_set_subset_of (sset, vecset)) + ref_all = true; + } + type = build_pointer_type_for_mode (type, ptr_mode, ref_all); *vecp = build1 (ADDR_EXPR, type1, *vecp); *vecp = convert (type, *vecp); } diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index cea1c67f71f..eeefce883d4 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -2418,7 +2418,9 @@ check_format_types (format_wanted_type *types) a second level of indirection. */ if (TREE_CODE (wanted_type) == INTEGER_TYPE && TREE_CODE (cur_type) == INTEGER_TYPE - && (!pedantic || i == 0 || (i == 1 && char_type_flag)) + && ((!pedantic && !warn_format_signedness) + || (i == 0 && !warn_format_signedness) + || (i == 1 && char_type_flag)) && (TYPE_UNSIGNED (wanted_type) ? wanted_type == c_common_unsigned_type (cur_type) : wanted_type == c_common_signed_type (cur_type))) diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index dc4d98147b3..e89ebc1873b 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "ubsan.h" #include "c-family/c-common.h" #include "c-family/c-ubsan.h" +#include "asan.h" /* Instrument division by zero and INT_MIN / -1. If not instrumenting, return NULL_TREE. */ @@ -185,6 +186,10 @@ ubsan_instrument_vla (location_t loc, tree size) tree ubsan_instrument_return (location_t loc) { + /* It is possible that PCH zapped table with definitions of sanitizer + builtins. Reinitialize them if needed. */ + initialize_sanitizer_builtins (); + tree data = ubsan_create_data ("__ubsan_missing_return_data", &loc, NULL, NULL_TREE); tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_MISSING_RETURN); diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 7d0a2cd4ac6..390c056becc 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -415,6 +415,10 @@ Wformat-security C ObjC C++ ObjC++ Var(warn_format_security) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) Warn about possible security problems with format functions +Wformat-signedness +C ObjC C++ ObjC++ Var(warn_format_signedness) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) +Warn about sign differences with format functions + Wformat-y2k C ObjC C++ ObjC++ Var(warn_format_y2k) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 2, 0) Warn about strftime formats yielding 2-digit years @@ -569,7 +573,7 @@ C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning Warn when non-templatized friend functions are declared within a template Wnon-virtual-dtor -C++ ObjC++ Var(warn_nonvdtor) Warning +C++ ObjC++ Var(warn_nonvdtor) Warning LangEnabledBy(C++ ObjC++,Weffc++) Warn about non-virtual destructors Wnonnull diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c index dfaa84d76ef..a952902533a 100644 --- a/gcc/c-family/cilk.c +++ b/gcc/c-family/cilk.c @@ -99,7 +99,6 @@ cilk_set_spawn_marker (location_t loc, tree fcall) it. */ return false; else if (TREE_CODE (fcall) != CALL_EXPR - && TREE_CODE (fcall) != FUNCTION_DECL /* In C++, TARGET_EXPR is generated when we have an overloaded '=' operator. */ && TREE_CODE (fcall) != TARGET_EXPR) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 6b819e9964d..bacfbe36702 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,13 @@ +2014-04-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/60469 + * c-array-notation.c (fix_builtin_array_notation_fn): Use + create_tmp_var instead build_decl for creating temps. + (build_array_notation_expr): Likewise. + (fix_conditional_array_notations_1): Likewise. + (fix_array_notation_expr): Likewise. + (fix_array_notation_call_expr): Likewise. + 2014-03-28 Jakub Jelinek <jakub@redhat.com> PR c++/60689 diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c index 6a5631c3b6f..0ac6ba8e119 100644 --- a/gcc/c/c-array-notation.c +++ b/gcc/c/c-array-notation.c @@ -70,6 +70,7 @@ #include "coretypes.h" #include "tree.h" #include "c-tree.h" +#include "gimple-expr.h" #include "tree-iterator.h" #include "opts.h" #include "c-family/c-common.h" @@ -282,8 +283,7 @@ fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var) for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + an_loop_info[ii].var = create_tmp_var (integer_type_node, NULL); an_loop_info[ii].ind_init = build_modify_expr (location, an_loop_info[ii].var, TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, @@ -781,8 +781,8 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, for (ii = 0; ii < lhs_rank; ii++) if (lhs_an_info[0][ii].is_vector) { - lhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + lhs_an_loop_info[ii].var = create_tmp_var (integer_type_node, + NULL); lhs_an_loop_info[ii].ind_init = build_modify_expr (location, lhs_an_loop_info[ii].var, TREE_TYPE (lhs_an_loop_info[ii].var), NOP_EXPR, @@ -793,8 +793,8 @@ build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype, { /* When we have a polynomial, we assume that the indices are of type integer. */ - rhs_an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + rhs_an_loop_info[ii].var = create_tmp_var (integer_type_node, + NULL); rhs_an_loop_info[ii].ind_init = build_modify_expr (location, rhs_an_loop_info[ii].var, TREE_TYPE (rhs_an_loop_info[ii].var), NOP_EXPR, @@ -970,8 +970,7 @@ fix_conditional_array_notations_1 (tree stmt) cilkplus_extract_an_triplets (array_list, list_size, rank, &an_info); for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + an_loop_info[ii].var = create_tmp_var (integer_type_node, NULL); an_loop_info[ii].ind_init = build_modify_expr (location, an_loop_info[ii].var, TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, @@ -1067,8 +1066,7 @@ fix_array_notation_expr (location_t location, enum tree_code code, loop_init = push_stmt_list (); for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + an_loop_info[ii].var = create_tmp_var (integer_type_node, NULL); an_loop_info[ii].ind_init = build_modify_expr (location, an_loop_info[ii].var, TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, @@ -1163,8 +1161,7 @@ fix_array_notation_call_expr (tree arg) } for (ii = 0; ii < rank; ii++) { - an_loop_info[ii].var = build_decl (location, VAR_DECL, NULL_TREE, - integer_type_node); + an_loop_info[ii].var = create_tmp_var (integer_type_node, NULL); an_loop_info[ii].ind_init = build_modify_expr (location, an_loop_info[ii].var, TREE_TYPE (an_loop_info[ii].var), NOP_EXPR, location, diff --git a/gcc/cfg.c b/gcc/cfg.c index a281c0fb823..3b6349aec49 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -743,11 +743,10 @@ dump_bb_info (FILE *outf, basic_block bb, int indent, int flags, fputs (", probably never executed", outf); } fputc ('\n', outf); - if (TDF_DETAILS) - check_bb_profile (bb, outf, indent, flags); if (flags & TDF_DETAILS) { + check_bb_profile (bb, outf, indent, flags); if (flags & TDF_COMMENT) fputs (";; ", outf); fprintf (outf, "%s prev block ", s_indent); diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 608ddd95e06..ab8b8090e98 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -174,12 +174,12 @@ struct GTY ((chain_next ("%h.next"))) loop { of the loop can be safely evaluated concurrently. */ int safelen; - /* True if we should try harder to vectorize this loop. */ - bool force_vect; - /* True if this loop should never be vectorized. */ bool dont_vectorize; + /* True if we should try harder to vectorize this loop. */ + bool force_vectorize; + /* For SIMD loops, this is a unique identifier of the loop, referenced by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE builtins. */ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index a3dd5ec146a..8e593bca611 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1478,13 +1478,14 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) { if (TREE_CODE (lhs) == SSA_NAME) { + tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl), + TREE_TYPE (lhs), NULL); + var = get_or_create_ssa_default_def + (DECL_STRUCT_FUNCTION (e->caller->decl), var); + gimple set_stmt = gimple_build_assign (lhs, var); gsi = gsi_for_stmt (new_stmt); - - tree var = create_tmp_var (TREE_TYPE (lhs), NULL); - tree def = get_or_create_ssa_default_def - (DECL_STRUCT_FUNCTION (e->caller->decl), var); - gimple set_stmt = gimple_build_assign (lhs, def); - gsi_insert_before (&gsi, set_stmt, GSI_SAME_STMT); + gsi_insert_before_without_update (&gsi, set_stmt, GSI_SAME_STMT); + update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), set_stmt); } gimple_call_set_lhs (new_stmt, NULL_TREE); update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt); @@ -2542,12 +2543,34 @@ collect_callers_of_node (struct cgraph_node *node) return redirect_callers; } -/* Return TRUE if NODE2 is equivalent to NODE or its clone. */ +/* Return TRUE if NODE2 a clone of NODE or is equivalent to it. */ + static bool clone_of_p (struct cgraph_node *node, struct cgraph_node *node2) { + bool skipped_thunk = false; node = cgraph_function_or_thunk_node (node, NULL); node2 = cgraph_function_or_thunk_node (node2, NULL); + + /* There are no virtual clones of thunks so check former_clone_of or if we + might have skipped thunks because this adjustments are no longer + necessary. */ + while (node->thunk.thunk_p) + { + if (node2->former_clone_of == node->decl) + return true; + if (!node->thunk.this_adjusting) + return false; + node = cgraph_function_or_thunk_node (node->callees->callee, NULL); + skipped_thunk = true; + } + + if (skipped_thunk + && (!node2->clone_of + || !node2->clone.args_to_skip + || !bitmap_bit_p (node2->clone.args_to_skip, 0))) + return false; + while (node != node2 && node2) node2 = node2->clone_of; return node2 != NULL; @@ -2647,10 +2670,8 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl) node = cgraph_function_or_thunk_node (node, NULL); if (e->callee->former_clone_of != node->decl - /* IPA-CP sometimes redirect edge to clone and then back to the former - function. This ping-pong has to go, eventually. */ && (node != cgraph_function_or_thunk_node (e->callee, NULL)) - && !clone_of_p (cgraph_function_or_thunk_node (node, NULL), e->callee)) + && !clone_of_p (node, e->callee)) return true; else return false; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 59d9ce66845..15310d88861 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -890,7 +890,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *, unsigned, gcov_type, int, bool); struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, int, bool, vec<cgraph_edge_p>, - bool, struct cgraph_node *); + bool, struct cgraph_node *, bitmap); tree clone_function_name (tree decl, const char *); struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node, vec<cgraph_edge_p>, diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index b2eb8ab5ce9..cd2d73d1c94 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -168,6 +168,212 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, return new_edge; } +/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the + return value if SKIP_RETURN is true. */ + +static tree +build_function_type_skip_args (tree orig_type, bitmap args_to_skip, + bool skip_return) +{ + tree new_type = NULL; + tree args, new_args = NULL, t; + tree new_reversed; + int i = 0; + + for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node; + args = TREE_CHAIN (args), i++) + if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) + new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args); + + new_reversed = nreverse (new_args); + if (args) + { + if (new_reversed) + TREE_CHAIN (new_args) = void_list_node; + else + new_reversed = void_list_node; + } + + /* Use copy_node to preserve as much as possible from original type + (debug info, attribute lists etc.) + Exception is METHOD_TYPEs must have THIS argument. + When we are asked to remove it, we need to build new FUNCTION_TYPE + instead. */ + if (TREE_CODE (orig_type) != METHOD_TYPE + || !args_to_skip + || !bitmap_bit_p (args_to_skip, 0)) + { + new_type = build_distinct_type_copy (orig_type); + TYPE_ARG_TYPES (new_type) = new_reversed; + } + else + { + new_type + = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type), + new_reversed)); + TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type); + } + + if (skip_return) + TREE_TYPE (new_type) = void_type_node; + + /* This is a new type, not a copy of an old type. Need to reassociate + variants. We can handle everything except the main variant lazily. */ + t = TYPE_MAIN_VARIANT (orig_type); + if (t != orig_type) + { + t = build_function_type_skip_args (t, args_to_skip, skip_return); + TYPE_MAIN_VARIANT (new_type) = t; + TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t); + TYPE_NEXT_VARIANT (t) = new_type; + } + else + { + TYPE_MAIN_VARIANT (new_type) = new_type; + TYPE_NEXT_VARIANT (new_type) = NULL; + } + + return new_type; +} + +/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the + return value if SKIP_RETURN is true. + + Arguments from DECL_ARGUMENTS list can't be removed now, since they are + linked by TREE_CHAIN directly. The caller is responsible for eliminating + them when they are being duplicated (i.e. copy_arguments_for_versioning). */ + +static tree +build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip, + bool skip_return) +{ + tree new_decl = copy_node (orig_decl); + tree new_type; + + new_type = TREE_TYPE (orig_decl); + if (prototype_p (new_type) + || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type)))) + new_type + = build_function_type_skip_args (new_type, args_to_skip, skip_return); + TREE_TYPE (new_decl) = new_type; + + /* For declarations setting DECL_VINDEX (i.e. methods) + we expect first argument to be THIS pointer. */ + if (args_to_skip && bitmap_bit_p (args_to_skip, 0)) + DECL_VINDEX (new_decl) = NULL_TREE; + + /* When signature changes, we need to clear builtin info. */ + if (DECL_BUILT_IN (new_decl) + && args_to_skip + && !bitmap_empty_p (args_to_skip)) + { + DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN; + DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0; + } + /* The FE might have information and assumptions about the other + arguments. */ + DECL_LANG_SPECIFIC (new_decl) = NULL; + return new_decl; +} + +/* Set flags of NEW_NODE and its decl. NEW_NODE is a newly created private + clone or its thunk. */ + +static void +set_new_clone_decl_and_node_flags (cgraph_node *new_node) +{ + DECL_EXTERNAL (new_node->decl) = 0; + DECL_COMDAT_GROUP (new_node->decl) = 0; + TREE_PUBLIC (new_node->decl) = 0; + DECL_COMDAT (new_node->decl) = 0; + DECL_WEAK (new_node->decl) = 0; + DECL_VIRTUAL_P (new_node->decl) = 0; + DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0; + DECL_STATIC_DESTRUCTOR (new_node->decl) = 0; + + new_node->externally_visible = 0; + new_node->local.local = 1; + new_node->lowered = true; +} + +/* Duplicate thunk THUNK if necessary but make it to refer to NODE. + ARGS_TO_SKIP, if non-NULL, determines which parameters should be omitted. + Function can return NODE if no thunk is necessary, which can happen when + thunk is this_adjusting but we are removing this parameter. */ + +static cgraph_node * +duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, + bitmap args_to_skip) +{ + cgraph_node *new_thunk, *thunk_of; + thunk_of = cgraph_function_or_thunk_node (thunk->callees->callee); + + if (thunk_of->thunk.thunk_p) + node = duplicate_thunk_for_node (thunk_of, node, args_to_skip); + + struct cgraph_edge *cs; + for (cs = node->callers; cs; cs = cs->next_caller) + if (cs->caller->thunk.thunk_p + && cs->caller->thunk.this_adjusting == thunk->thunk.this_adjusting + && cs->caller->thunk.fixed_offset == thunk->thunk.fixed_offset + && cs->caller->thunk.virtual_offset_p == thunk->thunk.virtual_offset_p + && cs->caller->thunk.virtual_value == thunk->thunk.virtual_value) + return cs->caller; + + tree new_decl; + if (!args_to_skip) + new_decl = copy_node (thunk->decl); + else + { + /* We do not need to duplicate this_adjusting thunks if we have removed + this. */ + if (thunk->thunk.this_adjusting + && bitmap_bit_p (args_to_skip, 0)) + return node; + + new_decl = build_function_decl_skip_args (thunk->decl, args_to_skip, + false); + } + gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl)); + gcc_checking_assert (!DECL_INITIAL (new_decl)); + gcc_checking_assert (!DECL_RESULT (new_decl)); + gcc_checking_assert (!DECL_RTL_SET_P (new_decl)); + + DECL_NAME (new_decl) = clone_function_name (thunk->decl, "artificial_thunk"); + SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); + DECL_SECTION_NAME (new_decl) = NULL; + + new_thunk = cgraph_create_node (new_decl); + set_new_clone_decl_and_node_flags (new_thunk); + new_thunk->definition = true; + new_thunk->thunk = thunk->thunk; + new_thunk->unique_name = in_lto_p; + new_thunk->former_clone_of = thunk->decl; + + struct cgraph_edge *e = cgraph_create_edge (new_thunk, node, NULL, 0, + CGRAPH_FREQ_BASE); + e->call_stmt_cannot_inline_p = true; + cgraph_call_edge_duplication_hooks (thunk->callees, e); + if (!expand_thunk (new_thunk, false)) + new_thunk->analyzed = true; + cgraph_call_node_duplication_hooks (thunk, new_thunk); + return new_thunk; +} + +/* If E does not lead to a thunk, simply redirect it to N. Otherwise create + one or more equivalent thunks for N and redirect E to the first in the + chain. */ + +void +redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n, + bitmap args_to_skip) +{ + cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee); + if (orig_to->thunk.thunk_p) + n = duplicate_thunk_for_node (orig_to, n, args_to_skip); + + cgraph_redirect_edge_callee (e, n); +} /* Create node representing clone of N executed COUNT times. Decrease the execution counts from original node too. @@ -190,7 +396,8 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, bool update_original, vec<cgraph_edge_p> redirect_callers, bool call_duplication_hook, - struct cgraph_node *new_inlined_to) + struct cgraph_node *new_inlined_to, + bitmap args_to_skip) { struct cgraph_node *new_node = cgraph_create_empty_node (); struct cgraph_edge *e; @@ -243,7 +450,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, if (!e->callee || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE) - cgraph_redirect_edge_callee (e, new_node); + redirect_edge_duplicating_thunks (e, new_node, args_to_skip); } @@ -292,114 +499,6 @@ clone_function_name (tree decl, const char *suffix) return get_identifier (tmp_name); } -/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the - return value if SKIP_RETURN is true. */ - -static tree -build_function_type_skip_args (tree orig_type, bitmap args_to_skip, - bool skip_return) -{ - tree new_type = NULL; - tree args, new_args = NULL, t; - tree new_reversed; - int i = 0; - - for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node; - args = TREE_CHAIN (args), i++) - if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) - new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args); - - new_reversed = nreverse (new_args); - if (args) - { - if (new_reversed) - TREE_CHAIN (new_args) = void_list_node; - else - new_reversed = void_list_node; - } - - /* Use copy_node to preserve as much as possible from original type - (debug info, attribute lists etc.) - Exception is METHOD_TYPEs must have THIS argument. - When we are asked to remove it, we need to build new FUNCTION_TYPE - instead. */ - if (TREE_CODE (orig_type) != METHOD_TYPE - || !args_to_skip - || !bitmap_bit_p (args_to_skip, 0)) - { - new_type = build_distinct_type_copy (orig_type); - TYPE_ARG_TYPES (new_type) = new_reversed; - } - else - { - new_type - = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type), - new_reversed)); - TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type); - } - - if (skip_return) - TREE_TYPE (new_type) = void_type_node; - - /* This is a new type, not a copy of an old type. Need to reassociate - variants. We can handle everything except the main variant lazily. */ - t = TYPE_MAIN_VARIANT (orig_type); - if (t != orig_type) - { - t = build_function_type_skip_args (t, args_to_skip, skip_return); - TYPE_MAIN_VARIANT (new_type) = t; - TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t); - TYPE_NEXT_VARIANT (t) = new_type; - } - else - { - TYPE_MAIN_VARIANT (new_type) = new_type; - TYPE_NEXT_VARIANT (new_type) = NULL; - } - - return new_type; -} - -/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the - return value if SKIP_RETURN is true. - - Arguments from DECL_ARGUMENTS list can't be removed now, since they are - linked by TREE_CHAIN directly. The caller is responsible for eliminating - them when they are being duplicated (i.e. copy_arguments_for_versioning). */ - -static tree -build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip, - bool skip_return) -{ - tree new_decl = copy_node (orig_decl); - tree new_type; - - new_type = TREE_TYPE (orig_decl); - if (prototype_p (new_type) - || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type)))) - new_type - = build_function_type_skip_args (new_type, args_to_skip, skip_return); - TREE_TYPE (new_decl) = new_type; - - /* For declarations setting DECL_VINDEX (i.e. methods) - we expect first argument to be THIS pointer. */ - if (args_to_skip && bitmap_bit_p (args_to_skip, 0)) - DECL_VINDEX (new_decl) = NULL_TREE; - - /* When signature changes, we need to clear builtin info. */ - if (DECL_BUILT_IN (new_decl) - && args_to_skip - && !bitmap_empty_p (args_to_skip)) - { - DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN; - DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0; - } - /* The FE might have information and assumptions about the other - arguments. */ - DECL_LANG_SPECIFIC (new_decl) = NULL; - return new_decl; -} - /* Create callgraph node clone with new declaration. The actual body will be copied later at compilation stage. @@ -453,22 +552,15 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, new_node = cgraph_clone_node (old_node, new_decl, old_node->count, CGRAPH_FREQ_BASE, false, - redirect_callers, false, NULL); + redirect_callers, false, NULL, args_to_skip); /* Update the properties. Make clone visible only within this translation unit. Make sure that is not weak also. ??? We cannot use COMDAT linkage because there is no ABI support for this. */ - DECL_EXTERNAL (new_node->decl) = 0; if (DECL_ONE_ONLY (old_decl)) DECL_SECTION_NAME (new_node->decl) = NULL; - DECL_COMDAT_GROUP (new_node->decl) = 0; - TREE_PUBLIC (new_node->decl) = 0; - DECL_COMDAT (new_node->decl) = 0; - DECL_WEAK (new_node->decl) = 0; - DECL_VIRTUAL_P (new_node->decl) = 0; - DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0; - DECL_STATIC_DESTRUCTOR (new_node->decl) = 0; + set_new_clone_decl_and_node_flags (new_node); new_node->clone.tree_map = tree_map; new_node->clone.args_to_skip = args_to_skip; @@ -508,9 +600,9 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, } else new_node->clone.combined_args_to_skip = args_to_skip; - new_node->externally_visible = 0; - new_node->local.local = 1; - new_node->lowered = true; + if (old_node->ipa_transforms_to_apply.exists ()) + new_node->ipa_transforms_to_apply + = old_node->ipa_transforms_to_apply.copy (); cgraph_call_node_duplication_hooks (old_node, new_node); @@ -882,6 +974,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node, cgraph_copy_node_for_versioning (old_version_node, new_decl, redirect_callers, bbs_to_copy); + gcc_assert (!old_version_node->ipa_transforms_to_apply.exists ()); /* Copy the OLD_VERSION_NODE function tree to the new version. */ tree_function_versioning (old_decl, new_decl, tree_map, false, args_to_skip, skip_return, bbs_to_copy, new_entry_block); diff --git a/gcc/common.opt b/gcc/common.opt index 62c72f0d2fb..da275e5cb45 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1267,6 +1267,10 @@ fgnu-tm Common Report Var(flag_tm) Enable support for GNU transactional memory +fgnu-unique +Common Report Var(flag_gnu_unique) Init(1) +Use STB_GNU_UNIQUE if supported by the assembler + floop-flatten Common Ignore Does nothing. Preserved for backward compatibility. @@ -1491,21 +1495,27 @@ flto= Common RejectNegative Joined Var(flag_lto) Link-time optimization with number of parallel jobs or jobserver. -flto-partition=1to1 -Common Var(flag_lto_partition_1to1) -Partition symbols and vars at linktime based on object files they originate from +Enum +Name(lto_partition_model) Type(enum lto_partition_model) UnknownError(unknown LTO partitioning model %qs) + +EnumValue +Enum(lto_partition_model) String(none) Value(LTO_PARTITION_NONE) + +EnumValue +Enum(lto_partition_model) String(one) Value(LTO_PARTITION_ONE) -flto-partition=balanced -Common Var(flag_lto_partition_balanced) -Partition functions and vars at linktime into approximately same sized buckets +EnumValue +Enum(lto_partition_model) String(balanced) Value(LTO_PARTITION_BALANCED) -flto-partition=max -Common Var(flag_lto_partition_max) -Put every symbol into separate partition +EnumValue +Enum(lto_partition_model) String(1to1) Value(LTO_PARTITION_1TO1) + +EnumValue +Enum(lto_partition_model) String(max) Value(LTO_PARTITION_MAX) -flto-partition=none -Common Var(flag_lto_partition_none) -Disable partioning and streaming +flto-partition= +Common Joined RejectNegative Enum(lto_partition_model) Var(flag_lto_partition) Init(LTO_PARTITION_BALANCED) +Specify the algorithm to partition symbols and vars at linktime ; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h. flto-compression-level= diff --git a/gcc/common/config/epiphany/epiphany-common.c b/gcc/common/config/epiphany/epiphany-common.c index 725dfb8356d..23d372ef376 100644 --- a/gcc/common/config/epiphany/epiphany-common.c +++ b/gcc/common/config/epiphany/epiphany-common.c @@ -39,6 +39,8 @@ along with GCC; see the file COPYING3. If not see static const struct default_options epiphany_option_optimization_table[] = { { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Enable section anchors by default at -O1 or higher. */ + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 6c7eae63dd1..2b12844cdb7 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -2134,7 +2134,7 @@ arc_save_restore (rtx base_reg, if (*first_offset) { /* "reg_size" won't be more than 127 . */ - gcc_assert (epilogue_p || abs (*first_offset <= 127)); + gcc_assert (epilogue_p || abs (*first_offset) <= 127); frame_add (base_reg, *first_offset); *first_offset = 0; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5a5290220e9..bb7dc6f0b77 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -72,6 +72,7 @@ struct four_ints }; /* Forward function declarations. */ +static bool arm_const_not_ok_for_debug_p (rtx); static bool arm_lra_p (void); static bool arm_needs_doubleword_align (enum machine_mode, const_tree); static int arm_compute_static_chain_stack_bytes (void); @@ -674,6 +675,9 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_CAN_USE_DOLOOP_P #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost +#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P +#define TARGET_CONST_NOT_OK_FOR_DEBUG_P arm_const_not_ok_for_debug_p + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -10666,10 +10670,16 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, return true; case ASM_OPERANDS: - /* Just a guess. Cost one insn per input. */ - *cost = COSTS_N_INSNS (ASM_OPERANDS_INPUT_LENGTH (x)); - return true; + { + /* Just a guess. Guess number of instructions in the asm + plus one insn per input. Always a minimum of COSTS_N_INSNS (1) + though (see PR60663). */ + int asm_length = MAX (1, asm_str_count (ASM_OPERANDS_TEMPLATE (x))); + int num_operands = ASM_OPERANDS_INPUT_LENGTH (x); + *cost = COSTS_N_INSNS (asm_length + num_operands); + return true; + } default: if (mode != VOIDmode) *cost = COSTS_N_INSNS (ARM_NUM_REGS (mode)); @@ -31116,4 +31126,46 @@ arm_asan_shadow_offset (void) return (unsigned HOST_WIDE_INT) 1 << 29; } + +/* This is a temporary fix for PR60655. Ideally we need + to handle most of these cases in the generic part but + currently we reject minus (..) (sym_ref). We try to + ameliorate the case with minus (sym_ref1) (sym_ref2) + where they are in the same section. */ + +static bool +arm_const_not_ok_for_debug_p (rtx p) +{ + tree decl_op0 = NULL; + tree decl_op1 = NULL; + + if (GET_CODE (p) == MINUS) + { + if (GET_CODE (XEXP (p, 1)) == SYMBOL_REF) + { + decl_op1 = SYMBOL_REF_DECL (XEXP (p, 1)); + if (decl_op1 + && GET_CODE (XEXP (p, 0)) == SYMBOL_REF + && (decl_op0 = SYMBOL_REF_DECL (XEXP (p, 0)))) + { + if ((TREE_CODE (decl_op1) == VAR_DECL + || TREE_CODE (decl_op1) == CONST_DECL) + && (TREE_CODE (decl_op0) == VAR_DECL + || TREE_CODE (decl_op0) == CONST_DECL)) + return (get_variable_section (decl_op1, false) + != get_variable_section (decl_op0, false)); + + if (TREE_CODE (decl_op1) == LABEL_DECL + && TREE_CODE (decl_op0) == LABEL_DECL) + return (DECL_CONTEXT (decl_op1) + != DECL_CONTEXT (decl_op0)); + } + + return true; + } + } + + return false; +} + #include "gt-arm.h" diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 7ca47a7ec70..597e69c6e03 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -937,13 +937,13 @@ extern int arm_arch_crc; #ifndef ARM_TARGET2_DWARF_FORMAT #define ARM_TARGET2_DWARF_FORMAT DW_EH_PE_pcrel +#endif /* ttype entries (the only interesting data references used) use TARGET2 relocations. */ #define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \ (((code) == 0 && (data) == 1 && ARM_UNWIND_INFO) ? ARM_TARGET2_DWARF_FORMAT \ : DW_EH_PE_absptr) -#endif /* The native (Norcroft) Pascal compiler for the ARM passes the static chain as an invisible last argument (possible since varargs don't exist in @@ -2194,14 +2194,9 @@ extern int making_const_table; #undef ASM_OUTPUT_BEFORE_CASE_LABEL #define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) /* Empty. */ -/* Make sure subsequent insns are aligned after a TBB. */ -#define ASM_OUTPUT_CASE_END(FILE, NUM, JUMPTABLE) \ - do \ - { \ - if (GET_MODE (PATTERN (JUMPTABLE)) == QImode) \ - ASM_OUTPUT_ALIGN (FILE, 1); \ - } \ - while (0) +#define LABEL_ALIGN_AFTER_BARRIER(LABEL) \ + (GET_CODE (PATTERN (prev_active_insn (LABEL))) == ADDR_DIFF_VEC \ + ? 1 : 0) #define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ do \ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 4df24a236a2..4b81ee27211 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2784,8 +2784,8 @@ (define_insn "insv_zero" [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") - (match_operand:SI 1 "const_int_operand" "M") - (match_operand:SI 2 "const_int_operand" "M")) + (match_operand:SI 1 "const_int_M_operand" "M") + (match_operand:SI 2 "const_int_M_operand" "M")) (const_int 0))] "arm_arch_thumb2" "bfc%?\t%0, %2, %1" @@ -2797,8 +2797,8 @@ (define_insn "insv_t2" [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") - (match_operand:SI 1 "const_int_operand" "M") - (match_operand:SI 2 "const_int_operand" "M")) + (match_operand:SI 1 "const_int_M_operand" "M") + (match_operand:SI 2 "const_int_M_operand" "M")) (match_operand:SI 3 "s_register_operand" "r"))] "arm_arch_thumb2" "bfi%?\t%0, %3, %2, %1" @@ -4480,8 +4480,8 @@ (define_insn "*extv_reg" [(set (match_operand:SI 0 "s_register_operand" "=r") (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "const_int_operand" "M") - (match_operand:SI 3 "const_int_operand" "M")))] + (match_operand:SI 2 "const_int_M_operand" "M") + (match_operand:SI 3 "const_int_M_operand" "M")))] "arm_arch_thumb2" "sbfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") @@ -4493,8 +4493,8 @@ (define_insn "extzv_t2" [(set (match_operand:SI 0 "s_register_operand" "=r") (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") - (match_operand:SI 2 "const_int_operand" "M") - (match_operand:SI 3 "const_int_operand" "M")))] + (match_operand:SI 2 "const_int_M_operand" "M") + (match_operand:SI 3 "const_int_M_operand" "M")))] "arm_arch_thumb2" "ubfx%?\t%0, %1, %3, %2" [(set_attr "length" "4") @@ -12073,7 +12073,7 @@ [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 1 "s_register_operand" "+rk") (plus:SI (match_dup 1) - (match_operand:SI 2 "const_int_operand" "I"))) + (match_operand:SI 2 "const_int_I_operand" "I"))) (set (match_operand:SI 3 "s_register_operand" "=rk") (mem:SI (match_dup 1))) ])] @@ -12102,7 +12102,7 @@ [(return) (set (match_operand:SI 1 "s_register_operand" "+rk") (plus:SI (match_dup 1) - (match_operand:SI 2 "const_int_operand" "I"))) + (match_operand:SI 2 "const_int_I_operand" "I"))) (set (match_operand:SI 3 "s_register_operand" "=rk") (mem:SI (match_dup 1))) ])] @@ -12155,7 +12155,7 @@ [(match_parallel 0 "pop_multiple_fp" [(set (match_operand:SI 1 "s_register_operand" "+rk") (plus:SI (match_dup 1) - (match_operand:SI 2 "const_int_operand" "I"))) + (match_operand:SI 2 "const_int_I_operand" "I"))) (set (match_operand:DF 3 "vfp_hard_register_operand" "") (mem:DF (match_dup 1)))])] "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" diff --git a/gcc/config/arm/cortex-a53.md b/gcc/config/arm/cortex-a53.md index b131c814d07..a629bd61dae 100644 --- a/gcc/config/arm/cortex-a53.md +++ b/gcc/config/arm/cortex-a53.md @@ -245,12 +245,12 @@ (define_insn_reservation "cortex_a53_fdivs" 14 (and (eq_attr "tune" "cortexa53") (eq_attr "type" "fdivs, fsqrts")) - "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 13") + "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 5") (define_insn_reservation "cortex_a53_fdivd" 29 (and (eq_attr "tune" "cortexa53") (eq_attr "type" "fdivd, fsqrtd")) - "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 28") + "cortex_a53_slot0, cortex_a53_fp_div_sqrt * 8") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ARMv8-A Cryptographic extensions. diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index ce5c9a830cd..6273e8820c6 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -153,6 +153,14 @@ (ior (match_operand 0 "arm_rhs_operand") (match_operand 0 "memory_operand"))) +(define_predicate "const_int_I_operand" + (and (match_operand 0 "const_int_operand") + (match_test "satisfies_constraint_I (op)"))) + +(define_predicate "const_int_M_operand" + (and (match_operand 0 "const_int_operand") + (match_test "satisfies_constraint_M (op)"))) + ;; This doesn't have to do much because the constant is already checked ;; in the shift_operator predicate. (define_predicate "shift_amount_operand" diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h index 6357e997cad..b3c7cc0855e 100644 --- a/gcc/config/avr/avr-arch.h +++ b/gcc/config/avr/avr-arch.h @@ -100,32 +100,12 @@ typedef struct /* Index in avr_arch_types[]. */ enum avr_arch arch; + /* device specific feature */ + int dev_attribute; + /* Must lie outside user's namespace. NULL == no macro. */ const char *const macro; - /* Stack pointer have 8 bits width. */ - int short_sp; - - /* Some AVR devices have a core erratum when skipping a 2-word instruction. - Skip instructions are: SBRC, SBRS, SBIC, SBIS, CPSE. - Problems will occur with return address is IRQ executes during the - skip sequence. - - A support ticket from Atmel returned the following information: - - Subject: (ATTicket:644469) On AVR skip-bug core Erratum - From: avr@atmel.com Date: 2011-07-27 - (Please keep the subject when replying to this mail) - - This errata exists only in AT90S8515 and ATmega103 devices. - - For information please refer the following respective errata links - http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf - http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf */ - - /* Core Erratum: Must not skip 2-word instruction. */ - int errata_skip; - /* Start of data section. */ int data_section_start; @@ -136,6 +116,42 @@ typedef struct const char *const library_name; } avr_mcu_t; +/* AVR device specific features. + +AVR_ISA_RMW + Only few avr devices have Read-Modify-Write (RMW) instructions + (XCH, LAC, LAS and LAT) + +AVR_SHORT_SP + Stack Pointer has only 8 bit width. + The device / multilib has an 8-bit stack pointer (no SPH). + +AVR_ERRATA_SKIP + Some AVR devices have a core erratum when skipping a 2-word instruction. + Skip instructions are: SBRC, SBRS, SBIC, SBIS, CPSE. + Problems will occur with return address is IRQ executes during the + skip sequence. + + A support ticket from Atmel returned the following information: + + Subject: (ATTicket:644469) On AVR skip-bug core Erratum + From: avr@atmel.com Date: 2011-07-27 + (Please keep the subject when replying to this mail) + + This errata exists only in AT90S8515 and ATmega103 devices. + + For information please refer the following respective errata links + http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf + http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf */ + +enum avr_device_specific_features +{ + AVR_ISA_NONE, + AVR_ISA_RMW = 0x1, /* device has RMW instructions. */ + AVR_SHORT_SP = 0x2, /* Stack Pointer has 8 bits width. */ + AVR_ERRATA_SKIP = 0x4 /* device has a core erratum. */ +}; + /* Map architecture to its texinfo string. */ typedef struct diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index 101d28092e7..c6a2f1f9471 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -347,7 +347,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) if (TARGET_NO_INTERRUPTS) cpp_define (pfile, "__NO_INTERRUPTS__"); - if (avr_current_device->errata_skip) + if (avr_current_device->dev_attribute & AVR_ERRATA_SKIP) { cpp_define (pfile, "__AVR_ERRATA_SKIP__"); @@ -355,6 +355,9 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) cpp_define (pfile, "__AVR_ERRATA_SKIP_JMP_CALL__"); } + if (avr_current_device->dev_attribute & AVR_ISA_RMW) + cpp_define (pfile, "__AVR_ISA_RMW__"); + cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x", avr_current_arch->sfr_offset); diff --git a/gcc/config/avr/avr-devices.c b/gcc/config/avr/avr-devices.c index 177f1961f14..2485cad65c4 100644 --- a/gcc/config/avr/avr-devices.c +++ b/gcc/config/avr/avr-devices.c @@ -104,11 +104,11 @@ avr_texinfo[] = const avr_mcu_t avr_mcu_types[] = { -#define AVR_MCU(NAME, ARCH, MACRO, SP8, ERR_SKIP, DATA_SEC, N_FLASH, LIBNAME)\ - { NAME, ARCH, MACRO, SP8, ERR_SKIP, DATA_SEC, N_FLASH, LIBNAME }, +#define AVR_MCU(NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, N_FLASH, LIBNAME)\ + { NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, N_FLASH, LIBNAME }, #include "avr-mcus.def" #undef AVR_MCU /* End of list. */ - { NULL, ARCH_UNKNOWN, NULL, 0, 0, 0, 0, NULL } + { NULL, ARCH_UNKNOWN, AVR_ISA_NONE, NULL, 0, 0, NULL } }; diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index d068f5e8017..483a3032173 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -33,291 +33,288 @@ Before including this file, define a macro: - AVR_MCU (NAME, ARCH, MACRO, SHORT_SP, ERRATA_SKIP, DATA_SEC, N_FLASH, - LIBRARY_NAME) + AVR_MCU (NAME, ARCH, DEV_ATTRIBUTE, MACRO, DATA_SEC, N_FLASH, LIBRARY_NAME) where the arguments are the fields of avr_mcu_t: - NAME Accept -mmcu=<NAME> + NAME Accept -mmcu=<NAME> - ARCH Specifies the multilib variant together with SHORT_SP + ARCH Specifies the multilib variant together with SHORT_SP - MACRO If NULL, this is a core and not a device. If non-NULL, - supply respective built-in macro. + DEV_ATTRIBUTE Specifies the device specific features + - additional ISA, short SP, errata skip etc., - SHORT_SP The device / multilib has an 8-bit stack pointer (no SPH). + MACRO If NULL, this is a core and not a device. If non-NULL, + supply respective built-in macro. - ERRATA_SKIP Apply work-around for the "skip 32-bit instruction" - silicon bug: Don't skip 32-bit instrctions. + DATA_SEC First address of SRAM, used in -Tdata= by the driver. - DATA_SEC First address of SRAM, used in -Tdata= by the driver. + N_FLASH Number of 64 KiB flash segments, rounded up. - N_FLASH Number of 64 KiB flash segments, rounded up. - - LIBRARY_NAME Used by the driver to linke startup code from avr-libc - as of crt<LIBRARY_NAME>.o + LIBRARY_NAME Used by the driver to linke startup code from avr-libc + as of crt<LIBRARY_NAME>.o "avr2" must be first for the "0" default to work as intended. */ /* Classic, <= 8K. */ -AVR_MCU ("avr2", ARCH_AVR2, NULL, 0, 1, 0x0060, 6, "s8515") -AVR_MCU ("at90s2313", ARCH_AVR2, "__AVR_AT90S2313__", 1, 0, 0x0060, 1, "s2313") -AVR_MCU ("at90s2323", ARCH_AVR2, "__AVR_AT90S2323__", 1, 0, 0x0060, 1, "s2323") -AVR_MCU ("at90s2333", ARCH_AVR2, "__AVR_AT90S2333__", 1, 0, 0x0060, 1, "s2333") -AVR_MCU ("at90s2343", ARCH_AVR2, "__AVR_AT90S2343__", 1, 0, 0x0060, 1, "s2343") -AVR_MCU ("attiny22", ARCH_AVR2, "__AVR_ATtiny22__", 1, 0, 0x0060, 1, "tn22") -AVR_MCU ("attiny26", ARCH_AVR2, "__AVR_ATtiny26__", 1, 0, 0x0060, 1, "tn26") -AVR_MCU ("at90s4414", ARCH_AVR2, "__AVR_AT90S4414__", 0, 0, 0x0060, 1, "s4414") -AVR_MCU ("at90s4433", ARCH_AVR2, "__AVR_AT90S4433__", 1, 0, 0x0060, 1, "s4433") -AVR_MCU ("at90s4434", ARCH_AVR2, "__AVR_AT90S4434__", 0, 0, 0x0060, 1, "s4434") -AVR_MCU ("at90s8515", ARCH_AVR2, "__AVR_AT90S8515__", 0, 1, 0x0060, 1, "s8515") -AVR_MCU ("at90c8534", ARCH_AVR2, "__AVR_AT90C8534__", 0, 0, 0x0060, 1, "c8534") -AVR_MCU ("at90s8535", ARCH_AVR2, "__AVR_AT90S8535__", 0, 0, 0x0060, 1, "s8535") +AVR_MCU ("avr2", ARCH_AVR2, AVR_ERRATA_SKIP, NULL, 0x0060, 6, "s8515") +AVR_MCU ("at90s2313", ARCH_AVR2, AVR_SHORT_SP, "__AVR_AT90S2313__", 0x0060, 1, "s2313") +AVR_MCU ("at90s2323", ARCH_AVR2, AVR_SHORT_SP, "__AVR_AT90S2323__", 0x0060, 1, "s2323") +AVR_MCU ("at90s2333", ARCH_AVR2, AVR_SHORT_SP, "__AVR_AT90S2333__", 0x0060, 1, "s2333") +AVR_MCU ("at90s2343", ARCH_AVR2, AVR_SHORT_SP, "__AVR_AT90S2343__", 0x0060, 1, "s2343") +AVR_MCU ("attiny22", ARCH_AVR2, AVR_SHORT_SP, "__AVR_ATtiny22__", 0x0060, 1, "tn22") +AVR_MCU ("attiny26", ARCH_AVR2, AVR_SHORT_SP, "__AVR_ATtiny26__", 0x0060, 1, "tn26") +AVR_MCU ("at90s4414", ARCH_AVR2, AVR_ISA_NONE, "__AVR_AT90S4414__", 0x0060, 1, "s4414") +AVR_MCU ("at90s4433", ARCH_AVR2, AVR_SHORT_SP, "__AVR_AT90S4433__", 0x0060, 1, "s4433") +AVR_MCU ("at90s4434", ARCH_AVR2, AVR_ISA_NONE, "__AVR_AT90S4434__", 0x0060, 1, "s4434") +AVR_MCU ("at90s8515", ARCH_AVR2, AVR_ERRATA_SKIP, "__AVR_AT90S8515__", 0x0060, 1, "s8515") +AVR_MCU ("at90c8534", ARCH_AVR2, AVR_ISA_NONE, "__AVR_AT90C8534__", 0x0060, 1, "c8534") +AVR_MCU ("at90s8535", ARCH_AVR2, AVR_ISA_NONE, "__AVR_AT90S8535__", 0x0060, 1, "s8535") /* Classic + MOVW, <= 8K. */ -AVR_MCU ("avr25", ARCH_AVR25, NULL, 0, 0, 0x0060, 1, "tn85") -AVR_MCU ("ata6289", ARCH_AVR25, "__AVR_ATA6289__", 0, 0, 0x0100, 1, "a6289") -AVR_MCU ("ata5272", ARCH_AVR25, "__AVR_ATA5272__", 0, 0, 0x0100, 1, "a5272") -AVR_MCU ("attiny13", ARCH_AVR25, "__AVR_ATtiny13__", 1, 0, 0x0060, 1, "tn13") -AVR_MCU ("attiny13a", ARCH_AVR25, "__AVR_ATtiny13A__", 1, 0, 0x0060, 1, "tn13a") -AVR_MCU ("attiny2313", ARCH_AVR25, "__AVR_ATtiny2313__", 1, 0, 0x0060, 1, "tn2313") -AVR_MCU ("attiny2313a", ARCH_AVR25, "__AVR_ATtiny2313A__", 1, 0, 0x0060, 1, "tn2313a") -AVR_MCU ("attiny24", ARCH_AVR25, "__AVR_ATtiny24__", 1, 0, 0x0060, 1, "tn24") -AVR_MCU ("attiny24a", ARCH_AVR25, "__AVR_ATtiny24A__", 1, 0, 0x0060, 1, "tn24a") -AVR_MCU ("attiny4313", ARCH_AVR25, "__AVR_ATtiny4313__", 0, 0, 0x0060, 1, "tn4313") -AVR_MCU ("attiny44", ARCH_AVR25, "__AVR_ATtiny44__", 0, 0, 0x0060, 1, "tn44") -AVR_MCU ("attiny44a", ARCH_AVR25, "__AVR_ATtiny44A__", 0, 0, 0x0060, 1, "tn44a") -AVR_MCU ("attiny84", ARCH_AVR25, "__AVR_ATtiny84__", 0, 0, 0x0060, 1, "tn84") -AVR_MCU ("attiny84a", ARCH_AVR25, "__AVR_ATtiny84A__", 0, 0, 0x0060, 1, "tn84") -AVR_MCU ("attiny25", ARCH_AVR25, "__AVR_ATtiny25__", 1, 0, 0x0060, 1, "tn25") -AVR_MCU ("attiny45", ARCH_AVR25, "__AVR_ATtiny45__", 0, 0, 0x0060, 1, "tn45") -AVR_MCU ("attiny85", ARCH_AVR25, "__AVR_ATtiny85__", 0, 0, 0x0060, 1, "tn85") -AVR_MCU ("attiny261", ARCH_AVR25, "__AVR_ATtiny261__", 1, 0, 0x0060, 1, "tn261") -AVR_MCU ("attiny261a", ARCH_AVR25, "__AVR_ATtiny261A__", 1, 0, 0x0060, 1, "tn261a") -AVR_MCU ("attiny461", ARCH_AVR25, "__AVR_ATtiny461__", 0, 0, 0x0060, 1, "tn461") -AVR_MCU ("attiny461a", ARCH_AVR25, "__AVR_ATtiny461A__", 0, 0, 0x0060, 1, "tn461a") -AVR_MCU ("attiny861", ARCH_AVR25, "__AVR_ATtiny861__", 0, 0, 0x0060, 1, "tn861") -AVR_MCU ("attiny861a", ARCH_AVR25, "__AVR_ATtiny861A__", 0, 0, 0x0060, 1, "tn861a") -AVR_MCU ("attiny43u", ARCH_AVR25, "__AVR_ATtiny43U__", 0, 0, 0x0060, 1, "tn43u") -AVR_MCU ("attiny87", ARCH_AVR25, "__AVR_ATtiny87__", 0, 0, 0x0100, 1, "tn87") -AVR_MCU ("attiny48", ARCH_AVR25, "__AVR_ATtiny48__", 0, 0, 0x0100, 1, "tn48") -AVR_MCU ("attiny88", ARCH_AVR25, "__AVR_ATtiny88__", 0, 0, 0x0100, 1, "tn88") -AVR_MCU ("at86rf401", ARCH_AVR25, "__AVR_AT86RF401__", 0, 0, 0x0060, 1, "86401") +AVR_MCU ("avr25", ARCH_AVR25, AVR_ISA_NONE, NULL, 0x0060, 1, "tn85") +AVR_MCU ("ata6289", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATA6289__", 0x0100, 1, "a6289") +AVR_MCU ("ata5272", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATA5272__", 0x0100, 1, "a5272") +AVR_MCU ("attiny13", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny13__", 0x0060, 1, "tn13") +AVR_MCU ("attiny13a", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny13A__", 0x0060, 1, "tn13a") +AVR_MCU ("attiny2313", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny2313__", 0x0060, 1, "tn2313") +AVR_MCU ("attiny2313a", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny2313A__", 0x0060, 1, "tn2313a") +AVR_MCU ("attiny24", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny24__", 0x0060, 1, "tn24") +AVR_MCU ("attiny24a", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny24A__", 0x0060, 1, "tn24a") +AVR_MCU ("attiny4313", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny4313__", 0x0060, 1, "tn4313") +AVR_MCU ("attiny44", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny44__", 0x0060, 1, "tn44") +AVR_MCU ("attiny44a", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny44A__", 0x0060, 1, "tn44a") +AVR_MCU ("attiny84", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny84__", 0x0060, 1, "tn84") +AVR_MCU ("attiny84a", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny84A__", 0x0060, 1, "tn84") +AVR_MCU ("attiny25", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny25__", 0x0060, 1, "tn25") +AVR_MCU ("attiny45", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny45__", 0x0060, 1, "tn45") +AVR_MCU ("attiny85", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny85__", 0x0060, 1, "tn85") +AVR_MCU ("attiny261", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny261__", 0x0060, 1, "tn261") +AVR_MCU ("attiny261a", ARCH_AVR25, AVR_SHORT_SP, "__AVR_ATtiny261A__", 0x0060, 1, "tn261a") +AVR_MCU ("attiny461", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny461__", 0x0060, 1, "tn461") +AVR_MCU ("attiny461a", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny461A__", 0x0060, 1, "tn461a") +AVR_MCU ("attiny861", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny861__", 0x0060, 1, "tn861") +AVR_MCU ("attiny861a", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny861A__", 0x0060, 1, "tn861a") +AVR_MCU ("attiny43u", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny43U__", 0x0060, 1, "tn43u") +AVR_MCU ("attiny87", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny87__", 0x0100, 1, "tn87") +AVR_MCU ("attiny48", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny48__", 0x0100, 1, "tn48") +AVR_MCU ("attiny88", ARCH_AVR25, AVR_ISA_NONE, "__AVR_ATtiny88__", 0x0100, 1, "tn88") +AVR_MCU ("at86rf401", ARCH_AVR25, AVR_ISA_NONE, "__AVR_AT86RF401__", 0x0060, 1, "86401") /* Classic, > 8K, <= 64K. */ -AVR_MCU ("avr3", ARCH_AVR3, NULL, 0, 0, 0x0060, 1, "43355") -AVR_MCU ("at43usb355", ARCH_AVR3, "__AVR_AT43USB355__", 0, 0, 0x0060, 1, "43355") -AVR_MCU ("at76c711", ARCH_AVR3, "__AVR_AT76C711__", 0, 0, 0x0060, 1, "76711") +AVR_MCU ("avr3", ARCH_AVR3, AVR_ISA_NONE, NULL, 0x0060, 1, "43355") +AVR_MCU ("at43usb355", ARCH_AVR3, AVR_ISA_NONE, "__AVR_AT43USB355__", 0x0060, 1, "43355") +AVR_MCU ("at76c711", ARCH_AVR3, AVR_ISA_NONE, "__AVR_AT76C711__", 0x0060, 1, "76711") /* Classic, == 128K. */ -AVR_MCU ("avr31", ARCH_AVR31, NULL, 0, 1, 0x0060, 2, "m103") -AVR_MCU ("atmega103", ARCH_AVR31, "__AVR_ATmega103__", 0, 1, 0x0060, 2, "m103") -AVR_MCU ("at43usb320", ARCH_AVR31, "__AVR_AT43USB320__", 0, 0, 0x0060, 2, "43320") +AVR_MCU ("avr31", ARCH_AVR31, AVR_ERRATA_SKIP, NULL, 0x0060, 2, "m103") +AVR_MCU ("atmega103", ARCH_AVR31, AVR_ERRATA_SKIP, "__AVR_ATmega103__", 0x0060, 2, "m103") +AVR_MCU ("at43usb320", ARCH_AVR31, AVR_ISA_NONE, "__AVR_AT43USB320__", 0x0060, 2, "43320") /* Classic + MOVW + JMP/CALL. */ -AVR_MCU ("avr35", ARCH_AVR35, NULL, 0, 0, 0x0100, 1, "usb162") -AVR_MCU ("ata5505", ARCH_AVR35, "__AVR_ATA5505__", 0, 0, 0x0100, 1, "a5505") -AVR_MCU ("at90usb82", ARCH_AVR35, "__AVR_AT90USB82__", 0, 0, 0x0100, 1, "usb82") -AVR_MCU ("at90usb162", ARCH_AVR35, "__AVR_AT90USB162__", 0, 0, 0x0100, 1, "usb162") -AVR_MCU ("atmega8u2", ARCH_AVR35, "__AVR_ATmega8U2__", 0, 0, 0x0100, 1, "m8u2") -AVR_MCU ("atmega16u2", ARCH_AVR35, "__AVR_ATmega16U2__", 0, 0, 0x0100, 1, "m16u2") -AVR_MCU ("atmega32u2", ARCH_AVR35, "__AVR_ATmega32U2__", 0, 0, 0x0100, 1, "m32u2") -AVR_MCU ("attiny167", ARCH_AVR35, "__AVR_ATtiny167__", 0, 0, 0x0100, 1, "tn167") -AVR_MCU ("attiny1634", ARCH_AVR35, "__AVR_ATtiny1634__", 0, 0, 0x0100, 1, "tn1634") +AVR_MCU ("avr35", ARCH_AVR35, AVR_ISA_NONE, NULL, 0x0100, 1, "usb162") +AVR_MCU ("ata5505", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATA5505__", 0x0100, 1, "a5505") +AVR_MCU ("at90usb82", ARCH_AVR35, AVR_ISA_NONE, "__AVR_AT90USB82__", 0x0100, 1, "usb82") +AVR_MCU ("at90usb162", ARCH_AVR35, AVR_ISA_NONE, "__AVR_AT90USB162__", 0x0100, 1, "usb162") +AVR_MCU ("atmega8u2", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATmega8U2__", 0x0100, 1, "m8u2") +AVR_MCU ("atmega16u2", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATmega16U2__", 0x0100, 1, "m16u2") +AVR_MCU ("atmega32u2", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATmega32U2__", 0x0100, 1, "m32u2") +AVR_MCU ("attiny167", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATtiny167__", 0x0100, 1, "tn167") +AVR_MCU ("attiny1634", ARCH_AVR35, AVR_ISA_NONE, "__AVR_ATtiny1634__", 0x0100, 1, "tn1634") /* Enhanced, <= 8K. */ -AVR_MCU ("avr4", ARCH_AVR4, NULL, 0, 0, 0x0060, 1, "m8") -AVR_MCU ("ata6285", ARCH_AVR4, "__AVR_ATA6285__", 0, 0, 0x0100, 1, "a6285") -AVR_MCU ("ata6286", ARCH_AVR4, "__AVR_ATA6286__", 0, 0, 0x0100, 1, "a6286") -AVR_MCU ("atmega8", ARCH_AVR4, "__AVR_ATmega8__", 0, 0, 0x0060, 1, "m8") -AVR_MCU ("atmega8a", ARCH_AVR4, "__AVR_ATmega8A__", 0, 0, 0x0060, 1, "m8a") -AVR_MCU ("atmega48", ARCH_AVR4, "__AVR_ATmega48__", 0, 0, 0x0100, 1, "m48") -AVR_MCU ("atmega48a", ARCH_AVR4, "__AVR_ATmega48A__", 0, 0, 0x0100, 1, "m48a") -AVR_MCU ("atmega48p", ARCH_AVR4, "__AVR_ATmega48P__", 0, 0, 0x0100, 1, "m48p") -AVR_MCU ("atmega48pa", ARCH_AVR4, "__AVR_ATmega48PA__", 0, 0, 0x0100, 1, "m48pa") -AVR_MCU ("atmega88", ARCH_AVR4, "__AVR_ATmega88__", 0, 0, 0x0100, 1, "m88") -AVR_MCU ("atmega88a", ARCH_AVR4, "__AVR_ATmega88A__", 0, 0, 0x0100, 1, "m88a") -AVR_MCU ("atmega88p", ARCH_AVR4, "__AVR_ATmega88P__", 0, 0, 0x0100, 1, "m88p") -AVR_MCU ("atmega88pa", ARCH_AVR4, "__AVR_ATmega88PA__", 0, 0, 0x0100, 1, "m88pa") -AVR_MCU ("atmega8515", ARCH_AVR4, "__AVR_ATmega8515__", 0, 0, 0x0060, 1, "m8515") -AVR_MCU ("atmega8535", ARCH_AVR4, "__AVR_ATmega8535__", 0, 0, 0x0060, 1, "m8535") -AVR_MCU ("atmega8hva", ARCH_AVR4, "__AVR_ATmega8HVA__", 0, 0, 0x0100, 1, "m8hva") -AVR_MCU ("at90pwm1", ARCH_AVR4, "__AVR_AT90PWM1__", 0, 0, 0x0100, 1, "90pwm1") -AVR_MCU ("at90pwm2", ARCH_AVR4, "__AVR_AT90PWM2__", 0, 0, 0x0100, 1, "90pwm2") -AVR_MCU ("at90pwm2b", ARCH_AVR4, "__AVR_AT90PWM2B__", 0, 0, 0x0100, 1, "90pwm2b") -AVR_MCU ("at90pwm3", ARCH_AVR4, "__AVR_AT90PWM3__", 0, 0, 0x0100, 1, "90pwm3") -AVR_MCU ("at90pwm3b", ARCH_AVR4, "__AVR_AT90PWM3B__", 0, 0, 0x0100, 1, "90pwm3b") -AVR_MCU ("at90pwm81", ARCH_AVR4, "__AVR_AT90PWM81__", 0, 0, 0x0100, 1, "90pwm81") +AVR_MCU ("avr4", ARCH_AVR4, AVR_ISA_NONE, NULL, 0x0060, 1, "m8") +AVR_MCU ("ata6285", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATA6285__", 0x0100, 1, "a6285") +AVR_MCU ("ata6286", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATA6286__", 0x0100, 1, "a6286") +AVR_MCU ("atmega8", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega8__", 0x0060, 1, "m8") +AVR_MCU ("atmega8a", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega8A__", 0x0060, 1, "m8a") +AVR_MCU ("atmega48", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega48__", 0x0100, 1, "m48") +AVR_MCU ("atmega48a", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega48A__", 0x0100, 1, "m48a") +AVR_MCU ("atmega48p", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega48P__", 0x0100, 1, "m48p") +AVR_MCU ("atmega48pa", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega48PA__", 0x0100, 1, "m48pa") +AVR_MCU ("atmega88", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega88__", 0x0100, 1, "m88") +AVR_MCU ("atmega88a", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega88A__", 0x0100, 1, "m88a") +AVR_MCU ("atmega88p", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega88P__", 0x0100, 1, "m88p") +AVR_MCU ("atmega88pa", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega88PA__", 0x0100, 1, "m88pa") +AVR_MCU ("atmega8515", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega8515__", 0x0060, 1, "m8515") +AVR_MCU ("atmega8535", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega8535__", 0x0060, 1, "m8535") +AVR_MCU ("atmega8hva", ARCH_AVR4, AVR_ISA_NONE, "__AVR_ATmega8HVA__", 0x0100, 1, "m8hva") +AVR_MCU ("at90pwm1", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM1__", 0x0100, 1, "90pwm1") +AVR_MCU ("at90pwm2", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM2__", 0x0100, 1, "90pwm2") +AVR_MCU ("at90pwm2b", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM2B__", 0x0100, 1, "90pwm2b") +AVR_MCU ("at90pwm3", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM3__", 0x0100, 1, "90pwm3") +AVR_MCU ("at90pwm3b", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM3B__", 0x0100, 1, "90pwm3b") +AVR_MCU ("at90pwm81", ARCH_AVR4, AVR_ISA_NONE, "__AVR_AT90PWM81__", 0x0100, 1, "90pwm81") /* Enhanced, > 8K, <= 64K. */ -AVR_MCU ("avr5", ARCH_AVR5, NULL, 0, 0, 0x0060, 1, "m16") -AVR_MCU ("ata5790", ARCH_AVR5, "__AVR_ATA5790__", 0, 0, 0x0100, 1, "a5790") -AVR_MCU ("ata5790n", ARCH_AVR5, "__AVR_ATA5790N__", 0, 0, 0x0100, 1, "a5790n") -AVR_MCU ("ata5795", ARCH_AVR5, "__AVR_ATA5795__", 0, 0, 0x0100, 1, "a5795") -AVR_MCU ("atmega16", ARCH_AVR5, "__AVR_ATmega16__", 0, 0, 0x0060, 1, "m16") -AVR_MCU ("atmega16a", ARCH_AVR5, "__AVR_ATmega16A__", 0, 0, 0x0060, 1, "m16a") -AVR_MCU ("atmega161", ARCH_AVR5, "__AVR_ATmega161__", 0, 0, 0x0060, 1, "m161") -AVR_MCU ("atmega162", ARCH_AVR5, "__AVR_ATmega162__", 0, 0, 0x0100, 1, "m162") -AVR_MCU ("atmega163", ARCH_AVR5, "__AVR_ATmega163__", 0, 0, 0x0060, 1, "m163") -AVR_MCU ("atmega164a", ARCH_AVR5, "__AVR_ATmega164A__", 0, 0, 0x0100, 1, "m164a") -AVR_MCU ("atmega164p", ARCH_AVR5, "__AVR_ATmega164P__", 0, 0, 0x0100, 1, "m164p") -AVR_MCU ("atmega164pa", ARCH_AVR5, "__AVR_ATmega164PA__", 0, 0, 0x0100, 1, "m164pa") -AVR_MCU ("atmega165", ARCH_AVR5, "__AVR_ATmega165__", 0, 0, 0x0100, 1, "m165") -AVR_MCU ("atmega165a", ARCH_AVR5, "__AVR_ATmega165A__", 0, 0, 0x0100, 1, "m165a") -AVR_MCU ("atmega165p", ARCH_AVR5, "__AVR_ATmega165P__", 0, 0, 0x0100, 1, "m165p") -AVR_MCU ("atmega165pa", ARCH_AVR5, "__AVR_ATmega165PA__", 0, 0, 0x0100, 1, "m165pa") -AVR_MCU ("atmega168", ARCH_AVR5, "__AVR_ATmega168__", 0, 0, 0x0100, 1, "m168") -AVR_MCU ("atmega168a", ARCH_AVR5, "__AVR_ATmega168A__", 0, 0, 0x0100, 1, "m168a") -AVR_MCU ("atmega168p", ARCH_AVR5, "__AVR_ATmega168P__", 0, 0, 0x0100, 1, "m168p") -AVR_MCU ("atmega168pa", ARCH_AVR5, "__AVR_ATmega168PA__", 0, 0, 0x0100, 1, "m168pa") -AVR_MCU ("atmega169", ARCH_AVR5, "__AVR_ATmega169__", 0, 0, 0x0100, 1, "m169") -AVR_MCU ("atmega169a", ARCH_AVR5, "__AVR_ATmega169A__", 0, 0, 0x0100, 1, "m169a") -AVR_MCU ("atmega169p", ARCH_AVR5, "__AVR_ATmega169P__", 0, 0, 0x0100, 1, "m169p") -AVR_MCU ("atmega169pa", ARCH_AVR5, "__AVR_ATmega169PA__", 0, 0, 0x0100, 1, "m169pa") -AVR_MCU ("atmega16hvb", ARCH_AVR5, "__AVR_ATmega16HVB__", 0, 0, 0x0100, 1, "m16hvb") -AVR_MCU ("atmega16hvbrevb", ARCH_AVR5, "__AVR_ATmega16HVBREVB__", 0, 0, 0x0100, 1, "m16hvbrevb") -AVR_MCU ("atmega16m1", ARCH_AVR5, "__AVR_ATmega16M1__", 0, 0, 0x0100, 1, "m16m1") -AVR_MCU ("atmega16u4", ARCH_AVR5, "__AVR_ATmega16U4__", 0, 0, 0x0100, 1, "m16u4") -AVR_MCU ("atmega26hvg", ARCH_AVR5, "__AVR_ATmega26HVG__", 0, 0, 0x0100, 1, "m26hvg") -AVR_MCU ("atmega32a", ARCH_AVR5, "__AVR_ATmega32A__", 0, 0, 0x0060, 1, "m32a") -AVR_MCU ("atmega32", ARCH_AVR5, "__AVR_ATmega32__", 0, 0, 0x0060, 1, "m32") -AVR_MCU ("atmega323", ARCH_AVR5, "__AVR_ATmega323__", 0, 0, 0x0060, 1, "m323") -AVR_MCU ("atmega324a", ARCH_AVR5, "__AVR_ATmega324A__", 0, 0, 0x0100, 1, "m324a") -AVR_MCU ("atmega324p", ARCH_AVR5, "__AVR_ATmega324P__", 0, 0, 0x0100, 1, "m324p") -AVR_MCU ("atmega324pa", ARCH_AVR5, "__AVR_ATmega324PA__", 0, 0, 0x0100, 1, "m324pa") -AVR_MCU ("atmega325", ARCH_AVR5, "__AVR_ATmega325__", 0, 0, 0x0100, 1, "m325") -AVR_MCU ("atmega325a", ARCH_AVR5, "__AVR_ATmega325A__", 0, 0, 0x0100, 1, "m325a") -AVR_MCU ("atmega325p", ARCH_AVR5, "__AVR_ATmega325P__", 0, 0, 0x0100, 1, "m325p") -AVR_MCU ("atmega3250", ARCH_AVR5, "__AVR_ATmega3250__", 0, 0, 0x0100, 1, "m3250") -AVR_MCU ("atmega3250a", ARCH_AVR5, "__AVR_ATmega3250A__", 0, 0, 0x0100, 1, "m3250a") -AVR_MCU ("atmega3250p", ARCH_AVR5, "__AVR_ATmega3250P__", 0, 0, 0x0100, 1, "m3250p") -AVR_MCU ("atmega3250pa", ARCH_AVR5, "__AVR_ATmega3250PA__", 0, 0, 0x0100, 1, "m3250pa") -AVR_MCU ("atmega328", ARCH_AVR5, "__AVR_ATmega328__", 0, 0, 0x0100, 1, "m328") -AVR_MCU ("atmega328p", ARCH_AVR5, "__AVR_ATmega328P__", 0, 0, 0x0100, 1, "m328p") -AVR_MCU ("atmega329", ARCH_AVR5, "__AVR_ATmega329__", 0, 0, 0x0100, 1, "m329") -AVR_MCU ("atmega329a", ARCH_AVR5, "__AVR_ATmega329A__", 0, 0, 0x0100, 1, "m329a") -AVR_MCU ("atmega329p", ARCH_AVR5, "__AVR_ATmega329P__", 0, 0, 0x0100, 1, "m329p") -AVR_MCU ("atmega329pa", ARCH_AVR5, "__AVR_ATmega329PA__", 0, 0, 0x0100, 1, "m329pa") -AVR_MCU ("atmega3290", ARCH_AVR5, "__AVR_ATmega3290__", 0, 0, 0x0100, 1, "m3290") -AVR_MCU ("atmega3290a", ARCH_AVR5, "__AVR_ATmega3290A__", 0, 0, 0x0100, 1, "m3290a") -AVR_MCU ("atmega3290p", ARCH_AVR5, "__AVR_ATmega3290P__", 0, 0, 0x0100, 1, "m3290p") -AVR_MCU ("atmega3290pa", ARCH_AVR5, "__AVR_ATmega3290PA__", 0, 0, 0x0100, 1, "m3290pa") -AVR_MCU ("atmega32c1", ARCH_AVR5, "__AVR_ATmega32C1__", 0, 0, 0x0100, 1, "m32c1") -AVR_MCU ("atmega32m1", ARCH_AVR5, "__AVR_ATmega32M1__", 0, 0, 0x0100, 1, "m32m1") -AVR_MCU ("atmega32u4", ARCH_AVR5, "__AVR_ATmega32U4__", 0, 0, 0x0100, 1, "m32u4") -AVR_MCU ("atmega32u6", ARCH_AVR5, "__AVR_ATmega32U6__", 0, 0, 0x0100, 1, "m32u6") -AVR_MCU ("atmega406", ARCH_AVR5, "__AVR_ATmega406__", 0, 0, 0x0100, 1, "m406") -AVR_MCU ("atmega64", ARCH_AVR5, "__AVR_ATmega64__", 0, 0, 0x0100, 1, "m64") -AVR_MCU ("atmega64a", ARCH_AVR5, "__AVR_ATmega64A__", 0, 0, 0x0100, 1, "m64a") -AVR_MCU ("atmega640", ARCH_AVR5, "__AVR_ATmega640__", 0, 0, 0x0200, 1, "m640") -AVR_MCU ("atmega644", ARCH_AVR5, "__AVR_ATmega644__", 0, 0, 0x0100, 1, "m644") -AVR_MCU ("atmega644a", ARCH_AVR5, "__AVR_ATmega644A__", 0, 0, 0x0100, 1, "m644a") -AVR_MCU ("atmega644p", ARCH_AVR5, "__AVR_ATmega644P__", 0, 0, 0x0100, 1, "m644p") -AVR_MCU ("atmega644pa", ARCH_AVR5, "__AVR_ATmega644PA__", 0, 0, 0x0100, 1, "m644pa") -AVR_MCU ("atmega645", ARCH_AVR5, "__AVR_ATmega645__", 0, 0, 0x0100, 1, "m645") -AVR_MCU ("atmega645a", ARCH_AVR5, "__AVR_ATmega645A__", 0, 0, 0x0100, 1, "m645a") -AVR_MCU ("atmega645p", ARCH_AVR5, "__AVR_ATmega645P__", 0, 0, 0x0100, 1, "m645p") -AVR_MCU ("atmega6450", ARCH_AVR5, "__AVR_ATmega6450__", 0, 0, 0x0100, 1, "m6450") -AVR_MCU ("atmega6450a", ARCH_AVR5, "__AVR_ATmega6450A__", 0, 0, 0x0100, 1, "m6450a") -AVR_MCU ("atmega6450p", ARCH_AVR5, "__AVR_ATmega6450P__", 0, 0, 0x0100, 1, "m6450p") -AVR_MCU ("atmega649", ARCH_AVR5, "__AVR_ATmega649__", 0, 0, 0x0100, 1, "m649") -AVR_MCU ("atmega649a", ARCH_AVR5, "__AVR_ATmega649A__", 0, 0, 0x0100, 1, "m649a") -AVR_MCU ("atmega649p", ARCH_AVR5, "__AVR_ATmega649P__", 0, 0, 0x0100, 1, "m649p") -AVR_MCU ("atmega6490", ARCH_AVR5, "__AVR_ATmega6490__", 0, 0, 0x0100, 1, "m6490") -AVR_MCU ("atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__", 0, 0, 0x0100, 1, "m16hva") -AVR_MCU ("atmega16hva2", ARCH_AVR5, "__AVR_ATmega16HVA2__", 0, 0, 0x0100, 1, "m16hva2") -AVR_MCU ("atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__", 0, 0, 0x0100, 1, "m32hvb") -AVR_MCU ("atmega6490a", ARCH_AVR5, "__AVR_ATmega6490A__", 0, 0, 0x0100, 1, "m6490a") -AVR_MCU ("atmega6490p", ARCH_AVR5, "__AVR_ATmega6490P__", 0, 0, 0x0100, 1, "m6490p") -AVR_MCU ("atmega64c1", ARCH_AVR5, "__AVR_ATmega64C1__", 0, 0, 0x0100, 1, "m64c1") -AVR_MCU ("atmega64m1", ARCH_AVR5, "__AVR_ATmega64M1__", 0, 0, 0x0100, 1, "m64m1") -AVR_MCU ("atmega64hve", ARCH_AVR5, "__AVR_ATmega64HVE__", 0, 0, 0x0100, 1, "m64hve") -AVR_MCU ("atmega64rfa2", ARCH_AVR5, "__AVR_ATmega64RFA2__", 0, 0, 0x0200, 1, "m64rfa2") -AVR_MCU ("atmega64rfr2", ARCH_AVR5, "__AVR_ATmega64RFR2__", 0, 0, 0x0200, 1, "m64rfr2") -AVR_MCU ("atmega32hvbrevb", ARCH_AVR5, "__AVR_ATmega32HVBREVB__", 0, 0, 0x0100, 1, "m32hvbrevb") -AVR_MCU ("atmega48hvf", ARCH_AVR5, "__AVR_ATmega48HVF__", 0, 0, 0x0100, 1, "m48hvf") -AVR_MCU ("at90can32", ARCH_AVR5, "__AVR_AT90CAN32__", 0, 0, 0x0100, 1, "can32") -AVR_MCU ("at90can64", ARCH_AVR5, "__AVR_AT90CAN64__", 0, 0, 0x0100, 1, "can64") -AVR_MCU ("at90pwm161", ARCH_AVR5, "__AVR_AT90PWM161__", 0, 0, 0x0100, 1, "90pwm161") -AVR_MCU ("at90pwm216", ARCH_AVR5, "__AVR_AT90PWM216__", 0, 0, 0x0100, 1, "90pwm216") -AVR_MCU ("at90pwm316", ARCH_AVR5, "__AVR_AT90PWM316__", 0, 0, 0x0100, 1, "90pwm316") -AVR_MCU ("at90scr100", ARCH_AVR5, "__AVR_AT90SCR100__", 0, 0, 0x0100, 1, "90scr100") -AVR_MCU ("at90usb646", ARCH_AVR5, "__AVR_AT90USB646__", 0, 0, 0x0100, 1, "usb646") -AVR_MCU ("at90usb647", ARCH_AVR5, "__AVR_AT90USB647__", 0, 0, 0x0100, 1, "usb647") -AVR_MCU ("at94k", ARCH_AVR5, "__AVR_AT94K__", 0, 0, 0x0060, 1, "at94k") -AVR_MCU ("m3000", ARCH_AVR5, "__AVR_M3000__", 0, 0, 0x1000, 1, "m3000") +AVR_MCU ("avr5", ARCH_AVR5, AVR_ISA_NONE, NULL, 0x0060, 1, "m16") +AVR_MCU ("ata5790", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATA5790__", 0x0100, 1, "a5790") +AVR_MCU ("ata5790n", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATA5790N__", 0x0100, 1, "a5790n") +AVR_MCU ("ata5795", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATA5795__", 0x0100, 1, "a5795") +AVR_MCU ("atmega16", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16__", 0x0060, 1, "m16") +AVR_MCU ("atmega16a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16A__", 0x0060, 1, "m16a") +AVR_MCU ("atmega161", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega161__", 0x0060, 1, "m161") +AVR_MCU ("atmega162", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega162__", 0x0100, 1, "m162") +AVR_MCU ("atmega163", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega163__", 0x0060, 1, "m163") +AVR_MCU ("atmega164a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega164A__", 0x0100, 1, "m164a") +AVR_MCU ("atmega164p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega164P__", 0x0100, 1, "m164p") +AVR_MCU ("atmega164pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega164PA__", 0x0100, 1, "m164pa") +AVR_MCU ("atmega165", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega165__", 0x0100, 1, "m165") +AVR_MCU ("atmega165a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega165A__", 0x0100, 1, "m165a") +AVR_MCU ("atmega165p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega165P__", 0x0100, 1, "m165p") +AVR_MCU ("atmega165pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega165PA__", 0x0100, 1, "m165pa") +AVR_MCU ("atmega168", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega168__", 0x0100, 1, "m168") +AVR_MCU ("atmega168a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega168A__", 0x0100, 1, "m168a") +AVR_MCU ("atmega168p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega168P__", 0x0100, 1, "m168p") +AVR_MCU ("atmega168pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega168PA__", 0x0100, 1, "m168pa") +AVR_MCU ("atmega169", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega169__", 0x0100, 1, "m169") +AVR_MCU ("atmega169a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega169A__", 0x0100, 1, "m169a") +AVR_MCU ("atmega169p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega169P__", 0x0100, 1, "m169p") +AVR_MCU ("atmega169pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega169PA__", 0x0100, 1, "m169pa") +AVR_MCU ("atmega16hvb", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16HVB__", 0x0100, 1, "m16hvb") +AVR_MCU ("atmega16hvbrevb", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16HVBREVB__", 0x0100, 1, "m16hvbrevb") +AVR_MCU ("atmega16m1", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16M1__", 0x0100, 1, "m16m1") +AVR_MCU ("atmega16u4", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16U4__", 0x0100, 1, "m16u4") +AVR_MCU ("atmega26hvg", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega26HVG__", 0x0100, 1, "m26hvg") +AVR_MCU ("atmega32a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32A__", 0x0060, 1, "m32a") +AVR_MCU ("atmega32", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32__", 0x0060, 1, "m32") +AVR_MCU ("atmega323", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega323__", 0x0060, 1, "m323") +AVR_MCU ("atmega324a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega324A__", 0x0100, 1, "m324a") +AVR_MCU ("atmega324p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega324P__", 0x0100, 1, "m324p") +AVR_MCU ("atmega324pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega324PA__", 0x0100, 1, "m324pa") +AVR_MCU ("atmega325", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega325__", 0x0100, 1, "m325") +AVR_MCU ("atmega325a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega325A__", 0x0100, 1, "m325a") +AVR_MCU ("atmega325p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega325P__", 0x0100, 1, "m325p") +AVR_MCU ("atmega3250", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3250__", 0x0100, 1, "m3250") +AVR_MCU ("atmega3250a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3250A__", 0x0100, 1, "m3250a") +AVR_MCU ("atmega3250p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3250P__", 0x0100, 1, "m3250p") +AVR_MCU ("atmega3250pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3250PA__", 0x0100, 1, "m3250pa") +AVR_MCU ("atmega328", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega328__", 0x0100, 1, "m328") +AVR_MCU ("atmega328p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega328P__", 0x0100, 1, "m328p") +AVR_MCU ("atmega329", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega329__", 0x0100, 1, "m329") +AVR_MCU ("atmega329a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega329A__", 0x0100, 1, "m329a") +AVR_MCU ("atmega329p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega329P__", 0x0100, 1, "m329p") +AVR_MCU ("atmega329pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega329PA__", 0x0100, 1, "m329pa") +AVR_MCU ("atmega3290", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3290__", 0x0100, 1, "m3290") +AVR_MCU ("atmega3290a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3290A__", 0x0100, 1, "m3290a") +AVR_MCU ("atmega3290p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3290P__", 0x0100, 1, "m3290p") +AVR_MCU ("atmega3290pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega3290PA__", 0x0100, 1, "m3290pa") +AVR_MCU ("atmega32c1", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32C1__", 0x0100, 1, "m32c1") +AVR_MCU ("atmega32m1", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32M1__", 0x0100, 1, "m32m1") +AVR_MCU ("atmega32u4", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32U4__", 0x0100, 1, "m32u4") +AVR_MCU ("atmega32u6", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32U6__", 0x0100, 1, "m32u6") +AVR_MCU ("atmega406", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega406__", 0x0100, 1, "m406") +AVR_MCU ("atmega64", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64__", 0x0100, 1, "m64") +AVR_MCU ("atmega64a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64A__", 0x0100, 1, "m64a") +AVR_MCU ("atmega640", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega640__", 0x0200, 1, "m640") +AVR_MCU ("atmega644", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega644__", 0x0100, 1, "m644") +AVR_MCU ("atmega644a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega644A__", 0x0100, 1, "m644a") +AVR_MCU ("atmega644p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega644P__", 0x0100, 1, "m644p") +AVR_MCU ("atmega644pa", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega644PA__", 0x0100, 1, "m644pa") +AVR_MCU ("atmega645", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega645__", 0x0100, 1, "m645") +AVR_MCU ("atmega645a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega645A__", 0x0100, 1, "m645a") +AVR_MCU ("atmega645p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega645P__", 0x0100, 1, "m645p") +AVR_MCU ("atmega6450", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6450__", 0x0100, 1, "m6450") +AVR_MCU ("atmega6450a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6450A__", 0x0100, 1, "m6450a") +AVR_MCU ("atmega6450p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6450P__", 0x0100, 1, "m6450p") +AVR_MCU ("atmega649", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega649__", 0x0100, 1, "m649") +AVR_MCU ("atmega649a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega649A__", 0x0100, 1, "m649a") +AVR_MCU ("atmega649p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega649P__", 0x0100, 1, "m649p") +AVR_MCU ("atmega6490", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6490__", 0x0100, 1, "m6490") +AVR_MCU ("atmega16hva", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16HVA__", 0x0100, 1, "m16hva") +AVR_MCU ("atmega16hva2", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega16HVA2__", 0x0100, 1, "m16hva2") +AVR_MCU ("atmega32hvb", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32HVB__", 0x0100, 1, "m32hvb") +AVR_MCU ("atmega6490a", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6490A__", 0x0100, 1, "m6490a") +AVR_MCU ("atmega6490p", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega6490P__", 0x0100, 1, "m6490p") +AVR_MCU ("atmega64c1", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64C1__", 0x0100, 1, "m64c1") +AVR_MCU ("atmega64m1", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64M1__", 0x0100, 1, "m64m1") +AVR_MCU ("atmega64hve", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64HVE__", 0x0100, 1, "m64hve") +AVR_MCU ("atmega64rfa2", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64RFA2__", 0x0200, 1, "m64rfa2") +AVR_MCU ("atmega64rfr2", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega64RFR2__", 0x0200, 1, "m64rfr2") +AVR_MCU ("atmega32hvbrevb", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega32HVBREVB__", 0x0100, 1, "m32hvbrevb") +AVR_MCU ("atmega48hvf", ARCH_AVR5, AVR_ISA_NONE, "__AVR_ATmega48HVF__", 0x0100, 1, "m48hvf") +AVR_MCU ("at90can32", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90CAN32__", 0x0100, 1, "can32") +AVR_MCU ("at90can64", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90CAN64__", 0x0100, 1, "can64") +AVR_MCU ("at90pwm161", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90PWM161__", 0x0100, 1, "90pwm161") +AVR_MCU ("at90pwm216", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90PWM216__", 0x0100, 1, "90pwm216") +AVR_MCU ("at90pwm316", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90PWM316__", 0x0100, 1, "90pwm316") +AVR_MCU ("at90scr100", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90SCR100__", 0x0100, 1, "90scr100") +AVR_MCU ("at90usb646", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90USB646__", 0x0100, 1, "usb646") +AVR_MCU ("at90usb647", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT90USB647__", 0x0100, 1, "usb647") +AVR_MCU ("at94k", ARCH_AVR5, AVR_ISA_NONE, "__AVR_AT94K__", 0x0060, 1, "at94k") +AVR_MCU ("m3000", ARCH_AVR5, AVR_ISA_NONE, "__AVR_M3000__", 0x1000, 1, "m3000") /* Enhanced, == 128K. */ -AVR_MCU ("avr51", ARCH_AVR51, NULL, 0, 0, 0x0100, 2, "m128") -AVR_MCU ("atmega128", ARCH_AVR51, "__AVR_ATmega128__", 0, 0, 0x0100, 2, "m128") -AVR_MCU ("atmega128a", ARCH_AVR51, "__AVR_ATmega128A__", 0, 0, 0x0100, 2, "m128a") -AVR_MCU ("atmega1280", ARCH_AVR51, "__AVR_ATmega1280__", 0, 0, 0x0200, 2, "m1280") -AVR_MCU ("atmega1281", ARCH_AVR51, "__AVR_ATmega1281__", 0, 0, 0x0200, 2, "m1281") -AVR_MCU ("atmega1284", ARCH_AVR51, "__AVR_ATmega1284__", 0, 0, 0x0100, 2, "m1284") -AVR_MCU ("atmega1284p", ARCH_AVR51, "__AVR_ATmega1284P__", 0, 0, 0x0100, 2, "m1284p") -AVR_MCU ("atmega128rfa1", ARCH_AVR51, "__AVR_ATmega128RFA1__", 0, 0, 0x0200, 2, "m128rfa1") -AVR_MCU ("at90can128", ARCH_AVR51, "__AVR_AT90CAN128__", 0, 0, 0x0100, 2, "can128") -AVR_MCU ("at90usb1286", ARCH_AVR51, "__AVR_AT90USB1286__", 0, 0, 0x0100, 2, "usb1286") -AVR_MCU ("at90usb1287", ARCH_AVR51, "__AVR_AT90USB1287__", 0, 0, 0x0100, 2, "usb1287") +AVR_MCU ("avr51", ARCH_AVR51, AVR_ISA_NONE, NULL, 0x0100, 2, "m128") +AVR_MCU ("atmega128", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega128__", 0x0100, 2, "m128") +AVR_MCU ("atmega128a", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega128A__", 0x0100, 2, "m128a") +AVR_MCU ("atmega1280", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega1280__", 0x0200, 2, "m1280") +AVR_MCU ("atmega1281", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega1281__", 0x0200, 2, "m1281") +AVR_MCU ("atmega1284", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega1284__", 0x0100, 2, "m1284") +AVR_MCU ("atmega1284p", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega1284P__", 0x0100, 2, "m1284p") +AVR_MCU ("atmega128rfa1", ARCH_AVR51, AVR_ISA_NONE, "__AVR_ATmega128RFA1__", 0x0200, 2, "m128rfa1") +AVR_MCU ("at90can128", ARCH_AVR51, AVR_ISA_NONE, "__AVR_AT90CAN128__", 0x0100, 2, "can128") +AVR_MCU ("at90usb1286", ARCH_AVR51, AVR_ISA_NONE, "__AVR_AT90USB1286__", 0x0100, 2, "usb1286") +AVR_MCU ("at90usb1287", ARCH_AVR51, AVR_ISA_NONE, "__AVR_AT90USB1287__", 0x0100, 2, "usb1287") /* 3-Byte PC. */ -AVR_MCU ("avr6", ARCH_AVR6, NULL, 0, 0, 0x0200, 4, "m2561") -AVR_MCU ("atmega2560", ARCH_AVR6, "__AVR_ATmega2560__", 0, 0, 0x0200, 4, "m2560") -AVR_MCU ("atmega2561", ARCH_AVR6, "__AVR_ATmega2561__", 0, 0, 0x0200, 4, "m2561") +AVR_MCU ("avr6", ARCH_AVR6, AVR_ISA_NONE, NULL, 0x0200, 4, "m2561") +AVR_MCU ("atmega2560", ARCH_AVR6, AVR_ISA_NONE, "__AVR_ATmega2560__", 0x0200, 4, "m2560") +AVR_MCU ("atmega2561", ARCH_AVR6, AVR_ISA_NONE, "__AVR_ATmega2561__", 0x0200, 4, "m2561") /* Xmega, 16K <= Flash < 64K, RAM <= 64K */ -AVR_MCU ("avrxmega2", ARCH_AVRXMEGA2, NULL, 0, 0, 0x2000, 1, "x32a4") -AVR_MCU ("atxmega16a4", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4__", 0, 0, 0x2000, 1, "x16a4") -AVR_MCU ("atxmega16d4", ARCH_AVRXMEGA2, "__AVR_ATxmega16D4__", 0, 0, 0x2000, 1, "x16d4") -AVR_MCU ("atxmega32a4", ARCH_AVRXMEGA2, "__AVR_ATxmega32A4__", 0, 0, 0x2000, 1, "x32a4") -AVR_MCU ("atxmega32d4", ARCH_AVRXMEGA2, "__AVR_ATxmega32D4__", 0, 0, 0x2000, 1, "x32d4") -AVR_MCU ("atxmega32x1", ARCH_AVRXMEGA2, "__AVR_ATxmega32X1__", 0, 0, 0x2000, 1, "x32x1") -AVR_MCU ("atmxt112sl", ARCH_AVRXMEGA2, "__AVR_ATMXT112SL__", 0, 0, 0x2000, 1, "mxt112sl") -AVR_MCU ("atmxt224", ARCH_AVRXMEGA2, "__AVR_ATMXT224__", 0, 0, 0x2000, 1, "mxt224") -AVR_MCU ("atmxt224e", ARCH_AVRXMEGA2, "__AVR_ATMXT224E__", 0, 0, 0x2000, 1, "mxt224e") -AVR_MCU ("atmxt336s", ARCH_AVRXMEGA2, "__AVR_ATMXT336S__", 0, 0, 0x2000, 1, "mxt336s") -AVR_MCU ("atxmega16a4u", ARCH_AVRXMEGA2, "__AVR_ATxmega16A4U__", 0, 0, 0x2000, 1, "x16a4u") -AVR_MCU ("atxmega16c4", ARCH_AVRXMEGA2, "__AVR_ATxmega16C4__", 0, 0, 0x2000, 1, "x16c4") -AVR_MCU ("atxmega32a4u", ARCH_AVRXMEGA2, "__AVR_ATxmega32A4U__", 0, 0, 0x2000, 1, "x32a4u") -AVR_MCU ("atxmega32c4", ARCH_AVRXMEGA2, "__AVR_ATxmega32C4__", 0, 0, 0x2000, 1, "x32c4") -AVR_MCU ("atxmega32e5", ARCH_AVRXMEGA2, "__AVR_ATxmega32E5__", 0, 0, 0x2000, 1, "x32e5") +AVR_MCU ("avrxmega2", ARCH_AVRXMEGA2, AVR_ISA_NONE, NULL, 0x2000, 1, "x32a4") +AVR_MCU ("atxmega16a4", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega16A4__", 0x2000, 1, "x16a4") +AVR_MCU ("atxmega16d4", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega16D4__", 0x2000, 1, "x16d4") +AVR_MCU ("atxmega32a4", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32A4__", 0x2000, 1, "x32a4") +AVR_MCU ("atxmega32d4", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32D4__", 0x2000, 1, "x32d4") +AVR_MCU ("atxmega32x1", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32X1__", 0x2000, 1, "x32x1") +AVR_MCU ("atmxt112sl", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATMXT112SL__", 0x2000, 1, "mxt112sl") +AVR_MCU ("atmxt224", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATMXT224__", 0x2000, 1, "mxt224") +AVR_MCU ("atmxt224e", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATMXT224E__", 0x2000, 1, "mxt224e") +AVR_MCU ("atmxt336s", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATMXT336S__", 0x2000, 1, "mxt336s") +AVR_MCU ("atxmega16a4u", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega16A4U__", 0x2000, 1, "x16a4u") +AVR_MCU ("atxmega16c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega16C4__", 0x2000, 1, "x16c4") +AVR_MCU ("atxmega32a4u", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32A4U__", 0x2000, 1, "x32a4u") +AVR_MCU ("atxmega32c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32C4__", 0x2000, 1, "x32c4") +AVR_MCU ("atxmega32e5", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32E5__", 0x2000, 1, "x32e5") /* Xmega, 64K < Flash <= 128K, RAM <= 64K */ -AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, NULL, 0, 0, 0x2000, 2, "x64a4") -AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3__", 0, 0, 0x2000, 2, "x64a3") -AVR_MCU ("atxmega64d3", ARCH_AVRXMEGA4, "__AVR_ATxmega64D3__", 0, 0, 0x2000, 2, "x64d3") -AVR_MCU ("atxmega64a3u", ARCH_AVRXMEGA4, "__AVR_ATxmega64A3U__", 0, 0, 0x2000, 2, "x64a3u") -AVR_MCU ("atxmega64a4u", ARCH_AVRXMEGA4, "__AVR_ATxmega64A4U__", 0, 0, 0x2000, 2, "x64a4u") -AVR_MCU ("atxmega64b1", ARCH_AVRXMEGA4, "__AVR_ATxmega64B1__", 0, 0, 0x2000, 2, "x64b1") -AVR_MCU ("atxmega64b3", ARCH_AVRXMEGA4, "__AVR_ATxmega64B3__", 0, 0, 0x2000, 2, "x64b3") -AVR_MCU ("atxmega64c3", ARCH_AVRXMEGA4, "__AVR_ATxmega64C3__", 0, 0, 0x2000, 2, "x64c3") -AVR_MCU ("atxmega64d4", ARCH_AVRXMEGA4, "__AVR_ATxmega64D4__", 0, 0, 0x2000, 2, "x64d4") +AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, AVR_ISA_NONE, NULL, 0x2000, 2, "x64a4") +AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64A3__", 0x2000, 2, "x64a3") +AVR_MCU ("atxmega64d3", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64D3__", 0x2000, 2, "x64d3") +AVR_MCU ("atxmega64a3u", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64A3U__", 0x2000, 2, "x64a3u") +AVR_MCU ("atxmega64a4u", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64A4U__", 0x2000, 2, "x64a4u") +AVR_MCU ("atxmega64b1", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64B1__", 0x2000, 2, "x64b1") +AVR_MCU ("atxmega64b3", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64B3__", 0x2000, 2, "x64b3") +AVR_MCU ("atxmega64c3", ARCH_AVRXMEGA4, AVR_ISA_RMW, "__AVR_ATxmega64C3__", 0x2000, 2, "x64c3") +AVR_MCU ("atxmega64d4", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64D4__", 0x2000, 2, "x64d4") /* Xmega, 64K < Flash <= 128K, RAM > 64K */ -AVR_MCU ("avrxmega5", ARCH_AVRXMEGA5, NULL, 0, 0, 0x2000, 2, "x64a1") -AVR_MCU ("atxmega64a1", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1__", 0, 0, 0x2000, 2, "x64a1") -AVR_MCU ("atxmega64a1u", ARCH_AVRXMEGA5, "__AVR_ATxmega64A1U__", 0, 0, 0x2000, 2, "x64a1u") +AVR_MCU ("avrxmega5", ARCH_AVRXMEGA5, AVR_ISA_NONE, NULL, 0x2000, 2, "x64a1") +AVR_MCU ("atxmega64a1", ARCH_AVRXMEGA5, AVR_ISA_NONE, "__AVR_ATxmega64A1__", 0x2000, 2, "x64a1") +AVR_MCU ("atxmega64a1u", ARCH_AVRXMEGA5, AVR_ISA_RMW, "__AVR_ATxmega64A1U__", 0x2000, 2, "x64a1u") /* Xmega, 128K < Flash, RAM <= 64K */ -AVR_MCU ("avrxmega6", ARCH_AVRXMEGA6, NULL, 0, 0, 0x2000, 6, "x128a3") -AVR_MCU ("atxmega128a3", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3__", 0, 0, 0x2000, 3, "x128a3") -AVR_MCU ("atxmega128d3", ARCH_AVRXMEGA6, "__AVR_ATxmega128D3__", 0, 0, 0x2000, 3, "x128d3") -AVR_MCU ("atxmega192a3", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3__", 0, 0, 0x2000, 4, "x192a3") -AVR_MCU ("atxmega192d3", ARCH_AVRXMEGA6, "__AVR_ATxmega192D3__", 0, 0, 0x2000, 4, "x192d3") -AVR_MCU ("atxmega256a3", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3__", 0, 0, 0x2000, 5, "x256a3") -AVR_MCU ("atxmega256a3b", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3B__", 0, 0, 0x2000, 5, "x256a3b") -AVR_MCU ("atxmega256a3bu", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3BU__", 0, 0, 0x2000, 5, "x256a3bu") -AVR_MCU ("atxmega256d3", ARCH_AVRXMEGA6, "__AVR_ATxmega256D3__", 0, 0, 0x2000, 5, "x256d3") -AVR_MCU ("atxmega128a3u", ARCH_AVRXMEGA6, "__AVR_ATxmega128A3U__", 0, 0, 0x2000, 3, "x128a3u") -AVR_MCU ("atxmega128b1", ARCH_AVRXMEGA6, "__AVR_ATxmega128B1__", 0, 0, 0x2000, 3, "x128b1") -AVR_MCU ("atxmega128b3", ARCH_AVRXMEGA6, "__AVR_ATxmega128B3__", 0, 0, 0x2000, 3, "x128b3") -AVR_MCU ("atxmega128c3", ARCH_AVRXMEGA6, "__AVR_ATxmega128C3__", 0, 0, 0x2000, 3, "x128c3") -AVR_MCU ("atxmega128d4", ARCH_AVRXMEGA6, "__AVR_ATxmega128D4__", 0, 0, 0x2000, 3, "x128d4") -AVR_MCU ("atmxt540s", ARCH_AVRXMEGA6, "__AVR_ATMXT540S__", 0, 0, 0x2000, 2, "mxt540s") -AVR_MCU ("atmxt540sreva", ARCH_AVRXMEGA6, "__AVR_ATMXT540SREVA__", 0, 0, 0x2000, 2, "mxt540sreva") -AVR_MCU ("atxmega192a3u", ARCH_AVRXMEGA6, "__AVR_ATxmega192A3U__", 0, 0, 0x2000, 4, "x192a3u") -AVR_MCU ("atxmega192c3", ARCH_AVRXMEGA6, "__AVR_ATxmega192C3__", 0, 0, 0x2000, 4, "x192c3") -AVR_MCU ("atxmega256a3u", ARCH_AVRXMEGA6, "__AVR_ATxmega256A3U__", 0, 0, 0x2000, 5, "x256a3u") -AVR_MCU ("atxmega256c3", ARCH_AVRXMEGA6, "__AVR_ATxmega256C3__", 0, 0, 0x2000, 5, "x256c3") -AVR_MCU ("atxmega384c3", ARCH_AVRXMEGA6, "__AVR_ATxmega384C3__", 0, 0, 0x2000, 6, "x384c3") -AVR_MCU ("atxmega384d3", ARCH_AVRXMEGA6, "__AVR_ATxmega384D3__", 0, 0, 0x2000, 6, "x384d3") +AVR_MCU ("avrxmega6", ARCH_AVRXMEGA6, AVR_ISA_NONE, NULL, 0x2000, 6, "x128a3") +AVR_MCU ("atxmega128a3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega128A3__", 0x2000, 3, "x128a3") +AVR_MCU ("atxmega128d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega128D3__", 0x2000, 3, "x128d3") +AVR_MCU ("atxmega192a3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega192A3__", 0x2000, 4, "x192a3") +AVR_MCU ("atxmega192d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega192D3__", 0x2000, 4, "x192d3") +AVR_MCU ("atxmega256a3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3__", 0x2000, 5, "x256a3") +AVR_MCU ("atxmega256a3b", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3B__", 0x2000, 5, "x256a3b") +AVR_MCU ("atxmega256a3bu", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256A3BU__", 0x2000, 5, "x256a3bu") +AVR_MCU ("atxmega256d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega256D3__", 0x2000, 5, "x256d3") +AVR_MCU ("atxmega128a3u", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128A3U__", 0x2000, 3, "x128a3u") +AVR_MCU ("atxmega128b1", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128B1__", 0x2000, 3, "x128b1") +AVR_MCU ("atxmega128b3", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128B3__", 0x2000, 3, "x128b3") +AVR_MCU ("atxmega128c3", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega128C3__", 0x2000, 3, "x128c3") +AVR_MCU ("atxmega128d4", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega128D4__", 0x2000, 3, "x128d4") +AVR_MCU ("atmxt540s", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATMXT540S__", 0x2000, 2, "mxt540s") +AVR_MCU ("atmxt540sreva", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATMXT540SREVA__", 0x2000, 2, "mxt540sreva") +AVR_MCU ("atxmega192a3u", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega192A3U__", 0x2000, 4, "x192a3u") +AVR_MCU ("atxmega192c3", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega192C3__", 0x2000, 4, "x192c3") +AVR_MCU ("atxmega256a3u", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega256A3U__", 0x2000, 5, "x256a3u") +AVR_MCU ("atxmega256c3", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega256C3__", 0x2000, 5, "x256c3") +AVR_MCU ("atxmega384c3", ARCH_AVRXMEGA6, AVR_ISA_RMW, "__AVR_ATxmega384C3__", 0x2000, 6, "x384c3") +AVR_MCU ("atxmega384d3", ARCH_AVRXMEGA6, AVR_ISA_NONE, "__AVR_ATxmega384D3__", 0x2000, 6, "x384d3") /* Xmega, 128K < Flash, RAM > 64K RAM. */ -AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, NULL, 0, 0, 0x2000, 3, "x128a1") -AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1__", 0, 0, 0x2000, 3, "x128a1") -AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, "__AVR_ATxmega128A1U__", 0, 0, 0x2000, 3, "x128a1u") -AVR_MCU ("atxmega128a4u", ARCH_AVRXMEGA7, "__AVR_ATxmega128A4U__", 0, 0, 0x2000, 3, "x128a4u") +AVR_MCU ("avrxmega7", ARCH_AVRXMEGA7, AVR_ISA_NONE, NULL, 0x2000, 3, "x128a1") +AVR_MCU ("atxmega128a1", ARCH_AVRXMEGA7, AVR_ISA_NONE, "__AVR_ATxmega128A1__", 0x2000, 3, "x128a1") +AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A1U__", 0x2000, 3, "x128a1u") +AVR_MCU ("atxmega128a4u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A4U__", 0x2000, 3, "x128a4u") /* Assembler only. */ -AVR_MCU ("avr1", ARCH_AVR1, NULL, 0, 0, 0x0060, 1, "s1200") -AVR_MCU ("at90s1200", ARCH_AVR1, "__AVR_AT90S1200__", 0, 0, 0x0060, 1, "s1200") -AVR_MCU ("attiny11", ARCH_AVR1, "__AVR_ATtiny11__", 0, 0, 0x0060, 1, "tn11") -AVR_MCU ("attiny12", ARCH_AVR1, "__AVR_ATtiny12__", 0, 0, 0x0060, 1, "tn12") -AVR_MCU ("attiny15", ARCH_AVR1, "__AVR_ATtiny15__", 0, 0, 0x0060, 1, "tn15") -AVR_MCU ("attiny28", ARCH_AVR1, "__AVR_ATtiny28__", 0, 0, 0x0060, 1, "tn28") +AVR_MCU ("avr1", ARCH_AVR1, AVR_ISA_NONE, NULL, 0x0060, 1, "s1200") +AVR_MCU ("at90s1200", ARCH_AVR1, AVR_ISA_NONE, "__AVR_AT90S1200__", 0x0060, 1, "s1200") +AVR_MCU ("attiny11", ARCH_AVR1, AVR_ISA_NONE, "__AVR_ATtiny11__", 0x0060, 1, "tn11") +AVR_MCU ("attiny12", ARCH_AVR1, AVR_ISA_NONE, "__AVR_ATtiny12__", 0x0060, 1, "tn12") +AVR_MCU ("attiny15", ARCH_AVR1, AVR_ISA_NONE, "__AVR_ATtiny15__", 0x0060, 1, "tn15") +AVR_MCU ("attiny28", ARCH_AVR1, AVR_ISA_NONE, "__AVR_ATtiny28__", 0x0060, 1, "tn28") diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index a1fb8eeae86..25075b2f4b3 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -10122,7 +10122,7 @@ test_hard_reg_class (enum reg_class rclass, rtx x) static bool avr_2word_insn_p (rtx insn) { - if (avr_current_device->errata_skip + if ((avr_current_device->dev_attribute & AVR_ERRATA_SKIP) || !insn || 2 != get_attr_length (insn)) { diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 74be83c8aa0..78434ec5e0d 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -88,8 +88,9 @@ enum __AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */ -#define AVR_HAVE_8BIT_SP \ - (avr_current_device->short_sp || TARGET_TINY_STACK || avr_sp8) +#define AVR_HAVE_8BIT_SP \ + ((avr_current_device->dev_attribute & AVR_SHORT_SP) || \ + TARGET_TINY_STACK || avr_sp8) #define AVR_HAVE_SPH (!avr_sp8) diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index f2d8605cd20..d7baa4a8383 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -5342,7 +5342,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "!AVR_HAVE_JMP_CALL - || !avr_current_device->errata_skip" + || !(avr_current_device->dev_attribute & AVR_ERRATA_SKIP)" { if (operands[2] == CONST0_RTX (<MODE>mode)) operands[2] = zero_reg_rtx; diff --git a/gcc/config/avr/driver-avr.c b/gcc/config/avr/driver-avr.c index cb5dd1d1d89..76c8b398064 100644 --- a/gcc/config/avr/driver-avr.c +++ b/gcc/config/avr/driver-avr.c @@ -59,8 +59,8 @@ avr_device_to_as (int argc, const char **argv) avr_set_current_device (argv[0]); return concat ("-mmcu=", avr_current_arch->arch_name, - avr_current_device->errata_skip ? "" : " -mno-skip-bug", - NULL); + avr_current_device->dev_attribute & AVR_ERRATA_SKIP ? "" : " -mno-skip-bug", + avr_current_device->dev_attribute & AVR_ISA_RMW ? " -mrmw" : "", NULL); } /* Returns command line parameters to pass to ld. */ @@ -144,7 +144,7 @@ avr_device_to_sp8 (int argc, const char **argv) || avr_current_device->arch == ARCH_AVR25)) return ""; - return avr_current_device->short_sp + return (avr_current_device->dev_attribute & AVR_SHORT_SP) ? "-msp8" : "%<msp8"; } diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk index 90e5e5cfd36..1dfeabbee49 100644 --- a/gcc/config/avr/genmultilib.awk +++ b/gcc/config/avr/genmultilib.awk @@ -86,7 +86,7 @@ BEGIN { name = $2 gsub ("\"", "", name) - if ($4 == "NULL") + if ($5 == "NULL") { core = name @@ -106,7 +106,17 @@ BEGIN { if (core == "avr1") next - tiny_stack[name] = $5 + # split device specific feature list + n = split($4,dev_attribute,"|") + + # set tiny_stack false by default + tiny_stack[name] = 0 + for (i=1; i <= n; i++) + if (dev_attribute[i] == "AVR_SHORT_SP") { + tiny_stack[name] = 1 + break + } + mcu[n_mcu] = name n_mcu++ option[name] = "mmcu=" name diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h index 1fce7011b2b..c1d5553123d 100644 --- a/gcc/config/elfos.h +++ b/gcc/config/elfos.h @@ -287,7 +287,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Write the extra assembler code needed to declare an object properly. */ #ifdef HAVE_GAS_GNU_UNIQUE_OBJECT -#define USE_GNU_UNIQUE_OBJECT 1 +#define USE_GNU_UNIQUE_OBJECT flag_gnu_unique #else #define USE_GNU_UNIQUE_OBJECT 0 #endif diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index 59b24107a68..f3955b916e9 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -145,6 +145,13 @@ static rtx frame_insn (rtx); hook_bool_const_tree_hwi_hwi_const_tree_true #define TARGET_ASM_OUTPUT_MI_THUNK epiphany_output_mi_thunk +/* ??? we can use larger offsets for wider-mode sized accesses, but there + is no concept of anchors being dependent on the modes that they are used + for, so we can only use an offset range that would suit all modes. */ +#define TARGET_MAX_ANCHOR_OFFSET (optimize_size ? 31 : 2047) +/* We further restrict the minimum to be a multiple of eight. */ +#define TARGET_MIN_ANCHOR_OFFSET (optimize_size ? 0 : -2040) + #include "target-def.h" #undef TARGET_ASM_ALIGNED_HI_OP @@ -763,6 +770,28 @@ epiphany_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (1); return true; + case COMPARE: + switch (GET_MODE (x)) + { + /* There are a number of single-insn combiner patterns that use + the flag side effects of arithmetic. */ + case CC_N_NEmode: + case CC_C_LTUmode: + case CC_C_GTUmode: + return true; + default: + return false; + } + + + case SET: + { + rtx src = SET_SRC (x); + if (BINARY_P (src)) + *total = 0; + return false; + } + default: return false; } @@ -2003,7 +2032,7 @@ epiphany_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) && LEGITIMATE_OFFSET_ADDRESS_P (mode, XEXP ((x), 1))) return true; if (mode == BLKmode) - return true; + return epiphany_legitimate_address_p (SImode, x, strict); return false; } diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h index cffb00c0354..1ca92e07b9e 100644 --- a/gcc/config/epiphany/epiphany.h +++ b/gcc/config/epiphany/epiphany.h @@ -942,4 +942,15 @@ extern rtl_opt_pass *make_pass_resolve_sw_modes (gcc::context *ctxt); #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ epiphany_start_function ((FILE), (NAME), (DECL)) +/* This is how we tell the assembler that two symbols have the same value. */ +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \ + do \ + { \ + assemble_name (FILE, NAME1); \ + fputs (" = ", FILE); \ + assemble_name (FILE, NAME2); \ + fputc ('\n', FILE); \ + } \ + while (0) + #endif /* !GCC_EPIPHANY_H */ diff --git a/gcc/config/epiphany/epiphany.md b/gcc/config/epiphany/epiphany.md index 2844eeea773..d8d5555b099 100644 --- a/gcc/config/epiphany/epiphany.md +++ b/gcc/config/epiphany/epiphany.md @@ -2380,7 +2380,7 @@ (plus:SI (reg:SI GPR_SP) (match_operand:SI 0 "arith_operand" "rL"))) (clobber (reg:CC CC_REGNUM)) (clobber (reg:SI STATUS_REGNUM)) - (clobber (match_operand:BLK 1 "memory_operand" "=m"))] + (clobber (match_operand:BLK 1 "memclob_operand" "=X"))] "reload_completed" "add sp,sp,%0") @@ -2396,7 +2396,7 @@ (match_operand 1 "any_gpr_operand" "r")) (set (reg:SI GPR_SP) (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn"))) - (clobber (match_operand:BLK 3 "memory_operand" "=m"))] + (clobber (match_operand:BLK 3 "memclob_operand" "=X"))] "reload_completed" { return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 diff --git a/gcc/config/epiphany/predicates.md b/gcc/config/epiphany/predicates.md index fb8fd88ba7e..fb5ee1239c4 100644 --- a/gcc/config/epiphany/predicates.md +++ b/gcc/config/epiphany/predicates.md @@ -358,6 +358,11 @@ (and (match_code "mem") (match_test "post_modify_address (XEXP (op, 0), Pmode)"))) +; used in the memory clobber of stack_adjust_str, allows addresses with +; large offsets. +(define_predicate "memclob_operand" + (match_code "mem")) + (define_predicate "nonsymbolic_immediate_operand" (ior (match_test "immediate_operand (op, mode)") (match_code "const_vector"))) /* Is this specific enough? */ diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c index 17048d7b585..41bee9276c8 100644 --- a/gcc/config/host-linux.c +++ b/gcc/config/host-linux.c @@ -86,6 +86,8 @@ # define TRY_EMPTY_VM_SPACE 0x60000000 #elif defined(__mc68000__) # define TRY_EMPTY_VM_SPACE 0x40000000 +#elif defined(__aarch64__) && defined(__ILP32__) +# define TRY_EMPTY_VM_SPACE 0x60000000 #elif defined(__aarch64__) # define TRY_EMPTY_VM_SPACE 0x1000000000 #elif defined(__ARM_EABI__) diff --git a/gcc/config/i386/bmiintrin.h b/gcc/config/i386/bmiintrin.h index b86adf179cf..b2d7c60eaf8 100644 --- a/gcc/config/i386/bmiintrin.h +++ b/gcc/config/i386/bmiintrin.h @@ -40,7 +40,6 @@ __tzcnt_u16 (unsigned short __X) return __builtin_ctzs (__X); } - extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __andn_u32 (unsigned int __X, unsigned int __Y) { @@ -66,17 +65,34 @@ __blsi_u32 (unsigned int __X) } extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u32 (unsigned int __X) +{ + return __blsi_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsmsk_u32 (unsigned int __X) { return __X ^ (__X - 1); } extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u32 (unsigned int __X) +{ + return __blsmsk_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsr_u32 (unsigned int __X) { return __X & (__X - 1); } +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u32 (unsigned int __X) +{ + return __blsr_u32 (__X); +} extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __tzcnt_u32 (unsigned int __X) @@ -84,6 +100,12 @@ __tzcnt_u32 (unsigned int __X) return __builtin_ctz (__X); } +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u32 (unsigned int __X) +{ + return __builtin_ctz (__X); +} + #ifdef __x86_64__ extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -111,23 +133,47 @@ __blsi_u64 (unsigned long long __X) } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u64 (unsigned long long __X) +{ + return __blsi_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsmsk_u64 (unsigned long long __X) { return __X ^ (__X - 1); } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u64 (unsigned long long __X) +{ + return __blsmsk_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsr_u64 (unsigned long long __X) { return __X & (__X - 1); } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u64 (unsigned long long __X) +{ + return __blsr_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __tzcnt_u64 (unsigned long long __X) { return __builtin_ctzll (__X); } +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u64 (unsigned long long __X) +{ + return __builtin_ctzll (__X); +} + #endif /* __x86_64__ */ #ifdef __DISABLE_BMI__ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 46a4d2e528d..3aa2ac4832c 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see #include "context.h" #include "pass_manager.h" #include "target-globals.h" +#include "tree-vectorizer.h" static rtx legitimize_dllimport_symbol (rtx, bool); static rtx legitimize_pe_coff_extern_decl (rtx, bool); @@ -1739,7 +1740,7 @@ struct processor_costs slm_cost = { 1, /* scalar load_cost. */ 1, /* scalar_store_cost. */ 1, /* vec_stmt_cost. */ - 1, /* vec_to_scalar_cost. */ + 4, /* vec_to_scalar_cost. */ 1, /* scalar_to_vec_cost. */ 1, /* vec_align_load_cost. */ 2, /* vec_unalign_load_cost. */ @@ -1816,7 +1817,7 @@ struct processor_costs intel_cost = { 1, /* scalar load_cost. */ 1, /* scalar_store_cost. */ 1, /* vec_stmt_cost. */ - 1, /* vec_to_scalar_cost. */ + 4, /* vec_to_scalar_cost. */ 1, /* scalar_to_vec_cost. */ 1, /* vec_align_load_cost. */ 2, /* vec_unalign_load_cost. */ @@ -6807,8 +6808,9 @@ classify_argument (enum machine_mode mode, const_tree type, } /* Examine the argument and return set number of register required in each - class. Return 0 iff parameter should be passed in memory. */ -static int + class. Return true iff parameter should be passed in memory. */ + +static bool examine_argument (enum machine_mode mode, const_tree type, int in_return, int *int_nregs, int *sse_nregs) { @@ -6817,8 +6819,9 @@ examine_argument (enum machine_mode mode, const_tree type, int in_return, *int_nregs = 0; *sse_nregs = 0; + if (!n) - return 0; + return true; for (n--; n >= 0; n--) switch (regclass[n]) { @@ -6836,15 +6839,15 @@ examine_argument (enum machine_mode mode, const_tree type, int in_return, break; case X86_64_X87_CLASS: case X86_64_X87UP_CLASS: + case X86_64_COMPLEX_X87_CLASS: if (!in_return) - return 0; + return true; break; - case X86_64_COMPLEX_X87_CLASS: - return in_return ? 2 : 0; case X86_64_MEMORY_CLASS: gcc_unreachable (); } - return 1; + + return false; } /* Construct container for the argument used by GCC interface. See @@ -6874,8 +6877,8 @@ construct_container (enum machine_mode mode, enum machine_mode orig_mode, n = classify_argument (mode, type, regclass, 0); if (!n) return NULL; - if (!examine_argument (mode, type, in_return, &needed_intregs, - &needed_sseregs)) + if (examine_argument (mode, type, in_return, &needed_intregs, + &needed_sseregs)) return NULL; if (needed_intregs > nintregs || needed_sseregs > nsseregs) return NULL; @@ -7194,7 +7197,7 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode, || VALID_AVX256_REG_MODE (mode))) return; - if (examine_argument (mode, type, 0, &int_nregs, &sse_nregs) + if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs) && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs) { cum->nregs -= int_nregs; @@ -7989,95 +7992,87 @@ ix86_libcall_value (enum machine_mode mode) /* Return true iff type is returned in memory. */ -static bool ATTRIBUTE_UNUSED -return_in_memory_32 (const_tree type, enum machine_mode mode) +static bool +ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) { +#ifdef SUBTARGET_RETURN_IN_MEMORY + return SUBTARGET_RETURN_IN_MEMORY (type, fntype); +#else + const enum machine_mode mode = type_natural_mode (type, NULL, true); HOST_WIDE_INT size; - if (mode == BLKmode) - return true; - - size = int_size_in_bytes (type); - - if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8) - return false; - - if (VECTOR_MODE_P (mode) || mode == TImode) + if (TARGET_64BIT) { - /* User-created vectors small enough to fit in EAX. */ - if (size < 8) - return false; - - /* MMX/3dNow values are returned in MM0, - except when it doesn't exits or the ABI prescribes otherwise. */ - if (size == 8) - return !TARGET_MMX || TARGET_VECT8_RETURNS; + if (ix86_function_type_abi (fntype) == MS_ABI) + { + size = int_size_in_bytes (type); - /* SSE values are returned in XMM0, except when it doesn't exist. */ - if (size == 16) - return !TARGET_SSE; + /* __m128 is returned in xmm0. */ + if ((!type || VECTOR_INTEGER_TYPE_P (type) + || INTEGRAL_TYPE_P (type) + || VECTOR_FLOAT_TYPE_P (type)) + && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode)) + && !COMPLEX_MODE_P (mode) + && (GET_MODE_SIZE (mode) == 16 || size == 16)) + return false; - /* AVX values are returned in YMM0, except when it doesn't exist. */ - if (size == 32) - return !TARGET_AVX; + /* Otherwise, the size must be exactly in [1248]. */ + return size != 1 && size != 2 && size != 4 && size != 8; + } + else + { + int needed_intregs, needed_sseregs; - /* AVX512F values are returned in ZMM0, except when it doesn't exist. */ - if (size == 64) - return !TARGET_AVX512F; + return examine_argument (mode, type, 1, + &needed_intregs, &needed_sseregs); + } } + else + { + if (mode == BLKmode) + return true; - if (mode == XFmode) - return false; + size = int_size_in_bytes (type); - if (size > 12) - return true; + if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8) + return false; - /* OImode shouldn't be used directly. */ - gcc_assert (mode != OImode); + if (VECTOR_MODE_P (mode) || mode == TImode) + { + /* User-created vectors small enough to fit in EAX. */ + if (size < 8) + return false; - return false; -} + /* Unless ABI prescibes otherwise, + MMX/3dNow values are returned in MM0 if available. */ + + if (size == 8) + return TARGET_VECT8_RETURNS || !TARGET_MMX; -static bool ATTRIBUTE_UNUSED -return_in_memory_64 (const_tree type, enum machine_mode mode) -{ - int needed_intregs, needed_sseregs; - return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs); -} + /* SSE values are returned in XMM0 if available. */ + if (size == 16) + return !TARGET_SSE; -static bool ATTRIBUTE_UNUSED -return_in_memory_ms_64 (const_tree type, enum machine_mode mode) -{ - HOST_WIDE_INT size = int_size_in_bytes (type); + /* AVX values are returned in YMM0 if available. */ + if (size == 32) + return !TARGET_AVX; - /* __m128 is returned in xmm0. */ - if ((!type || VECTOR_INTEGER_TYPE_P (type) || INTEGRAL_TYPE_P (type) - || VECTOR_FLOAT_TYPE_P (type)) - && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode)) - && !COMPLEX_MODE_P (mode) && (GET_MODE_SIZE (mode) == 16 || size == 16)) - return false; + /* AVX512F values are returned in ZMM0 if available. */ + if (size == 64) + return !TARGET_AVX512F; + } - /* Otherwise, the size must be exactly in [1248]. */ - return size != 1 && size != 2 && size != 4 && size != 8; -} + if (mode == XFmode) + return false; -static bool -ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) -{ -#ifdef SUBTARGET_RETURN_IN_MEMORY - return SUBTARGET_RETURN_IN_MEMORY (type, fntype); -#else - const enum machine_mode mode = type_natural_mode (type, NULL, true); + if (size > 12) + return true; - if (TARGET_64BIT) - { - if (ix86_function_type_abi (fntype) == MS_ABI) - return return_in_memory_ms_64 (type, mode); - else - return return_in_memory_64 (type, mode); + /* OImode shouldn't be used directly. */ + gcc_assert (mode != OImode); + + return false; } - else - return return_in_memory_32 (type, mode); #endif } @@ -44031,7 +44026,7 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) gcc_unreachable (); case V8HImode: - if (TARGET_SSSE3) + if (TARGET_SSSE3 && !TARGET_SLOW_PSHUFB) return expand_vec_perm_pshufb2 (d); else { @@ -44054,7 +44049,7 @@ expand_vec_perm_even_odd_1 (struct expand_vec_perm_d *d, unsigned odd) break; case V16QImode: - if (TARGET_SSSE3) + if (TARGET_SSSE3 && !TARGET_SLOW_PSHUFB) return expand_vec_perm_pshufb2 (d); else { @@ -46334,6 +46329,18 @@ ix86_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, count *= 50; /* FIXME. */ retval = (unsigned) (count * stmt_cost); + + /* We need to multiply all vector stmt cost by 1.7 (estimated cost) + for Silvermont as it has out of order integer pipeline and can execute + 2 scalar instruction per tick, but has in order SIMD pipeline. */ + if (TARGET_SILVERMONT || TARGET_INTEL) + if (stmt_info && stmt_info->stmt) + { + tree lhs_op = gimple_get_lhs (stmt_info->stmt); + if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE) + retval = (retval * 17) / 10; + } + cost[where] += retval; return retval; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 51659deb309..1a884d86c35 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -425,6 +425,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST]; ix86_tune_features[X86_TUNE_USE_VECTOR_FP_CONVERTS] #define TARGET_USE_VECTOR_CONVERTS \ ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS] +#define TARGET_SLOW_PSHUFB \ + ix86_tune_features[X86_TUNE_SLOW_PSHUFB] #define TARGET_FUSE_CMP_AND_BRANCH_32 \ ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH_32] #define TARGET_FUSE_CMP_AND_BRANCH_64 \ diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index 8399102671c..9b0ff360ab3 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -386,6 +386,10 @@ DEF_TUNE (X86_TUNE_USE_VECTOR_FP_CONVERTS, "use_vector_fp_converts", from integer to FP. */ DEF_TUNE (X86_TUNE_USE_VECTOR_CONVERTS, "use_vector_converts", m_AMDFAM10) +/* X86_TUNE_SLOW_SHUFB: Indicates tunings with slow pshufb instruction. */ +DEF_TUNE (X86_TUNE_SLOW_PSHUFB, "slow_pshufb", + m_BONNELL | m_SILVERMONT | m_INTEL) + /*****************************************************************************/ /* AVX instruction selection tuning (some of SSE flags affects AVX, too) */ /*****************************************************************************/ diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index 49e48954f51..f6834fd1e94 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -92,6 +92,9 @@ ;; but the DSP version allows any accumulator target. (define_register_constraint "ka" "ISA_HAS_DSP_MULT ? ACC_REGS : MD_REGS") +(define_register_constraint "kb" "M16_STORE_REGS" + "@internal") + (define_constraint "kf" "@internal" (match_operand 0 "force_to_mem_operand")) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 143169bc150..83fe55b6661 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -648,14 +648,15 @@ static mips_one_only_stub *mips16_set_fcsr_stub; /* Index R is the smallest register class that contains register R. */ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = { - LEA_REGS, LEA_REGS, M16_REGS, V1_REG, - M16_REGS, M16_REGS, M16_REGS, M16_REGS, - LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, - LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, - M16_REGS, M16_REGS, LEA_REGS, LEA_REGS, - LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, - T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS, - LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + LEA_REGS, LEA_REGS, M16_STORE_REGS, V1_REG, + M16_STORE_REGS, M16_STORE_REGS, M16_STORE_REGS, M16_STORE_REGS, + LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + M16_REGS, M16_STORE_REGS, LEA_REGS, LEA_REGS, + LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS, + LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index a786d4ce303..b25865b6dfb 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1870,6 +1870,7 @@ struct mips_cpu_info { enum reg_class { NO_REGS, /* no registers in set */ + M16_STORE_REGS, /* microMIPS store registers */ M16_REGS, /* mips16 directly accessible registers */ T_REG, /* mips16 T register ($24) */ M16_T_REGS, /* mips16 registers plus T register */ @@ -1907,6 +1908,7 @@ enum reg_class #define REG_CLASS_NAMES \ { \ "NO_REGS", \ + "M16_STORE_REGS", \ "M16_REGS", \ "T_REG", \ "M16_T_REGS", \ @@ -1947,6 +1949,7 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ + { 0x000200fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_STORE_REGS */ \ { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_REGS */ \ { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* T_REG */ \ { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_T_REGS */ \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 1e3e9e65957..f914ab67d8a 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4437,7 +4437,7 @@ (define_insn "*mov<mode>_internal" [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,!u,!u,d,e,!u,!ks,d,ZS,ZT,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m") - (match_operand:IMOVE32 1 "move_operand" "d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!u,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] + (match_operand:IMOVE32 1 "move_operand" "d,J,Udb7,Yd,Yf,ZT,ZS,m,!ks,!kbJ,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] "!TARGET_MIPS16 && (register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode))" @@ -4578,7 +4578,7 @@ (define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZU,m,*a,*d") - (match_operand:HI 1 "move_operand" "d,J,I,ZU,m,!u,dJ,*d*J,*a"))] + (match_operand:HI 1 "move_operand" "d,J,I,ZU,m,!kbJ,dJ,*d*J,*a"))] "!TARGET_MIPS16 && (register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode))" @@ -4654,7 +4654,7 @@ (define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,!u,d,!u,d,ZV,m,*a,*d") - (match_operand:QI 1 "move_operand" "d,J,I,ZW,m,!u,dJ,*d*J,*a"))] + (match_operand:QI 1 "move_operand" "d,J,I,ZW,m,!kbJ,dJ,*d*J,*a"))] "!TARGET_MIPS16 && (register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode))" diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h index 5379a431140..3a01dbab46d 100644 --- a/gcc/config/moxie/moxie.h +++ b/gcc/config/moxie/moxie.h @@ -59,7 +59,7 @@ #define DOUBLE_TYPE_SIZE 64 #define LONG_DOUBLE_TYPE_SIZE 64 -#define DEFAULT_SIGNED_CHAR 1 +#define DEFAULT_SIGNED_CHAR 0 #undef SIZE_TYPE #define SIZE_TYPE "unsigned int" @@ -68,7 +68,7 @@ #define PTRDIFF_TYPE "int" #undef WCHAR_TYPE -#define WCHAR_TYPE "long int" +#define WCHAR_TYPE "unsigned int" #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD diff --git a/gcc/config/moxie/moxie.md b/gcc/config/moxie/moxie.md index 713f9b65dcf..793cac3f8ca 100644 --- a/gcc/config/moxie/moxie.md +++ b/gcc/config/moxie/moxie.md @@ -239,6 +239,56 @@ ldo.l %0, %1" [(set_attr "length" "2,2,6,2,6,2,6,6,6")]) +(define_insn_and_split "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,W,A,B")))] + "" + "@ + ; + ld.b %0, %1 + lda.b %0, %1 + ldo.b %0, %1" + "reload_completed" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (zero_extend:SI (match_dup 2)))] +{ + operands[2] = gen_lowpart (QImode, operands[0]); +} + [(set_attr "length" "0,2,6,6")]) + +(define_insn_and_split "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,W,A,B")))] + "" + "@ + ; + ld.s %0, %1 + lda.s %0, %1 + ldo.s %0, %1" + "reload_completed" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (zero_extend:SI (match_dup 2)))] +{ + operands[2] = gen_lowpart (HImode, operands[0]); +} + [(set_attr "length" "0,2,6,6")]) + +(define_insn "extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r")))] + "" + "@ + sex.b %0, %1" + [(set_attr "length" "2")]) + +(define_insn "extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))] + "" + "@ + sex.s %0, %1" + [(set_attr "length" "2")]) + (define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index fb698d20d80..871e4e5c6e8 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4187,13 +4187,17 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) if (TARGET_SOM && TARGET_GAS) { - /* We done with this subspace except possibly for some additional + /* We are done with this subspace except possibly for some additional debug information. Forget that we are in this subspace to ensure that the next function is output in its own subspace. */ in_section = NULL; cfun->machine->in_nsubspa = 2; } + /* Thunks do their own accounting. */ + if (cfun->is_thunk) + return; + if (INSN_ADDRESSES_SET_P ()) { insn = get_last_nonnote_insn (); @@ -8259,8 +8263,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, xoperands[1] = XEXP (DECL_RTL (thunk_fndecl), 0); xoperands[2] = GEN_INT (delta); - ASM_OUTPUT_LABEL (file, XSTR (xoperands[1], 0)); - fprintf (file, "\t.PROC\n\t.CALLINFO FRAME=0,NO_CALLS\n\t.ENTRY\n"); + final_start_function (emit_barrier (), file, 1); /* Output the thunk. We know that the function is in the same translation unit (i.e., the same space) as the thunk, and that @@ -8466,16 +8469,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, } } - fprintf (file, "\t.EXIT\n\t.PROCEND\n"); - - if (TARGET_SOM && TARGET_GAS) - { - /* We done with this subspace except possibly for some additional - debug information. Forget that we are in this subspace to ensure - that the next function is output in its own subspace. */ - in_section = NULL; - cfun->machine->in_nsubspa = 2; - } + final_end_function (); if (TARGET_SOM && flag_pic && TREE_PUBLIC (function)) { diff --git a/gcc/config/rl78/rl78-expand.md b/gcc/config/rl78/rl78-expand.md index f794d7cb13d..f61e444b5da 100644 --- a/gcc/config/rl78/rl78-expand.md +++ b/gcc/config/rl78/rl78-expand.md @@ -30,18 +30,23 @@ if (rl78_far_p (operands[0]) && rl78_far_p (operands[1])) operands[1] = copy_to_mode_reg (QImode, operands[1]); - /* FIXME: Not sure how GCC can generate (SUBREG (SYMBOL_REF)), - but it does. Since this makes no sense, reject it here. */ + /* GCC can generate (SUBREG (SYMBOL_REF)) when it has to store a symbol + into a bitfield, or a packed ordinary field. We can handle this + provided that the destination is a register. If not, then load the + source into a register first. */ if (GET_CODE (operands[1]) == SUBREG - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - FAIL; + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF + && ! REG_P (operands[0])) + operands[1] = copy_to_mode_reg (QImode, operands[1]); + /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). cf. g++.dg/abi/packed.C. */ if (GET_CODE (operands[1]) == SUBREG && GET_CODE (XEXP (operands[1], 0)) == CONST && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS - && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF) - FAIL; + && GET_CODE (XEXP (XEXP (XEXP (operands[1], 0), 0), 0)) == SYMBOL_REF + && ! REG_P (operands[0])) + operands[1] = copy_to_mode_reg (QImode, operands[1]); if (CONST_INT_P (operands[1]) && ! IN_RANGE (INTVAL (operands[1]), (-1 << 8) + 1, (1 << 8) - 1)) FAIL; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6724dcbe465..51283aae5f2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1752,9 +1752,6 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) modes and DImode. */ if (FP_REGNO_P (regno)) { - if (TARGET_SOFT_FLOAT || !TARGET_FPRS) - return 0; - if (SCALAR_FLOAT_MODE_P (mode) && (mode != TDmode || (regno % 2) == 0) && FP_REGNO_P (last_regno)) @@ -1783,6 +1780,10 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) return (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) || mode == V1TImode); + /* ...but GPRs can hold SIMD data on the SPE in one register. */ + if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) + return 1; + /* We cannot put non-VSX TImode or PTImode anywhere except general register and it must be able to fit within the register set. */ @@ -5638,11 +5639,15 @@ rs6000_expand_vector_set (rtx target, rtx val, int elt) UNSPEC_VPERM); else { - /* Invert selector. */ + /* Invert selector. We prefer to generate VNAND on P8 so + that future fusion opportunities can kick in, but must + generate VNOR elsewhere. */ rtx notx = gen_rtx_NOT (V16QImode, force_reg (V16QImode, x)); - rtx andx = gen_rtx_AND (V16QImode, notx, notx); + rtx iorx = (TARGET_P8_VECTOR + ? gen_rtx_IOR (V16QImode, notx, notx) + : gen_rtx_AND (V16QImode, notx, notx)); rtx tmp = gen_reg_rtx (V16QImode); - emit_move_insn (tmp, andx); + emit_insn (gen_rtx_SET (VOIDmode, tmp, iorx)); /* Permute with operands reversed and adjusted selector. */ x = gen_rtx_UNSPEC (mode, gen_rtvec (3, reg, target, tmp), @@ -30214,12 +30219,12 @@ altivec_expand_vec_perm_const_le (rtx operands[4]) /* Similarly to altivec_expand_vec_perm_const_le, we must adjust the permute control vector. But here it's not a constant, so we must - generate a vector NOR to do the adjustment. */ + generate a vector NAND or NOR to do the adjustment. */ void altivec_expand_vec_perm_le (rtx operands[4]) { - rtx notx, andx, unspec; + rtx notx, iorx, unspec; rtx target = operands[0]; rtx op0 = operands[1]; rtx op1 = operands[2]; @@ -30238,10 +30243,13 @@ altivec_expand_vec_perm_le (rtx operands[4]) if (!REG_P (target)) tmp = gen_reg_rtx (mode); - /* Invert the selector with a VNOR. */ + /* Invert the selector with a VNAND if available, else a VNOR. + The VNAND is preferred for future fusion opportunities. */ notx = gen_rtx_NOT (V16QImode, sel); - andx = gen_rtx_AND (V16QImode, notx, notx); - emit_move_insn (norreg, andx); + iorx = (TARGET_P8_VECTOR + ? gen_rtx_IOR (V16QImode, notx, notx) + : gen_rtx_AND (V16QImode, notx, notx)); + emit_insn (gen_rtx_SET (VOIDmode, norreg, iorx)); /* Permute with operands reversed and adjusted selector. */ unspec = gen_rtx_UNSPEC (mode, gen_rtvec (3, op1, op0, norreg), diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index aee6f4fce75..6fab081c36a 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9394,9 +9394,8 @@ [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] "! TARGET_POWERPC64 - && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) - || TARGET_SOFT_FLOAT - || (<MODE>mode == DDmode && TARGET_E500_DOUBLE)) + && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) + || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) && (gpc_reg_operand (operands[0], <MODE>mode) || gpc_reg_operand (operands[1], <MODE>mode))" "#" @@ -10029,13 +10028,16 @@ rtx op0 = operands[0]; rtx op1 = operands[1]; rtx op2 = operands[2]; - rtx op0_di = simplify_gen_subreg (DImode, op0, SFmode, 0); + /* Also use the destination register to hold the unconverted DImode value. + This is conceptually a separate value from OP0, so we use gen_rtx_REG + rather than simplify_gen_subreg. */ + rtx op0_di = gen_rtx_REG (DImode, REGNO (op0)); rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); /* Move SF value to upper 32-bits for xscvspdpn. */ emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); emit_move_insn (op0_di, op2); - emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); + emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0_di)); DONE; } [(set_attr "length" "8") diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index a06cdd507e4..d83cdc3df34 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -1223,7 +1223,7 @@ ;; Used by direct move to move a SFmode value from GPR to VSX register (define_insn "vsx_xscvspdpn_directmove" [(set (match_operand:SF 0 "vsx_register_operand" "=wa") - (unspec:SF [(match_operand:SF 1 "vsx_register_operand" "wa")] + (unspec:SF [(match_operand:DI 1 "vsx_register_operand" "wa")] UNSPEC_VSX_CVSPDPN))] "TARGET_XSCVSPDPN" "xscvspdpn %x0,%x1" diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index bdb577c9748..aac8de848ac 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4613,7 +4613,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) int smode_bsize, mode_bsize; rtx op, clobber; - if (bitsize + bitpos > GET_MODE_SIZE (mode)) + if (bitsize + bitpos > GET_MODE_BITSIZE (mode)) return false; /* Generate INSERT IMMEDIATE (IILL et al). */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7d9d1ad7ecd..b17c1fac875 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -7001,6 +7001,21 @@ "" "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;") +; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing +; simplifications. So its better to have something matching. +(define_split + [(set (match_operand:INT 0 "nonimmediate_operand" "") + (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))] + "" + [(parallel + [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[2] = constm1_rtx; + if (!s390_logical_operator_ok_p (operands)) + FAIL; +}) + ; ; xordi3 instruction pattern(s). ; diff --git a/gcc/config/sh/sh-mem.cc b/gcc/config/sh/sh-mem.cc index 45af23acb48..1b84f9b63b7 100644 --- a/gcc/config/sh/sh-mem.cc +++ b/gcc/config/sh/sh-mem.cc @@ -586,9 +586,35 @@ sh_expand_strlen (rtx *operands) emit_move_insn (current_addr, plus_constant (Pmode, current_addr, -4)); - /* start byte loop. */ addr1 = adjust_address (addr1, QImode, 0); + /* unroll remaining bytes. */ + emit_insn (gen_extendqisi2 (tmp1, addr1)); + emit_insn (gen_cmpeqsi_t (tmp1, const0_rtx)); + jump = emit_jump_insn (gen_branch_true (L_return)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + + emit_move_insn (current_addr, plus_constant (Pmode, current_addr, 1)); + + emit_insn (gen_extendqisi2 (tmp1, addr1)); + emit_insn (gen_cmpeqsi_t (tmp1, const0_rtx)); + jump = emit_jump_insn (gen_branch_true (L_return)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + + emit_move_insn (current_addr, plus_constant (Pmode, current_addr, 1)); + + emit_insn (gen_extendqisi2 (tmp1, addr1)); + emit_insn (gen_cmpeqsi_t (tmp1, const0_rtx)); + jump = emit_jump_insn (gen_branch_true (L_return)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + + emit_move_insn (current_addr, plus_constant (Pmode, current_addr, 1)); + + emit_insn (gen_extendqisi2 (tmp1, addr1)); + jump = emit_jump_insn (gen_jump_compact (L_return)); + emit_barrier_after (jump); + + /* start byte loop. */ emit_label (L_loop_byte); emit_insn (gen_extendqisi2 (tmp1, addr1)); @@ -600,11 +626,114 @@ sh_expand_strlen (rtx *operands) /* end loop. */ - emit_label (L_return); - emit_insn (gen_addsi3 (start_addr, start_addr, GEN_INT (1))); + emit_label (L_return); + emit_insn (gen_subsi3 (operands[0], current_addr, start_addr)); return true; } + +/* Emit code to perform a memset + + OPERANDS[0] is the destination. + OPERANDS[1] is the size; + OPERANDS[2] is the char to search. + OPERANDS[3] is the alignment. */ +void +sh_expand_setmem (rtx *operands) +{ + rtx L_loop_byte = gen_label_rtx (); + rtx L_loop_word = gen_label_rtx (); + rtx L_return = gen_label_rtx (); + rtx jump; + rtx dest = copy_rtx (operands[0]); + rtx dest_addr = copy_addr_to_reg (XEXP (dest, 0)); + rtx val = force_reg (SImode, operands[2]); + int align = INTVAL (operands[3]); + int count = 0; + rtx len = force_reg (SImode, operands[1]); + + if (! CONST_INT_P (operands[1])) + return; + + count = INTVAL (operands[1]); + + if (CONST_INT_P (operands[2]) + && (INTVAL (operands[2]) == 0 || INTVAL (operands[2]) == -1) && count > 8) + { + rtx lenw = gen_reg_rtx (SImode); + + if (align < 4) + { + emit_insn (gen_tstsi_t (GEN_INT (3), dest_addr)); + jump = emit_jump_insn (gen_branch_false (L_loop_byte)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + } + + /* word count. Do we have iterations ? */ + emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2))); + + dest = adjust_automodify_address (dest, SImode, dest_addr, 0); + + /* start loop. */ + emit_label (L_loop_word); + + if (TARGET_SH2) + emit_insn (gen_dect (lenw, lenw)); + else + { + emit_insn (gen_addsi3 (lenw, lenw, GEN_INT (-1))); + emit_insn (gen_tstsi_t (lenw, lenw)); + } + + emit_move_insn (dest, val); + emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr, + GET_MODE_SIZE (SImode))); + + + jump = emit_jump_insn (gen_branch_false (L_loop_word)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + count = count % 4; + + dest = adjust_address (dest, QImode, 0); + + val = gen_lowpart (QImode, val); + + while (count--) + { + emit_move_insn (dest, val); + emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr, + GET_MODE_SIZE (QImode))); + } + + jump = emit_jump_insn (gen_jump_compact (L_return)); + emit_barrier_after (jump); + } + + dest = adjust_automodify_address (dest, QImode, dest_addr, 0); + + /* start loop. */ + emit_label (L_loop_byte); + + if (TARGET_SH2) + emit_insn (gen_dect (len, len)); + else + { + emit_insn (gen_addsi3 (len, len, GEN_INT (-1))); + emit_insn (gen_tstsi_t (len, len)); + } + + val = gen_lowpart (QImode, val); + emit_move_insn (dest, val); + emit_move_insn (dest_addr, plus_constant (Pmode, dest_addr, + GET_MODE_SIZE (QImode))); + + jump = emit_jump_insn (gen_branch_false (L_loop_byte)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + + emit_label (L_return); + + return; +} diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index defc76a3243..685cd23207c 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -119,6 +119,7 @@ extern void prepare_move_operands (rtx[], enum machine_mode mode); extern bool sh_expand_cmpstr (rtx *); extern bool sh_expand_cmpnstr (rtx *); extern bool sh_expand_strlen (rtx *); +extern void sh_expand_setmem (rtx *); extern enum rtx_code prepare_cbranch_operands (rtx *, enum machine_mode mode, enum rtx_code comparison); extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int); diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 8819300116e..8c30e5c14bd 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -1594,6 +1594,11 @@ struct sh_args { #define SET_BY_PIECES_P(SIZE, ALIGN) STORE_BY_PIECES_P(SIZE, ALIGN) +/* If a memory clear move would take CLEAR_RATIO or more simple + move-instruction pairs, we will do a setmem instead. */ + +#define CLEAR_RATIO(speed) ((speed) ? 15 : 3) + /* Macros to check register numbers against specific register classes. */ /* These assume that REGNO is a hard or pseudo reg number. diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index ab1f0a51c22..9035bfcb1a8 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -12089,6 +12089,20 @@ label: FAIL; }) +(define_expand "setmemqi" + [(parallel [(set (match_operand:BLK 0 "memory_operand") + (match_operand 2 "const_int_operand")) + (use (match_operand:QI 1 "const_int_operand")) + (use (match_operand:QI 3 "const_int_operand"))])] + "TARGET_SH1 && optimize" + { + if (optimize_insn_for_size_p ()) + FAIL; + + sh_expand_setmem (operands); + DONE; + }) + ;; ------------------------------------------------------------------------- ;; Floating point instructions. diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 302d7e06b6d..88e3f5e5909 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -2064,7 +2064,7 @@ pad_bb(void) } hbr_insn = insn; } - if (INSN_CODE (insn) == CODE_FOR_blockage) + if (INSN_CODE (insn) == CODE_FOR_blockage && next_insn) { if (GET_MODE (insn) == TImode) PUT_MODE (next_insn, TImode); diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index 228b2285969..3ac4bfc0b7c 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -2851,7 +2851,13 @@ (match_operand:SI 2 "const_int_operand" "")) (match_operand 3 "nonmemory_operand" ""))] "" - { spu_expand_insv(operands); DONE; }) + { + if (INTVAL (operands[1]) + INTVAL (operands[2]) + > GET_MODE_BITSIZE (GET_MODE (operands[0]))) + FAIL; + spu_expand_insv(operands); + DONE; + }) ;; Simplify a number of patterns that get generated by extv, extzv, ;; insv, and loads. diff --git a/gcc/configure b/gcc/configure index 415377adc19..11fb90aae6c 100755 --- a/gcc/configure +++ b/gcc/configure @@ -23283,7 +23283,7 @@ foo: .long 25 tls_first_major=2 tls_first_minor=17 ;; - i[34567]86-*-* | x86_64-*-solaris2.1[0-9]*) + i[34567]86-*-* | x86_64-*-*) case "$target" in i[34567]86-*-solaris2.*) on_solaris=yes @@ -23314,7 +23314,9 @@ $as_echo "#define TLS_SECTION_ASM_FLAG 't'" >>confdefs.h tls_section_flag=T tls_as_opt="--fatal-warnings" fi - conftest_s="$conftest_s + case "$target" in + i[34567]86-*-*) + conftest_s="$conftest_s foo: .long 25 .text movl %gs:0, %eax @@ -23328,23 +23330,26 @@ foo: .long 25 movl \$foo@tpoff, %eax subl \$foo@tpoff, %eax leal foo@ntpoff(%ecx), %eax" - ;; - x86_64-*-*) - conftest_s=' - .section ".tdata","awT",@progbits + ;; + x86_64-*-*) + if test x$on_solaris = xyes; then + case $gas_flag in + yes) tls_as_opt="$tls_as_opt --64" ;; + no) tls_as_opt="$tls_as_opt -xarch=amd64" ;; + esac + fi + conftest_s="$conftest_s foo: .long 25 .text movq %fs:0, %rax - leaq foo@TLSGD(%rip), %rdi - leaq foo@TLSLD(%rip), %rdi - leaq foo@DTPOFF(%rax), %rdx - movq foo@GOTTPOFF(%rip), %rax - movq $foo@TPOFF, %rax' - tls_first_major=2 - tls_first_minor=14 - tls_section_flag=T - tls_as_opt=--fatal-warnings - ;; + leaq foo@tlsgd(%rip), %rdi + leaq foo@tlsld(%rip), %rdi + leaq foo@dtpoff(%rax), %rdx + movq foo@gottpoff(%rip), %rax + movq \$foo@tpoff, %rax" + ;; + esac + ;; ia64-*-*) conftest_s=' .section ".tdata","awT",@progbits diff --git a/gcc/configure.ac b/gcc/configure.ac index 0336066ccd2..47e85d5deb9 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2954,7 +2954,7 @@ foo: .long 25 tls_first_major=2 tls_first_minor=17 ;; - i[34567]86-*-* | x86_64-*-solaris2.1[0-9]*) + i[34567]86-*-* | x86_64-*-*) case "$target" in i[34567]86-*-solaris2.*) on_solaris=yes @@ -2986,7 +2986,9 @@ changequote(,)dnl tls_section_flag=T tls_as_opt="--fatal-warnings" fi - conftest_s="$conftest_s + case "$target" in + i[34567]86-*-*) + conftest_s="$conftest_s foo: .long 25 .text movl %gs:0, %eax @@ -3000,23 +3002,26 @@ foo: .long 25 movl \$foo@tpoff, %eax subl \$foo@tpoff, %eax leal foo@ntpoff(%ecx), %eax" - ;; - x86_64-*-*) - conftest_s=' - .section ".tdata","awT",@progbits + ;; + x86_64-*-*) + if test x$on_solaris = xyes; then + case $gas_flag in + yes) tls_as_opt="$tls_as_opt --64" ;; + no) tls_as_opt="$tls_as_opt -xarch=amd64" ;; + esac + fi + conftest_s="$conftest_s foo: .long 25 .text movq %fs:0, %rax - leaq foo@TLSGD(%rip), %rdi - leaq foo@TLSLD(%rip), %rdi - leaq foo@DTPOFF(%rax), %rdx - movq foo@GOTTPOFF(%rip), %rax - movq $foo@TPOFF, %rax' - tls_first_major=2 - tls_first_minor=14 - tls_section_flag=T - tls_as_opt=--fatal-warnings - ;; + leaq foo@tlsgd(%rip), %rdi + leaq foo@tlsld(%rip), %rdi + leaq foo@dtpoff(%rax), %rdx + movq foo@gottpoff(%rip), %rax + movq \$foo@tpoff, %rax" + ;; + esac + ;; ia64-*-*) conftest_s=' .section ".tdata","awT",@progbits diff --git a/gcc/coverage.c b/gcc/coverage.c index 4c06fa47908..ff1e67d0a03 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -555,18 +555,29 @@ coverage_compute_lineno_checksum (void) unsigned coverage_compute_profile_id (struct cgraph_node *n) { - expanded_location xloc - = expand_location (DECL_SOURCE_LOCATION (n->decl)); - unsigned chksum = xloc.line; + unsigned chksum; - chksum = coverage_checksum_string (chksum, xloc.file); - chksum = coverage_checksum_string - (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); - if (first_global_object_name) - chksum = coverage_checksum_string - (chksum, first_global_object_name); - chksum = coverage_checksum_string - (chksum, aux_base_name); + /* Externally visible symbols have unique name. */ + if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl)) + { + chksum = coverage_checksum_string + (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); + } + else + { + expanded_location xloc + = expand_location (DECL_SOURCE_LOCATION (n->decl)); + + chksum = xloc.line; + chksum = coverage_checksum_string (chksum, xloc.file); + chksum = coverage_checksum_string + (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); + if (first_global_object_name) + chksum = coverage_checksum_string + (chksum, first_global_object_name); + chksum = coverage_checksum_string + (chksum, aux_base_name); + } /* Non-negative integers are hopefully small enough to fit in all targets. */ return chksum & 0x7fffffff; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 43094b38c8c..e10a2272219 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,155 @@ +2014-04-16 Marc Glisse <marc.glisse@inria.fr> + + * decl.c (reshape_init_r): Handle a single element of vector type. + +2014-04-16 Patrick Palka <patrick@parcs.ath.cx> + + PR c++/60765 + * decl2.c (cplus_decl_attributes): Handle + pointer-to-member-function declarations. + +2014-04-16 Patrick Palka <patrick@parcs.ath.cx> + + PR c++/60764 + * call.c (build_user_type_coversion): Use build_dummy_object + to create the placeholder object for a constructor method call. + (build_special_member_call): Likewise. + (build_over_call): Check for the placeholder object with + is_dummy_object. + (build_new_method_call_1): Likewise. Don't attempt to resolve + a dummy object for a constructor method call. + +2014-04-16 Paul Pluzhnikov <ppluzhnikov@google.com> + + PR c++/59295 + * friend.c (add_friend, make_friend_class): Move repeated friend + warning under Wredundant_decls. + +2014-04-15 Paolo Carlini <paolo.carlini@oracle.com> + + * decl.c (duplicate_decls): Remove redundant TYPE_NAME use. + * name-lookup.c (pushdecl_maybe_friend_1): Likewise. + (do_class_using_decl): Likewise. + * mangle.c (dump_substitution_candidates): Use TYPE_NAME_STRING. + +2014-04-15 Jakub Jelinek <jakub@redhat.com> + + PR plugins/59335 + * Make-lang.h (CP_PLUGIN_HEADERS): Add type-utils.h. + +2014-04-14 Paolo Carlini <paolo.carlini@oracle.com> + + * cp-tree.h (TYPE_IDENTIFIER): Remove declaration. + +2014-04-14 Paolo Carlini <paolo.carlini@oracle.com> + + * pt.c (mark_template_parm): Use template_parm_level_and_index. + +2014-04-11 Jason Merrill <jason@redhat.com> + + * parser.h (struct cp_token): Rename ambiguous_p to error_reported. + * parser.c: Adjust. + (cp_lexer_get_preprocessor_token): Always clear it. + (cp_parser_lambda_expression): Use it to avoid duplicate diagnostics. + + DR 1467 + PR c++/51747 + * decl.c (reshape_init_r): Handle a single element of class type. + + DR 1338 + * decl.c (cxx_init_decl_processing): Set DECL_IS_MALLOC on + built-in operator new. + +2014-04-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58600 + * name-lookup.c (parse_using_directive): Return early if the + attribs argument is error_mark_node; use get_attribute_name. + +2014-04-11 Jason Merrill <jason@redhat.com> + + DR 1030 + PR c++/51253 + * cp-tree.h (CALL_EXPR_LIST_INIT_P): New. + * call.c (struct z_candidate): Add flags field. + (add_candidate): Add flags parm. + (add_function_candidate, add_conv_candidate, build_builtin_candidate) + (add_template_candidate_real): Pass it. + (build_over_call): Set CALL_EXPR_LIST_INIT_P. + * tree.c (build_aggr_init_expr): Copy it. + * semantics.c (simplify_aggr_init_expr): Preevaluate args if it's set. + +2014-04-10 Richard Biener <rguenther@suse.de> + Jakub Jelinek <jakub@redhat.com> + + PR ipa/60761 + * error.c (dump_decl) <case FUNCTION_DECL>: If + DECL_LANG_SPECIFIC is NULL, but DECL_ABSTRACT_ORIGIN is not, + recurse on DECL_ABSTRACT_ORIGIN instead of printing + <built-in>. + +2014-04-09 Fabien Chêne <fabien@gcc.gnu.org> + + * pt.c (check_template_variable): Check for the return of pedwarn + before emitting a note. + * parser.c (cp_parser_lambda_introducer): Likewise. + +2014-04-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/59115 + * pt.c (process_template_parm): For an invalid non-type parameter + only set TREE_TYPE to error_mark_node. + (push_inline_template_parms_recursive, comp_template_parms, + redeclare_class_template, coerce_template_template_parm, + coerce_template_template_parms, unify): Use error_operand_p. + +2014-04-08 Nathan Sidwell <nathan@codesourcery.com> + + * class.c (check_bases_and_members): Warn about non-virtual dtors + in public bases only. Check warn_ecpp before complaining about + non-polymorphic bases. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * decl.c (duplicate_decls): Check for the return of warning_at + before emitting a note. + (warn_misplaced_attr_for_class_type): Likewise. + (check_tag_decl): Likewise. + +2014-04-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58207 + * semantics.c (sort_constexpr_mem_initializers): Robustify loop. + +2014-04-04 Patrick Palka <patrick@parcs.ath.cx> + + PR c++/44613 + * semantics.c (add_stmt): Set STATEMENT_LIST_HAS_LABEL. + * decl.c (cp_finish_decl): Create a new BIND_EXPR before + instantiating a variable-sized type. + + PR c++/21113 + * decl.c (decl_jump_unsafe): Consider variably-modified decls. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * class.c (find_abi_tags_r): Check for the return of warning + before emitting a note. + (one_inherited_ctor): Likewise. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * decl.c (duplicate_decls): Check for the return of permerror + before emitting a note. + +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * class.c (accessible_nvdtor_p): New. + (check_bases): Don't check base destructor here ... + (check_bases_and_members): ... check them here. Trigger on + Wnon-virtual-dtor flag. + (finish_struct_1): Use accessible_nvdtor_p. + 2014-04-01 Jason Merrill <jason@redhat.com> * pt.c (process_partial_specialization): Say "not deducible" @@ -58,9 +210,9 @@ 2014-03-26 Fabien Chêne <fabien@gcc.gnu.org> PR c++/52369 - * cp/method.c (walk_field_subobs): Improve the diagnostic + * method.c (walk_field_subobs): Improve the diagnostic locations for both REFERENCE_TYPEs and non-static const members. - * cp/init.c (diagnose_uninitialized_cst_or_ref_member): Use %q#D + * init.c (diagnose_uninitialized_cst_or_ref_member): Use %q#D instead of %qD to be consistent with the c++11 diagnostic. 2014-03-25 Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 5480c4eaeb2..bd1c1d78f88 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -39,7 +39,7 @@ CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)') GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)') CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)') GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)') -CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h +CP_PLUGIN_HEADERS := cp-tree.h cxx-pretty-print.h name-lookup.h type-utils.h # # Define the names for selecting c++ in LANGUAGES. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2ccf59c5e41..96b4adac0b5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -207,7 +207,7 @@ static conversion *maybe_handle_ref_bind (conversion **); static void maybe_handle_implicit_object (conversion **); static struct z_candidate *add_candidate (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t, - conversion **, tree, tree, int, struct rejection_reason *); + conversion **, tree, tree, int, struct rejection_reason *, int); static tree source_type (conversion *); static void add_warning (struct z_candidate *, struct z_candidate *); static bool reference_compatible_p (tree, tree); @@ -521,7 +521,6 @@ struct z_candidate { sequence from the type returned by FN to the desired destination type. */ conversion *second_conv; - int viable; struct rejection_reason *reason; /* If FN is a member function, the binfo indicating the path used to qualify the name of FN at the call site. This path is used to @@ -539,6 +538,10 @@ struct z_candidate { tree explicit_targs; candidate_warning *warnings; z_candidate *next; + int viable; + + /* The flags active in add_candidate. */ + int flags; }; /* Returns true iff T is a null pointer constant in the sense of @@ -1811,7 +1814,8 @@ add_candidate (struct z_candidate **candidates, tree fn, tree first_arg, const vec<tree, va_gc> *args, size_t num_convs, conversion **convs, tree access_path, tree conversion_path, - int viable, struct rejection_reason *reason) + int viable, struct rejection_reason *reason, + int flags) { struct z_candidate *cand = (struct z_candidate *) conversion_obstack_alloc (sizeof (struct z_candidate)); @@ -1826,6 +1830,7 @@ add_candidate (struct z_candidate **candidates, cand->viable = viable; cand->reason = reason; cand->next = *candidates; + cand->flags = flags; *candidates = cand; return cand; @@ -2062,7 +2067,7 @@ add_function_candidate (struct z_candidate **candidates, out: return add_candidate (candidates, fn, orig_first_arg, args, len, convs, - access_path, conversion_path, viable, reason); + access_path, conversion_path, viable, reason, flags); } /* Create an overload candidate for the conversion function FN which will @@ -2164,7 +2169,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, } return add_candidate (candidates, totype, first_arg, arglist, len, convs, - access_path, conversion_path, viable, reason); + access_path, conversion_path, viable, reason, flags); } static void @@ -2239,7 +2244,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname, num_convs, convs, /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE, - viable, reason); + viable, reason, flags); } static bool @@ -3057,7 +3062,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, return cand; fail: return add_candidate (candidates, tmpl, first_arg, arglist, nargs, NULL, - access_path, conversion_path, 0, reason); + access_path, conversion_path, 0, reason, flags); } @@ -3520,8 +3525,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags, { int ctorflags = flags; - first_arg = build_int_cst (build_pointer_type (totype), 0); - first_arg = build_fold_indirect_ref (first_arg); + first_arg = build_dummy_object (totype); /* We should never try to call the abstract or base constructor from here. */ @@ -7095,7 +7099,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a temp or an INIT_EXPR otherwise. */ fa = argarray[0]; - if (integer_zerop (fa)) + if (is_dummy_object (fa)) { if (TREE_CODE (arg) == TARGET_EXPR) return arg; @@ -7218,7 +7222,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return error_mark_node; } - return build_cxx_call (fn, nargs, argarray, complain|decltype_flag); + tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag); + if (TREE_CODE (call) == CALL_EXPR + && (cand->flags & LOOKUP_LIST_INIT_CTOR)) + CALL_EXPR_LIST_INIT_P (call) = true; + return call; } /* Build and return a call to FN, using NARGS arguments in ARGARRAY. @@ -7433,10 +7441,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, /* Handle the special case where INSTANCE is NULL_TREE. */ if (name == complete_ctor_identifier && !instance) - { - instance = build_int_cst (build_pointer_type (class_type), 0); - instance = build1 (INDIRECT_REF, class_type, instance); - } + instance = build_dummy_object (class_type); else { if (name == complete_dtor_identifier @@ -7746,8 +7751,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, if (init) { - if (INDIRECT_REF_P (instance) - && integer_zerop (TREE_OPERAND (instance, 0))) + if (is_dummy_object (instance)) return get_target_expr_sfinae (init, complain); init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init); TREE_SIDE_EFFECTS (init) = true; @@ -7846,6 +7850,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, } if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE + && !DECL_CONSTRUCTOR_P (fn) && is_dummy_object (instance)) { instance = maybe_resolve_dummy (instance); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 8d9bffe3cb1..67413761d8c 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -150,6 +150,7 @@ static tree *build_base_field (record_layout_info, tree, splay_tree, tree *); static void build_base_fields (record_layout_info, splay_tree, tree *); static void check_methods (tree); static void remove_zero_width_bit_fields (tree); +static bool accessible_nvdtor_p (tree); static void check_bases (tree, int *, int *); static void check_bases_and_members (tree); static tree create_vtable_ptr (tree, tree *); @@ -1385,19 +1386,21 @@ find_abi_tags_r (tree *tp, int *walk_subtrees, void *data) /* Otherwise we're diagnosing missing tags. */ else if (TYPE_P (p->subob)) { - warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " - "that base %qT has", p->t, tag, p->subob); - inform (location_of (p->subob), "%qT declared here", - p->subob); + if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " + "that base %qT has", p->t, tag, p->subob)) + inform (location_of (p->subob), "%qT declared here", + p->subob); } else { - warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " - "that %qT (used in the type of %qD) has", - p->t, tag, *tp, p->subob); - inform (location_of (p->subob), "%qD declared here", - p->subob); - inform (location_of (*tp), "%qT declared here", *tp); + if (warning (OPT_Wabi_tag, "%qT does not have the %E abi tag " + "that %qT (used in the type of %qD) has", + p->t, tag, *tp, p->subob)) + { + inform (location_of (p->subob), "%qD declared here", + p->subob); + inform (location_of (*tp), "%qT declared here", *tp); + } } } } @@ -1477,6 +1480,33 @@ inherit_targ_abi_tags (tree t) mark_type_abi_tags (t, false); } +/* Return true, iff class T has a non-virtual destructor that is + accessible from outside the class heirarchy (i.e. is public, or + there's a suitable friend. */ + +static bool +accessible_nvdtor_p (tree t) +{ + tree dtor = CLASSTYPE_DESTRUCTORS (t); + + /* An implicitly declared destructor is always public. And, + if it were virtual, we would have created it by now. */ + if (!dtor) + return true; + + if (DECL_VINDEX (dtor)) + return false; /* Virtual */ + + if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) + return true; /* Public */ + + if (CLASSTYPE_FRIEND_CLASSES (t) + || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) + return true; /* Has friends */ + + return false; +} + /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P, and NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of the bases. */ @@ -1513,13 +1543,6 @@ check_bases (tree t, if (!CLASSTYPE_LITERAL_P (basetype)) CLASSTYPE_LITERAL_P (t) = false; - /* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P - here because the case of virtual functions but non-virtual - dtor is handled in finish_struct_1. */ - if (!TYPE_POLYMORPHIC_P (basetype)) - warning (OPT_Weffc__, - "base class %q#T has a non-virtual destructor", basetype); - /* If the base class doesn't have copy constructors or assignment operators that take const references, then the derived class cannot have such a member automatically @@ -3063,9 +3086,9 @@ one_inherited_ctor (tree ctor, tree t) one_inheriting_sig (t, ctor, new_parms, i); if (parms == NULL_TREE) { - warning (OPT_Winherited_variadic_ctor, - "the ellipsis in %qD is not inherited", ctor); - inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor); + if (warning (OPT_Winherited_variadic_ctor, + "the ellipsis in %qD is not inherited", ctor)) + inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor); } } @@ -5548,6 +5571,30 @@ check_bases_and_members (tree t) TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t); TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t); + /* Warn if a public base of a polymorphic type has an accessible + non-virtual destructor. It is only now that we know the class is + polymorphic. Although a polymorphic base will have a already + been diagnosed during its definition, we warn on use too. */ + if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor) + { + tree binfo = TYPE_BINFO (t); + vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo); + tree base_binfo; + unsigned i; + + for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) + { + tree basetype = TREE_TYPE (base_binfo); + + if ((*accesses)[i] == access_public_node + && (TYPE_POLYMORPHIC_P (basetype) || warn_ecpp) + && accessible_nvdtor_p (basetype)) + warning (OPT_Wnon_virtual_dtor, + "base class %q#T has accessible non-virtual destructor", + basetype); + } + } + /* If the class has no user-declared constructor, but does have non-static const or reference data members that can never be initialized, issue a warning. */ @@ -6598,25 +6645,11 @@ finish_struct_1 (tree t) /* This warning does not make sense for Java classes, since they cannot have destructors. */ - if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t)) - { - tree dtor; - - dtor = CLASSTYPE_DESTRUCTORS (t); - if (/* An implicitly declared destructor is always public. And, - if it were virtual, we would have created it by now. */ - !dtor - || (!DECL_VINDEX (dtor) - && (/* public non-virtual */ - (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor)) - || (/* non-public non-virtual with friends */ - (TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor)) - && (CLASSTYPE_FRIEND_CLASSES (t) - || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))))))) - warning (OPT_Wnon_virtual_dtor, - "%q#T has virtual functions and accessible" - " non-virtual destructor", t); - } + if (!TYPE_FOR_JAVA (t) && warn_nonvdtor + && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t)) + warning (OPT_Wnon_virtual_dtor, + "%q#T has virtual functions and accessible" + " non-virtual destructor", t); complete_vars (t); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e9fe86ee4cd..f459e55bc84 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -101,12 +101,14 @@ c-common.h, not after. FNDECL_USED_AUTO (in FUNCTION_DECL) DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF) + AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). ICS_BAD_FLAG (in _CONV) FN_TRY_BLOCK_P (in TRY_BLOCK) IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) BIND_EXPR_BODY_BLOCK (in BIND_EXPR) DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) + CALL_EXPR_LIST_INIT_P (in CALL_EXPR, AGGR_INIT_EXPR) 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, or FIELD_DECL). IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) @@ -1250,7 +1252,6 @@ extern bool statement_code_p[MAX_TREE_CODES]; enum languages { lang_c, lang_cplusplus, lang_java }; /* Macros to make error reporting functions' lives easier. */ -#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) #define TYPE_LINKAGE_IDENTIFIER(NODE) \ (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE))) #define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) @@ -3026,6 +3027,10 @@ extern void decl_shadowed_for_var_insert (tree, tree); should be performed at instantiation time. */ #define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE)) +/* True if CALL_EXPR expresses list-initialization of an object. */ +#define CALL_EXPR_LIST_INIT_P(NODE) \ + TREE_LANG_FLAG_3 (TREE_CHECK2 ((NODE),CALL_EXPR,AGGR_INIT_EXPR)) + /* Indicates whether a string literal has been parenthesized. Such usages are disallowed in certain circumstances. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 11fbc355a85..833570b1e72 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1381,7 +1381,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) tree t = TREE_VALUE (t1); if (TYPE_PTR_P (t) - && TYPE_NAME (TREE_TYPE (t)) && TYPE_IDENTIFIER (TREE_TYPE (t)) == get_identifier ("FILE") && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2))) @@ -1649,10 +1648,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) && prototype_p (TREE_TYPE (newdecl))) { /* Prototype decl follows defn w/o prototype. */ - warning_at (DECL_SOURCE_LOCATION (newdecl), 0, - "prototype specified for %q#D", newdecl); - inform (DECL_SOURCE_LOCATION (olddecl), - "previous non-prototype definition here"); + if (warning_at (DECL_SOURCE_LOCATION (newdecl), 0, + "prototype specified for %q#D", newdecl)) + inform (DECL_SOURCE_LOCATION (olddecl), + "previous non-prototype definition here"); } else if (VAR_OR_FUNCTION_DECL_P (olddecl) && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) @@ -1738,9 +1737,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (permerror (input_location, "default argument given for parameter " "%d of %q#D", i, newdecl)) - permerror (DECL_SOURCE_LOCATION (olddecl), - "previous specification in %q#D here", - olddecl); + inform (DECL_SOURCE_LOCATION (olddecl), + "previous specification in %q#D here", + olddecl); } else { @@ -2786,12 +2785,11 @@ decl_jump_unsafe (tree decl) || type == error_mark_node) return 0; - type = strip_array_types (type); - - if (DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + if (DECL_NONTRIVIALLY_INITIALIZED_P (decl) + || variably_modified_type_p (type, NULL_TREE)) return 2; - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) return 1; return 0; @@ -3849,8 +3847,12 @@ cxx_init_decl_processing (void) newtype = build_exception_variant (newtype, new_eh_spec); deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr); deltype = build_exception_variant (deltype, empty_except_spec); - DECL_IS_OPERATOR_NEW (push_cp_library_fn (NEW_EXPR, newtype, 0)) = 1; - DECL_IS_OPERATOR_NEW (push_cp_library_fn (VEC_NEW_EXPR, newtype, 0)) = 1; + tree opnew = push_cp_library_fn (NEW_EXPR, newtype, 0); + DECL_IS_MALLOC (opnew) = 1; + DECL_IS_OPERATOR_NEW (opnew) = 1; + opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0); + DECL_IS_MALLOC (opnew) = 1; + DECL_IS_OPERATOR_NEW (opnew) = 1; global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW); push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW); @@ -4243,12 +4245,12 @@ warn_misplaced_attr_for_class_type (source_location location, { gcc_assert (OVERLOAD_TYPE_P (class_type)); - warning_at (location, OPT_Wattributes, - "attribute ignored in declaration " - "of %q#T", class_type); - inform (location, - "attribute for %q#T must follow the %qs keyword", - class_type, class_key_or_enum_as_string (class_type)); + if (warning_at (location, OPT_Wattributes, + "attribute ignored in declaration " + "of %q#T", class_type)) + inform (location, + "attribute for %q#T must follow the %qs keyword", + class_type, class_key_or_enum_as_string (class_type)); } /* Make sure that a declaration with no declarator is well-formed, i.e. @@ -4375,12 +4377,12 @@ check_tag_decl (cp_decl_specifier_seq *declspecs, No attribute-specifier-seq shall appertain to an explicit instantiation. */ { - warning_at (loc, OPT_Wattributes, - "attribute ignored in explicit instantiation %q#T", - declared_type); - inform (loc, - "no attribute can be applied to " - "an explicit instantiation"); + if (warning_at (loc, OPT_Wattributes, + "attribute ignored in explicit instantiation %q#T", + declared_type)) + inform (loc, + "no attribute can be applied to " + "an explicit instantiation"); } else warn_misplaced_attr_for_class_type (loc, declared_type); @@ -5403,6 +5405,18 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, return init; } + /* "If T is a class type and the initializer list has a single element of + type cv U, where U is T or a class derived from T, the object is + initialized from that element." Even if T is an aggregate. */ + if (cxx_dialect >= cxx11 && (CLASS_TYPE_P (type) || VECTOR_TYPE_P (type)) + && first_initializer_p + && d->end - d->cur == 1 + && reference_related_p (type, TREE_TYPE (init))) + { + d->cur++; + return init; + } + /* [dcl.init.aggr] All implicit type conversions (clause _conv_) are considered when @@ -6442,7 +6456,24 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, after the call to check_initializer so that the DECL_EXPR for a reference temp is added before the DECL_EXPR for the reference itself. */ if (DECL_FUNCTION_SCOPE_P (decl)) - add_decl_expr (decl); + { + /* If we're building a variable sized type, and we might be + reachable other than via the top of the current binding + level, then create a new BIND_EXPR so that we deallocate + the object at the right time. */ + if (VAR_P (decl) + && DECL_SIZE (decl) + && !TREE_CONSTANT (DECL_SIZE (decl)) + && STATEMENT_LIST_HAS_LABEL (cur_stmt_list)) + { + tree bind; + bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + BIND_EXPR_BODY (bind) = push_stmt_list (); + } + add_decl_expr (decl); + } /* Let the middle end know about variables and functions -- but not static data members in uninstantiated class templates. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 6c52e53bca0..8a7a8369f19 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1427,7 +1427,15 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) if (TREE_CODE (*decl) == TEMPLATE_DECL) decl = &DECL_TEMPLATE_RESULT (*decl); - decl_attributes (decl, attributes, flags); + if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl))) + { + attributes + = decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT); + decl_attributes (&TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (*decl)), + attributes, flags); + } + else + decl_attributes (decl, attributes, flags); if (TREE_CODE (*decl) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl)); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 454feb51989..699d5458a40 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1145,7 +1145,12 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) case FUNCTION_DECL: if (! DECL_LANG_SPECIFIC (t)) - pp_string (pp, M_("<built-in>")); + { + if (DECL_ABSTRACT_ORIGIN (t)) + dump_decl (pp, DECL_ABSTRACT_ORIGIN (t), flags); + else + pp_string (pp, M_("<built-in>")); + } else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t)) dump_global_iord (pp, t); else diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 150b392b62a..a30918c0006 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -148,7 +148,8 @@ add_friend (tree type, tree decl, bool complain) if (decl == TREE_VALUE (friends)) { if (complain) - warning (0, "%qD is already a friend of class %qT", + warning (OPT_Wredundant_decls, + "%qD is already a friend of class %qT", decl, type); return; } @@ -376,7 +377,8 @@ make_friend_class (tree type, tree friend_type, bool complain) if (friend_type == probe) { if (complain) - warning (0, "%qD is already a friend of %qT", probe, type); + warning (OPT_Wredundant_decls, + "%qD is already a friend of %qT", probe, type); break; } } @@ -385,7 +387,8 @@ make_friend_class (tree type, tree friend_type, bool complain) if (same_type_p (probe, friend_type)) { if (complain) - warning (0, "%qT is already a friend of %qT", probe, type); + warning (OPT_Wredundant_decls, + "%qT is already a friend of %qT", probe, type); break; } } diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index f8f83469b37..97fb4c6ec3c 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -324,7 +324,7 @@ dump_substitution_candidates (void) else if (TREE_CODE (el) == TREE_LIST) name = IDENTIFIER_POINTER (DECL_NAME (TREE_VALUE (el))); else if (TYPE_NAME (el)) - name = IDENTIFIER_POINTER (TYPE_IDENTIFIER (el)); + name = TYPE_NAME_STRING (el); fprintf (stderr, " S%d_ = ", i - 1); if (TYPE_P (el) && (CP_TYPE_RESTRICT_P (el) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 0137c3f4a33..d900560490e 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -945,7 +945,6 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) set_underlying_type (x); if (type != error_mark_node - && TYPE_NAME (type) && TYPE_IDENTIFIER (type)) set_identifier_type_value (DECL_NAME (x), x); @@ -3333,7 +3332,7 @@ do_class_using_decl (tree scope, tree name) } /* Using T::T declares inheriting ctors, even if T is a typedef. */ if (MAYBE_CLASS_TYPE_P (scope) - && ((TYPE_NAME (scope) && name == TYPE_IDENTIFIER (scope)) + && (name == TYPE_IDENTIFIER (scope) || constructor_name_p (name, scope))) { maybe_warn_cpp0x (CPP0X_INHERITING_CTORS); @@ -4019,13 +4018,14 @@ do_using_directive (tree name_space) void parse_using_directive (tree name_space, tree attribs) { - tree a; - do_using_directive (name_space); - for (a = attribs; a; a = TREE_CHAIN (a)) + if (attribs == error_mark_node) + return; + + for (tree a = attribs; a; a = TREE_CHAIN (a)) { - tree name = TREE_PURPOSE (a); + tree name = get_attribute_name (a); if (is_attribute_p ("strong", name)) { if (!toplevel_bindings_p ()) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7bea3d20029..bb59e3bcdd1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -762,6 +762,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) token->keyword = RID_MAX; token->pragma_kind = PRAGMA_NONE; token->purged_p = false; + token->error_reported = false; /* On some systems, some header files are surrounded by an implicit extern "C" block. Set a flag in the token if it @@ -797,7 +798,6 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token) C_SET_RID_CODE (token->u.value, RID_MAX); } - token->ambiguous_p = false; token->keyword = RID_MAX; } } @@ -3011,7 +3011,7 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) if (token->type == CPP_NESTED_NAME_SPECIFIER) { cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2); - if (next->type == CPP_NAME && next->ambiguous_p) + if (next->type == CPP_NAME && next->error_reported) goto out; } @@ -4535,7 +4535,7 @@ cp_parser_primary_expression (cp_parser *parser, we've already issued an error message; there's no reason to check again. */ if (id_expr_token->type == CPP_NAME - && id_expr_token->ambiguous_p) + && id_expr_token->error_reported) { cp_parser_simulate_error (parser); return error_mark_node; @@ -5313,7 +5313,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, token = cp_lexer_consume_token (parser->lexer); if (!error_p) { - if (!token->ambiguous_p) + if (!token->error_reported) { tree decl; tree ambiguous_decls; @@ -8719,14 +8719,18 @@ cp_parser_lambda_expression (cp_parser* parser) tree lambda_expr = build_lambda_expr (); tree type; bool ok = true; + cp_token *token = cp_lexer_peek_token (parser->lexer); - LAMBDA_EXPR_LOCATION (lambda_expr) - = cp_lexer_peek_token (parser->lexer)->location; + LAMBDA_EXPR_LOCATION (lambda_expr) = token->location; if (cp_unevaluated_operand) { - error_at (LAMBDA_EXPR_LOCATION (lambda_expr), - "lambda-expression in unevaluated context"); + if (!token->error_reported) + { + error_at (LAMBDA_EXPR_LOCATION (lambda_expr), + "lambda-expression in unevaluated context"); + token->error_reported = true; + } ok = false; } @@ -8961,10 +8965,10 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (VAR_P (capture_init_expr) && decl_storage_duration (capture_init_expr) != dk_auto) { - pedwarn (capture_token->location, 0, "capture of variable " - "%qD with non-automatic storage duration", - capture_init_expr); - inform (0, "%q+#D declared here", capture_init_expr); + if (pedwarn (capture_token->location, 0, "capture of variable " + "%qD with non-automatic storage duration", + capture_init_expr)) + inform (0, "%q+#D declared here", capture_init_expr); continue; } @@ -19129,7 +19133,7 @@ cp_parser_class_name (cp_parser *parser, /* Look for the identifier. */ identifier_token = cp_lexer_peek_token (parser->lexer); - ambiguous_p = identifier_token->ambiguous_p; + ambiguous_p = identifier_token->error_reported; identifier = cp_parser_identifier (parser); /* If the next token isn't an identifier, we are certainly not looking at a class-name. */ diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index d558c607f4d..758c6df3c27 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -51,10 +51,10 @@ typedef struct GTY (()) cp_token { ENUM_BITFIELD (pragma_kind) pragma_kind : 6; /* True if this token is from a context where it is implicitly extern "C" */ BOOL_BITFIELD implicit_extern_c : 1; - /* True for a CPP_NAME token that is not a keyword (i.e., for which - KEYWORD is RID_MAX) iff this name was looked up and found to be - ambiguous. An error has already been reported. */ - BOOL_BITFIELD ambiguous_p : 1; + /* True if an error has already been reported for this token, such as a + CPP_NAME token that is not a keyword (i.e., for which KEYWORD is + RID_MAX) iff this name was looked up and found to be ambiguous. */ + BOOL_BITFIELD error_reported : 1; /* True for a token that has been purged. If a token is purged, it is no longer a valid token and it should be considered deleted. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7f4ef8b3519..c74e7ae7586 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -414,7 +414,7 @@ push_inline_template_parms_recursive (tree parmlist, int levels) { tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - if (parm == error_mark_node) + if (error_operand_p (parm)) continue; gcc_assert (DECL_P (parm)); @@ -2304,10 +2304,10 @@ check_template_variable (tree decl) "%qD is not a static data member of a class template", decl); else if (template_header_count > wanted) { - pedwarn (DECL_SOURCE_LOCATION (decl), 0, - "too many template headers for %D (should be %d)", - decl, wanted); - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) + bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "too many template headers for %D (should be %d)", + decl, wanted); + if (warned && CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) inform (DECL_SOURCE_LOCATION (decl), "members of an explicitly specialized class are defined " "without a template header"); @@ -2829,7 +2829,7 @@ comp_template_parms (const_tree parms1, const_tree parms2) /* If either of the template parameters are invalid, assume they match for the sake of error recovery. */ - if (parm1 == error_mark_node || parm2 == error_mark_node) + if (error_operand_p (parm1) || error_operand_p (parm2)) return 1; if (TREE_CODE (parm1) != TREE_CODE (parm2)) @@ -3640,11 +3640,7 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args, to the LIST being built. This new parameter is a non-type parameter iff IS_NON_TYPE is true. This new parameter is a parameter pack iff IS_PARAMETER_PACK is true. The location of PARM - is in PARM_LOC. NUM_TEMPLATE_PARMS is the size of the template - parameter list PARM belongs to. This is used used to create a - proper canonical type for the type of PARM that is to be created, - iff PARM is a type. If the size is not known, this parameter shall - be set to 0. */ + is in PARM_LOC. */ tree process_template_parm (tree list, location_t parm_loc, tree parm, @@ -3652,7 +3648,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm, { tree decl = 0; tree defval; - tree err_parm_list; int idx = 0; gcc_assert (TREE_CODE (parm) == TREE_LIST); @@ -3673,8 +3668,6 @@ process_template_parm (tree list, location_t parm_loc, tree parm, ++idx; } - else - idx = 0; if (is_non_type) { @@ -3682,39 +3675,29 @@ process_template_parm (tree list, location_t parm_loc, tree parm, SET_DECL_TEMPLATE_PARM_P (parm); - if (TREE_TYPE (parm) == error_mark_node) - { - err_parm_list = build_tree_list (defval, parm); - TREE_VALUE (err_parm_list) = error_mark_node; - return chainon (list, err_parm_list); - } - else - { - /* [temp.param] - - The top-level cv-qualifiers on the template-parameter are - ignored when determining its type. */ - TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); - if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) - { - err_parm_list = build_tree_list (defval, parm); - TREE_VALUE (err_parm_list) = error_mark_node; - return chainon (list, err_parm_list); - } + if (TREE_TYPE (parm) != error_mark_node) + { + /* [temp.param] + + The top-level cv-qualifiers on the template-parameter are + ignored when determining its type. */ + TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); + if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1)) + TREE_TYPE (parm) = error_mark_node; + else if (uses_parameter_packs (TREE_TYPE (parm)) + && !is_parameter_pack + /* If we're in a nested template parameter list, the template + template parameter could be a parameter pack. */ + && processing_template_parmlist == 1) + { + /* This template parameter is not a parameter pack, but it + should be. Complain about "bare" parameter packs. */ + check_for_bare_parameter_packs (TREE_TYPE (parm)); - if (uses_parameter_packs (TREE_TYPE (parm)) && !is_parameter_pack - /* If we're in a nested template parameter list, the template - template parameter could be a parameter pack. */ - && processing_template_parmlist == 1) - { - /* This template parameter is not a parameter pack, but it - should be. Complain about "bare" parameter packs. */ - check_for_bare_parameter_packs (TREE_TYPE (parm)); - - /* Recover by calling this a parameter pack. */ - is_parameter_pack = true; - } - } + /* Recover by calling this a parameter pack. */ + is_parameter_pack = true; + } + } /* A template parameter is not modifiable. */ TREE_CONSTANT (parm) = 1; @@ -4045,16 +4028,7 @@ mark_template_parm (tree t, void* data) int idx; struct template_parm_data* tpd = (struct template_parm_data*) data; - if (TREE_CODE (t) == TEMPLATE_PARM_INDEX) - { - level = TEMPLATE_PARM_LEVEL (t); - idx = TEMPLATE_PARM_IDX (t); - } - else - { - level = TEMPLATE_TYPE_LEVEL (t); - idx = TEMPLATE_TYPE_IDX (t); - } + template_parm_level_and_index (t, &level, &idx); if (level == tpd->level) { @@ -5127,7 +5101,7 @@ redeclare_class_template (tree type, tree parms) continue; tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); - if (tmpl_parm == error_mark_node) + if (error_operand_p (tmpl_parm)) return false; parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); @@ -6087,8 +6061,8 @@ coerce_template_template_parm (tree parm, tree in_decl, tree outer_args) { - if (arg == NULL_TREE || arg == error_mark_node - || parm == NULL_TREE || parm == error_mark_node) + if (arg == NULL_TREE || error_operand_p (arg) + || parm == NULL_TREE || error_operand_p (parm)) return 0; if (TREE_CODE (arg) != TREE_CODE (parm)) @@ -6181,7 +6155,7 @@ coerce_template_template_parms (tree parm_parms, { parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, nparms - 1)); - if (parm == error_mark_node) + if (error_operand_p (parm)) return 0; switch (TREE_CODE (parm)) @@ -17517,7 +17491,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); if (TEMPLATE_TYPE_LEVEL (parm) @@ -17535,7 +17509,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, idx = TEMPLATE_TYPE_IDX (parm); targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); /* Check for mixed types and values. */ @@ -17718,7 +17692,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case TEMPLATE_PARM_INDEX: tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - if (tparm == error_mark_node) + if (error_operand_p (tparm)) return unify_invalid (explain_p); if (TEMPLATE_PARM_LEVEL (parm) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 07d10576957..795086a5854 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -386,6 +386,9 @@ add_stmt (tree t) STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); } + if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) + STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; + /* Add T to the statement-tree. Non-side-effect statements need to be recorded during statement expressions. */ gcc_checking_assert (!stmt_list_stack->is_empty ()); @@ -3864,6 +3867,7 @@ simplify_aggr_init_expr (tree *tp) aggr_init_expr_nargs (aggr_init_expr), AGGR_INIT_EXPR_ARGP (aggr_init_expr)); TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); + tree ret = call_expr; if (style == ctor) { @@ -3879,7 +3883,7 @@ simplify_aggr_init_expr (tree *tp) expand_call{,_inline}. */ cxx_mark_addressable (slot); CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true; - call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr); + ret = build2 (INIT_EXPR, TREE_TYPE (ret), slot, ret); } else if (style == pcc) { @@ -3887,11 +3891,25 @@ simplify_aggr_init_expr (tree *tp) need to copy the returned value out of the static buffer into the SLOT. */ push_deferring_access_checks (dk_no_check); - call_expr = build_aggr_init (slot, call_expr, - DIRECT_BIND | LOOKUP_ONLYCONVERTING, - tf_warning_or_error); + ret = build_aggr_init (slot, ret, + DIRECT_BIND | LOOKUP_ONLYCONVERTING, + tf_warning_or_error); pop_deferring_access_checks (); - call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot); + ret = build2 (COMPOUND_EXPR, TREE_TYPE (slot), ret, slot); + } + + /* DR 1030 says that we need to evaluate the elements of an + initializer-list in forward order even when it's used as arguments to + a constructor. So if the target wants to evaluate them in reverse + order and there's more than one argument other than 'this', force + pre-evaluation. */ + if (PUSH_ARGS_REVERSED && CALL_EXPR_LIST_INIT_P (aggr_init_expr) + && aggr_init_expr_nargs (aggr_init_expr) > 2) + { + tree preinit; + stabilize_call (call_expr, &preinit); + if (preinit) + ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), preinit, ret); } if (AGGR_INIT_ZERO_FIRST (aggr_init_expr)) @@ -3899,11 +3917,10 @@ simplify_aggr_init_expr (tree *tp) tree init = build_zero_init (type, NULL_TREE, /*static_storage_p=*/false); init = build2 (INIT_EXPR, void_type_node, slot, init); - call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr), - init, call_expr); + ret = build2 (COMPOUND_EXPR, TREE_TYPE (ret), init, ret); } - *tp = call_expr; + *tp = ret; } /* Emit all thunks to FN that should be emitted when FN is emitted. */ @@ -7717,8 +7734,8 @@ sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) { tree pri = CLASSTYPE_PRIMARY_BINFO (type); tree field_type; - constructor_elt elt; - int i; + unsigned i; + constructor_elt *ce; if (pri) field_type = BINFO_TYPE (pri); @@ -7729,14 +7746,14 @@ sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v) /* Find the element for the primary base or vptr and move it to the beginning of the vec. */ - vec<constructor_elt, va_gc> &vref = *v; - for (i = 0; ; ++i) - if (TREE_TYPE (vref[i].index) == field_type) + for (i = 0; vec_safe_iterate (v, i, &ce); ++i) + if (TREE_TYPE (ce->index) == field_type) break; - if (i > 0) + if (i > 0 && i < vec_safe_length (v)) { - elt = vref[i]; + vec<constructor_elt, va_gc> &vref = *v; + constructor_elt elt = vref[i]; for (; i > 0; --i) vref[i] = vref[i-1]; vref[0] = elt; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7d895bd96bd..e14002482be 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -454,6 +454,7 @@ build_aggr_init_expr (tree type, tree init) TREE_SIDE_EFFECTS (rval) = 1; AGGR_INIT_VIA_CTOR_P (rval) = is_ctor; TREE_NOTHROW (rval) = TREE_NOTHROW (init); + CALL_EXPR_LIST_INIT_P (rval) = CALL_EXPR_LIST_INIT_P (init); } else rval = init; diff --git a/gcc/cse.c b/gcc/cse.c index 73755849975..abe5dfcfbe4 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -4648,6 +4648,13 @@ cse_insn (rtx insn) && REGNO (dest) >= FIRST_PSEUDO_REGISTER) sets[i].src_volatile = 1; + /* Also do not record result of a non-volatile inline asm with + more than one result or with clobbers, we do not want CSE to + break the inline asm apart. */ + else if (GET_CODE (src) == ASM_OPERANDS + && GET_CODE (x) == PARALLEL) + sets[i].src_volatile = 1; + #if 0 /* It is no longer clear why we used to do this, but it doesn't appear to still be needed. So let's try without it since this diff --git a/gcc/dbxout.c b/gcc/dbxout.c index a44f8b0f4ed..f8618db357a 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -2110,12 +2110,12 @@ dbxout_type (tree type, int full) another type's definition; instead, output an xref and let the definition come when the name is defined. */ stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu"); - if (TYPE_NAME (type) != 0 - /* The C frontend creates for anonymous variable length - records/unions TYPE_NAME with DECL_NAME NULL. */ - && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL - || DECL_NAME (TYPE_NAME (type)))) - dbxout_type_name (type); + if (TYPE_IDENTIFIER (type)) + { + /* Note that the C frontend creates for anonymous variable + length records/unions TYPE_NAME with DECL_NAME NULL. */ + dbxout_type_name (type); + } else { stabstr_S ("$$"); @@ -2748,9 +2748,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) DBX format, and it confuses some tools such as objdump. */ && tree_fits_uhwi_p (TYPE_SIZE (type))) { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + tree name = TYPE_IDENTIFIER (type); dbxout_begin_complex_stabs (); stabstr_I (name); @@ -2807,9 +2805,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED) This is what represents `struct foo' with no typedef. */ /* In C++, the name of a type is the corresponding typedef. In C, it is an IDENTIFIER_NODE. */ - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + tree name = TYPE_IDENTIFIER (type); dbxout_begin_complex_stabs (); stabstr_I (name); diff --git a/gcc/doc/bugreport.texi b/gcc/doc/bugreport.texi index be035222597..e465c24b0b4 100644 --- a/gcc/doc/bugreport.texi +++ b/gcc/doc/bugreport.texi @@ -16,11 +16,9 @@ report the problem. @menu * Criteria: Bug Criteria. Have you really found a bug? * Reporting: Bug Reporting. How to report a bug effectively. -* Known: Trouble. Known problems. -* Help: Service. Where to ask for help. @end menu -@node Bug Criteria,Bug Reporting,,Bugs +@node Bug Criteria @section Have You Found a Bug? @cindex bug criteria @@ -83,7 +81,7 @@ If you are an experienced user of one of the languages GCC supports, your suggestions for improvement of GCC are welcome in any case. @end itemize -@node Bug Reporting,,Bug Criteria,Bugs +@node Bug Reporting @section How and where to Report Bugs @cindex compiler bugs, reporting diff --git a/gcc/doc/gcc.texi b/gcc/doc/gcc.texi index 1e0fc46d00b..c1f385774b7 100644 --- a/gcc/doc/gcc.texi +++ b/gcc/doc/gcc.texi @@ -140,7 +140,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}. * Gcov:: @command{gcov}---a test coverage program. * Trouble:: If you have trouble using GCC. * Bugs:: How, why and where to report bugs. -* Service:: How to find suppliers of support for GCC. +* Service:: How To Get Help with GCC * Contributing:: How to contribute to testing and developing GCC. * Funding:: How to help assure funding for free software. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index eca4e8f1afa..3fdfeb9571d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -246,7 +246,7 @@ Objective-C and Objective-C++ Dialects}. -Wno-endif-labels -Werror -Werror=* @gol -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol --Wformat-security -Wformat-y2k @gol +-Wformat-security -Wformat-signedness -Wformat-y2k @gol -Wframe-larger-than=@var{len} -Wno-free-nonheap-object -Wjump-misses-init @gol -Wignored-qualifiers @gol -Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol @@ -1070,6 +1070,7 @@ See S/390 and zSeries Options. -ffixed-@var{reg} -fexceptions @gol -fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables @gol -fasynchronous-unwind-tables @gol +-fno-gnu-unique @gol -finhibit-size-directive -finstrument-functions @gol -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol -finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{} @gol @@ -1088,28 +1089,6 @@ See S/390 and zSeries Options. -fvisibility -fstrict-volatile-bitfields -fsync-libcalls} @end table -@menu -* Overall Options:: Controlling the kind of output: - an executable, object files, assembler files, - or preprocessed source. -* C Dialect Options:: Controlling the variant of C language compiled. -* C++ Dialect Options:: Variations on C++. -* Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C - and Objective-C++. -* Language Independent Options:: Controlling how diagnostics should be - formatted. -* Warning Options:: How picky should the compiler be? -* Debugging Options:: Symbol tables, measurements, and debugging dumps. -* Optimize Options:: How much optimization? -* Preprocessor Options:: Controlling header files and macro definitions. - Also, getting dependency information for Make. -* Assembler Options:: Passing options to the assembler. -* Link Options:: Specifying libraries and so on. -* Directory Options:: Where to find header files and libraries. - Where to find the compiler executable files. -* Spec Files:: How to pass switches to sub-processes. -* Target Options:: Running a cross-compiler, or an old version of GCC. -@end menu @node Overall Options @section Options Controlling the Kind of Output @@ -2670,9 +2649,10 @@ the compiler to never throw an exception. @opindex Wnon-virtual-dtor @opindex Wno-non-virtual-dtor Warn when a class has virtual functions and an accessible non-virtual -destructor, in which case it is possible but unsafe to delete -an instance of a derived class through a pointer to the base class. -This warning is also enabled if @option{-Weffc++} is specified. +destructor itself or in an accessible polymorphic base class, in which +case it is possible but unsafe to delete an instance of a derived +class through a pointer to the class itself or base class. This +warning is automatically enabled if @option{-Weffc++} is specified. @item -Wreorder @r{(C++ and Objective-C++ only)} @opindex Wreorder @@ -2716,40 +2696,36 @@ The following @option{-W@dots{}} options are not affected by @option{-Wall}. @opindex Weffc++ @opindex Wno-effc++ Warn about violations of the following style guidelines from Scott Meyers' -@cite{Effective C++, Second Edition} book: +@cite{Effective C++} series of books: @itemize @bullet @item -Item 11: Define a copy constructor and an assignment operator for classes +Define a copy constructor and an assignment operator for classes with dynamically-allocated memory. @item -Item 12: Prefer initialization to assignment in constructors. - -@item -Item 14: Make destructors virtual in base classes. +Prefer initialization to assignment in constructors. @item -Item 15: Have @code{operator=} return a reference to @code{*this}. +Have @code{operator=} return a reference to @code{*this}. @item -Item 23: Don't try to return a reference when you must return an object. - -@end itemize - -Also warn about violations of the following style guidelines from -Scott Meyers' @cite{More Effective C++} book: +Don't try to return a reference when you must return an object. -@itemize @bullet @item -Item 6: Distinguish between prefix and postfix forms of increment and +Distinguish between prefix and postfix forms of increment and decrement operators. @item -Item 7: Never overload @code{&&}, @code{||}, or @code{,}. +Never overload @code{&&}, @code{||}, or @code{,}. @end itemize +This option also enables @option{-Wnon-virtual-dtor}, which is also +one of the effective C++ recommendations. However, the check is +extended to warn about the lack of virtual destructor in accessible +non-polymorphic bases classes too. + When selecting this option, be aware that the standard library headers do not obey all of these guidelines; use @samp{grep -v} to filter out those warnings. @@ -3563,7 +3539,7 @@ The C standard specifies that zero-length formats are allowed. @opindex Wformat=2 Enable @option{-Wformat} plus additional format checks. Currently equivalent to @option{-Wformat -Wformat-nonliteral -Wformat-security --Wformat-y2k}. +-Wformat-signedness -Wformat-y2k}. @item -Wformat-nonliteral @opindex Wformat-nonliteral @@ -3585,6 +3561,12 @@ currently a subset of what @option{-Wformat-nonliteral} warns about, but in future warnings may be added to @option{-Wformat-security} that are not included in @option{-Wformat-nonliteral}.) +@item -Wformat-signedness +@opindex Wformat-signedness +@opindex Wno-format-signedness +If @option{-Wformat} is specified, also warn if the format string +requires an unsigned argument and the argument is signed and vice versa. + @item -Wformat-y2k @opindex Wformat-y2k @opindex Wno-format-y2k @@ -7414,7 +7396,7 @@ Attempt to remove redundant extension instructions. This is especially helpful for the x86-64 architecture, which implicitly zero-extends in 64-bit registers after writing to their lower 32-bit half. -Enabled for x86 at levels @option{-O2}, @option{-O3}. +Enabled for AArch64 and x86 at levels @option{-O2}, @option{-O3}. @item -flive-range-shrinkage @opindex flive-range-shrinkage @@ -12988,6 +12970,9 @@ instructions because of a hardware erratum. Skip instructions are The second macro is only defined if @code{__AVR_HAVE_JMP_CALL__} is also set. +@item __AVR_ISA_RMW__ +The device has Read-Modify-Write instructions (XCH, LAC, LAS and LAT). + @item __AVR_SFR_OFFSET__=@var{offset} Instructions that can address I/O special function registers directly like @code{IN}, @code{OUT}, @code{SBI}, etc.@: may use a different @@ -22015,6 +22000,20 @@ Generate unwind table in DWARF 2 format, if supported by target machine. The table is exact at each instruction boundary, so it can be used for stack unwinding from asynchronous events (such as debugger or garbage collector). +@item -fno-gnu-unique +@opindex fno-gnu-unique +On systems with recent GNU assembler and C library, the C++ compiler +uses the @code{STB_GNU_UNIQUE} binding to make sure that definitions +of template static data members and static local variables in inline +functions are unique even in the presence of @code{RTLD_LOCAL}; this +is necessary to avoid problems with a library used by two different +@code{RTLD_LOCAL} plugins depending on a definition in one of them and +therefore disagreeing with the other one about the binding of the +symbol. But this causes @code{dlclose} to be ignored for affected +DSOs; if your program relies on reinitialization of a DSO via +@code{dlclose} and @code{dlopen}, you can use +@option{-fno-gnu-unique}. + @item -fpcc-struct-return @opindex fpcc-struct-return Return ``short'' @code{struct} and @code{union} values in memory like diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 85ef819c767..914860813ca 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1428,6 +1428,10 @@ Target supports a vector widening multiplication of @code{short} operands into @code{int} results, or can promote (unpack) from @code{short} to @code{int} and perform non-widening multiplication of @code{int}. +@item vect_widen_mult_si_to_di_pattern +Target supports a vector widening multiplication of @code{int} operands +into @code{long} results. + @item vect_sdot_qi Target supports a vector dot-product of @code{signed char}. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 2fb3c423bba..46b5cb528d4 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9766,6 +9766,8 @@ for @var{entity}. For any fixed @var{entity}, @code{mode_priority_to_mode} Generate one or more insns to set @var{entity} to @var{mode}. @var{hard_reg_live} is the set of hard registers live at the point where the insn(s) are to be inserted. +Sets of a lower numbered entity will be emitted before sets of a higher +numbered entity to a mode of the same or lower priority. @end defmac @node Target Attributes diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 9015c3c3acc..de7aa92df37 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7435,6 +7435,8 @@ for @var{entity}. For any fixed @var{entity}, @code{mode_priority_to_mode} Generate one or more insns to set @var{entity} to @var{mode}. @var{hard_reg_live} is the set of hard registers live at the point where the insn(s) are to be inserted. +Sets of a lower numbered entity will be emitted before sets of a higher +numbered entity to a mode of the same or lower priority. @end defmac @node Target Attributes diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 641cbb57079..940502090c1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -10364,9 +10364,7 @@ is_cxx_auto (tree type) { if (is_cxx ()) { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + tree name = TYPE_IDENTIFIER (type); if (name == get_identifier ("auto") || name == get_identifier ("decltype(auto)")) return true; @@ -10643,10 +10641,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, /* This probably indicates a bug. */ else if (mod_type_die && mod_type_die->die_tag == DW_TAG_base_type) { - name = TYPE_NAME (type); - if (name - && TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + name = TYPE_IDENTIFIER (type); add_name_attribute (mod_type_die, name ? IDENTIFIER_POINTER (name) : "__unknown__"); } @@ -11459,8 +11454,18 @@ const_ok_for_output_1 (rtx *rtlp, void *data ATTRIBUTE_UNUSED) return 1; } + /* FIXME: Refer to PR60655. It is possible for simplification + of rtl expressions in var tracking to produce such expressions. + We should really identify / validate expressions + enclosed in CONST that can be handled by assemblers on various + targets and only handle legitimate cases here. */ if (GET_CODE (rtl) != SYMBOL_REF) - return 0; + { + if (GET_CODE (rtl) == NOT) + return 1; + + return 0; + } if (CONSTANT_POOL_ADDRESS_P (rtl)) { @@ -16372,20 +16377,31 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b && tree_to_shwi (bound) == dflt) ; - /* Otherwise represent the bound as an unsigned value with the - precision of its type. The precision and signedness of the - type will be necessary to re-interpret it unambiguously. */ - else if (prec < HOST_BITS_PER_WIDE_INT) + /* If HOST_WIDE_INT is big enough then represent the bound as + a constant value. We need to choose a form based on + whether the type is signed or unsigned. We cannot just + call add_AT_unsigned if the value itself is positive + (add_AT_unsigned might add the unsigned value encoded as + DW_FORM_data[1248]). Some DWARF consumers will lookup the + bounds type and then sign extend any unsigned values found + for signed types. This is needed only for + DW_AT_{lower,upper}_bound, since for most other attributes, + consumers will treat DW_FORM_data[1248] as unsigned values, + regardless of the underlying type. */ + else if (prec <= HOST_BITS_PER_WIDE_INT + || tree_fits_uhwi_p (bound)) { - unsigned HOST_WIDE_INT mask - = ((unsigned HOST_WIDE_INT) 1 << prec) - 1; - add_AT_unsigned (subrange_die, bound_attr, - TREE_INT_CST_LOW (bound) & mask); + if (TYPE_UNSIGNED (TREE_TYPE (bound))) + add_AT_unsigned (subrange_die, bound_attr, + TREE_INT_CST_LOW (bound)); + else + add_AT_int (subrange_die, bound_attr, TREE_INT_CST_LOW (bound)); } - else if (prec == HOST_BITS_PER_WIDE_INT || tree_fits_uhwi_p (bound)) - add_AT_unsigned (subrange_die, bound_attr, - TREE_INT_CST_LOW (bound)); else + /* Otherwise represent the bound as an unsigned value with + the precision of its type. The precision and signedness + of the type will be necessary to re-interpret it + unambiguously. */ add_AT_wide (subrange_die, bound_attr, bound); } break; @@ -17528,22 +17544,23 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) if (simple_type_size_in_bits (TREE_TYPE (value)) <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value)) - /* DWARF2 does not provide a way of indicating whether or - not enumeration constants are signed or unsigned. GDB - always assumes the values are signed, so we output all - values as if they were signed. That means that - enumeration constants with very large unsigned values - will appear to have negative values in the debugger. - - TODO: the above comment is wrong, DWARF2 does provide - DW_FORM_sdata/DW_FORM_udata to represent signed/unsigned data. - This should be re-worked to use correct signed/unsigned - int/double tags for all cases, instead of always treating as - signed. */ - add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW (value)); + { + /* For constant forms created by add_AT_unsigned DWARF + consumers (GDB, elfutils, etc.) always zero extend + the value. Only when the actual value is negative + do we need to use add_AT_int to generate a constant + form that can represent negative values. */ + HOST_WIDE_INT val = TREE_INT_CST_LOW (value); + if (TYPE_UNSIGNED (TREE_TYPE (value)) || val >= 0) + add_AT_unsigned (enum_die, DW_AT_const_value, + (unsigned HOST_WIDE_INT) val); + else + add_AT_int (enum_die, DW_AT_const_value, val); + } else /* Enumeration constants may be wider than HOST_WIDE_INT. Handle - that here. */ + that here. TODO: This should be re-worked to use correct + signed/unsigned double tags for all cases. */ add_AT_wide (enum_die, DW_AT_const_value, value); } @@ -20017,10 +20034,9 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, dw_die_ref type_die = lookup_type_die (type); if (type_die == NULL) { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - type_die = new_die (DW_TAG_unspecified_type, comp_unit_die (), type); + tree name = TYPE_IDENTIFIER (type); + type_die = new_die (DW_TAG_unspecified_type, comp_unit_die (), + type); add_name_attribute (type_die, IDENTIFIER_POINTER (name)); equate_type_number_to_die (type, type_die); } @@ -20030,9 +20046,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, default: if (is_cxx_auto (type)) { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + tree name = TYPE_IDENTIFIER (type); dw_die_ref *die = (name == get_identifier ("auto") ? &auto_die : &decltype_auto_die); if (!*die) diff --git a/gcc/explow.c b/gcc/explow.c index bf7ed68e718..bc97c964e61 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -1700,6 +1700,9 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) emit_stack_probe (addr); } } + + /* Make sure nothing is scheduled before we are done. */ + emit_insn (gen_blockage ()); } /* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes) diff --git a/gcc/expmed.c b/gcc/expmed.c index e76b6fcc724..cffceb2c4a0 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4971,7 +4971,7 @@ make_tree (tree type, rtx x) return t; case CONST_DOUBLE: - STATIC_ASSERT (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT); + gcc_assert (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT); if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode) t = wide_int_to_tree (type, wide_int::from_array (&CONST_DOUBLE_LOW (x), 2, diff --git a/gcc/expr.c b/gcc/expr.c index b21422c4be7..d71622b3e99 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -551,9 +551,9 @@ convert_move (rtx to, rtx from, int unsignedp) if (unsignedp) fill_value = const0_rtx; else - fill_value = emit_store_flag (gen_reg_rtx (word_mode), - LT, lowfrom, const0_rtx, - VOIDmode, 0, -1); + fill_value = emit_store_flag_force (gen_reg_rtx (word_mode), + LT, lowfrom, const0_rtx, + lowpart_mode, 0, -1); /* Fill the remaining words. */ for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++) diff --git a/gcc/final.c b/gcc/final.c index 57ad6816157..c50c4293340 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -776,6 +776,8 @@ compute_alignments (void) /* In case block is frequent and reached mostly by non-fallthru edge, align it. It is most likely a first block of loop. */ if (has_fallthru + && !(single_succ_p (bb) + && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) && optimize_bb_for_speed_p (bb) && branch_frequency + fallthru_frequency > freq_threshold && (branch_frequency diff --git a/gcc/flag-types.h b/gcc/flag-types.h index ec16faa18a3..97382719ff7 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -229,4 +229,14 @@ enum vtv_priority { VTV_STANDARD_PRIORITY = 1, VTV_PREINIT_PRIORITY = 2 }; + +/* flag_lto_partition initialization values. */ +enum lto_partition_model { + LTO_PARTITION_NONE = 0, + LTO_PARTITION_ONE = 1, + LTO_PARTITION_BALANCED = 2, + LTO_PARTITION_1TO1 = 3, + LTO_PARTITION_MAX = 4 +}; + #endif /* ! GCC_FLAG_TYPES_H */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c05e77ca526..3a5237d0e5c 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -461,8 +461,6 @@ negate_expr_p (tree t) case TRUNC_DIV_EXPR: case ROUND_DIV_EXPR: - case FLOOR_DIV_EXPR: - case CEIL_DIV_EXPR: case EXACT_DIV_EXPR: /* In general we can't negate A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined @@ -657,8 +655,6 @@ fold_negate_expr (location_t loc, tree t) case TRUNC_DIV_EXPR: case ROUND_DIV_EXPR: - case FLOOR_DIV_EXPR: - case CEIL_DIV_EXPR: case EXACT_DIV_EXPR: /* In general we can't negate A / B, because if A is INT_MIN and B is 1, we may turn this into INT_MIN / -1 which is undefined diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 3d8cb5cdfc8..29ea5f7871c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,42 @@ +2014-04-13 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/58085 + PR fortran/60717 + * trans.h: Add 'use_offset' bitfield to gfc_se. + * trans-array.c (gfc_conv_expr_descriptor): Use 'use_offset' + as a trigger to unconditionally recalculate the offset for + array slices and constant arrays. + trans-expr.c (gfc_conv_intrinsic_to_class): Use it. + trans-stmt.c (trans_associate_var): Ditto. + (gfc_conv_procedure_call): Ditto. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR fortran/58880 + PR fortran/60495 + * resolve.c (gfc_resolve_finalizers): Ensure that vtables + and finalization wrappers are generated. + +2014-04-11 Janne Blomqvist <jb@gcc.gnu.org> + + * intrinsic.texi (RANDOM_SEED): Improve example. + +2014-04-10 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * class.c (gfc_build_class_symbol): Append "_t" to target class + names to make the generated type names unique. + +2014-04-04 Bernd Edlinger <bernd.edlinger@hotmail.de> + + PR fortran/60191 + * trans-types.c (gfc_get_function_type): In case of recursion + build a variadic function type with empty argument list instead of a + stdarg-like function type with incomplete argument list. + +2014-04-04 Tobias Burnus <burnus@net-b.de> + + * check.c (gfc_check_cmplx): Fix typo. + 2014-03-28 Mikael Morin <mikael@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 119750aab8f..b83d9da148d 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -1278,12 +1278,12 @@ gfc_check_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *kind) if (!kind && gfc_option.gfc_warn_conversion && x->ts.type == BT_REAL && x->ts.kind > gfc_default_real_kind) gfc_warning_now ("Conversion from %s to default-kind COMPLEX(%d) at %L " - "might loose precision, consider using the KIND argument", + "might lose precision, consider using the KIND argument", gfc_typename (&x->ts), gfc_default_real_kind, &x->where); else if (y && !kind && gfc_option.gfc_warn_conversion && y->ts.type == BT_REAL && y->ts.kind > gfc_default_real_kind) gfc_warning_now ("Conversion from %s to default-kind COMPLEX(%d) at %L " - "might loose precision, consider using the KIND argument", + "might lose precision, consider using the KIND argument", gfc_typename (&y->ts), gfc_default_real_kind, &y->where); return true; diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c index d01d7d8c97a..346aee65205 100644 --- a/gcc/fortran/class.c +++ b/gcc/fortran/class.c @@ -588,13 +588,13 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr, else if ((*as) && attr->pointer) sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank); else if ((*as)) - sprintf (name, "__class_%s_%d_%d", tname, rank, (*as)->corank); + sprintf (name, "__class_%s_%d_%dt", tname, rank, (*as)->corank); else if (attr->pointer) sprintf (name, "__class_%s_p", tname); else if (attr->allocatable) sprintf (name, "__class_%s_a", tname); else - sprintf (name, "__class_%s", tname); + sprintf (name, "__class_%s_t", tname); if (ts->u.derived->attr.unlimited_polymorphic) { diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 792518d468c..926ffe954ed 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -10207,11 +10207,12 @@ the @var{SIZE} argument. @item @emph{Example}: @smallexample subroutine init_random_seed() + use iso_fortran_env, only: int64 implicit none integer, allocatable :: seed(:) - integer :: i, n, un, istat, dt(8), pid, t(2), s - integer(8) :: count, tms - + integer :: i, n, un, istat, dt(8), pid + integer(int64) :: t + call random_seed(size = n) allocate(seed(n)) ! First try if the OS provides a random number generator @@ -10224,34 +10225,37 @@ subroutine init_random_seed() ! Fallback to XOR:ing the current time and pid. The PID is ! useful in case one launches multiple instances of the same ! program in parallel. - call system_clock(count) - if (count /= 0) then - t = transfer(count, t) - else + call system_clock(t) + if (t == 0) then call date_and_time(values=dt) - tms = (dt(1) - 1970) * 365_8 * 24 * 60 * 60 * 1000 & - + dt(2) * 31_8 * 24 * 60 * 60 * 1000 & - + dt(3) * 24 * 60 * 60 * 60 * 1000 & + t = (dt(1) - 1970) * 365_int64 * 24 * 60 * 60 * 1000 & + + dt(2) * 31_int64 * 24 * 60 * 60 * 1000 & + + dt(3) * 24_int64 * 60 * 60 * 1000 & + dt(5) * 60 * 60 * 1000 & + dt(6) * 60 * 1000 + dt(7) * 1000 & + dt(8) - t = transfer(tms, t) - end if - s = ieor(t(1), t(2)) - pid = getpid() + 1099279 ! Add a prime - s = ieor(s, pid) - if (n >= 3) then - seed(1) = t(1) + 36269 - seed(2) = t(2) + 72551 - seed(3) = pid - if (n > 3) then - seed(4:) = s + 37 * (/ (i, i = 0, n - 4) /) - end if - else - seed = s + 37 * (/ (i, i = 0, n - 1 ) /) end if + pid = getpid() + t = ieor(t, int(pid, kind(t))) + do i = 1, n + seed(i) = lcg(t) + end do end if call random_seed(put=seed) +contains + ! This simple PRNG might not be good enough for real work, but is + ! sufficient for seeding a better PRNG. + function lcg(s) + integer :: lcg + integer(int64) :: s + if (s == 0) then + s = 104729 + else + s = mod(s, 4294967296_int64) + end if + s = mod(s * 279470273_int64, 4294967291_int64) + lcg = int(mod(s, int(huge(0), int64)), kind(0)) + end function lcg end subroutine init_random_seed @end smallexample diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 6e23e570b17..38755fef6a2 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -11200,15 +11200,36 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) the requirements of the standard for procedures used as finalizers. */ static bool -gfc_resolve_finalizers (gfc_symbol* derived) +gfc_resolve_finalizers (gfc_symbol* derived, bool *finalizable) { gfc_finalizer* list; gfc_finalizer** prev_link; /* For removing wrong entries from the list. */ bool result = true; bool seen_scalar = false; + gfc_symbol *vtab; + gfc_component *c; + /* Return early when not finalizable. Additionally, ensure that derived-type + components have a their finalizables resolved. */ if (!derived->f2k_derived || !derived->f2k_derived->finalizers) - return true; + { + bool has_final = false; + for (c = derived->components; c; c = c->next) + if (c->ts.type == BT_DERIVED + && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable) + { + bool has_final2 = false; + if (!gfc_resolve_finalizers (c->ts.u.derived, &has_final)) + return false; /* Error. */ + has_final = has_final || has_final2; + } + if (!has_final) + { + if (finalizable) + *finalizable = false; + return true; + } + } /* Walk over the list of finalizer-procedures, check them, and if any one does not fit in with the standard's definition, print an error and remove @@ -11330,12 +11351,15 @@ gfc_resolve_finalizers (gfc_symbol* derived) /* Remove wrong nodes immediately from the list so we don't risk any troubles in the future when they might fail later expectations. */ error: - result = false; i = list; *prev_link = list->next; gfc_free_finalizer (i); + result = false; } + if (result == false) + return false; + /* Warn if we haven't seen a scalar finalizer procedure (but we know there were nodes in the list, must have been for arrays. It is surely a good idea to have a scalar version there if there's something to finalize. */ @@ -11344,8 +11368,14 @@ error: " defined at %L, suggest also scalar one", derived->name, &derived->declared_at); - gfc_find_derived_vtab (derived); - return result; + vtab = gfc_find_derived_vtab (derived); + c = vtab->ts.u.derived->components->next->next->next->next->next; + gfc_set_sym_referenced (c->initializer->symtree->n.sym); + + if (finalizable) + *finalizable = true; + + return true; } @@ -12513,7 +12543,7 @@ resolve_fl_derived (gfc_symbol *sym) return false; /* Resolve the finalizer procedures. */ - if (!gfc_resolve_finalizers (sym)) + if (!gfc_resolve_finalizers (sym, NULL)) return false; if (sym->attr.is_class && sym->ts.u.derived == NULL) diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index ff9a737a398..bb648f05891 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -6800,8 +6800,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) /* Set offset for assignments to pointer only to zero if it is not the full array. */ - if (se->direct_byref - && info->ref && info->ref->u.ar.type != AR_FULL) + if ((se->direct_byref || se->use_offset) + && ((info->ref && info->ref->u.ar.type != AR_FULL) + || (expr->expr_type == EXPR_ARRAY && se->use_offset))) base = gfc_index_zero_node; else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) base = gfc_evaluate_now (gfc_conv_array_offset (desc), &loop.pre); @@ -6886,13 +6887,13 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) stride, info->stride[n]); if (se->direct_byref - && info->ref - && info->ref->u.ar.type != AR_FULL) + && ((info->ref && info->ref->u.ar.type != AR_FULL) + || (expr->expr_type == EXPR_ARRAY && se->use_offset))) { base = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (base), base, stride); } - else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) + else if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)) || se->use_offset) { tmp = gfc_conv_array_lbound (desc, n); tmp = fold_build2_loc (input_location, MINUS_EXPR, @@ -6928,8 +6929,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) gfc_get_dataptr_offset (&loop.pre, parm, desc, offset, subref_array_target, expr); - if ((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) - && !se->data_not_needed) + if (((se->direct_byref || GFC_ARRAY_TYPE_P (TREE_TYPE (desc))) + && !se->data_not_needed) + || (se->use_offset && base != NULL_TREE)) { /* Set the offset. */ gfc_conv_descriptor_offset_set (&loop.pre, parm, base); diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index ba22368b500..c8386ec1207 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -593,6 +593,7 @@ gfc_conv_intrinsic_to_class (gfc_se *parmse, gfc_expr *e, else { parmse->ss = ss; + parmse->use_offset = 1; gfc_conv_expr_descriptor (parmse, e); gfc_add_modify (&parmse->pre, ctree, parmse->expr); } @@ -4380,6 +4381,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, || CLASS_DATA (fsym)->attr.codimension)) { /* Pass a class array. */ + parmse.use_offset = 1; gfc_conv_expr_descriptor (&parmse, e); /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 1a9068c0f46..00c99fcfb5b 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1170,16 +1170,18 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) /* If association is to an expression, evaluate it and create temporary. Otherwise, get descriptor of target for pointer assignment. */ gfc_init_se (&se, NULL); - if (sym->assoc->variable) + if (sym->assoc->variable || e->expr_type == EXPR_ARRAY) { se.direct_byref = 1; + se.use_offset = 1; se.expr = desc; } + gfc_conv_expr_descriptor (&se, e); /* If we didn't already do the pointer assignment, set associate-name descriptor to the one generated for the temporary. */ - if (!sym->assoc->variable) + if (!sym->assoc->variable && e->expr_type != EXPR_ARRAY) { int dim; diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 86e4e84081a..1f48bb00981 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2709,11 +2709,11 @@ tree gfc_get_function_type (gfc_symbol * sym) { tree type; - vec<tree, va_gc> *typelist; + vec<tree, va_gc> *typelist = NULL; gfc_formal_arglist *f; gfc_symbol *arg; - int alternate_return; - bool is_varargs = true, recursive_type = false; + int alternate_return = 0; + bool is_varargs = true; /* Make sure this symbol is a function, a subroutine or the main program. */ @@ -2725,15 +2725,12 @@ gfc_get_function_type (gfc_symbol * sym) if (sym->backend_decl == NULL) sym->backend_decl = error_mark_node; else if (sym->backend_decl == error_mark_node) - recursive_type = true; + goto arg_type_list_done; else if (sym->attr.proc_pointer) return TREE_TYPE (TREE_TYPE (sym->backend_decl)); else return TREE_TYPE (sym->backend_decl); - alternate_return = 0; - typelist = NULL; - if (sym->attr.entry_master) /* Additional parameter for selecting an entry point. */ vec_safe_push (typelist, gfc_array_index_type); @@ -2781,13 +2778,6 @@ gfc_get_function_type (gfc_symbol * sym) if (arg->attr.flavor == FL_PROCEDURE) { - /* We don't know in the general case which argument causes - recursion. But we know that it is a procedure. So we give up - creating the procedure argument type list at the first - procedure argument. */ - if (recursive_type) - goto arg_type_list_done; - type = gfc_get_function_type (arg); type = build_pointer_type (type); } @@ -2841,11 +2831,11 @@ gfc_get_function_type (gfc_symbol * sym) || sym->attr.if_source != IFSRC_UNKNOWN) is_varargs = false; -arg_type_list_done: - - if (!recursive_type && sym->backend_decl == error_mark_node) + if (sym->backend_decl == error_mark_node) sym->backend_decl = NULL_TREE; +arg_type_list_done: + if (alternate_return) type = integer_type_node; else if (!sym->attr.function || gfc_return_by_reference (sym)) @@ -2883,7 +2873,7 @@ arg_type_list_done: else type = gfc_sym_type (sym); - if (is_varargs || recursive_type) + if (is_varargs) type = build_varargs_function_type_vec (type, typelist); else type = build_function_type_vec (type, typelist); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 4ae68c6cb85..f8d29ecf2ec 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -87,6 +87,10 @@ typedef struct gfc_se args alias. */ unsigned force_tmp:1; + /* Unconditionally calculate offset for array segments and constant + arrays in gfc_conv_expr_descriptor. */ + unsigned use_offset:1; + unsigned want_coarray:1; /* Scalarization parameters. */ @@ -99,7 +103,7 @@ gfc_se; /* Denotes different types of coarray. Please keep in sync with libgfortran/caf/libcaf.h. */ -typedef enum +typedef enum { GFC_CAF_COARRAY_STATIC, GFC_CAF_COARRAY_ALLOC, @@ -178,7 +182,7 @@ typedef enum /* An intrinsic function call. Many intrinsic functions which map directly to library calls are created as GFC_SS_FUNCTION nodes. */ GFC_SS_INTRINSIC, - + /* A component of a derived type. */ GFC_SS_COMPONENT } diff --git a/gcc/function.h b/gcc/function.h index 38a0fc4688d..0aa6c9a1545 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -661,8 +661,8 @@ struct GTY(()) function { unsigned int is_thunk : 1; /* Nonzero if the current function contains any loops with - loop->force_vect set. */ - unsigned int has_force_vect_loops : 1; + loop->force_vectorize set. */ + unsigned int has_force_vectorize_loops : 1; /* Nonzero if the current function contains any loops with nonzero value in loop->simduid. */ diff --git a/gcc/gcc.c b/gcc/gcc.c index 5cb485acbd3..c8ab7d67484 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -7490,7 +7490,7 @@ used_arg (const char *p, int len) { const char *r; - for (q = multilib_options; *q != '\0'; q++) + for (q = multilib_options; *q != '\0'; *q && q++) { while (*q == ' ') q++; diff --git a/gcc/gcse.c b/gcc/gcse.c index 2bb0b5fec1e..b852aa1bf22 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -2502,6 +2502,65 @@ pre_insert_copies (void) } } +struct set_data +{ + rtx insn; + const_rtx set; + int nsets; +}; + +/* Increment number of sets and record set in DATA. */ + +static void +record_set_data (rtx dest, const_rtx set, void *data) +{ + struct set_data *s = (struct set_data *)data; + + if (GET_CODE (set) == SET) + { + /* We allow insns having multiple sets, where all but one are + dead as single set insns. In the common case only a single + set is present, so we want to avoid checking for REG_UNUSED + notes unless necessary. */ + if (s->nsets == 1 + && find_reg_note (s->insn, REG_UNUSED, SET_DEST (s->set)) + && !side_effects_p (s->set)) + s->nsets = 0; + + if (!s->nsets) + { + /* Record this set. */ + s->nsets += 1; + s->set = set; + } + else if (!find_reg_note (s->insn, REG_UNUSED, dest) + || side_effects_p (set)) + s->nsets += 1; + } +} + +static const_rtx +single_set_gcse (rtx insn) +{ + struct set_data s; + rtx pattern; + + gcc_assert (INSN_P (insn)); + + /* Optimize common case. */ + pattern = PATTERN (insn); + if (GET_CODE (pattern) == SET) + return pattern; + + s.insn = insn; + s.nsets = 0; + note_stores (pattern, record_set_data, &s); + + /* Considered invariant insns have exactly one set. */ + gcc_assert (s.nsets == 1); + return s.set; +} + /* Emit move from SRC to DEST noting the equivalence with expression computed in INSN. */ @@ -2509,7 +2568,8 @@ static rtx gcse_emit_move_after (rtx dest, rtx src, rtx insn) { rtx new_rtx; - rtx set = single_set (insn), set2; + const_rtx set = single_set_gcse (insn); + rtx set2; rtx note; rtx eqv = NULL_RTX; @@ -3369,13 +3429,12 @@ hoist_code (void) FOR_EACH_VEC_ELT (occrs_to_hoist, j, occr) { rtx insn; - rtx set; + const_rtx set; gcc_assert (!occr->deleted_p); insn = occr->insn; - set = single_set (insn); - gcc_assert (set); + set = single_set_gcse (insn); /* Create a pseudo-reg to store the result of reaching expressions into. Get the mode for the new pseudo @@ -3456,10 +3515,8 @@ get_pressure_class_and_nregs (rtx insn, int *nregs) { rtx reg; enum reg_class pressure_class; - rtx set = single_set (insn); + const_rtx set = single_set_gcse (insn); - /* Considered invariant insns have only one set. */ - gcc_assert (set != NULL_RTX); reg = SET_DEST (set); if (GET_CODE (reg) == SUBREG) reg = SUBREG_REG (reg); diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index 2c4da474eff..da663d6fb79 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -527,6 +527,24 @@ create_tmp_reg (tree type, const char *prefix) return tmp; } +/* Create a new temporary variable declaration of type TYPE by calling + create_tmp_var and if TYPE is a vector or a complex number, mark the new + temporary as gimple register. */ + +tree +create_tmp_reg_fn (struct function *fn, tree type, const char *prefix) +{ + tree tmp; + + tmp = create_tmp_var_raw (type, prefix); + gimple_add_tmp_var_fn (fn, tmp); + if (TREE_CODE (type) == COMPLEX_TYPE + || TREE_CODE (type) == VECTOR_TYPE) + DECL_GIMPLE_REG_P (tmp) = 1; + + return tmp; +} + /* ----- Expression related ----- */ diff --git a/gcc/gimple-expr.h b/gcc/gimple-expr.h index ed8e338beca..3b6cda8441b 100644 --- a/gcc/gimple-expr.h +++ b/gcc/gimple-expr.h @@ -33,6 +33,7 @@ extern tree create_tmp_var_name (const char *); extern tree create_tmp_var_raw (tree, const char *); extern tree create_tmp_var (tree, const char *); extern tree create_tmp_reg (tree, const char *); +extern tree create_tmp_reg_fn (struct function *, tree, const char *); extern void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 80fd786fdde..da3fb9fb35e 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -841,11 +841,6 @@ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi) void record_vars_into (tree vars, tree fn) { - bool change_cfun = fn != current_function_decl; - - if (change_cfun) - push_cfun (DECL_STRUCT_FUNCTION (fn)); - for (; vars; vars = DECL_CHAIN (vars)) { tree var = vars; @@ -860,11 +855,8 @@ record_vars_into (tree vars, tree fn) continue; /* Record the variable. */ - add_local_decl (cfun, var); + add_local_decl (DECL_STRUCT_FUNCTION (fn), var); } - - if (change_cfun) - pop_cfun (); } diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index 8431d26eae3..5e35b12d3c8 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -2992,10 +2992,10 @@ ncd_with_phi (slsr_cand_t c, const widest_int &incr, gimple phi, { slsr_cand_t arg_cand = base_cand_from_table (arg); widest_int diff = arg_cand->index - basis->index; + basic_block pred = gimple_phi_arg_edge (phi, i)->src; if ((incr == diff) || (!address_arithmetic_p && incr == -diff)) - ncd = ncd_for_two_cands (ncd, gimple_bb (arg_cand->cand_stmt), - *where, arg_cand, where); + ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where); } } } diff --git a/gcc/gimple.c b/gcc/gimple.c index 4d3b99ed9d2..f7f00e7a0f3 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1464,9 +1464,12 @@ gimple_set_bb (gimple stmt, basic_block bb) { stmt->bb = bb; + if (gimple_code (stmt) != GIMPLE_LABEL) + return; + /* If the statement is a label, add the label to block-to-labels map so that we can speed up edge creation for GIMPLE_GOTOs. */ - if (cfun->cfg && gimple_code (stmt) == GIMPLE_LABEL) + if (cfun->cfg) { tree t; int uid; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ad2178dd914..d7470fbb0a6 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -627,6 +627,25 @@ force_constant_size (tree var) /* Push the temporary variable TMP into the current binding. */ void +gimple_add_tmp_var_fn (struct function *fn, tree tmp) +{ + gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); + + /* Later processing assumes that the object size is constant, which might + not be true at this point. Force the use of a constant upper bound in + this case. */ + if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp))) + force_constant_size (tmp); + + DECL_CONTEXT (tmp) = fn->decl; + DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; + + record_vars_into (tmp, fn->decl); +} + +/* Push the temporary variable TMP into the current binding. */ + +void gimple_add_tmp_var (tree tmp) { gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); @@ -2794,15 +2813,18 @@ gimple_boolify (tree expr) return expr; case ANNOTATE_EXPR: - if ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)) - == annot_expr_ivdep_kind) + switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1))) { + case annot_expr_ivdep_kind: + case annot_expr_no_vector_kind: + case annot_expr_vector_kind: TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0)); if (TREE_CODE (type) != BOOLEAN_TYPE) TREE_TYPE (expr) = boolean_type_node; return expr; + default: + gcc_unreachable (); } - /* FALLTHRU */ default: if (COMPARISON_CLASS_P (expr)) @@ -7509,7 +7531,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case ANNOTATE_EXPR: { tree cond = TREE_OPERAND (*expr_p, 0); - tree id = TREE_OPERAND (*expr_p, 1); + tree kind = TREE_OPERAND (*expr_p, 1); tree type = TREE_TYPE (cond); if (!INTEGRAL_TYPE_P (type)) { @@ -7519,8 +7541,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, } tree tmp = create_tmp_var (type, NULL); gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p)); - gimple call = gimple_build_call_internal (IFN_ANNOTATE, 2, - cond, id); + gimple call + = gimple_build_call_internal (IFN_ANNOTATE, 2, cond, kind); gimple_call_set_lhs (call, tmp); gimplify_seq_add_stmt (pre_p, call); *expr_p = tmp; diff --git a/gcc/gimplify.h b/gcc/gimplify.h index 6bc0057c30e..47e72130add 100644 --- a/gcc/gimplify.h +++ b/gcc/gimplify.h @@ -60,6 +60,7 @@ extern tree get_formal_tmp_var (tree, gimple_seq *); extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); extern void declare_vars (tree, gimple, bool); extern void gimple_add_tmp_var (tree); +extern void gimple_add_tmp_var_fn (struct function *, tree); extern tree unshare_expr (tree); extern tree unshare_expr_without_location (tree); extern tree voidify_wrapper_expr (tree, tree); diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 689578e2064..0d153fa02e6 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,22 @@ +2014-04-14 Chris Manghane <cmang@google.com> + + * go-gcc.cc: Include "convert.h". + (Gcc_backend::string_constant_expression): New function. + (Gcc_backend::real_part_expression): Likewise. + (Gcc_backend::imag_part_expression): Likewise. + (Gcc_backend::complex_expression): Likewise. + (Gcc_backend::constructor_expression): Likewise. + (Gcc_backend::array_constructor_expression): Likewise. + (Gcc_backend::pointer_offset_expression): Likewise. + (Gcc_backend::array_index_expression): Likewise. + (Gcc_backend::call_expression): Likewise. + (Gcc_backend::exception_handler_statement): Likewise. + (Gcc_backend::function_defer_statement): Likewise. + (Gcc_backend::function_set_parameters): Likewise. + (Gcc_backend::function_set_body): Likewise. + (Gcc_backend::convert_expression): Handle various type + conversions. + 2014-03-03 Ian Lance Taylor <iant@google.com> * go-gcc.cc (Gcc_backend::immutable_struct): If IS_COMMON, set diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 37a837f021e..b91a7848cda 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -29,6 +29,7 @@ #include "stor-layout.h" #include "varasm.h" #include "tree-iterator.h" +#include "convert.h" #include "basic-block.h" #include "gimple-expr.h" #include "toplev.h" @@ -235,6 +236,18 @@ class Gcc_backend : public Backend complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag); Bexpression* + string_constant_expression(const std::string& val); + + Bexpression* + real_part_expression(Bexpression* bcomplex, Location); + + Bexpression* + imag_part_expression(Bexpression* bcomplex, Location); + + Bexpression* + complex_expression(Bexpression* breal, Bexpression* bimag, Location); + + Bexpression* convert_expression(Btype* type, Bexpression* expr, Location); Bexpression* @@ -259,6 +272,23 @@ class Gcc_backend : public Backend Bexpression* binary_expression(Operator, Bexpression*, Bexpression*, Location); + Bexpression* + constructor_expression(Btype*, const std::vector<Bexpression*>&, Location); + + Bexpression* + array_constructor_expression(Btype*, const std::vector<unsigned long>&, + const std::vector<Bexpression*>&, Location); + + Bexpression* + pointer_offset_expression(Bexpression* base, Bexpression* offset, Location); + + Bexpression* + array_index_expression(Bexpression* array, Bexpression* index, Location); + + Bexpression* + call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, + Location); + // Statements. Bstatement* @@ -294,6 +324,10 @@ class Gcc_backend : public Backend Bstatement* statement_list(const std::vector<Bstatement*>&); + Bstatement* + exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt, + Bstatement* finally_stmt, Location); + // Blocks. Bblock* @@ -372,6 +406,16 @@ class Gcc_backend : public Backend bool is_visible, bool is_declaration, bool is_inlinable, bool disable_split_stack, bool in_unique_section, Location); + Bstatement* + function_defer_statement(Bfunction* function, Bexpression* undefer, + Bexpression* defer, Location); + + bool + function_set_parameters(Bfunction* function, const std::vector<Bvariable*>&); + + bool + function_set_body(Bfunction* function, Bstatement* code_stmt); + private: // Make a Bexpression from a tree. Bexpression* @@ -973,18 +1017,108 @@ Gcc_backend::complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag) return tree_to_expr(ret); } +// Make a constant string expression. + +Bexpression* +Gcc_backend::string_constant_expression(const std::string& val) +{ + tree index_type = build_index_type(size_int(val.length())); + tree const_char_type = build_qualified_type(unsigned_char_type_node, + TYPE_QUAL_CONST); + tree string_type = build_array_type(const_char_type, index_type); + string_type = build_variant_type_copy(string_type); + TYPE_STRING_FLAG(string_type) = 1; + tree string_val = build_string(val.length(), val.data()); + TREE_TYPE(string_val) = string_type; + + return this->make_expression(string_val); +} + +// Return the real part of a complex expression. + +Bexpression* +Gcc_backend::real_part_expression(Bexpression* bcomplex, Location location) +{ + tree complex_tree = bcomplex->get_tree(); + if (complex_tree == error_mark_node) + return this->error_expression(); + gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree))); + tree ret = fold_build1_loc(location.gcc_location(), REALPART_EXPR, + TREE_TYPE(TREE_TYPE(complex_tree)), + complex_tree); + return this->make_expression(ret); +} + +// Return the imaginary part of a complex expression. + +Bexpression* +Gcc_backend::imag_part_expression(Bexpression* bcomplex, Location location) +{ + tree complex_tree = bcomplex->get_tree(); + if (complex_tree == error_mark_node) + return this->error_expression(); + gcc_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(complex_tree))); + tree ret = fold_build1_loc(location.gcc_location(), IMAGPART_EXPR, + TREE_TYPE(TREE_TYPE(complex_tree)), + complex_tree); + return this->make_expression(ret); +} + +// Make a complex expression given its real and imaginary parts. + +Bexpression* +Gcc_backend::complex_expression(Bexpression* breal, Bexpression* bimag, + Location location) +{ + tree real_tree = breal->get_tree(); + tree imag_tree = bimag->get_tree(); + if (real_tree == error_mark_node || imag_tree == error_mark_node) + return this->error_expression(); + gcc_assert(TYPE_MAIN_VARIANT(TREE_TYPE(real_tree)) + == TYPE_MAIN_VARIANT(TREE_TYPE(imag_tree))); + gcc_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(real_tree))); + tree ret = fold_build2_loc(location.gcc_location(), COMPLEX_EXPR, + build_complex_type(TREE_TYPE(real_tree)), + real_tree, imag_tree); + return this->make_expression(ret); +} + // An expression that converts an expression to a different type. Bexpression* -Gcc_backend::convert_expression(Btype* type, Bexpression* expr, Location) +Gcc_backend::convert_expression(Btype* type, Bexpression* expr, + Location location) { tree type_tree = type->get_tree(); tree expr_tree = expr->get_tree(); - if (type_tree == error_mark_node || expr_tree == error_mark_node) + if (type_tree == error_mark_node + || expr_tree == error_mark_node + || TREE_TYPE(expr_tree) == error_mark_node) return this->error_expression(); - tree ret = fold_convert(type_tree, expr_tree); - return tree_to_expr(ret); + tree ret; + if (this->type_size(type) == 0) + { + // Do not convert zero-sized types. + ret = expr_tree; + } + else if (TREE_CODE(type_tree) == INTEGER_TYPE) + ret = fold(convert_to_integer(type_tree, expr_tree)); + else if (TREE_CODE(type_tree) == REAL_TYPE) + ret = fold(convert_to_real(type_tree, expr_tree)); + else if (TREE_CODE(type_tree) == COMPLEX_TYPE) + ret = fold(convert_to_complex(type_tree, expr_tree)); + else if (TREE_CODE(type_tree) == POINTER_TYPE + && TREE_CODE(TREE_TYPE(expr_tree)) == INTEGER_TYPE) + ret = fold(convert_to_pointer(type_tree, expr_tree)); + else if (TREE_CODE(type_tree) == RECORD_TYPE + || TREE_CODE(type_tree) == ARRAY_TYPE) + ret = fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR, + type_tree, expr_tree); + else + ret = fold_convert_loc(location.gcc_location(), type_tree, expr_tree); + + return this->make_expression(ret); } // Get the address of a function. @@ -1242,6 +1376,205 @@ Gcc_backend::binary_expression(Operator op, Bexpression* left, return this->make_expression(ret); } +// Return an expression that constructs BTYPE with VALS. + +Bexpression* +Gcc_backend::constructor_expression(Btype* btype, + const std::vector<Bexpression*>& vals, + Location location) +{ + tree type_tree = btype->get_tree(); + if (type_tree == error_mark_node) + return this->error_expression(); + + vec<constructor_elt, va_gc> *init; + vec_alloc(init, vals.size()); + + bool is_constant = true; + tree field = TYPE_FIELDS(type_tree); + for (std::vector<Bexpression*>::const_iterator p = vals.begin(); + p != vals.end(); + ++p, field = DECL_CHAIN(field)) + { + gcc_assert(field != NULL_TREE); + tree val = (*p)->get_tree(); + if (TREE_TYPE(field) == error_mark_node + || val == error_mark_node + || TREE_TYPE(val) == error_mark_node) + return this->error_expression(); + + constructor_elt empty = {NULL, NULL}; + constructor_elt* elt = init->quick_push(empty); + elt->index = field; + elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), + val); + if (!TREE_CONSTANT(elt->value)) + is_constant = false; + } + gcc_assert(field == NULL_TREE); + tree ret = build_constructor(type_tree, init); + if (is_constant) + TREE_CONSTANT(ret) = 1; + + return this->make_expression(ret); +} + +Bexpression* +Gcc_backend::array_constructor_expression( + Btype* array_btype, const std::vector<unsigned long>& indexes, + const std::vector<Bexpression*>& vals, Location) +{ + tree type_tree = array_btype->get_tree(); + if (type_tree == error_mark_node) + return this->error_expression(); + + gcc_assert(indexes.size() == vals.size()); + vec<constructor_elt, va_gc> *init; + vec_alloc(init, vals.size()); + + bool is_constant = true; + for (size_t i = 0; i < vals.size(); ++i) + { + tree index = size_int(indexes[i]); + tree val = (vals[i])->get_tree(); + + if (index == error_mark_node + || val == error_mark_node) + return this->error_expression(); + + if (!TREE_CONSTANT(val)) + is_constant = false; + + constructor_elt empty = {NULL, NULL}; + constructor_elt* elt = init->quick_push(empty); + elt->index = index; + elt->value = val; + } + + tree ret = build_constructor(type_tree, init); + if (is_constant) + TREE_CONSTANT(ret) = 1; + return this->make_expression(ret); +} + +// Return an expression for the address of BASE[INDEX]. + +Bexpression* +Gcc_backend::pointer_offset_expression(Bexpression* base, Bexpression* index, + Location location) +{ + tree base_tree = base->get_tree(); + tree index_tree = index->get_tree(); + tree element_type_tree = TREE_TYPE(TREE_TYPE(base_tree)); + if (base_tree == error_mark_node + || TREE_TYPE(base_tree) == error_mark_node + || index_tree == error_mark_node + || element_type_tree == error_mark_node) + return this->error_expression(); + + tree element_size = TYPE_SIZE_UNIT(element_type_tree); + index_tree = fold_convert_loc(location.gcc_location(), sizetype, index_tree); + tree offset = fold_build2_loc(location.gcc_location(), MULT_EXPR, sizetype, + index_tree, element_size); + tree ptr = fold_build2_loc(location.gcc_location(), POINTER_PLUS_EXPR, + TREE_TYPE(base_tree), base_tree, offset); + return this->make_expression(ptr); +} + +// Return an expression representing ARRAY[INDEX] + +Bexpression* +Gcc_backend::array_index_expression(Bexpression* array, Bexpression* index, + Location location) +{ + tree array_tree = array->get_tree(); + tree index_tree = index->get_tree(); + if (array_tree == error_mark_node + || TREE_TYPE(array_tree) == error_mark_node + || index_tree == error_mark_node) + return this->error_expression(); + + tree ret = build4_loc(location.gcc_location(), ARRAY_REF, + TREE_TYPE(TREE_TYPE(array_tree)), array_tree, + index_tree, NULL_TREE, NULL_TREE); + return this->make_expression(ret); +} + +// Create an expression for a call to FN_EXPR with FN_ARGS. +Bexpression* +Gcc_backend::call_expression(Bexpression* fn_expr, + const std::vector<Bexpression*>& fn_args, + Location location) +{ + tree fn = fn_expr->get_tree(); + if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node) + return this->error_expression(); + + gcc_assert(FUNCTION_POINTER_TYPE_P(TREE_TYPE(fn))); + tree rettype = TREE_TYPE(TREE_TYPE(TREE_TYPE(fn))); + + size_t nargs = fn_args.size(); + tree* args = nargs == 0 ? NULL : new tree[nargs]; + for (size_t i = 0; i < nargs; ++i) + { + args[i] = fn_args.at(i)->get_tree(); + if (args[i] == error_mark_node) + return this->error_expression(); + } + + tree fndecl = fn; + if (TREE_CODE(fndecl) == ADDR_EXPR) + fndecl = TREE_OPERAND(fndecl, 0); + + // This is to support builtin math functions when using 80387 math. + tree excess_type = NULL_TREE; + if (optimize + && TREE_CODE(fndecl) == FUNCTION_DECL + && DECL_IS_BUILTIN(fndecl) + && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL + && nargs > 0 + && ((SCALAR_FLOAT_TYPE_P(rettype) + && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0]))) + || (COMPLEX_FLOAT_TYPE_P(rettype) + && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0]))))) + { + excess_type = excess_precision_type(TREE_TYPE(args[0])); + if (excess_type != NULL_TREE) + { + tree excess_fndecl = mathfn_built_in(excess_type, + DECL_FUNCTION_CODE(fndecl)); + if (excess_fndecl == NULL_TREE) + excess_type = NULL_TREE; + else + { + fn = build_fold_addr_expr_loc(location.gcc_location(), + excess_fndecl); + for (size_t i = 0; i < nargs; ++i) + { + if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i])) + || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i]))) + args[i] = ::convert(excess_type, args[i]); + } + } + } + } + + tree ret = + build_call_array_loc(location.gcc_location(), + excess_type != NULL_TREE ? excess_type : rettype, + fn, nargs, args); + + if (excess_type != NULL_TREE) + { + // Calling convert here can undo our excess precision change. + // That may or may not be a bug in convert_to_real. + ret = build1_loc(location.gcc_location(), NOP_EXPR, rettype, ret); + } + + delete[] args; + return this->make_expression(ret); +} + // An expression as a statement. Bstatement* @@ -1401,6 +1734,40 @@ Gcc_backend::return_statement(Bfunction* bfunction, return this->make_statement(ret); } +// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an +// error occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and if not +// NULL, it will always be executed. This is used for handling defers in Go +// functions. In C++, the resulting code is of this form: +// try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; } + +Bstatement* +Gcc_backend::exception_handler_statement(Bstatement* bstat, + Bstatement* except_stmt, + Bstatement* finally_stmt, + Location location) +{ + tree stat_tree = bstat->get_tree(); + tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree(); + tree finally_tree = finally_stmt == NULL + ? NULL_TREE + : finally_stmt->get_tree(); + + if (stat_tree == error_mark_node + || except_tree == error_mark_node + || finally_tree == error_mark_node) + return this->error_statement(); + + if (except_tree != NULL_TREE) + stat_tree = build2_loc(location.gcc_location(), TRY_CATCH_EXPR, + void_type_node, stat_tree, + build2_loc(location.gcc_location(), CATCH_EXPR, + void_type_node, NULL, except_tree)); + if (finally_tree != NULL_TREE) + stat_tree = build2_loc(location.gcc_location(), TRY_FINALLY_EXPR, + void_type_node, stat_tree, finally_tree); + return this->make_statement(stat_tree); +} + // If. Bstatement* @@ -2069,6 +2436,78 @@ Gcc_backend::function(Btype* fntype, const std::string& name, return new Bfunction(decl); } +// Create a statement that runs all deferred calls for FUNCTION. This should +// be a statement that looks like this in C++: +// finish: +// try { UNDEFER; } catch { CHECK_DEFER; goto finish; } + +Bstatement* +Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer, + Bexpression* defer, Location location) +{ + tree undefer_tree = undefer->get_tree(); + tree defer_tree = defer->get_tree(); + + if (undefer_tree == error_mark_node + || defer_tree == error_mark_node) + return this->error_statement(); + + tree stmt_list = NULL; + Blabel* blabel = this->label(function, "", location); + Bstatement* label_def = this->label_definition_statement(blabel); + append_to_statement_list(label_def->get_tree(), &stmt_list); + + Bstatement* jump_stmt = this->goto_statement(blabel, location); + tree jump = jump_stmt->get_tree(); + tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer_tree, jump); + catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body); + tree try_catch = + build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body); + append_to_statement_list(try_catch, &stmt_list); + + return this->make_statement(stmt_list); +} + +// Record PARAM_VARS as the variables to use for the parameters of FUNCTION. +// This will only be called for a function definition. + +bool +Gcc_backend::function_set_parameters(Bfunction* function, + const std::vector<Bvariable*>& param_vars) +{ + tree func_tree = function->get_tree(); + if (func_tree == error_mark_node) + return false; + + tree params = NULL_TREE; + tree *pp = ¶ms; + for (std::vector<Bvariable*>::const_iterator pv = param_vars.begin(); + pv != param_vars.end(); + ++pv) + { + *pp = (*pv)->get_tree(); + gcc_assert(*pp != error_mark_node); + pp = &DECL_CHAIN(*pp); + } + *pp = NULL_TREE; + DECL_ARGUMENTS(func_tree) = params; + return true; +} + +// Set the function body for FUNCTION using the code in CODE_BLOCK. + +bool +Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt) +{ + tree func_tree = function->get_tree(); + tree code = code_stmt->get_tree(); + + if (func_tree == error_mark_node || code == error_mark_node) + return false; + DECL_SAVED_TREE(func_tree) = code; + return true; +} + // The single backend. static Gcc_backend gcc_backend; diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h index cbe5f22b6ad..fd657ecc989 100644 --- a/gcc/go/gofrontend/backend.h +++ b/gcc/go/gofrontend/backend.h @@ -269,6 +269,22 @@ class Backend virtual Bexpression* complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag) = 0; + // Return an expression for the string value VAL. + virtual Bexpression* + string_constant_expression(const std::string& val) = 0; + + // Return an expression for the real part of BCOMPLEX. + virtual Bexpression* + real_part_expression(Bexpression* bcomplex, Location) = 0; + + // Return an expression for the imaginary part of BCOMPLEX. + virtual Bexpression* + imag_part_expression(Bexpression* bcomplex, Location) = 0; + + // Return an expression for the complex number (BREAL, BIMAG). + virtual Bexpression* + complex_expression(Bexpression* breal, Bexpression* bimag, Location) = 0; + // Return an expression that converts EXPR to TYPE. virtual Bexpression* convert_expression(Btype* type, Bexpression* expr, Location) = 0; @@ -312,6 +328,38 @@ class Backend binary_expression(Operator op, Bexpression* left, Bexpression* right, Location) = 0; + // Return an expression that constructs BTYPE with VALS. BTYPE must be the + // backend representation a of struct. VALS must be in the same order as the + // corresponding fields in BTYPE. + virtual Bexpression* + constructor_expression(Btype* btype, const std::vector<Bexpression*>& vals, + Location) = 0; + + // Return an expression that constructs an array of BTYPE with INDEXES and + // VALS. INDEXES and VALS must have the same amount of elements. Each index + // in INDEXES must be in the same order as the corresponding value in VALS. + virtual Bexpression* + array_constructor_expression(Btype* btype, + const std::vector<unsigned long>& indexes, + const std::vector<Bexpression*>& vals, + Location) = 0; + + // Return an expression for the address of BASE[INDEX]. + // BASE has a pointer type. This is used for slice indexing. + virtual Bexpression* + pointer_offset_expression(Bexpression* base, Bexpression* index, + Location) = 0; + + // Return an expression for ARRAY[INDEX] as an l-value. ARRAY is a valid + // fixed-length array, not a slice. + virtual Bexpression* + array_index_expression(Bexpression* array, Bexpression* index, Location) = 0; + + // Create an expression for a call to FN with ARGS. + virtual Bexpression* + call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, + Location) = 0; + // Statements. // Create an error statement. This is used for cases which should @@ -367,6 +415,15 @@ class Backend virtual Bstatement* statement_list(const std::vector<Bstatement*>&) = 0; + // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if + // an exception occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and + // if not NULL, it will always be executed. This is used for handling defers + // in Go functions. In C++, the resulting code is of this form: + // try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; } + virtual Bstatement* + exception_handler_statement(Bstatement* bstat, Bstatement* except_stmt, + Bstatement* finally_stmt, Location) = 0; + // Blocks. // Create a block. The frontend will call this function when it @@ -570,6 +627,26 @@ class Backend function(Btype* fntype, const std::string& name, const std::string& asm_name, bool is_visible, bool is_declaration, bool is_inlinable, bool disable_split_stack, bool in_unique_section, Location) = 0; + + // Create a statement that runs all deferred calls for FUNCTION. This should + // be a statement that looks like this in C++: + // finish: + // try { UNDEFER; } catch { CHECK_DEFER; goto finish; } + virtual Bstatement* + function_defer_statement(Bfunction* function, Bexpression* undefer, + Bexpression* check_defer, Location) = 0; + + // Record PARAM_VARS as the variables to use for the parameters of FUNCTION. + // This will only be called for a function definition. Returns true on + // success, false on failure. + virtual bool + function_set_parameters(Bfunction* function, + const std::vector<Bvariable*>& param_vars) = 0; + + // Set the function body for FUNCTION using the code in CODE_STMT. Returns + // true on success, false on failure. + virtual bool + function_set_body(Bfunction* function, Bstatement* code_stmt) = 0; }; // The backend interface has to define this function. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index f45b4a22709..bd2e3183bfe 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -140,128 +140,81 @@ Expression::determine_type_no_context() this->do_determine_type(&context); } -// Return a tree handling any conversions which must be done during +// Return an expression handling any conversions which must be done during // assignment. -tree -Expression::convert_for_assignment(Translate_context* context, Type* lhs_type, - Type* rhs_type, tree rhs_tree, - Location location) +Expression* +Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type, + Expression* rhs, Location location) { - if (lhs_type->is_error() || rhs_type->is_error()) - return error_mark_node; - - if (rhs_tree == error_mark_node || TREE_TYPE(rhs_tree) == error_mark_node) - return error_mark_node; - - Gogo* gogo = context->gogo(); - - tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo)); - if (lhs_type_tree == error_mark_node) - return error_mark_node; + Type* rhs_type = rhs->type(); + if (lhs_type->is_error() + || rhs_type->is_error() + || rhs->is_error_expression()) + return Expression::make_error(location); if (lhs_type->forwarded() != rhs_type->forwarded() && lhs_type->interface_type() != NULL) { if (rhs_type->interface_type() == NULL) - return Expression::convert_type_to_interface(context, lhs_type, - rhs_type, rhs_tree, - location); + return Expression::convert_type_to_interface(lhs_type, rhs, location); else - return Expression::convert_interface_to_interface(context, lhs_type, - rhs_type, rhs_tree, - false, location); + return Expression::convert_interface_to_interface(lhs_type, rhs, false, + location); } else if (lhs_type->forwarded() != rhs_type->forwarded() && rhs_type->interface_type() != NULL) - return Expression::convert_interface_to_type(context, lhs_type, rhs_type, - rhs_tree, location); + return Expression::convert_interface_to_type(lhs_type, rhs, location); else if (lhs_type->is_slice_type() && rhs_type->is_nil_type()) { - // Assigning nil to an open array. - go_assert(TREE_CODE(lhs_type_tree) == RECORD_TYPE); - - vec<constructor_elt, va_gc> *init; - vec_alloc(init, 3); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = init->quick_push(empty); - tree field = TYPE_FIELDS(lhs_type_tree); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), - "__values") == 0); - elt->index = field; - elt->value = fold_convert(TREE_TYPE(field), null_pointer_node); - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), - "__count") == 0); - elt->index = field; - elt->value = fold_convert(TREE_TYPE(field), integer_zero_node); - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), - "__capacity") == 0); - elt->index = field; - elt->value = fold_convert(TREE_TYPE(field), integer_zero_node); - - tree val = build_constructor(lhs_type_tree, init); - TREE_CONSTANT(val) = 1; - - return val; + // Assigning nil to a slice. + mpz_t zval; + mpz_init_set_ui(zval, 0UL); + Expression* zero = Expression::make_integer(&zval, NULL, location); + mpz_clear(zval); + Expression* nil = Expression::make_nil(location); + return Expression::make_slice_value(lhs_type, nil, zero, zero, location); } else if (rhs_type->is_nil_type()) - { - // The left hand side should be a pointer type at the tree - // level. - go_assert(POINTER_TYPE_P(lhs_type_tree)); - return fold_convert(lhs_type_tree, null_pointer_node); - } - else if (lhs_type_tree == TREE_TYPE(rhs_tree)) + return Expression::make_nil(location); + else if (Type::are_identical(lhs_type, rhs_type, false, NULL)) { // No conversion is needed. - return rhs_tree; - } - else if (POINTER_TYPE_P(lhs_type_tree) - || INTEGRAL_TYPE_P(lhs_type_tree) - || SCALAR_FLOAT_TYPE_P(lhs_type_tree) - || COMPLEX_FLOAT_TYPE_P(lhs_type_tree)) - return fold_convert_loc(location.gcc_location(), lhs_type_tree, rhs_tree); - else if ((TREE_CODE(lhs_type_tree) == RECORD_TYPE - && TREE_CODE(TREE_TYPE(rhs_tree)) == RECORD_TYPE) - || (TREE_CODE(lhs_type_tree) == ARRAY_TYPE - && TREE_CODE(TREE_TYPE(rhs_tree)) == ARRAY_TYPE)) + return rhs; + } + else if (lhs_type->points_to() != NULL) + return Expression::make_unsafe_cast(lhs_type, rhs, location); + else if (lhs_type->is_numeric_type()) + return Expression::make_cast(lhs_type, rhs, location); + else if ((lhs_type->struct_type() != NULL + && rhs_type->struct_type() != NULL) + || (lhs_type->array_type() != NULL + && rhs_type->array_type() != NULL)) { // Avoid confusion from zero sized variables which may be // represented as non-zero-sized. - if (int_size_in_bytes(lhs_type_tree) == 0 - || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0) - return rhs_tree; + // TODO(cmang): This check is for a GCC-specific issue, and should be + // removed from the frontend. FIXME. + size_t lhs_size = gogo->backend()->type_size(lhs_type->get_backend(gogo)); + size_t rhs_size = gogo->backend()->type_size(rhs_type->get_backend(gogo)); + if (rhs_size == 0 || lhs_size == 0) + return rhs; // This conversion must be permitted by Go, or we wouldn't have // gotten here. - go_assert(int_size_in_bytes(lhs_type_tree) - == int_size_in_bytes(TREE_TYPE(rhs_tree))); - return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR, - lhs_type_tree, rhs_tree); + return Expression::make_unsafe_cast(lhs_type, rhs, location); } else - { - go_assert(useless_type_conversion_p(lhs_type_tree, TREE_TYPE(rhs_tree))); - return rhs_tree; - } + return rhs; } -// Return a tree for a conversion from a non-interface type to an +// Return an expression for a conversion from a non-interface type to an // interface type. -tree -Expression::convert_type_to_interface(Translate_context* context, - Type* lhs_type, Type* rhs_type, - tree rhs_tree, Location location) +Expression* +Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs, + Location location) { - Gogo* gogo = context->gogo(); Interface_type* lhs_interface_type = lhs_type->interface_type(); bool lhs_is_empty = lhs_interface_type->is_empty(); @@ -270,29 +223,22 @@ Expression::convert_type_to_interface(Translate_context* context, // When setting an interface to nil, we just set both fields to // NULL. + Type* rhs_type = rhs->type(); if (rhs_type->is_nil_type()) { - Btype* lhs_btype = lhs_type->get_backend(gogo); - return expr_to_tree(gogo->backend()->zero_expression(lhs_btype)); + Expression* nil = Expression::make_nil(location); + return Expression::make_interface_value(lhs_type, nil, nil, location); } // This should have been checked already. go_assert(lhs_interface_type->implements_interface(rhs_type, NULL)); - tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo)); - if (lhs_type_tree == error_mark_node) - return error_mark_node; - // An interface is a tuple. If LHS_TYPE is an empty interface type, // then the first field is the type descriptor for RHS_TYPE. // Otherwise it is the interface method table for RHS_TYPE. - tree first_field_value; + Expression* first_field; if (lhs_is_empty) - { - Bexpression* rhs_bexpr = - rhs_type->type_descriptor_pointer(gogo, location); - first_field_value = expr_to_tree(rhs_bexpr); - } + first_field = Expression::make_type_descriptor(rhs_type, location); else { // Build the interface method table for this interface and this @@ -307,131 +253,72 @@ Expression::convert_type_to_interface(Translate_context* context, rhs_struct_type = rhs_type->deref()->struct_type(); is_pointer = true; } - tree method_table; if (rhs_named_type != NULL) - method_table = - rhs_named_type->interface_method_table(gogo, lhs_interface_type, - is_pointer); + first_field = + rhs_named_type->interface_method_table(lhs_interface_type, + is_pointer); else if (rhs_struct_type != NULL) - method_table = - rhs_struct_type->interface_method_table(gogo, lhs_interface_type, - is_pointer); + first_field = + rhs_struct_type->interface_method_table(lhs_interface_type, + is_pointer); else - method_table = null_pointer_node; - first_field_value = fold_convert_loc(location.gcc_location(), - const_ptr_type_node, method_table); + first_field = Expression::make_nil(location); } - if (first_field_value == error_mark_node) - return error_mark_node; - - // Start building a constructor for the value we will return. - - vec<constructor_elt, va_gc> *init; - vec_alloc(init, 2); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = init->quick_push(empty); - tree field = TYPE_FIELDS(lhs_type_tree); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), - (lhs_is_empty ? "__type_descriptor" : "__methods")) == 0); - elt->index = field; - elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), - first_field_value); - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__object") == 0); - elt->index = field; + Expression* obj; if (rhs_type->points_to() != NULL) { - // We are assigning a pointer to the interface; the interface + // We are assigning a pointer to the interface; the interface // holds the pointer itself. - elt->value = rhs_tree; - return build_constructor(lhs_type_tree, init); + obj = rhs; + } + else + { + // We are assigning a non-pointer value to the interface; the + // interface gets a copy of the value in the heap. + obj = Expression::make_heap_expression(rhs, location); } - // We are assigning a non-pointer value to the interface; the - // interface gets a copy of the value in the heap. + return Expression::make_interface_value(lhs_type, first_field, obj, location); +} - tree object_size = TYPE_SIZE_UNIT(TREE_TYPE(rhs_tree)); +// Return an expression for the type descriptor of RHS. - tree space = gogo->allocate_memory(rhs_type, object_size, location); - space = fold_convert_loc(location.gcc_location(), - build_pointer_type(TREE_TYPE(rhs_tree)), space); - space = save_expr(space); +Expression* +Expression::get_interface_type_descriptor(Expression* rhs) +{ + go_assert(rhs->type()->interface_type() != NULL); + Location location = rhs->location(); - tree ref = build_fold_indirect_ref_loc(location.gcc_location(), space); - TREE_THIS_NOTRAP(ref) = 1; - tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR, - void_type_node, ref, rhs_tree); + // The type descriptor is the first field of an empty interface. + if (rhs->type()->interface_type()->is_empty()) + return Expression::make_interface_info(rhs, INTERFACE_INFO_TYPE_DESCRIPTOR, + location); - elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), - space); + Expression* mtable = + Expression::make_interface_info(rhs, INTERFACE_INFO_METHODS, location); - return build2(COMPOUND_EXPR, lhs_type_tree, set, - build_constructor(lhs_type_tree, init)); -} + Expression* descriptor = + Expression::make_unary(OPERATOR_MULT, mtable, location); + descriptor = Expression::make_field_reference(descriptor, 0, location); + Expression* nil = Expression::make_nil(location); -// Return a tree for the type descriptor of RHS_TREE, which has -// interface type RHS_TYPE. If RHS_TREE is nil the result will be -// NULL. + Expression* eq = + Expression::make_binary(OPERATOR_EQEQ, mtable, nil, location); + return Expression::make_conditional(eq, nil, descriptor, location); +} -tree -Expression::get_interface_type_descriptor(Translate_context*, - Type* rhs_type, tree rhs_tree, - Location location) -{ - tree rhs_type_tree = TREE_TYPE(rhs_tree); - go_assert(TREE_CODE(rhs_type_tree) == RECORD_TYPE); - tree rhs_field = TYPE_FIELDS(rhs_type_tree); - tree v = build3(COMPONENT_REF, TREE_TYPE(rhs_field), rhs_tree, rhs_field, - NULL_TREE); - if (rhs_type->interface_type()->is_empty()) - { - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(rhs_field)), - "__type_descriptor") == 0); - return v; - } - - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(rhs_field)), "__methods") - == 0); - go_assert(POINTER_TYPE_P(TREE_TYPE(v))); - v = save_expr(v); - tree v1 = build_fold_indirect_ref_loc(location.gcc_location(), v); - go_assert(TREE_CODE(TREE_TYPE(v1)) == RECORD_TYPE); - tree f = TYPE_FIELDS(TREE_TYPE(v1)); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(f)), "__type_descriptor") - == 0); - v1 = build3(COMPONENT_REF, TREE_TYPE(f), v1, f, NULL_TREE); - - tree eq = fold_build2_loc(location.gcc_location(), EQ_EXPR, boolean_type_node, - v, fold_convert_loc(location.gcc_location(), - TREE_TYPE(v), - null_pointer_node)); - tree n = fold_convert_loc(location.gcc_location(), TREE_TYPE(v1), - null_pointer_node); - return fold_build3_loc(location.gcc_location(), COND_EXPR, TREE_TYPE(v1), - eq, n, v1); -} - -// Return a tree for the conversion of an interface type to an +// Return an expression for the conversion of an interface type to an // interface type. -tree -Expression::convert_interface_to_interface(Translate_context* context, - Type *lhs_type, Type *rhs_type, - tree rhs_tree, bool for_type_guard, - Location location) +Expression* +Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs, + bool for_type_guard, + Location location) { - Gogo* gogo = context->gogo(); Interface_type* lhs_interface_type = lhs_type->interface_type(); bool lhs_is_empty = lhs_interface_type->is_empty(); - tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo)); - if (lhs_type_tree == error_mark_node) - return error_mark_node; - // In the general case this requires runtime examination of the type // method table to match it up with the interface methods. @@ -442,169 +329,75 @@ Expression::convert_interface_to_interface(Translate_context* context, // Get the type descriptor for the right hand side. This will be // NULL for a nil interface. + Expression* rhs_type_expr = Expression::get_interface_type_descriptor(rhs); + Expression* lhs_type_expr = + Expression::make_type_descriptor(lhs_type, location); - if (!DECL_P(rhs_tree)) - rhs_tree = save_expr(rhs_tree); - - tree rhs_type_descriptor = - Expression::get_interface_type_descriptor(context, rhs_type, rhs_tree, - location); - - // The result is going to be a two element constructor. - - vec<constructor_elt, va_gc> *init; - vec_alloc (init, 2); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = init->quick_push(empty); - tree field = TYPE_FIELDS(lhs_type_tree); - elt->index = field; - + Expression* first_field; if (for_type_guard) { // A type assertion fails when converting a nil interface. - Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, - location); - tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); - static tree assert_interface_decl; - tree call = Gogo::call_builtin(&assert_interface_decl, - location, - "__go_assert_interface", - 2, - ptr_type_node, - TREE_TYPE(lhs_type_descriptor), - lhs_type_descriptor, - TREE_TYPE(rhs_type_descriptor), - rhs_type_descriptor); - if (call == error_mark_node) - return error_mark_node; - // This will panic if the interface conversion fails. - TREE_NOTHROW(assert_interface_decl) = 0; - elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), - call); + first_field = + Runtime::make_call(Runtime::ASSERT_INTERFACE, location, 2, + lhs_type_expr, rhs_type_expr); } else if (lhs_is_empty) { - // A convertion to an empty interface always succeeds, and the + // A conversion to an empty interface always succeeds, and the // first field is just the type descriptor of the object. - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), - "__type_descriptor") == 0); - elt->value = fold_convert_loc(location.gcc_location(), - TREE_TYPE(field), rhs_type_descriptor); + first_field = rhs_type_expr; } else { // A conversion to a non-empty interface may fail, but unlike a // type assertion converting nil will always succeed. - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__methods") - == 0); - Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, - location); - tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); - - static tree convert_interface_decl; - tree call = Gogo::call_builtin(&convert_interface_decl, - location, - "__go_convert_interface", - 2, - ptr_type_node, - TREE_TYPE(lhs_type_descriptor), - lhs_type_descriptor, - TREE_TYPE(rhs_type_descriptor), - rhs_type_descriptor); - if (call == error_mark_node) - return error_mark_node; - // This will panic if the interface conversion fails. - TREE_NOTHROW(convert_interface_decl) = 0; - elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), - call); + first_field = + Runtime::make_call(Runtime::CONVERT_INTERFACE, location, 2, + lhs_type_expr, rhs_type_expr); } // The second field is simply the object pointer. - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__object") == 0); - elt->index = field; - - tree rhs_type_tree = TREE_TYPE(rhs_tree); - go_assert(TREE_CODE(rhs_type_tree) == RECORD_TYPE); - tree rhs_field = DECL_CHAIN(TYPE_FIELDS(rhs_type_tree)); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(rhs_field)), "__object") == 0); - elt->value = build3(COMPONENT_REF, TREE_TYPE(rhs_field), rhs_tree, rhs_field, - NULL_TREE); - - return build_constructor(lhs_type_tree, init); + Expression* obj = + Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, location); + return Expression::make_interface_value(lhs_type, first_field, obj, location); } -// Return a tree for the conversion of an interface type to a +// Return an expression for the conversion of an interface type to a // non-interface type. -tree -Expression::convert_interface_to_type(Translate_context* context, - Type *lhs_type, Type* rhs_type, - tree rhs_tree, Location location) +Expression* +Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs, + Location location) { - Gogo* gogo = context->gogo(); - tree rhs_type_tree = TREE_TYPE(rhs_tree); - - tree lhs_type_tree = type_to_tree(lhs_type->get_backend(gogo)); - if (lhs_type_tree == error_mark_node) - return error_mark_node; - // Call a function to check that the type is valid. The function // will panic with an appropriate runtime type error if the type is // not valid. - Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo, - location); - tree lhs_type_descriptor = expr_to_tree(lhs_type_expr); - - if (!DECL_P(rhs_tree)) - rhs_tree = save_expr(rhs_tree); - - tree rhs_type_descriptor = - Expression::get_interface_type_descriptor(context, rhs_type, rhs_tree, - location); - - Bexpression* rhs_inter_expr = rhs_type->type_descriptor_pointer(gogo, - location); - tree rhs_inter_descriptor = expr_to_tree(rhs_inter_expr); - - static tree check_interface_type_decl; - tree call = Gogo::call_builtin(&check_interface_type_decl, - location, - "__go_check_interface_type", - 3, - void_type_node, - TREE_TYPE(lhs_type_descriptor), - lhs_type_descriptor, - TREE_TYPE(rhs_type_descriptor), - rhs_type_descriptor, - TREE_TYPE(rhs_inter_descriptor), - rhs_inter_descriptor); - if (call == error_mark_node) - return error_mark_node; - // This call will panic if the conversion is invalid. - TREE_NOTHROW(check_interface_type_decl) = 0; + Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type, + location); + Expression* rhs_descriptor = + Expression::get_interface_type_descriptor(rhs); + + Type* rhs_type = rhs->type(); + Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type, + location); + + Expression* check_iface = Runtime::make_call(Runtime::CHECK_INTERFACE_TYPE, + location, 3, lhs_type_expr, + rhs_descriptor, rhs_inter_expr); // If the call succeeds, pull out the value. - go_assert(TREE_CODE(rhs_type_tree) == RECORD_TYPE); - tree rhs_field = DECL_CHAIN(TYPE_FIELDS(rhs_type_tree)); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(rhs_field)), "__object") == 0); - tree val = build3(COMPONENT_REF, TREE_TYPE(rhs_field), rhs_tree, rhs_field, - NULL_TREE); + Expression* obj = Expression::make_interface_info(rhs, INTERFACE_INFO_OBJECT, + location); // If the value is a pointer, then it is the value we want. // Otherwise it points to the value. if (lhs_type->points_to() == NULL) { - val = fold_convert_loc(location.gcc_location(), - build_pointer_type(lhs_type_tree), val); - val = build_fold_indirect_ref_loc(location.gcc_location(), val); + obj = Expression::make_unsafe_cast(Type::make_pointer_type(lhs_type), obj, + location); + obj = Expression::make_unary(OPERATOR_MULT, obj, location); } - - return build2(COMPOUND_EXPR, lhs_type_tree, call, - fold_convert_loc(location.gcc_location(), lhs_type_tree, val)); + return Expression::make_compound(check_iface, obj, location); } // Convert an expression to a tree. This is implemented by the child @@ -674,54 +467,71 @@ Expression::backend_numeric_constant_expression(Translate_context* context, return ret; } -// Return a tree which evaluates to true if VAL, of arbitrary integer -// type, is negative or is more than the maximum value of BOUND_TYPE. -// If SOFAR is not NULL, it is or'red into the result. The return -// value may be NULL if SOFAR is NULL. +// Return an expression which evaluates to true if VAL, of arbitrary integer +// type, is negative or is more than the maximum value of the Go type "int". -tree -Expression::check_bounds(tree val, tree bound_type, tree sofar, - Location loc) +Expression* +Expression::check_bounds(Expression* val, Location loc) { - tree val_type = TREE_TYPE(val); - tree ret = NULL_TREE; + Type* val_type = val->type(); + Type* bound_type = Type::lookup_integer_type("int"); + + int val_type_size; + bool val_is_unsigned = false; + if (val_type->integer_type() != NULL) + { + val_type_size = val_type->integer_type()->bits(); + val_is_unsigned = val_type->integer_type()->is_unsigned(); + } + else + { + if (!val_type->is_numeric_type() + || !Type::are_convertible(bound_type, val_type, NULL)) + { + go_assert(saw_errors()); + return Expression::make_boolean(true, loc); + } + + if (val_type->complex_type() != NULL) + val_type_size = val_type->complex_type()->bits(); + else + val_type_size = val_type->float_type()->bits(); + } - if (!TYPE_UNSIGNED(val_type)) + Expression* negative_index = Expression::make_boolean(false, loc); + Expression* index_overflows = Expression::make_boolean(false, loc); + if (!val_is_unsigned) { - ret = fold_build2_loc(loc.gcc_location(), LT_EXPR, boolean_type_node, val, - build_int_cst(val_type, 0)); - if (ret == boolean_false_node) - ret = NULL_TREE; + mpz_t zval; + mpz_init_set_ui(zval, 0UL); + Expression* zero = Expression::make_integer(&zval, val_type, loc); + mpz_clear(zval); + + negative_index = Expression::make_binary(OPERATOR_LT, val, zero, loc); } - HOST_WIDE_INT val_type_size = int_size_in_bytes(val_type); - HOST_WIDE_INT bound_type_size = int_size_in_bytes(bound_type); - go_assert(val_type_size != -1 && bound_type_size != -1); + int bound_type_size = bound_type->integer_type()->bits(); if (val_type_size > bound_type_size || (val_type_size == bound_type_size - && TYPE_UNSIGNED(val_type) - && !TYPE_UNSIGNED(bound_type))) - { - tree max = TYPE_MAX_VALUE(bound_type); - tree big = fold_build2_loc(loc.gcc_location(), GT_EXPR, boolean_type_node, - val, fold_convert_loc(loc.gcc_location(), - val_type, max)); - if (big == boolean_false_node) - ; - else if (ret == NULL_TREE) - ret = big; - else - ret = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, ret, big); + && val_is_unsigned)) + { + mpz_t one; + mpz_init_set_ui(one, 1UL); + + // maxval = 2^(bound_type_size - 1) - 1 + mpz_t maxval; + mpz_init(maxval); + mpz_mul_2exp(maxval, one, bound_type_size - 1); + mpz_sub_ui(maxval, maxval, 1); + Expression* max = Expression::make_integer(&maxval, val_type, loc); + mpz_clear(one); + mpz_clear(maxval); + + index_overflows = Expression::make_binary(OPERATOR_GT, val, max, loc); } - if (ret == NULL_TREE) - return sofar; - else if (sofar == NULL_TREE) - return ret; - else - return fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, boolean_type_node, - sofar, ret); + return Expression::make_binary(OPERATOR_OROR, negative_index, index_overflows, + loc); } void @@ -1719,7 +1529,23 @@ String_expression::do_determine_type(const Type_context* context) tree String_expression::do_get_tree(Translate_context* context) { - return context->gogo()->go_string_constant_tree(this->val_); + Gogo* gogo = context->gogo(); + Btype* btype = Type::make_string_type()->get_backend(gogo); + + Location loc = this->location(); + std::vector<Bexpression*> init(2); + Bexpression* str_cst = + gogo->backend()->string_constant_expression(this->val_); + init[0] = gogo->backend()->address_expression(str_cst, loc); + + Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo); + mpz_t lenval; + mpz_init_set_ui(lenval, this->val_.length()); + init[1] = gogo->backend()->integer_constant_expression(int_btype, lenval); + mpz_clear(lenval); + + Bexpression* ret = gogo->backend()->constructor_expression(btype, init, loc); + return expr_to_tree(ret); } // Write string literal to string dump. @@ -1826,6 +1652,116 @@ Expression::make_string(const std::string& val, Location location) return new String_expression(val, location); } +// An expression that evaluates to some characteristic of a string. +// This is used when indexing, bound-checking, or nil checking a string. + +class String_info_expression : public Expression +{ + public: + String_info_expression(Expression* string, String_info string_info, + Location location) + : Expression(EXPRESSION_STRING_INFO, location), + string_(string), string_info_(string_info) + { } + + protected: + Type* + do_type(); + + void + do_determine_type(const Type_context*) + { go_unreachable(); } + + Expression* + do_copy() + { + return new String_info_expression(this->string_->copy(), this->string_info_, + this->location()); + } + + tree + do_get_tree(Translate_context* context); + + void + do_dump_expression(Ast_dump_context*) const; + + void + do_issue_nil_check() + { this->string_->issue_nil_check(); } + + private: + // The string for which we are getting information. + Expression* string_; + // What information we want. + String_info string_info_; +}; + +// Return the type of the string info. + +Type* +String_info_expression::do_type() +{ + switch (this->string_info_) + { + case STRING_INFO_DATA: + { + Type* byte_type = Type::lookup_integer_type("uint8"); + return Type::make_pointer_type(byte_type); + } + case STRING_INFO_LENGTH: + return Type::lookup_integer_type("int"); + default: + go_unreachable(); + } +} + +// Return string information in GENERIC. + +tree +String_info_expression::do_get_tree(Translate_context* context) +{ + Gogo* gogo = context->gogo(); + + Bexpression* bstring = tree_to_expr(this->string_->get_tree(context)); + Bexpression* ret; + switch (this->string_info_) + { + case STRING_INFO_DATA: + case STRING_INFO_LENGTH: + ret = gogo->backend()->struct_field_expression(bstring, this->string_info_, + this->location()); + break; + default: + go_unreachable(); + } + return expr_to_tree(ret); +} + +// Dump ast representation for a type info expression. + +void +String_info_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "stringinfo("; + this->string_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ","; + ast_dump_context->ostream() << + (this->string_info_ == STRING_INFO_DATA ? "data" + : this->string_info_ == STRING_INFO_LENGTH ? "length" + : "unknown"); + ast_dump_context->ostream() << ")"; +} + +// Make a string info expression. + +Expression* +Expression::make_string_info(Expression* string, String_info string_info, + Location location) +{ + return new String_info_expression(string, string_info, location); +} + // Make an integer expression. class Integer_expression : public Expression @@ -2826,16 +2762,8 @@ Const_expression::do_check_types(Gogo*) tree Const_expression::do_get_tree(Translate_context* context) { - Gogo* gogo = context->gogo(); - tree type_tree; - if (this->type_ == NULL) - type_tree = NULL_TREE; - else - { - type_tree = type_to_tree(this->type_->get_backend(gogo)); - if (type_tree == error_mark_node) - return error_mark_node; - } + if (this->type_ != NULL && this->type_->is_error()) + return error_mark_node; // If the type has been set for this expression, but the underlying // object is an abstract int or float, we try to get the abstract @@ -2855,24 +2783,15 @@ Const_expression::do_get_tree(Translate_context* context) } } - tree const_tree = this->constant_->get_tree(gogo, context->function()); - if (this->type_ == NULL - || const_tree == error_mark_node - || TREE_TYPE(const_tree) == error_mark_node) - return const_tree; - - tree ret; - if (TYPE_MAIN_VARIANT(type_tree) == TYPE_MAIN_VARIANT(TREE_TYPE(const_tree))) - ret = fold_convert(type_tree, const_tree); - else if (TREE_CODE(type_tree) == INTEGER_TYPE) - ret = fold(convert_to_integer(type_tree, const_tree)); - else if (TREE_CODE(type_tree) == REAL_TYPE) - ret = fold(convert_to_real(type_tree, const_tree)); - else if (TREE_CODE(type_tree) == COMPLEX_TYPE) - ret = fold(convert_to_complex(type_tree, const_tree)); - else - go_unreachable(); - return ret; + Gogo* gogo = context->gogo(); + Bexpression* ret = + tree_to_expr(this->constant_->get_tree(gogo, context->function())); + if (this->type_ != NULL) + { + Btype* btype = this->type_->get_backend(gogo); + ret = gogo->backend()->convert_expression(btype, ret, this->location()); + } + return expr_to_tree(ret); } // Dump ast representation for constant expression. @@ -3221,8 +3140,10 @@ Expression* Type_conversion_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) { - if (this->type()->is_string_type() - && this->expr_->type()->is_slice_type() + if (((this->type()->is_string_type() + && this->expr_->type()->is_slice_type()) + || (this->type()->interface_type() != NULL + && this->expr_->type()->interface_type() != NULL)) && !this->expr_->is_variable()) { Temporary_statement* temp = @@ -3325,73 +3246,50 @@ Type_conversion_expression::do_check_types(Gogo*) tree Type_conversion_expression::do_get_tree(Translate_context* context) { - Gogo* gogo = context->gogo(); - tree type_tree = type_to_tree(this->type_->get_backend(gogo)); - tree expr_tree = this->expr_->get_tree(context); - - if (type_tree == error_mark_node - || expr_tree == error_mark_node - || TREE_TYPE(expr_tree) == error_mark_node) - return error_mark_node; - - if (TYPE_MAIN_VARIANT(type_tree) == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree))) - return fold_convert(type_tree, expr_tree); - Type* type = this->type_; Type* expr_type = this->expr_->type(); - tree ret; - if (type->interface_type() != NULL || expr_type->interface_type() != NULL) - ret = Expression::convert_for_assignment(context, type, expr_type, - expr_tree, this->location()); - else if (type->integer_type() != NULL) - { - if (expr_type->integer_type() != NULL - || expr_type->float_type() != NULL - || expr_type->is_unsafe_pointer_type()) - ret = fold(convert_to_integer(type_tree, expr_tree)); - else - go_unreachable(); - } - else if (type->float_type() != NULL) + + Gogo* gogo = context->gogo(); + Btype* btype = type->get_backend(gogo); + Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context)); + Location loc = this->location(); + + if (Type::are_identical(type, expr_type, false, NULL)) { - if (expr_type->integer_type() != NULL - || expr_type->float_type() != NULL) - ret = fold(convert_to_real(type_tree, expr_tree)); - else - go_unreachable(); + Bexpression* bconvert = + gogo->backend()->convert_expression(btype, bexpr, loc); + return expr_to_tree(bconvert); } - else if (type->complex_type() != NULL) + else if (type->interface_type() != NULL + || expr_type->interface_type() != NULL) { - if (expr_type->complex_type() != NULL) - ret = fold(convert_to_complex(type_tree, expr_tree)); - else - go_unreachable(); + Expression* conversion = + Expression::convert_for_assignment(gogo, type, this->expr_, + this->location()); + return conversion->get_tree(context); } else if (type->is_string_type() && expr_type->integer_type() != NULL) { - Type* int_type = Type::lookup_integer_type("int"); - tree int_type_tree = type_to_tree(int_type->get_backend(gogo)); - - expr_tree = fold_convert(int_type_tree, expr_tree); - if (tree_fits_shwi_p (expr_tree)) + mpz_t intval; + Numeric_constant nc; + if (this->expr_->numeric_constant_value(&nc) + && nc.to_int(&intval) + && mpz_fits_ushort_p(intval)) { - HOST_WIDE_INT intval = tree_to_shwi (expr_tree); std::string s; - Lex::append_char(intval, true, &s, this->location()); - Expression* se = Expression::make_string(s, this->location()); + Lex::append_char(mpz_get_ui(intval), true, &s, loc); + mpz_clear(intval); + Expression* se = Expression::make_string(s, loc); return se->get_tree(context); } Expression* i2s_expr = - Runtime::make_call(Runtime::INT_TO_STRING, this->location(), 1, - this->expr_); - i2s_expr = Expression::make_cast(type, i2s_expr, this->location()); - ret = i2s_expr->get_tree(context); + Runtime::make_call(Runtime::INT_TO_STRING, loc, 1, this->expr_); + return Expression::make_cast(type, i2s_expr, loc)->get_tree(context); } else if (type->is_string_type() && expr_type->is_slice_type()) { - Location location = this->location(); Array_type* a = expr_type->array_type(); Type* e = a->element_type()->forwarded(); go_assert(e->integer_type() != NULL); @@ -3407,46 +3305,50 @@ Type_conversion_expression::do_get_tree(Translate_context* context) } Expression* valptr = a->get_value_pointer(gogo, this->expr_); Expression* len = a->get_length(gogo, this->expr_); - Expression* a2s_expr = Runtime::make_call(code, location, 2, valptr, len); - ret = a2s_expr->get_tree(context); + return Runtime::make_call(code, loc, 2, valptr, len)->get_tree(context); } else if (type->is_slice_type() && expr_type->is_string_type()) { Type* e = type->array_type()->element_type()->forwarded(); go_assert(e->integer_type() != NULL); - Expression* s2a_expr; + Runtime::Function code; if (e->integer_type()->is_byte()) - s2a_expr = Runtime::make_call(Runtime::STRING_TO_BYTE_ARRAY, - this->location(), 1, this->expr_); + code = Runtime::STRING_TO_BYTE_ARRAY; else { go_assert(e->integer_type()->is_rune()); - s2a_expr = Runtime::make_call(Runtime::STRING_TO_INT_ARRAY, - this->location(), 1, this->expr_); + code = Runtime::STRING_TO_INT_ARRAY; } - s2a_expr = Expression::make_unsafe_cast(type, s2a_expr, - this->location()); - ret = s2a_expr->get_tree(context); + Expression* s2a = Runtime::make_call(code, loc, 1, this->expr_); + return Expression::make_unsafe_cast(type, s2a, loc)->get_tree(context); + } + else if (type->is_numeric_type()) + { + go_assert(Type::are_convertible(type, expr_type, NULL)); + Bexpression* bconvert = + gogo->backend()->convert_expression(btype, bexpr, loc); + return expr_to_tree(bconvert); } else if ((type->is_unsafe_pointer_type() - && expr_type->points_to() != NULL) - || (expr_type->is_unsafe_pointer_type() - && type->points_to() != NULL)) - ret = fold_convert(type_tree, expr_tree); - else if (type->is_unsafe_pointer_type() - && expr_type->integer_type() != NULL) - ret = convert_to_pointer(type_tree, expr_tree); - else if (this->may_convert_function_types_ - && type->function_type() != NULL - && expr_type->function_type() != NULL) - ret = fold_convert_loc(this->location().gcc_location(), type_tree, - expr_tree); + && (expr_type->points_to() != NULL + || expr_type->integer_type())) + || (expr_type->is_unsafe_pointer_type() + && type->points_to() != NULL) + || (this->may_convert_function_types_ + && type->function_type() != NULL + && expr_type->function_type() != NULL)) + { + Bexpression* bconvert = + gogo->backend()->convert_expression(btype, bexpr, loc); + return expr_to_tree(bconvert); + } else - ret = Expression::convert_for_assignment(context, type, expr_type, - expr_tree, this->location()); - - return ret; + { + Expression* conversion = + Expression::convert_for_assignment(gogo, type, this->expr_, loc); + return conversion->get_tree(context); + } } // Output a type conversion in a constant expression. @@ -3560,58 +3462,57 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context) Type* t = this->type_; Type* et = this->expr_->type(); - - tree type_tree = type_to_tree(this->type_->get_backend(context->gogo())); - tree expr_tree = this->expr_->get_tree(context); - if (type_tree == error_mark_node || expr_tree == error_mark_node) - return error_mark_node; - - Location loc = this->location(); - - bool use_view_convert = false; - if (t->is_slice_type()) + if (t->array_type() != NULL) + go_assert(et->array_type() != NULL + && t->is_slice_type() == et->is_slice_type()); + else if (t->struct_type() != NULL) { - go_assert(et->is_slice_type()); - use_view_convert = true; + if (t->named_type() != NULL + && et->named_type() != NULL + && !Type::are_convertible(t, et, NULL)) + { + go_assert(saw_errors()); + return error_mark_node; + } + + go_assert(et->struct_type() != NULL + && Type::are_convertible(t, et, NULL)); } else if (t->map_type() != NULL) go_assert(et->map_type() != NULL); else if (t->channel_type() != NULL) go_assert(et->channel_type() != NULL); else if (t->points_to() != NULL) - go_assert(et->points_to() != NULL || et->is_nil_type()); + go_assert(et->points_to() != NULL + || et->channel_type() != NULL + || et->map_type() != NULL + || et->function_type() != NULL + || et->is_nil_type()); else if (et->is_unsafe_pointer_type()) go_assert(t->points_to() != NULL); - else if (t->interface_type() != NULL && !t->interface_type()->is_empty()) - { - go_assert(et->interface_type() != NULL - && !et->interface_type()->is_empty()); - use_view_convert = true; - } - else if (t->interface_type() != NULL && t->interface_type()->is_empty()) + else if (t->interface_type() != NULL) { + bool empty_iface = t->interface_type()->is_empty(); go_assert(et->interface_type() != NULL - && et->interface_type()->is_empty()); - use_view_convert = true; + && et->interface_type()->is_empty() == empty_iface); } else if (t->integer_type() != NULL) - { - go_assert(et->is_boolean_type() - || et->integer_type() != NULL - || et->function_type() != NULL - || et->points_to() != NULL - || et->map_type() != NULL - || et->channel_type() != NULL); - return convert_to_integer(type_tree, expr_tree); - } + go_assert(et->is_boolean_type() + || et->integer_type() != NULL + || et->function_type() != NULL + || et->points_to() != NULL + || et->map_type() != NULL + || et->channel_type() != NULL); else go_unreachable(); - if (use_view_convert) - return fold_build1_loc(loc.gcc_location(), VIEW_CONVERT_EXPR, type_tree, - expr_tree); - else - return fold_convert_loc(loc.gcc_location(), type_tree, expr_tree); + Gogo* gogo = context->gogo(); + Btype* btype = t->get_backend(gogo); + Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context)); + Location loc = this->location(); + Bexpression* ret = + gogo->backend()->convert_expression(btype, bexpr, loc); + return expr_to_tree(ret); } // Dump ast representation for an unsafe type conversion expression. @@ -3757,7 +3658,7 @@ class Unary_expression : public Expression }; // If we are taking the address of a composite literal, and the -// contents are not constant, then we want to make a heap composite +// contents are not constant, then we want to make a heap expression // instead. Expression* @@ -4758,9 +4659,19 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc, { case OPERATOR_PLUS: mpz_add(val, left_val, right_val); + if (mpz_sizeinbase(val, 2) > 0x100000) + { + error_at(location, "constant addition overflow"); + mpz_set_ui(val, 1); + } break; case OPERATOR_MINUS: mpz_sub(val, left_val, right_val); + if (mpz_sizeinbase(val, 2) > 0x100000) + { + error_at(location, "constant subtraction overflow"); + mpz_set_ui(val, 1); + } break; case OPERATOR_OR: mpz_ior(val, left_val, right_val); @@ -4770,6 +4681,11 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc, break; case OPERATOR_MULT: mpz_mul(val, left_val, right_val); + if (mpz_sizeinbase(val, 2) > 0x100000) + { + error_at(location, "constant multiplication overflow"); + mpz_set_ui(val, 1); + } break; case OPERATOR_DIV: if (mpz_sgn(right_val) != 0) @@ -4797,7 +4713,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc, else { error_at(location, "shift count overflow"); - mpz_set_ui(val, 0); + mpz_set_ui(val, 1); } break; } @@ -4808,7 +4724,7 @@ Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc, if (mpz_cmp_ui(right_val, shift) != 0) { error_at(location, "shift count overflow"); - mpz_set_ui(val, 0); + mpz_set_ui(val, 1); } else { @@ -6888,7 +6804,7 @@ Bound_method_expression::do_get_tree(Translate_context* context) vals->push_back(val); Expression* ret = Expression::make_struct_composite_literal(st, vals, loc); - ret = Expression::make_heap_composite(ret, loc); + ret = Expression::make_heap_expression(ret, loc); tree ret_tree = ret->get_tree(context); @@ -7776,27 +7692,33 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const return false; if (arg_type->is_abstract()) return false; + if (this->seen_) + return false; unsigned int ret; if (this->code_ == BUILTIN_SIZEOF) { - if (!arg_type->backend_type_size(this->gogo_, &ret)) + this->seen_ = true; + bool ok = arg_type->backend_type_size(this->gogo_, &ret); + this->seen_ = false; + if (!ok) return false; } else if (this->code_ == BUILTIN_ALIGNOF) { + bool ok; + this->seen_ = true; if (arg->field_reference_expression() == NULL) - { - if (!arg_type->backend_type_align(this->gogo_, &ret)) - return false; - } + ok = arg_type->backend_type_align(this->gogo_, &ret); else { // Calling unsafe.Alignof(s.f) returns the alignment of // the type of f when it is used as a field in a struct. - if (!arg_type->backend_type_field_align(this->gogo_, &ret)) - return false; + ok = arg_type->backend_type_field_align(this->gogo_, &ret); } + this->seen_ = false; + if (!ok) + return false; } else go_unreachable(); @@ -7813,6 +7735,9 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const Field_reference_expression* farg = arg->field_reference_expression(); if (farg == NULL) return false; + if (this->seen_) + return false; + unsigned int total_offset = 0; while (true) { @@ -7823,10 +7748,13 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const if (st->named_type() != NULL) st->named_type()->convert(this->gogo_); unsigned int offset; - if (!st->struct_type()->backend_field_offset(this->gogo_, - farg->field_index(), - &offset)) - return false; + this->seen_ = true; + bool ok = st->struct_type()->backend_field_offset(this->gogo_, + farg->field_index(), + &offset); + this->seen_ = false; + if (!ok) + return false; total_offset += offset; if (farg->implicit() && struct_expr->field_reference_expression() != NULL) { @@ -8439,7 +8367,7 @@ Builtin_call_expression::do_get_tree(Translate_context* context) { const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 1); - Expression* arg = *args->begin(); + Expression* arg = args->front(); Type* arg_type = arg->type(); if (this->seen_) @@ -8448,31 +8376,22 @@ Builtin_call_expression::do_get_tree(Translate_context* context) return error_mark_node; } this->seen_ = true; - - tree arg_tree = arg->get_tree(context); - this->seen_ = false; - - if (arg_tree == error_mark_node) - return error_mark_node; - if (arg_type->points_to() != NULL) { arg_type = arg_type->points_to(); go_assert(arg_type->array_type() != NULL && !arg_type->is_slice_type()); - go_assert(POINTER_TYPE_P(TREE_TYPE(arg_tree))); - arg_tree = build_fold_indirect_ref(arg_tree); + arg = Expression::make_unary(OPERATOR_MULT, arg, location); } Type* int_type = Type::lookup_integer_type("int"); - tree int_type_tree = type_to_tree(int_type->get_backend(gogo)); - - tree val_tree; + Expression* val; if (this->code_ == BUILTIN_LEN) { if (arg_type->is_string_type()) - val_tree = String_type::length_tree(gogo, arg_tree); + val = Expression::make_string_info(arg, STRING_INFO_LENGTH, + location); else if (arg_type->array_type() != NULL) { if (this->seen_) @@ -8481,34 +8400,13 @@ Builtin_call_expression::do_get_tree(Translate_context* context) return error_mark_node; } this->seen_ = true; - Expression* len = arg_type->array_type()->get_length(gogo, arg); - val_tree = len->get_tree(context); + val = arg_type->array_type()->get_length(gogo, arg); this->seen_ = false; } else if (arg_type->map_type() != NULL) - { - tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo)); - static tree map_len_fndecl; - val_tree = Gogo::call_builtin(&map_len_fndecl, - location, - "__go_map_len", - 1, - int_type_tree, - arg_type_tree, - arg_tree); - } + val = Runtime::make_call(Runtime::MAP_LEN, location, 1, arg); else if (arg_type->channel_type() != NULL) - { - tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo)); - static tree chan_len_fndecl; - val_tree = Gogo::call_builtin(&chan_len_fndecl, - location, - "__go_chan_len", - 1, - int_type_tree, - arg_type_tree, - arg_tree); - } + val = Runtime::make_call(Runtime::CHAN_LEN, location, 1, arg); else go_unreachable(); } @@ -8522,36 +8420,24 @@ Builtin_call_expression::do_get_tree(Translate_context* context) return error_mark_node; } this->seen_ = true; - Expression* cap = - arg_type->array_type()->get_capacity(gogo, arg); - val_tree = cap->get_tree(context); + val = arg_type->array_type()->get_capacity(gogo, arg); this->seen_ = false; } else if (arg_type->channel_type() != NULL) - { - tree arg_type_tree = type_to_tree(arg_type->get_backend(gogo)); - static tree chan_cap_fndecl; - val_tree = Gogo::call_builtin(&chan_cap_fndecl, - location, - "__go_chan_cap", - 1, - int_type_tree, - arg_type_tree, - arg_tree); - } + val = Runtime::make_call(Runtime::CHAN_CAP, location, 1, arg); else go_unreachable(); } - return fold_convert_loc(location.gcc_location(), int_type_tree, - val_tree); + return Expression::make_cast(int_type, val, + location)->get_tree(context); } case BUILTIN_PRINT: case BUILTIN_PRINTLN: { const bool is_ln = this->code_ == BUILTIN_PRINTLN; - tree stmt_list = NULL_TREE; + Expression* print_stmts = NULL; const Expression_list* call_args = this->args(); if (call_args != NULL) @@ -8562,139 +8448,91 @@ Builtin_call_expression::do_get_tree(Translate_context* context) { if (is_ln && p != call_args->begin()) { - static tree print_space_fndecl; - tree call = Gogo::call_builtin(&print_space_fndecl, - location, - "__go_print_space", - 0, - void_type_node); - if (call == error_mark_node) - return error_mark_node; - append_to_statement_list(call, &stmt_list); - } - - Type* type = (*p)->type(); + Expression* print_space = + Runtime::make_call(Runtime::PRINT_SPACE, + this->location(), 0); - tree arg = (*p)->get_tree(context); - if (arg == error_mark_node) - return error_mark_node; + print_stmts = + Expression::make_compound(print_stmts, print_space, + location); + } - tree* pfndecl; - const char* fnname; + Expression* arg = *p; + Type* type = arg->type(); + Runtime::Function code; if (type->is_string_type()) - { - static tree print_string_fndecl; - pfndecl = &print_string_fndecl; - fnname = "__go_print_string"; - } + code = Runtime::PRINT_STRING; else if (type->integer_type() != NULL && type->integer_type()->is_unsigned()) { - static tree print_uint64_fndecl; - pfndecl = &print_uint64_fndecl; - fnname = "__go_print_uint64"; Type* itype = Type::lookup_integer_type("uint64"); - Btype* bitype = itype->get_backend(gogo); - arg = fold_convert_loc(location.gcc_location(), - type_to_tree(bitype), arg); + arg = Expression::make_cast(itype, arg, location); + code = Runtime::PRINT_UINT64; } else if (type->integer_type() != NULL) { - static tree print_int64_fndecl; - pfndecl = &print_int64_fndecl; - fnname = "__go_print_int64"; Type* itype = Type::lookup_integer_type("int64"); - Btype* bitype = itype->get_backend(gogo); - arg = fold_convert_loc(location.gcc_location(), - type_to_tree(bitype), arg); + arg = Expression::make_cast(itype, arg, location); + code = Runtime::PRINT_INT64; } else if (type->float_type() != NULL) { - static tree print_double_fndecl; - pfndecl = &print_double_fndecl; - fnname = "__go_print_double"; - arg = fold_convert_loc(location.gcc_location(), - double_type_node, arg); + Type* dtype = Type::lookup_float_type("float64"); + arg = Expression::make_cast(dtype, arg, location); + code = Runtime::PRINT_DOUBLE; } else if (type->complex_type() != NULL) { - static tree print_complex_fndecl; - pfndecl = &print_complex_fndecl; - fnname = "__go_print_complex"; - arg = fold_convert_loc(location.gcc_location(), - complex_double_type_node, arg); + Type* ctype = Type::lookup_complex_type("complex128"); + arg = Expression::make_cast(ctype, arg, location); + code = Runtime::PRINT_COMPLEX; } else if (type->is_boolean_type()) - { - static tree print_bool_fndecl; - pfndecl = &print_bool_fndecl; - fnname = "__go_print_bool"; - } + code = Runtime::PRINT_BOOL; else if (type->points_to() != NULL || type->channel_type() != NULL || type->map_type() != NULL || type->function_type() != NULL) { - static tree print_pointer_fndecl; - pfndecl = &print_pointer_fndecl; - fnname = "__go_print_pointer"; - arg = fold_convert_loc(location.gcc_location(), - ptr_type_node, arg); + arg = Expression::make_cast(type, arg, location); + code = Runtime::PRINT_POINTER; } else if (type->interface_type() != NULL) { if (type->interface_type()->is_empty()) - { - static tree print_empty_interface_fndecl; - pfndecl = &print_empty_interface_fndecl; - fnname = "__go_print_empty_interface"; - } + code = Runtime::PRINT_EMPTY_INTERFACE; else - { - static tree print_interface_fndecl; - pfndecl = &print_interface_fndecl; - fnname = "__go_print_interface"; - } + code = Runtime::PRINT_INTERFACE; } else if (type->is_slice_type()) - { - static tree print_slice_fndecl; - pfndecl = &print_slice_fndecl; - fnname = "__go_print_slice"; - } + code = Runtime::PRINT_SLICE; else { go_assert(saw_errors()); return error_mark_node; } - tree call = Gogo::call_builtin(pfndecl, - location, - fnname, - 1, - void_type_node, - TREE_TYPE(arg), - arg); - if (call == error_mark_node) - return error_mark_node; - append_to_statement_list(call, &stmt_list); + Expression* call = Runtime::make_call(code, location, 1, arg); + if (print_stmts == NULL) + print_stmts = call; + else + print_stmts = Expression::make_compound(print_stmts, call, + location); } } if (is_ln) { - static tree print_nl_fndecl; - tree call = Gogo::call_builtin(&print_nl_fndecl, - location, - "__go_print_nl", - 0, - void_type_node); - if (call == error_mark_node) - return error_mark_node; - append_to_statement_list(call, &stmt_list); + Expression* print_nl = + Runtime::make_call(Runtime::PRINT_NL, location, 0); + if (print_stmts == NULL) + print_stmts = print_nl; + else + print_stmts = Expression::make_compound(print_stmts, print_nl, + location); } - return stmt_list; + return print_stmts->get_tree(context); } case BUILTIN_PANIC: @@ -8702,29 +8540,13 @@ Builtin_call_expression::do_get_tree(Translate_context* context) const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 1); Expression* arg = args->front(); - tree arg_tree = arg->get_tree(context); - if (arg_tree == error_mark_node) - return error_mark_node; Type *empty = Type::make_empty_interface_type(Linemap::predeclared_location()); - arg_tree = Expression::convert_for_assignment(context, empty, - arg->type(), - arg_tree, location); - static tree panic_fndecl; - tree call = Gogo::call_builtin(&panic_fndecl, - location, - "__go_panic", - 1, - void_type_node, - TREE_TYPE(arg_tree), - arg_tree); - if (call == error_mark_node) - return error_mark_node; - // This function will throw an exception. - TREE_NOTHROW(panic_fndecl) = 0; - // This function will not return. - TREE_THIS_VOLATILE(panic_fndecl) = 1; - return call; + arg = Expression::convert_for_assignment(gogo, empty, arg, location); + + Expression* panic = + Runtime::make_call(Runtime::PANIC, location, 1, arg); + return panic->get_tree(context); } case BUILTIN_RECOVER: @@ -8734,49 +8556,22 @@ Builtin_call_expression::do_get_tree(Translate_context* context) const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 1); Expression* arg = args->front(); - tree arg_tree = arg->get_tree(context); - if (arg_tree == error_mark_node) - return error_mark_node; - Type *empty = Type::make_empty_interface_type(Linemap::predeclared_location()); - tree empty_tree = type_to_tree(empty->get_backend(context->gogo())); - Type* nil_type = Type::make_nil_type(); Expression* nil = Expression::make_nil(location); - tree nil_tree = nil->get_tree(context); - tree empty_nil_tree = Expression::convert_for_assignment(context, - empty, - nil_type, - nil_tree, - location); + nil = Expression::convert_for_assignment(gogo, empty, nil, location); // We need to handle a deferred call to recover specially, // because it changes whether it can recover a panic or not. // See test7 in test/recover1.go. - tree call; - if (this->is_deferred()) - { - static tree deferred_recover_fndecl; - call = Gogo::call_builtin(&deferred_recover_fndecl, - location, - "__go_deferred_recover", - 0, - empty_tree); - } - else - { - static tree recover_fndecl; - call = Gogo::call_builtin(&recover_fndecl, - location, - "__go_recover", - 0, - empty_tree); - } - if (call == error_mark_node) - return error_mark_node; - return fold_build3_loc(location.gcc_location(), COND_EXPR, empty_tree, - arg_tree, call, empty_nil_tree); + Expression* recover = Runtime::make_call((this->is_deferred() + ? Runtime::DEFERRED_RECOVER + : Runtime::RECOVER), + location, 0); + Expression* cond = + Expression::make_conditional(arg, recover, nil, location); + return cond->get_tree(context); } case BUILTIN_CLOSE: @@ -8784,17 +8579,9 @@ Builtin_call_expression::do_get_tree(Translate_context* context) const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 1); Expression* arg = args->front(); - tree arg_tree = arg->get_tree(context); - if (arg_tree == error_mark_node) - return error_mark_node; - static tree close_fndecl; - return Gogo::call_builtin(&close_fndecl, - location, - "__go_builtin_close", - 1, - void_type_node, - TREE_TYPE(arg_tree), - arg_tree); + Expression* close = Runtime::make_call(Runtime::CLOSE, location, + 1, arg); + return close->get_tree(context); } case BUILTIN_SIZEOF: @@ -8810,8 +8597,12 @@ Builtin_call_expression::do_get_tree(Translate_context* context) return error_mark_node; } Type* uintptr_type = Type::lookup_integer_type("uintptr"); - tree type = type_to_tree(uintptr_type->get_backend(gogo)); - return build_int_cst(type, val); + mpz_t ival; + nc.get_int(&ival); + Expression* int_cst = + Expression::make_integer(&ival, uintptr_type, location); + mpz_clear(ival); + return int_cst->get_tree(context); } case BUILTIN_COPY: @@ -8821,88 +8612,51 @@ Builtin_call_expression::do_get_tree(Translate_context* context) Expression* arg1 = args->front(); Expression* arg2 = args->back(); - tree arg1_tree = arg1->get_tree(context); - tree arg2_tree = arg2->get_tree(context); - if (arg1_tree == error_mark_node || arg2_tree == error_mark_node) - return error_mark_node; - Type* arg1_type = arg1->type(); Array_type* at = arg1_type->array_type(); go_assert(arg1->is_variable()); - Expression* arg1_valptr = at->get_value_pointer(gogo, arg1); - Expression* arg1_len_expr = at->get_length(gogo, arg1); - tree arg1_val = arg1_valptr->get_tree(context); - tree arg1_len = arg1_len_expr->get_tree(context); - if (arg1_val == error_mark_node || arg1_len == error_mark_node) - return error_mark_node; + Expression* arg1_val = at->get_value_pointer(gogo, arg1); + Expression* arg1_len = at->get_length(gogo, arg1); Type* arg2_type = arg2->type(); - tree arg2_val; - tree arg2_len; + go_assert(arg2->is_variable()); + Expression* arg2_val; + Expression* arg2_len; if (arg2_type->is_slice_type()) { at = arg2_type->array_type(); - go_assert(arg2->is_variable()); - Expression* arg2_valptr = at->get_value_pointer(gogo, arg2); - Expression* arg2_len_expr = at->get_length(gogo, arg2); - arg2_val = arg2_valptr->get_tree(context); - arg2_len = arg2_len_expr->get_tree(context); + arg2_val = at->get_value_pointer(gogo, arg2); + arg2_len = at->get_length(gogo, arg2); } else { - arg2_tree = save_expr(arg2_tree); - arg2_val = String_type::bytes_tree(gogo, arg2_tree); - arg2_len = String_type::length_tree(gogo, arg2_tree); + go_assert(arg2->is_variable()); + arg2_val = Expression::make_string_info(arg2, STRING_INFO_DATA, + location); + arg2_len = Expression::make_string_info(arg2, STRING_INFO_LENGTH, + location); } - if (arg2_val == error_mark_node || arg2_len == error_mark_node) - return error_mark_node; - - arg1_len = save_expr(arg1_len); - arg2_len = save_expr(arg2_len); - tree len = fold_build3_loc(location.gcc_location(), COND_EXPR, - TREE_TYPE(arg1_len), - fold_build2_loc(location.gcc_location(), - LT_EXPR, boolean_type_node, - arg1_len, arg2_len), - arg1_len, arg2_len); - len = save_expr(len); + Expression* cond = + Expression::make_binary(OPERATOR_LT, arg1_len, arg2_len, location); + Expression* length = + Expression::make_conditional(cond, arg1_len, arg2_len, location); Type* element_type = at->element_type(); Btype* element_btype = element_type->get_backend(gogo); - tree element_type_tree = type_to_tree(element_btype); - if (element_type_tree == error_mark_node) - return error_mark_node; - tree element_size = TYPE_SIZE_UNIT(element_type_tree); - tree bytecount = fold_convert_loc(location.gcc_location(), - TREE_TYPE(element_size), len); - bytecount = fold_build2_loc(location.gcc_location(), MULT_EXPR, - TREE_TYPE(element_size), - bytecount, element_size); - bytecount = fold_convert_loc(location.gcc_location(), size_type_node, - bytecount); - - arg1_val = fold_convert_loc(location.gcc_location(), ptr_type_node, - arg1_val); - arg2_val = fold_convert_loc(location.gcc_location(), ptr_type_node, - arg2_val); - - static tree copy_fndecl; - tree call = Gogo::call_builtin(©_fndecl, - location, - "__go_copy", - 3, - void_type_node, - ptr_type_node, - arg1_val, - ptr_type_node, - arg2_val, - size_type_node, - bytecount); - if (call == error_mark_node) - return error_mark_node; - return fold_build2_loc(location.gcc_location(), COMPOUND_EXPR, - TREE_TYPE(len), call, len); + mpz_t size; + size_t element_size = gogo->backend()->type_size(element_btype); + mpz_init_set_ui(size, element_size); + Expression* size_expr = Expression::make_integer(&size, length->type(), location); + mpz_clear(size); + + Expression* bytecount = + Expression::make_binary(OPERATOR_MULT, size_expr, length, location); + Expression* copy = Runtime::make_call(Runtime::COPY, location, 3, + arg1_val, arg2_val, bytecount); + + Expression* compound = Expression::make_compound(copy, length, location); + return compound->get_tree(context); } case BUILTIN_APPEND: @@ -8912,67 +8666,40 @@ Builtin_call_expression::do_get_tree(Translate_context* context) Expression* arg1 = args->front(); Expression* arg2 = args->back(); - tree arg1_tree = arg1->get_tree(context); - tree arg2_tree = arg2->get_tree(context); - if (arg1_tree == error_mark_node || arg2_tree == error_mark_node) - return error_mark_node; - Array_type* at = arg1->type()->array_type(); Type* element_type = at->element_type()->forwarded(); - tree arg2_val; - tree arg2_len; - tree element_size; + go_assert(arg2->is_variable()); + Expression* arg2_val; + Expression* arg2_len; + mpz_t size; if (arg2->type()->is_string_type() && element_type->integer_type() != NULL && element_type->integer_type()->is_byte()) { - arg2_tree = save_expr(arg2_tree); - arg2_val = String_type::bytes_tree(gogo, arg2_tree); - arg2_len = String_type::length_tree(gogo, arg2_tree); - element_size = size_int(1); + arg2_val = Expression::make_string_info(arg2, STRING_INFO_DATA, + location); + arg2_len = Expression::make_string_info(arg2, STRING_INFO_LENGTH, + location); + mpz_init_set_ui(size, 1UL); } else { - go_assert(arg2->is_variable()); - arg2_val = - at->get_value_pointer(gogo, arg2)->get_tree(context); - arg2_len = at->get_length(gogo, arg2)->get_tree(context); + arg2_val = at->get_value_pointer(gogo, arg2); + arg2_len = at->get_length(gogo, arg2); Btype* element_btype = element_type->get_backend(gogo); - tree element_type_tree = type_to_tree(element_btype); - if (element_type_tree == error_mark_node) - return error_mark_node; - element_size = TYPE_SIZE_UNIT(element_type_tree); + size_t element_size = gogo->backend()->type_size(element_btype); + mpz_init_set_ui(size, element_size); } - - arg2_val = fold_convert_loc(location.gcc_location(), ptr_type_node, - arg2_val); - arg2_len = fold_convert_loc(location.gcc_location(), size_type_node, - arg2_len); - element_size = fold_convert_loc(location.gcc_location(), size_type_node, - element_size); - - if (arg2_val == error_mark_node - || arg2_len == error_mark_node - || element_size == error_mark_node) - return error_mark_node; - - // We rebuild the decl each time since the slice types may - // change. - tree append_fndecl = NULL_TREE; - return Gogo::call_builtin(&append_fndecl, - location, - "__go_append", - 4, - TREE_TYPE(arg1_tree), - TREE_TYPE(arg1_tree), - arg1_tree, - ptr_type_node, - arg2_val, - size_type_node, - arg2_len, - size_type_node, - element_size); + Expression* element_size = + Expression::make_integer(&size, NULL, location); + mpz_clear(size); + + Expression* append = Runtime::make_call(Runtime::APPEND, location, 4, + arg1, arg2_val, arg2_len, + element_size); + append = Expression::make_unsafe_cast(arg1->type(), append, location); + return append->get_tree(context); } case BUILTIN_REAL: @@ -8981,34 +8708,25 @@ Builtin_call_expression::do_get_tree(Translate_context* context) const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 1); Expression* arg = args->front(); - tree arg_tree = arg->get_tree(context); - if (arg_tree == error_mark_node) - return error_mark_node; - go_assert(COMPLEX_FLOAT_TYPE_P(TREE_TYPE(arg_tree))); - if (this->code_ == BUILTIN_REAL) - return fold_build1_loc(location.gcc_location(), REALPART_EXPR, - TREE_TYPE(TREE_TYPE(arg_tree)), - arg_tree); - else - return fold_build1_loc(location.gcc_location(), IMAGPART_EXPR, - TREE_TYPE(TREE_TYPE(arg_tree)), - arg_tree); + + Bexpression* ret; + Bexpression* bcomplex = tree_to_expr(arg->get_tree(context)); + if (this->code_ == BUILTIN_REAL) + ret = gogo->backend()->real_part_expression(bcomplex, location); + else + ret = gogo->backend()->imag_part_expression(bcomplex, location); + return expr_to_tree(ret); } case BUILTIN_COMPLEX: { const Expression_list* args = this->args(); go_assert(args != NULL && args->size() == 2); - tree r = args->front()->get_tree(context); - tree i = args->back()->get_tree(context); - if (r == error_mark_node || i == error_mark_node) - return error_mark_node; - go_assert(TYPE_MAIN_VARIANT(TREE_TYPE(r)) - == TYPE_MAIN_VARIANT(TREE_TYPE(i))); - go_assert(SCALAR_FLOAT_TYPE_P(TREE_TYPE(r))); - return fold_build2_loc(location.gcc_location(), COMPLEX_EXPR, - build_complex_type(TREE_TYPE(r)), - r, i); + Bexpression* breal = tree_to_expr(args->front()->get_tree(context)); + Bexpression* bimag = tree_to_expr(args->back()->get_tree(context)); + Bexpression* ret = + gogo->backend()->complex_expression(breal, bimag, location); + return expr_to_tree(ret); } default: @@ -9382,6 +9100,37 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function, this->varargs_are_lowered_ = true; } +// Flatten a call with multiple results into a temporary. + +Expression* +Call_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) +{ + size_t rc = this->result_count(); + if (rc > 1 && this->call_temp_ == NULL) + { + Struct_field_list* sfl = new Struct_field_list(); + Function_type* fntype = this->get_function_type(); + const Typed_identifier_list* results = fntype->results(); + Location loc = this->location(); + + int i = 0; + char buf[10]; + for (Typed_identifier_list::const_iterator p = results->begin(); + p != results->end(); + ++p, ++i) + { + snprintf(buf, sizeof buf, "res%d", i); + sfl->push_back(Struct_field(Typed_identifier(buf, p->type(), loc))); + } + + Struct_type* st = Type::make_struct_type(sfl, loc); + this->call_temp_ = Statement::make_temporary(st, NULL, loc); + inserter->insert(this->call_temp_); + } + + return this; +} + // Get the function type. This can return NULL in error cases. Function_type* @@ -9703,8 +9452,8 @@ Call_expression::interface_method_function( tree Call_expression::do_get_tree(Translate_context* context) { - if (this->tree_ != NULL_TREE) - return this->tree_; + if (this->call_ != NULL) + return expr_to_tree(this->call_); Function_type* fntype = this->get_function_type(); if (fntype == NULL) @@ -9733,11 +9482,12 @@ Call_expression::do_get_tree(Translate_context* context) has_closure_arg = true; int nargs; - tree* args; + std::vector<Bexpression*> fn_args; if (this->args_ == NULL || this->args_->empty()) { nargs = is_interface_method ? 1 : 0; - args = nargs == 0 ? NULL : new tree[nargs]; + if (nargs > 0) + fn_args.resize(1); } else if (fntype->parameters() == NULL || fntype->parameters()->empty()) { @@ -9746,8 +9496,8 @@ Call_expression::do_get_tree(Translate_context* context) && fntype->is_method() && this->args_->size() == 1); nargs = 1; - args = new tree[nargs]; - args[0] = this->args_->front()->get_tree(context); + fn_args.resize(1); + fn_args[0] = tree_to_expr(this->args_->front()->get_tree(context)); } else { @@ -9756,239 +9506,138 @@ Call_expression::do_get_tree(Translate_context* context) nargs = this->args_->size(); int i = is_interface_method ? 1 : 0; nargs += i; - args = new tree[nargs]; + fn_args.resize(nargs); Typed_identifier_list::const_iterator pp = params->begin(); Expression_list::const_iterator pe = this->args_->begin(); if (!is_interface_method && fntype->is_method()) { - args[i] = (*pe)->get_tree(context); + fn_args[i] = tree_to_expr((*pe)->get_tree(context)); ++pe; ++i; } for (; pe != this->args_->end(); ++pe, ++pp, ++i) { go_assert(pp != params->end()); - tree arg_val = (*pe)->get_tree(context); - args[i] = Expression::convert_for_assignment(context, - pp->type(), - (*pe)->type(), - arg_val, - location); - if (args[i] == error_mark_node) - return error_mark_node; + Expression* arg = + Expression::convert_for_assignment(gogo, pp->type(), *pe, + location); + fn_args[i] = tree_to_expr(arg->get_tree(context)); } go_assert(pp == params->end()); go_assert(i == nargs); } - tree fntype_tree = type_to_tree(fntype->get_backend(gogo)); - tree fnfield_type = type_to_tree(fntype->get_backend_fntype(gogo)); - if (fntype_tree == error_mark_node || fnfield_type == error_mark_node) - return error_mark_node; - go_assert(FUNCTION_POINTER_TYPE_P(fnfield_type)); - tree rettype = TREE_TYPE(TREE_TYPE(fnfield_type)); - if (rettype == error_mark_node) - return error_mark_node; - - tree fn; - tree closure_tree; + Expression* fn; + Expression* closure = NULL; if (func != NULL) { Named_object* no = func->named_object(); - fn = expr_to_tree(Func_expression::get_code_pointer(gogo, no, location)); - if (!has_closure) - closure_tree = NULL_TREE; - else - { - closure_tree = func->closure()->get_tree(context); - if (closure_tree == error_mark_node) - return error_mark_node; - } + fn = Expression::make_func_code_reference(no, location); + if (has_closure) + closure = func->closure(); } else if (!is_interface_method) { - closure_tree = this->fn_->get_tree(context); - if (closure_tree == error_mark_node) - return error_mark_node; - tree fnc = fold_convert_loc(location.gcc_location(), fntype_tree, - closure_tree); - go_assert(POINTER_TYPE_P(TREE_TYPE(fnc)) - && (TREE_CODE(TREE_TYPE(TREE_TYPE(fnc))) - == RECORD_TYPE)); - tree field = TYPE_FIELDS(TREE_TYPE(TREE_TYPE(fnc))); - fn = fold_build3_loc(location.gcc_location(), COMPONENT_REF, - TREE_TYPE(field), - build_fold_indirect_ref_loc(location.gcc_location(), - fnc), - field, NULL_TREE); - } + closure = this->fn_; + + // The backend representation of this function type is a pointer + // to a struct whose first field is the actual function to call. + Type* pfntype = + Type::make_pointer_type( + Type::make_pointer_type(Type::make_void_type())); + fn = Expression::make_unsafe_cast(pfntype, this->fn_, location); + fn = Expression::make_unary(OPERATOR_MULT, fn, location); + } else { Expression* first_arg; - Expression* fn_expr = - this->interface_method_function(interface_method, &first_arg); - args[0] = first_arg->get_tree(context); - fn = fn_expr->get_tree(context); - - if (fn == error_mark_node) - return error_mark_node; - closure_tree = NULL_TREE; - } - - if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node) - return error_mark_node; - - tree fndecl = fn; - if (TREE_CODE(fndecl) == ADDR_EXPR) - fndecl = TREE_OPERAND(fndecl, 0); - - // Add a type cast in case the type of the function is a recursive - // type which refers to itself. We don't do this for an interface - // method because 1) an interface method never refers to itself, so - // we always have a function type here; 2) we pass an extra first - // argument to an interface method, so fnfield_type is not correct. - if ((!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl)) && !is_interface_method) - fn = fold_convert_loc(location.gcc_location(), fnfield_type, fn); - - // This is to support builtin math functions when using 80387 math. - tree excess_type = NULL_TREE; - if (optimize - && TREE_CODE(fndecl) == FUNCTION_DECL - && DECL_IS_BUILTIN(fndecl) - && DECL_BUILT_IN_CLASS(fndecl) == BUILT_IN_NORMAL - && nargs > 0 - && ((SCALAR_FLOAT_TYPE_P(rettype) - && SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[0]))) - || (COMPLEX_FLOAT_TYPE_P(rettype) - && COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[0]))))) - { - excess_type = excess_precision_type(TREE_TYPE(args[0])); - if (excess_type != NULL_TREE) - { - tree excess_fndecl = mathfn_built_in(excess_type, - DECL_FUNCTION_CODE(fndecl)); - if (excess_fndecl == NULL_TREE) - excess_type = NULL_TREE; - else - { - fn = build_fold_addr_expr_loc(location.gcc_location(), - excess_fndecl); - for (int i = 0; i < nargs; ++i) - { - if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i])) - || COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i]))) - args[i] = ::convert(excess_type, args[i]); - } - } - } + fn = this->interface_method_function(interface_method, &first_arg); + fn_args[0] = tree_to_expr(first_arg->get_tree(context)); } - if (func == NULL) - fn = save_expr(fn); - if (!has_closure_arg) - go_assert(closure_tree == NULL_TREE); + go_assert(closure == NULL); else { // Pass the closure argument by calling the function function // __go_set_closure. In the order_evaluations pass we have // ensured that if any parameters contain call expressions, they // will have been moved out to temporary variables. - - go_assert(closure_tree != NULL_TREE); - closure_tree = fold_convert_loc(location.gcc_location(), ptr_type_node, - closure_tree); - static tree set_closure_fndecl; - tree set_closure = Gogo::call_builtin(&set_closure_fndecl, - location, - "__go_set_closure", - 1, - void_type_node, - ptr_type_node, - closure_tree); - if (set_closure == error_mark_node) - return error_mark_node; - fn = build2_loc(location.gcc_location(), COMPOUND_EXPR, - TREE_TYPE(fn), set_closure, fn); + go_assert(closure != NULL); + Expression* set_closure = + Runtime::make_call(Runtime::SET_CLOSURE, location, 1, closure); + fn = Expression::make_compound(set_closure, fn, location); } - tree ret = build_call_array(excess_type != NULL_TREE ? excess_type : rettype, - fn, nargs, args); - delete[] args; - - SET_EXPR_LOCATION(ret, location.gcc_location()); + Btype* bft = fntype->get_backend_fntype(gogo); + Bexpression* bfn = tree_to_expr(fn->get_tree(context)); + bfn = gogo->backend()->convert_expression(bft, bfn, location); + Bexpression* call = gogo->backend()->call_expression(bfn, fn_args, location); - // If this is a recursive function type which returns itself, as in - // type F func() F - // we have used ptr_type_node for the return type. Add a cast here - // to the correct type. - if (TREE_TYPE(ret) == ptr_type_node) + if (this->results_ != NULL) { - tree t = type_to_tree(this->type()->base()->get_backend(gogo)); - ret = fold_convert_loc(location.gcc_location(), t, ret); - } + go_assert(this->call_temp_ != NULL); + Expression* call_ref = + Expression::make_temporary_reference(this->call_temp_, location); + Bexpression* bcall_ref = tree_to_expr(call_ref->get_tree(context)); + Bstatement* assn_stmt = + gogo->backend()->assignment_statement(bcall_ref, call, location); - if (excess_type != NULL_TREE) - { - // Calling convert here can undo our excess precision change. - // That may or may not be a bug in convert_to_real. - ret = build1(NOP_EXPR, rettype, ret); - } + this->call_ = this->set_results(context, bcall_ref); - if (this->results_ != NULL) - ret = this->set_results(context, ret); - - this->tree_ = ret; + Bexpression* set_and_call = + gogo->backend()->compound_expression(assn_stmt, this->call_, + location); + return expr_to_tree(set_and_call); + } - return ret; + this->call_ = call; + return expr_to_tree(this->call_); } // Set the result variables if this call returns multiple results. -tree -Call_expression::set_results(Translate_context* context, tree call_tree) +Bexpression* +Call_expression::set_results(Translate_context* context, Bexpression* call) { - tree stmt_list = NULL_TREE; - - call_tree = save_expr(call_tree); - - if (TREE_CODE(TREE_TYPE(call_tree)) != RECORD_TYPE) - { - go_assert(saw_errors()); - return call_tree; - } + Gogo* gogo = context->gogo(); + Bexpression* results = NULL; Location loc = this->location(); - tree field = TYPE_FIELDS(TREE_TYPE(call_tree)); + size_t rc = this->result_count(); - for (size_t i = 0; i < rc; ++i, field = DECL_CHAIN(field)) + for (size_t i = 0; i < rc; ++i) { - go_assert(field != NULL_TREE); - Temporary_statement* temp = this->result(i); if (temp == NULL) { go_assert(saw_errors()); - return error_mark_node; + return gogo->backend()->error_expression(); } Temporary_reference_expression* ref = Expression::make_temporary_reference(temp, loc); ref->set_is_lvalue(); - tree temp_tree = ref->get_tree(context); - if (temp_tree == error_mark_node) - return error_mark_node; - tree val_tree = build3_loc(loc.gcc_location(), COMPONENT_REF, - TREE_TYPE(field), call_tree, field, NULL_TREE); - tree set_tree = build2_loc(loc.gcc_location(), MODIFY_EXPR, - void_type_node, temp_tree, val_tree); + Bexpression* result_ref = tree_to_expr(ref->get_tree(context)); + Bexpression* call_result = + gogo->backend()->struct_field_expression(call, i, loc); + Bstatement* assn_stmt = + gogo->backend()->assignment_statement(result_ref, call_result, loc); - append_to_statement_list(set_tree, &stmt_list); - } - go_assert(field == NULL_TREE); + Bexpression* result = + gogo->backend()->compound_expression(assn_stmt, call_result, loc); - return save_expr(stmt_list); + if (results == NULL) + results = result; + else + { + Bstatement* expr_stmt = gogo->backend()->expression_statement(result); + results = + gogo->backend()->compound_expression(expr_stmt, results, loc); + } + } + return results; } // Dump ast representation for a call expressin. @@ -10333,6 +9982,9 @@ class Array_index_expression : public Expression int do_traverse(Traverse*); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + Type* do_type(); @@ -10343,9 +9995,6 @@ class Array_index_expression : public Expression do_check_types(Gogo*); Expression* - do_flatten(Gogo*, Named_object*, Statement_inserter*); - - Expression* do_copy() { return Expression::make_array_index(this->array_->copy(), @@ -10586,19 +10235,41 @@ Array_index_expression::do_check_types(Gogo*) } } -// Flatten array indexing by using a temporary variable for slices. +// Flatten array indexing by using temporary variables for slices and indexes. Expression* Array_index_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) { Location loc = this->location(); + Temporary_statement* temp; if (this->array_->type()->is_slice_type() && !this->array_->is_variable()) { - Temporary_statement* temp = Statement::make_temporary(NULL, this->array_, loc); + temp = Statement::make_temporary(NULL, this->array_, loc); inserter->insert(temp); this->array_ = Expression::make_temporary_reference(temp, loc); } + if (!this->start_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->start_, loc); + inserter->insert(temp); + this->start_ = Expression::make_temporary_reference(temp, loc); + } + if (this->end_ != NULL + && !this->end_->is_nil_expression() + && !this->end_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->end_, loc); + inserter->insert(temp); + this->end_ = Expression::make_temporary_reference(temp, loc); + } + if (this->cap_ != NULL && !this->cap_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->cap_, loc); + inserter->insert(temp); + this->cap_ = Expression::make_temporary_reference(temp, loc); + } + return this; } @@ -10625,9 +10296,6 @@ Array_index_expression::do_is_addressable() const tree Array_index_expression::do_get_tree(Translate_context* context) { - Gogo* gogo = context->gogo(); - Location loc = this->location(); - Array_type* array_type = this->array_->type()->array_type(); if (array_type == NULL) { @@ -10636,66 +10304,40 @@ Array_index_expression::do_get_tree(Translate_context* context) } go_assert(!array_type->is_slice_type() || this->array_->is_variable()); - tree type_tree = type_to_tree(array_type->get_backend(gogo)); - if (type_tree == error_mark_node) - return error_mark_node; + Location loc = this->location(); + Gogo* gogo = context->gogo(); + + Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo); - tree length_tree = NULL_TREE; + // We need to convert the length and capacity to the Go "int" type here + // because the length of a fixed-length array could be of type "uintptr" + // and gimple disallows binary operations between "uintptr" and other + // integer types. FIXME. + Bexpression* length = NULL; if (this->end_ == NULL || this->end_->is_nil_expression()) { Expression* len = array_type->get_length(gogo, this->array_); - length_tree = len->get_tree(context); - if (length_tree == error_mark_node) - return error_mark_node; - length_tree = save_expr(length_tree); + length = tree_to_expr(len->get_tree(context)); + length = gogo->backend()->convert_expression(int_btype, length, loc); } - tree capacity_tree = NULL_TREE; + Bexpression* capacity = NULL; if (this->end_ != NULL) { Expression* cap = array_type->get_capacity(gogo, this->array_); - capacity_tree = cap->get_tree(context); - if (capacity_tree == error_mark_node) - return error_mark_node; - capacity_tree = save_expr(capacity_tree); + capacity = tree_to_expr(cap->get_tree(context)); + capacity = gogo->backend()->convert_expression(int_btype, capacity, loc); } - tree cap_arg = capacity_tree; + Bexpression* cap_arg = capacity; if (this->cap_ != NULL) { - cap_arg = this->cap_->get_tree(context); - if (cap_arg == error_mark_node) - return error_mark_node; + cap_arg = tree_to_expr(this->cap_->get_tree(context)); + cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc); } - tree length_type = (length_tree != NULL_TREE - ? TREE_TYPE(length_tree) - : TREE_TYPE(cap_arg)); - - tree bad_index = boolean_false_node; - - tree start_tree = this->start_->get_tree(context); - if (start_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(start_tree)) - start_tree = save_expr(start_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(start_tree))) - start_tree = convert_to_integer(length_type, start_tree); - - bad_index = Expression::check_bounds(start_tree, length_type, bad_index, - loc); - - start_tree = fold_convert_loc(loc.gcc_location(), length_type, start_tree); - bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, bad_index, - fold_build2_loc(loc.gcc_location(), - (this->end_ == NULL - ? GE_EXPR - : GT_EXPR), - boolean_type_node, start_tree, - (this->end_ == NULL - ? length_tree - : capacity_tree))); + if (length == NULL) + length = cap_arg; int code = (array_type->length() != NULL ? (this->end_ == NULL @@ -10704,168 +10346,124 @@ Array_index_expression::do_get_tree(Translate_context* context) : (this->end_ == NULL ? RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS : RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS)); - tree crash = gogo->runtime_error(code, loc)->get_tree(context); + Bexpression* crash = + tree_to_expr(gogo->runtime_error(code, loc)->get_tree(context)); + + Expression* bounds_check = Expression::check_bounds(this->start_, loc); + Bexpression* bad_index = tree_to_expr(bounds_check->get_tree(context)); + + Bexpression* start = tree_to_expr(this->start_->get_tree(context)); + start = gogo->backend()->convert_expression(int_btype, start, loc); + Bexpression* start_too_large = + gogo->backend()->binary_expression((this->end_ == NULL + ? OPERATOR_GE + : OPERATOR_GT), + start, + (this->end_ == NULL + ? length + : capacity), + loc); + bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, start_too_large, + bad_index, loc); if (this->end_ == NULL) { // Simple array indexing. This has to return an l-value, so - // wrap the index check into START_TREE. - start_tree = build2(COMPOUND_EXPR, TREE_TYPE(start_tree), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - start_tree); - start_tree = fold_convert_loc(loc.gcc_location(), sizetype, start_tree); + // wrap the index check into START. + start = + gogo->backend()->conditional_expression(int_btype, bad_index, + crash, start, loc); + Bexpression* ret; if (array_type->length() != NULL) { - // Fixed array. - tree array_tree = this->array_->get_tree(context); - if (array_tree == error_mark_node) - return error_mark_node; - return build4(ARRAY_REF, TREE_TYPE(type_tree), array_tree, - start_tree, NULL_TREE, NULL_TREE); + Bexpression* array = tree_to_expr(this->array_->get_tree(context)); + ret = gogo->backend()->array_index_expression(array, start, loc); } else { - // Open array. - Expression* valptr = + // Slice. + Expression* valptr = array_type->get_value_pointer(gogo, this->array_); - tree values = valptr->get_tree(context); - Type* element_type = array_type->element_type(); - Btype* belement_type = element_type->get_backend(gogo); - tree element_type_tree = type_to_tree(belement_type); - if (element_type_tree == error_mark_node) - return error_mark_node; - tree element_size = TYPE_SIZE_UNIT(element_type_tree); - tree offset = fold_build2_loc(loc.gcc_location(), MULT_EXPR, sizetype, - start_tree, element_size); - tree ptr = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR, - TREE_TYPE(values), values, offset); - return build_fold_indirect_ref(ptr); + Bexpression* ptr = tree_to_expr(valptr->get_tree(context)); + ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc); + ret = gogo->backend()->indirect_expression(ptr, true, loc); } + return expr_to_tree(ret); } // Array slice. if (this->cap_ != NULL) { - if (!DECL_P(cap_arg)) - cap_arg = save_expr(cap_arg); - if (!INTEGRAL_TYPE_P(TREE_TYPE(cap_arg))) - cap_arg = convert_to_integer(length_type, cap_arg); - - bad_index = Expression::check_bounds(cap_arg, length_type, bad_index, - loc); - cap_arg = fold_convert_loc(loc.gcc_location(), length_type, cap_arg); - - tree bad_cap = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, - fold_build2_loc(loc.gcc_location(), - LT_EXPR, boolean_type_node, - cap_arg, start_tree), - fold_build2_loc(loc.gcc_location(), - GT_EXPR, boolean_type_node, - cap_arg, capacity_tree)); - bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, bad_index, bad_cap); - } - - tree end_tree; + bounds_check = Expression::check_bounds(this->cap_, loc); + Bexpression* bounds_bcheck = + tree_to_expr(bounds_check->get_tree(context)); + bad_index = + gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck, + bad_index, loc); + cap_arg = gogo->backend()->convert_expression(int_btype, cap_arg, loc); + + Bexpression* cap_too_small = + gogo->backend()->binary_expression(OPERATOR_LT, cap_arg, start, loc); + Bexpression* cap_too_large = + gogo->backend()->binary_expression(OPERATOR_GT, cap_arg, capacity, loc); + Bexpression* bad_cap = + gogo->backend()->binary_expression(OPERATOR_OROR, cap_too_small, + cap_too_large, loc); + bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_cap, + bad_index, loc); + } + + Bexpression* end; if (this->end_->is_nil_expression()) - end_tree = length_tree; + end = length; else { - end_tree = this->end_->get_tree(context); - if (end_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(end_tree)) - end_tree = save_expr(end_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(end_tree))) - end_tree = convert_to_integer(length_type, end_tree); - - bad_index = Expression::check_bounds(end_tree, length_type, bad_index, - loc); + bounds_check = Expression::check_bounds(this->end_, loc); + Bexpression* bounds_bcheck = + tree_to_expr(bounds_check->get_tree(context)); - end_tree = fold_convert_loc(loc.gcc_location(), length_type, end_tree); + bad_index = + gogo->backend()->binary_expression(OPERATOR_OROR, bounds_bcheck, + bad_index, loc); - tree bad_end = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, - fold_build2_loc(loc.gcc_location(), - LT_EXPR, boolean_type_node, - end_tree, start_tree), - fold_build2_loc(loc.gcc_location(), - GT_EXPR, boolean_type_node, - end_tree, cap_arg)); - bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, bad_index, bad_end); + end = tree_to_expr(this->end_->get_tree(context)); + end = gogo->backend()->convert_expression(int_btype, end, loc); + Bexpression* end_too_small = + gogo->backend()->binary_expression(OPERATOR_LT, end, start, loc); + Bexpression* end_too_large = + gogo->backend()->binary_expression(OPERATOR_GT, end, cap_arg, loc); + Bexpression* bad_end = + gogo->backend()->binary_expression(OPERATOR_OROR, end_too_small, + end_too_large, loc); + bad_index = gogo->backend()->binary_expression(OPERATOR_OROR, bad_end, + bad_index, loc); } - - Type* element_type = array_type->element_type(); - tree element_type_tree = type_to_tree(element_type->get_backend(gogo)); - if (element_type_tree == error_mark_node) - return error_mark_node; - tree element_size = TYPE_SIZE_UNIT(element_type_tree); - - tree offset = fold_build2_loc(loc.gcc_location(), MULT_EXPR, sizetype, - fold_convert_loc(loc.gcc_location(), sizetype, - start_tree), - element_size); - Expression* valptr = array_type->get_value_pointer(gogo, this->array_); - tree value_pointer = valptr->get_tree(context); - if (value_pointer == error_mark_node) - return error_mark_node; + Bexpression* val = tree_to_expr(valptr->get_tree(context)); + val = gogo->backend()->pointer_offset_expression(val, start, loc); - value_pointer = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR, - TREE_TYPE(value_pointer), - value_pointer, offset); + Bexpression* result_length = + gogo->backend()->binary_expression(OPERATOR_MINUS, end, start, loc); - tree result_length_tree = fold_build2_loc(loc.gcc_location(), MINUS_EXPR, - length_type, end_tree, start_tree); + Bexpression* result_capacity = + gogo->backend()->binary_expression(OPERATOR_MINUS, cap_arg, start, loc); - tree result_capacity_tree = fold_build2_loc(loc.gcc_location(), MINUS_EXPR, - length_type, cap_arg, start_tree); - - tree struct_tree = type_to_tree(this->type()->get_backend(gogo)); - go_assert(TREE_CODE(struct_tree) == RECORD_TYPE); - - vec<constructor_elt, va_gc> *init; - vec_alloc (init, 3); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = init->quick_push(empty); - tree field = TYPE_FIELDS(struct_tree); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__values") == 0); - elt->index = field; - elt->value = value_pointer; + Btype* struct_btype = this->type()->get_backend(gogo); + std::vector<Bexpression*> init; + init.push_back(val); + init.push_back(result_length); + init.push_back(result_capacity); - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__count") == 0); - elt->index = field; - elt->value = fold_convert_loc(loc.gcc_location(), TREE_TYPE(field), - result_length_tree); - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__capacity") == 0); - elt->index = field; - elt->value = fold_convert_loc(loc.gcc_location(), TREE_TYPE(field), - result_capacity_tree); - - tree constructor = build_constructor(struct_tree, init); - - if (TREE_CONSTANT(value_pointer) - && TREE_CONSTANT(result_length_tree) - && TREE_CONSTANT(result_capacity_tree)) - TREE_CONSTANT(constructor) = 1; + Bexpression* ctor = + gogo->backend()->constructor_expression(struct_btype, init, loc); + Bexpression* ret = + gogo->backend()->conditional_expression(struct_btype, bad_index, + crash, ctor, loc); - return fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR, - TREE_TYPE(constructor), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - constructor); + return expr_to_tree(ret); } // Dump ast representation for an array index expression. @@ -10903,6 +10501,9 @@ class String_index_expression : public Expression int do_traverse(Traverse*); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + Type* do_type(); @@ -10963,6 +10564,36 @@ String_index_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +Expression* +String_index_expression::do_flatten(Gogo*, Named_object*, + Statement_inserter* inserter) +{ + Temporary_statement* temp; + Location loc = this->location(); + if (!this->string_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->string_, loc); + inserter->insert(temp); + this->string_ = Expression::make_temporary_reference(temp, loc); + } + if (!this->start_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->start_, loc); + inserter->insert(temp); + this->start_ = Expression::make_temporary_reference(temp, loc); + } + if (this->end_ != NULL + && !this->end_->is_nil_expression() + && !this->end_->is_variable()) + { + temp = Statement::make_temporary(NULL, this->end_, loc); + inserter->insert(temp); + this->end_ = Expression::make_temporary_reference(temp, loc); + } + + return this; +} + // Return the type of a string index. Type* @@ -11049,112 +10680,87 @@ tree String_index_expression::do_get_tree(Translate_context* context) { Location loc = this->location(); + Expression* string_arg = this->string_; + if (this->string_->type()->points_to() != NULL) + string_arg = Expression::make_unary(OPERATOR_MULT, this->string_, loc); - tree string_tree = this->string_->get_tree(context); - if (string_tree == error_mark_node) - return error_mark_node; + Expression* bad_index = Expression::check_bounds(this->start_, loc); - if (this->string_->type()->points_to() != NULL) - string_tree = build_fold_indirect_ref(string_tree); - if (!DECL_P(string_tree)) - string_tree = save_expr(string_tree); - tree string_type = TREE_TYPE(string_tree); + int code = (this->end_ == NULL + ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS + : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS); - tree length_tree = String_type::length_tree(context->gogo(), string_tree); - length_tree = save_expr(length_tree); + Gogo* gogo = context->gogo(); + Bexpression* crash = + tree_to_expr(gogo->runtime_error(code, loc)->get_tree(context)); Type* int_type = Type::lookup_integer_type("int"); - tree length_type = type_to_tree(int_type->get_backend(context->gogo())); - tree bad_index = boolean_false_node; + // It is possible that an error occurred earlier because the start index + // cannot be represented as an integer type. In this case, we shouldn't + // try casting the starting index into an integer since + // Type_conversion_expression will fail to get the backend representation. + // FIXME. + if (this->start_->type()->integer_type() == NULL + && !Type::are_convertible(int_type, this->start_->type(), NULL)) + { + go_assert(saw_errors()); + return error_mark_node; + } - tree start_tree = this->start_->get_tree(context); - if (start_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(start_tree)) - start_tree = save_expr(start_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(start_tree))) - start_tree = convert_to_integer(length_type, start_tree); + Expression* start = Expression::make_cast(int_type, this->start_, loc); - bad_index = Expression::check_bounds(start_tree, length_type, bad_index, - loc); + if (this->end_ == NULL) + { + Expression* length = + Expression::make_string_info(this->string_, STRING_INFO_LENGTH, loc); - start_tree = fold_convert_loc(loc.gcc_location(), length_type, start_tree); + Expression* start_too_large = + Expression::make_binary(OPERATOR_GE, start, length, loc); + bad_index = Expression::make_binary(OPERATOR_OROR, start_too_large, + bad_index, loc); + Expression* bytes = + Expression::make_string_info(this->string_, STRING_INFO_DATA, loc); - int code = (this->end_ == NULL - ? RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS - : RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS); - tree crash = context->gogo()->runtime_error(code, loc)->get_tree(context); + Bexpression* bstart = tree_to_expr(start->get_tree(context)); + Bexpression* ptr = tree_to_expr(bytes->get_tree(context)); + ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc); + Bexpression* index = gogo->backend()->indirect_expression(ptr, true, loc); - if (this->end_ == NULL) + Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo); + Bexpression* index_error = tree_to_expr(bad_index->get_tree(context)); + Bexpression* ret = + gogo->backend()->conditional_expression(byte_btype, index_error, + crash, index, loc); + return expr_to_tree(ret); + } + + Expression* end = NULL; + if (this->end_->is_nil_expression()) { - bad_index = fold_build2_loc(loc.gcc_location(), TRUTH_OR_EXPR, - boolean_type_node, bad_index, - fold_build2_loc(loc.gcc_location(), GE_EXPR, - boolean_type_node, - start_tree, length_tree)); - - tree bytes_tree = String_type::bytes_tree(context->gogo(), string_tree); - tree ptr = fold_build2_loc(loc.gcc_location(), POINTER_PLUS_EXPR, - TREE_TYPE(bytes_tree), - bytes_tree, - fold_convert_loc(loc.gcc_location(), sizetype, - start_tree)); - tree index = build_fold_indirect_ref_loc(loc.gcc_location(), ptr); - - return build2(COMPOUND_EXPR, TREE_TYPE(index), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - index); + mpz_t neg_one; + mpz_init_set_si(neg_one, -1); + end = Expression::make_integer(&neg_one, int_type, loc); + mpz_clear(neg_one); } else { - tree end_tree; - if (this->end_->is_nil_expression()) - end_tree = build_int_cst(length_type, -1); - else - { - end_tree = this->end_->get_tree(context); - if (end_tree == error_mark_node) - return error_mark_node; - if (!DECL_P(end_tree)) - end_tree = save_expr(end_tree); - if (!INTEGRAL_TYPE_P(TREE_TYPE(end_tree))) - end_tree = convert_to_integer(length_type, end_tree); - - bad_index = Expression::check_bounds(end_tree, length_type, - bad_index, loc); - - end_tree = fold_convert_loc(loc.gcc_location(), length_type, - end_tree); - } - - static tree strslice_fndecl; - tree ret = Gogo::call_builtin(&strslice_fndecl, - loc, - "__go_string_slice", - 3, - string_type, - string_type, - string_tree, - length_type, - start_tree, - length_type, - end_tree); - if (ret == error_mark_node) - return error_mark_node; - // This will panic if the bounds are out of range for the - // string. - TREE_NOTHROW(strslice_fndecl) = 0; - - if (bad_index == boolean_false_node) - return ret; - else - return build2(COMPOUND_EXPR, TREE_TYPE(ret), - build3(COND_EXPR, void_type_node, - bad_index, crash, NULL_TREE), - ret); + Expression* bounds_check = Expression::check_bounds(this->end_, loc); + bad_index = + Expression::make_binary(OPERATOR_OROR, bounds_check, bad_index, loc); + end = Expression::make_cast(int_type, this->end_, loc); } + + Expression* strslice = Runtime::make_call(Runtime::STRING_SLICE, loc, 3, + string_arg, start, end); + Bexpression* bstrslice = tree_to_expr(strslice->get_tree(context)); + + Btype* str_btype = strslice->type()->get_backend(gogo); + Bexpression* index_error = tree_to_expr(bad_index->get_tree(context)); + Bexpression* ret = + gogo->backend()->conditional_expression(str_btype, index_error, + crash, bstrslice, loc); + return expr_to_tree(ret); } // Dump ast representation for a string index expression. @@ -11199,6 +10805,44 @@ Map_index_expression::do_traverse(Traverse* traverse) return Expression::traverse(&this->index_, traverse); } +// We need to pass in a pointer to the key, so flatten the index into a +// temporary variable if it isn't already. The value pointer will be +// dereferenced and checked for nil, so flatten into a temporary to avoid +// recomputation. + +Expression* +Map_index_expression::do_flatten(Gogo*, Named_object*, + Statement_inserter* inserter) +{ + Map_type* mt = this->get_map_type(); + if (this->index_->type() != mt->key_type()) + this->index_ = Expression::make_cast(mt->key_type(), this->index_, + this->location()); + + if (!this->index_->is_variable()) + { + Temporary_statement* temp = Statement::make_temporary(NULL, this->index_, + this->location()); + inserter->insert(temp); + this->index_ = Expression::make_temporary_reference(temp, + this->location()); + } + + if (this->value_pointer_ == NULL) + this->get_value_pointer(this->is_lvalue_); + if (!this->value_pointer_->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, this->value_pointer_, + this->location()); + inserter->insert(temp); + this->value_pointer_ = + Expression::make_temporary_reference(temp, this->location()); + } + + return this; +} + // Return the type of a map index. Type* @@ -11258,131 +10902,84 @@ Map_index_expression::do_get_tree(Translate_context* context) { Map_type* type = this->get_map_type(); if (type == NULL) - return error_mark_node; - - tree valptr = this->get_value_pointer(context, this->is_lvalue_); - if (valptr == error_mark_node) - return error_mark_node; - valptr = save_expr(valptr); + { + go_assert(saw_errors()); + return error_mark_node; + } - tree val_type_tree = TREE_TYPE(TREE_TYPE(valptr)); + go_assert(this->value_pointer_ != NULL + && this->value_pointer_->is_variable()); + Bexpression* ret; if (this->is_lvalue_) - return build_fold_indirect_ref(valptr); + { + Expression* val = + Expression::make_unary(OPERATOR_MULT, this->value_pointer_, + this->location()); + ret = tree_to_expr(val->get_tree(context)); + } else if (this->is_in_tuple_assignment_) { // Tuple_map_assignment_statement is responsible for using this // appropriately. - return valptr; + ret = tree_to_expr(this->value_pointer_->get_tree(context)); } else { + Location loc = this->location(); + + Expression* nil_check = + Expression::make_binary(OPERATOR_EQEQ, this->value_pointer_, + Expression::make_nil(loc), loc); + Bexpression* bnil_check = tree_to_expr(nil_check->get_tree(context)); + Expression* val = + Expression::make_unary(OPERATOR_MULT, this->value_pointer_, loc); + Bexpression* bval = tree_to_expr(val->get_tree(context)); + Gogo* gogo = context->gogo(); Btype* val_btype = type->val_type()->get_backend(gogo); Bexpression* val_zero = gogo->backend()->zero_expression(val_btype); - return fold_build3(COND_EXPR, val_type_tree, - fold_build2(EQ_EXPR, boolean_type_node, valptr, - fold_convert(TREE_TYPE(valptr), - null_pointer_node)), - expr_to_tree(val_zero), - build_fold_indirect_ref(valptr)); + ret = gogo->backend()->conditional_expression(val_btype, bnil_check, + val_zero, bval, loc); } + + return expr_to_tree(ret); } -// Get a tree for the map index. This returns a tree which evaluates -// to a pointer to a value. The pointer will be NULL if the key is +// Get an expression for the map index. This returns an expression which +// evaluates to a pointer to a value. The pointer will be NULL if the key is // not in the map. -tree -Map_index_expression::get_value_pointer(Translate_context* context, - bool insert) +Expression* +Map_index_expression::get_value_pointer(bool insert) { - Map_type* type = this->get_map_type(); - if (type == NULL) - return error_mark_node; - - tree map_tree = this->map_->get_tree(context); - tree index_tree = this->index_->get_tree(context); - index_tree = Expression::convert_for_assignment(context, type->key_type(), - this->index_->type(), - index_tree, - this->location()); - if (map_tree == error_mark_node || index_tree == error_mark_node) - return error_mark_node; - - if (this->map_->type()->points_to() != NULL) - map_tree = build_fold_indirect_ref(map_tree); - - // We need to pass in a pointer to the key, so stuff it into a - // variable. - tree tmp; - tree make_tmp; - if (current_function_decl != NULL) - { - tmp = create_tmp_var(TREE_TYPE(index_tree), get_name(index_tree)); - DECL_IGNORED_P(tmp) = 0; - DECL_INITIAL(tmp) = index_tree; - make_tmp = build1(DECL_EXPR, void_type_node, tmp); - TREE_ADDRESSABLE(tmp) = 1; - } - else + if (this->value_pointer_ == NULL) { - tmp = build_decl(this->location().gcc_location(), VAR_DECL, - create_tmp_var_name("M"), - TREE_TYPE(index_tree)); - DECL_EXTERNAL(tmp) = 0; - TREE_PUBLIC(tmp) = 0; - TREE_STATIC(tmp) = 1; - DECL_ARTIFICIAL(tmp) = 1; - if (!TREE_CONSTANT(index_tree)) - make_tmp = fold_build2_loc(this->location().gcc_location(), - INIT_EXPR, void_type_node, - tmp, index_tree); - else + Map_type* type = this->get_map_type(); + if (type == NULL) { - TREE_READONLY(tmp) = 1; - TREE_CONSTANT(tmp) = 1; - DECL_INITIAL(tmp) = index_tree; - make_tmp = NULL_TREE; + go_assert(saw_errors()); + return Expression::make_error(this->location()); } - rest_of_decl_compilation(tmp, 1, 0); - } - tree tmpref = - fold_convert_loc(this->location().gcc_location(), const_ptr_type_node, - build_fold_addr_expr_loc(this->location().gcc_location(), - tmp)); - - static tree map_index_fndecl; - tree call = Gogo::call_builtin(&map_index_fndecl, - this->location(), - "__go_map_index", - 3, - const_ptr_type_node, - TREE_TYPE(map_tree), - map_tree, - const_ptr_type_node, - tmpref, - boolean_type_node, - (insert - ? boolean_true_node - : boolean_false_node)); - if (call == error_mark_node) - return error_mark_node; - // This can panic on a map of interface type if the interface holds - // an uncomparable or unhashable type. - TREE_NOTHROW(map_index_fndecl) = 0; - Type* val_type = type->val_type(); - tree val_type_tree = type_to_tree(val_type->get_backend(context->gogo())); - if (val_type_tree == error_mark_node) - return error_mark_node; - tree ptr_val_type_tree = build_pointer_type(val_type_tree); + Location loc = this->location(); + Expression* map_ref = this->map_; + if (this->map_->type()->points_to() != NULL) + map_ref = Expression::make_unary(OPERATOR_MULT, map_ref, loc); - tree ret = fold_convert_loc(this->location().gcc_location(), - ptr_val_type_tree, call); - if (make_tmp != NULL_TREE) - ret = build2(COMPOUND_EXPR, ptr_val_type_tree, make_tmp, ret); - return ret; + Expression* index_ptr = Expression::make_unary(OPERATOR_AND, this->index_, + loc); + Expression* map_index = + Runtime::make_call(Runtime::MAP_INDEX, loc, 3, + map_ref, index_ptr, + Expression::make_boolean(insert, loc)); + + Type* val_type = type->val_type(); + this->value_pointer_ = + Expression::make_unsafe_cast(Type::make_pointer_type(val_type), + map_index, this->location()); + } + return this->value_pointer_; } // Dump ast representation for a map index expression @@ -11841,7 +11438,7 @@ Interface_field_reference_expression::do_get_tree(Translate_context* context) vals->push_back(this->expr_); Expression* expr = Expression::make_struct_composite_literal(st, vals, loc); - expr = Expression::make_heap_composite(expr, loc); + expr = Expression::make_heap_expression(expr, loc); Bexpression* bclosure = tree_to_expr(expr->get_tree(context)); Expression* nil_check = @@ -12193,15 +11790,13 @@ class Allocation_expression : public Expression tree Allocation_expression::do_get_tree(Translate_context* context) { - tree type_tree = type_to_tree(this->type_->get_backend(context->gogo())); - if (type_tree == error_mark_node) - return error_mark_node; - tree size_tree = TYPE_SIZE_UNIT(type_tree); - tree space = context->gogo()->allocate_memory(this->type_, size_tree, - this->location()); - if (space == error_mark_node) - return error_mark_node; - return fold_convert(build_pointer_type(type_tree), space); + Gogo* gogo = context->gogo(); + Location loc = this->location(); + Expression* space = gogo->allocate_memory(this->type_, loc); + Bexpression* bspace = tree_to_expr(space->get_tree(context)); + Btype* pbtype = gogo->backend()->pointer_type(this->type_->get_backend(gogo)); + Bexpression* ret = gogo->backend()->convert_expression(pbtype, bspace, loc); + return expr_to_tree(ret); } // Dump ast representation for an allocation expression. @@ -12453,64 +12048,38 @@ Struct_construction_expression::do_get_tree(Translate_context* context) { Gogo* gogo = context->gogo(); + Btype* btype = this->type_->get_backend(gogo); if (this->vals_ == NULL) - { - Btype* btype = this->type_->get_backend(gogo); - return expr_to_tree(gogo->backend()->zero_expression(btype)); - } - - tree type_tree = type_to_tree(this->type_->get_backend(gogo)); - if (type_tree == error_mark_node) - return error_mark_node; - go_assert(TREE_CODE(type_tree) == RECORD_TYPE); + return expr_to_tree(gogo->backend()->zero_expression(btype)); - bool is_constant = true; const Struct_field_list* fields = this->type_->struct_type()->fields(); - vec<constructor_elt, va_gc> *elts; - vec_alloc (elts, fields->size()); - Struct_field_list::const_iterator pf = fields->begin(); Expression_list::const_iterator pv = this->vals_->begin(); - for (tree field = TYPE_FIELDS(type_tree); - field != NULL_TREE; - field = DECL_CHAIN(field), ++pf) + std::vector<Bexpression*> init; + for (Struct_field_list::const_iterator pf = fields->begin(); + pf != fields->end(); + ++pf) { - go_assert(pf != fields->end()); - Btype* fbtype = pf->type()->get_backend(gogo); - - tree val; if (pv == this->vals_->end()) - val = expr_to_tree(gogo->backend()->zero_expression(fbtype)); + init.push_back(gogo->backend()->zero_expression(fbtype)); else if (*pv == NULL) { - val = expr_to_tree(gogo->backend()->zero_expression(fbtype)); + init.push_back(gogo->backend()->zero_expression(fbtype)); ++pv; } else { - val = Expression::convert_for_assignment(context, pf->type(), - (*pv)->type(), - (*pv)->get_tree(context), - this->location()); + Expression* val = + Expression::convert_for_assignment(gogo, pf->type(), + *pv, this->location()); + init.push_back(tree_to_expr(val->get_tree(context))); ++pv; } - - if (val == error_mark_node || TREE_TYPE(val) == error_mark_node) - return error_mark_node; - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = elts->quick_push(empty); - elt->index = field; - elt->value = val; - if (!TREE_CONSTANT(val)) - is_constant = false; } - go_assert(pf == fields->end()); - tree ret = build_constructor(type_tree, elts); - if (is_constant) - TREE_CONSTANT(ret) = 1; - return ret; + Bexpression* ret = + gogo->backend()->constructor_expression(btype, init, this->location()); + return expr_to_tree(ret); } // Export a struct construction. @@ -12555,7 +12124,7 @@ Expression::make_struct_composite_literal(Type* type, Expression_list* vals, // Construct an array. This class is not used directly; instead we // use the child classes, Fixed_array_construction_expression and -// Open_array_construction_expression. +// Slice_construction_expression. class Array_construction_expression : public Expression { @@ -12608,9 +12177,9 @@ protected: vals() { return this->vals_; } - // Get a constructor tree for the array values. - tree - get_constructor_tree(Translate_context* context, tree type_tree); + // Get the backend constructor for the array values. + Bexpression* + get_constructor(Translate_context* context, Btype* btype); void do_dump_expression(Ast_dump_context*) const; @@ -12723,16 +12292,17 @@ Array_construction_expression::do_check_types(Gogo*) } } -// Get a constructor tree for the array values. +// Get a constructor expression for the array values. -tree -Array_construction_expression::get_constructor_tree(Translate_context* context, - tree type_tree) +Bexpression* +Array_construction_expression::get_constructor(Translate_context* context, + Btype* array_btype) { - vec<constructor_elt, va_gc> *values; - vec_alloc (values, (this->vals_ == NULL ? 0 : this->vals_->size())); Type* element_type = this->type_->array_type()->element_type(); - bool is_constant = true; + + std::vector<unsigned long> indexes; + std::vector<Bexpression*> vals; + Gogo* gogo = context->gogo(); if (this->vals_ != NULL) { size_t i = 0; @@ -12745,45 +12315,32 @@ Array_construction_expression::get_constructor_tree(Translate_context* context, { if (this->indexes_ != NULL) go_assert(pi != this->indexes_->end()); - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = values->quick_push(empty); if (this->indexes_ == NULL) - elt->index = size_int(i); + indexes.push_back(i); else - elt->index = size_int(*pi); - + indexes.push_back(*pi); if (*pv == NULL) { - Gogo* gogo = context->gogo(); Btype* ebtype = element_type->get_backend(gogo); Bexpression *zv = gogo->backend()->zero_expression(ebtype); - elt->value = expr_to_tree(zv); + vals.push_back(zv); } else { - tree value_tree = (*pv)->get_tree(context); - elt->value = Expression::convert_for_assignment(context, - element_type, - (*pv)->type(), - value_tree, - this->location()); + Expression* val_expr = + Expression::convert_for_assignment(gogo, element_type, *pv, + this->location()); + vals.push_back(tree_to_expr(val_expr->get_tree(context))); } - if (elt->value == error_mark_node) - return error_mark_node; - if (!TREE_CONSTANT(elt->value)) - is_constant = false; if (this->indexes_ != NULL) ++pi; } if (this->indexes_ != NULL) go_assert(pi == this->indexes_->end()); } - - tree ret = build_constructor(type_tree, values); - if (is_constant) - TREE_CONSTANT(ret) = 1; - return ret; + return gogo->backend()->array_constructor_expression(array_btype, indexes, + vals, this->location()); } // Export an array construction. @@ -12894,43 +12451,47 @@ Fixed_array_construction_expression::do_get_tree(Translate_context* context) { Type* type = this->type(); Btype* btype = type->get_backend(context->gogo()); - return this->get_constructor_tree(context, type_to_tree(btype)); + return expr_to_tree(this->get_constructor(context, btype)); } -// Construct an open array. +// Construct a slice. -class Open_array_construction_expression : public Array_construction_expression +class Slice_construction_expression : public Array_construction_expression { public: - Open_array_construction_expression(Type* type, - const std::vector<unsigned long>* indexes, - Expression_list* vals, Location location) - : Array_construction_expression(EXPRESSION_OPEN_ARRAY_CONSTRUCTION, - type, indexes, vals, location) + Slice_construction_expression(Type* type, + const std::vector<unsigned long>* indexes, + Expression_list* vals, Location location) + : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION, + type, indexes, vals, location), + valtype_(NULL) { go_assert(type->is_slice_type()); } protected: - // Note that taking the address of an open array literal is invalid. + // Note that taking the address of a slice literal is invalid. Expression* do_copy() { - return new Open_array_construction_expression(this->type(), - this->indexes(), - (this->vals() == NULL - ? NULL - : this->vals()->copy()), - this->location()); + return new Slice_construction_expression(this->type(), this->indexes(), + (this->vals() == NULL + ? NULL + : this->vals()->copy()), + this->location()); } tree do_get_tree(Translate_context*); + + private: + // The type of the values in this slice. + Type* valtype_; }; -// Return a tree for constructing an open array. +// Return a tree for constructing a slice. tree -Open_array_construction_expression::do_get_tree(Translate_context* context) +Slice_construction_expression::do_get_tree(Translate_context* context) { Array_type* array_type = this->type()->array_type(); if (array_type == NULL) @@ -12940,49 +12501,43 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) } Type* element_type = array_type->element_type(); - Btype* belement_type = element_type->get_backend(context->gogo()); - tree element_type_tree = type_to_tree(belement_type); - if (element_type_tree == error_mark_node) - return error_mark_node; + if (this->valtype_ == NULL) + { + mpz_t lenval; + Expression* length; + if (this->vals() == NULL || this->vals()->empty()) + mpz_init_set_ui(lenval, 0); + else + { + if (this->indexes() == NULL) + mpz_init_set_ui(lenval, this->vals()->size()); + else + mpz_init_set_ui(lenval, this->indexes()->back() + 1); + } + Location loc = this->location(); + Type* int_type = Type::lookup_integer_type("int"); + length = Expression::make_integer(&lenval, int_type, loc); + mpz_clear(lenval); + this->valtype_ = Type::make_array_type(element_type, length); + } tree values; - tree length_tree; + Gogo* gogo = context->gogo(); + Btype* val_btype = this->valtype_->get_backend(gogo); if (this->vals() == NULL || this->vals()->empty()) { // We need to create a unique value. - tree max = size_int(0); - tree constructor_type = build_array_type(element_type_tree, - build_index_type(max)); - if (constructor_type == error_mark_node) - return error_mark_node; - vec<constructor_elt, va_gc> *vec; - vec_alloc(vec, 1); - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = vec->quick_push(empty); - elt->index = size_int(0); - Gogo* gogo = context->gogo(); - Btype* btype = element_type->get_backend(gogo); - elt->value = expr_to_tree(gogo->backend()->zero_expression(btype)); - values = build_constructor(constructor_type, vec); - if (TREE_CONSTANT(elt->value)) - TREE_CONSTANT(values) = 1; - length_tree = size_int(0); + Btype* int_btype = Type::lookup_integer_type("int")->get_backend(gogo); + Bexpression* zero = gogo->backend()->zero_expression(int_btype); + std::vector<unsigned long> index(1, 0); + std::vector<Bexpression*> val(1, zero); + Bexpression* ctor = + gogo->backend()->array_constructor_expression(val_btype, index, val, + this->location()); + values = expr_to_tree(ctor); } else - { - unsigned long max_index; - if (this->indexes() == NULL) - max_index = this->vals()->size() - 1; - else - max_index = this->indexes()->back(); - tree max_tree = size_int(max_index); - tree constructor_type = build_array_type(element_type_tree, - build_index_type(max_tree)); - if (constructor_type == error_mark_node) - return error_mark_node; - values = this->get_constructor_tree(context, constructor_type); - length_tree = size_int(max_index + 1); - } + values = expr_to_tree(this->get_constructor(context, val_btype)); if (values == error_mark_node) return error_mark_node; @@ -13030,10 +12585,9 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) } else { - tree memsize = TYPE_SIZE_UNIT(TREE_TYPE(values)); - space = context->gogo()->allocate_memory(element_type, memsize, - this->location()); - space = save_expr(space); + Expression* alloc = + context->gogo()->allocate_memory(this->valtype_, this->location()); + space = save_expr(alloc->get_tree(context)); tree s = fold_convert(build_pointer_type(TREE_TYPE(values)), space); tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(), @@ -13042,7 +12596,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) set = build2(MODIFY_EXPR, void_type_node, ref, values); } - // Build a constructor for the open array. + // Build a constructor for the slice. tree type_tree = type_to_tree(this->type()->get_backend(context->gogo())); if (type_tree == error_mark_node) @@ -13059,6 +12613,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) elt->index = field; elt->value = fold_convert(TREE_TYPE(field), space); + tree length_tree = this->valtype_->array_type()->length()->get_tree(context); elt = init->quick_push(empty); field = DECL_CHAIN(field); go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__count") == 0); @@ -13091,7 +12646,7 @@ Expression::make_slice_composite_literal(Type* type, Expression_list* vals, Location location) { go_assert(type->is_slice_type()); - return new Open_array_construction_expression(type, NULL, vals, location); + return new Slice_construction_expression(type, NULL, vals, location); } // Construct a map. @@ -13102,13 +12657,16 @@ class Map_construction_expression : public Expression Map_construction_expression(Type* type, Expression_list* vals, Location location) : Expression(EXPRESSION_MAP_CONSTRUCTION, location), - type_(type), vals_(vals) + type_(type), vals_(vals), element_type_(NULL), constructor_temp_(NULL) { go_assert(vals == NULL || vals->size() % 2 == 0); } protected: int do_traverse(Traverse* traverse); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + Type* do_type() { return this->type_; } @@ -13140,6 +12698,10 @@ class Map_construction_expression : public Expression Type* type_; // The list of values. Expression_list* vals_; + // The type of the key-value pair struct for each map element. + Struct_type* element_type_; + // A temporary reference to the variable storing the constructor initializer. + Temporary_statement* constructor_temp_; }; // Traversal. @@ -13155,6 +12717,69 @@ Map_construction_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +// Flatten constructor initializer into a temporary variable since +// we need to take its address for __go_construct_map. + +Expression* +Map_construction_expression::do_flatten(Gogo* gogo, Named_object*, + Statement_inserter* inserter) +{ + if (!this->is_error_expression() + && this->vals_ != NULL + && !this->vals_->empty() + && this->constructor_temp_ == NULL) + { + Map_type* mt = this->type_->map_type(); + Type* key_type = mt->key_type(); + Type* val_type = mt->val_type(); + this->element_type_ = Type::make_builtin_struct_type(2, + "__key", key_type, + "__val", val_type); + + Expression_list* value_pairs = new Expression_list(); + Location loc = this->location(); + + size_t i = 0; + for (Expression_list::const_iterator pv = this->vals_->begin(); + pv != this->vals_->end(); + ++pv, ++i) + { + Expression_list* key_value_pair = new Expression_list(); + Expression* key = + Expression::convert_for_assignment(gogo, key_type, *pv, loc); + + ++pv; + Expression* val = + Expression::convert_for_assignment(gogo, val_type, *pv, loc); + + key_value_pair->push_back(key); + key_value_pair->push_back(val); + value_pairs->push_back( + Expression::make_struct_composite_literal(this->element_type_, + key_value_pair, loc)); + } + + mpz_t lenval; + mpz_init_set_ui(lenval, i); + Expression* element_count = Expression::make_integer(&lenval, NULL, loc); + mpz_clear(lenval); + + Type* ctor_type = + Type::make_array_type(this->element_type_, element_count); + Expression* constructor = + new Fixed_array_construction_expression(ctor_type, NULL, + value_pairs, loc); + + this->constructor_temp_ = + Statement::make_temporary(NULL, constructor, loc); + constructor->issue_nil_check(); + this->constructor_temp_->set_is_address_taken(); + inserter->insert(this->constructor_temp_); + } + + return this; +} + // Final type determination. void @@ -13216,167 +12841,53 @@ Map_construction_expression::do_check_types(Gogo*) tree Map_construction_expression::do_get_tree(Translate_context* context) { - Gogo* gogo = context->gogo(); - Location loc = this->location(); - - Map_type* mt = this->type_->map_type(); - - // Build a struct to hold the key and value. - tree struct_type = make_node(RECORD_TYPE); - - Type* key_type = mt->key_type(); - tree id = get_identifier("__key"); - tree key_type_tree = type_to_tree(key_type->get_backend(gogo)); - if (key_type_tree == error_mark_node) - return error_mark_node; - tree key_field = build_decl(loc.gcc_location(), FIELD_DECL, id, - key_type_tree); - DECL_CONTEXT(key_field) = struct_type; - TYPE_FIELDS(struct_type) = key_field; - - Type* val_type = mt->val_type(); - id = get_identifier("__val"); - tree val_type_tree = type_to_tree(val_type->get_backend(gogo)); - if (val_type_tree == error_mark_node) + if (this->is_error_expression()) return error_mark_node; - tree val_field = build_decl(loc.gcc_location(), FIELD_DECL, id, - val_type_tree); - DECL_CONTEXT(val_field) = struct_type; - DECL_CHAIN(key_field) = val_field; - - layout_type(struct_type); + Location loc = this->location(); - bool is_constant = true; size_t i = 0; - tree valaddr; - tree make_tmp; - + Expression* ventries; if (this->vals_ == NULL || this->vals_->empty()) - { - valaddr = null_pointer_node; - make_tmp = NULL_TREE; - } + ventries = Expression::make_nil(loc); else { - vec<constructor_elt, va_gc> *values; - vec_alloc(values, this->vals_->size() / 2); - - for (Expression_list::const_iterator pv = this->vals_->begin(); - pv != this->vals_->end(); - ++pv, ++i) - { - bool one_is_constant = true; - - vec<constructor_elt, va_gc> *one; - vec_alloc(one, 2); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = one->quick_push(empty); - elt->index = key_field; - tree val_tree = (*pv)->get_tree(context); - elt->value = Expression::convert_for_assignment(context, key_type, - (*pv)->type(), - val_tree, loc); - if (elt->value == error_mark_node) - return error_mark_node; - if (!TREE_CONSTANT(elt->value)) - one_is_constant = false; - - ++pv; - - elt = one->quick_push(empty); - elt->index = val_field; - val_tree = (*pv)->get_tree(context); - elt->value = Expression::convert_for_assignment(context, val_type, - (*pv)->type(), - val_tree, loc); - if (elt->value == error_mark_node) - return error_mark_node; - if (!TREE_CONSTANT(elt->value)) - one_is_constant = false; - - elt = values->quick_push(empty); - elt->index = size_int(i); - elt->value = build_constructor(struct_type, one); - if (one_is_constant) - TREE_CONSTANT(elt->value) = 1; - else - is_constant = false; - } + go_assert(this->constructor_temp_ != NULL); + i = this->vals_->size() / 2; - tree index_type = build_index_type(size_int(i - 1)); - tree array_type = build_array_type(struct_type, index_type); - tree init = build_constructor(array_type, values); - if (is_constant) - TREE_CONSTANT(init) = 1; - tree tmp; - if (current_function_decl != NULL) - { - tmp = create_tmp_var(array_type, get_name(array_type)); - DECL_INITIAL(tmp) = init; - make_tmp = fold_build1_loc(loc.gcc_location(), DECL_EXPR, - void_type_node, tmp); - TREE_ADDRESSABLE(tmp) = 1; - } - else - { - tmp = build_decl(loc.gcc_location(), VAR_DECL, - create_tmp_var_name("M"), array_type); - DECL_EXTERNAL(tmp) = 0; - TREE_PUBLIC(tmp) = 0; - TREE_STATIC(tmp) = 1; - DECL_ARTIFICIAL(tmp) = 1; - if (!TREE_CONSTANT(init)) - make_tmp = fold_build2_loc(loc.gcc_location(), INIT_EXPR, - void_type_node, tmp, init); - else - { - TREE_READONLY(tmp) = 1; - TREE_CONSTANT(tmp) = 1; - DECL_INITIAL(tmp) = init; - make_tmp = NULL_TREE; - } - rest_of_decl_compilation(tmp, 1, 0); - } - - valaddr = build_fold_addr_expr(tmp); + Expression* ctor_ref = + Expression::make_temporary_reference(this->constructor_temp_, loc); + ventries = Expression::make_unary(OPERATOR_AND, ctor_ref, loc); } - Bexpression* bdescriptor = mt->map_descriptor_pointer(gogo, loc); - tree descriptor = expr_to_tree(bdescriptor); - - tree type_tree = type_to_tree(this->type_->get_backend(gogo)); - if (type_tree == error_mark_node) - return error_mark_node; - - static tree construct_map_fndecl; - tree call = Gogo::call_builtin(&construct_map_fndecl, - loc, - "__go_construct_map", - 6, - type_tree, - TREE_TYPE(descriptor), - descriptor, - sizetype, - size_int(i), - sizetype, - TYPE_SIZE_UNIT(struct_type), - sizetype, - byte_position(val_field), - sizetype, - TYPE_SIZE_UNIT(TREE_TYPE(val_field)), - const_ptr_type_node, - fold_convert(const_ptr_type_node, valaddr)); - if (call == error_mark_node) - return error_mark_node; - - tree ret; - if (make_tmp == NULL) - ret = call; - else - ret = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR, type_tree, - make_tmp, call); - return ret; + Map_type* mt = this->type_->map_type(); + if (this->element_type_ == NULL) + this->element_type_ = + Type::make_builtin_struct_type(2, + "__key", mt->key_type(), + "__val", mt->val_type()); + Expression* descriptor = Expression::make_map_descriptor(mt, loc); + + Type* uintptr_t = Type::lookup_integer_type("uintptr"); + mpz_t countval; + mpz_init_set_ui(countval, i); + Expression* count = Expression::make_integer(&countval, uintptr_t, loc); + mpz_clear(countval); + + Expression* entry_size = + Expression::make_type_info(this->element_type_, TYPE_INFO_SIZE); + + unsigned int field_index; + const Struct_field* valfield = + this->element_type_->find_local_field("__val", &field_index); + Expression* val_offset = + Expression::make_struct_field_offset(this->element_type_, valfield); + Expression* val_size = + Expression::make_type_info(mt->val_type(), TYPE_INFO_SIZE); + + Expression* map_ctor = + Runtime::make_call(Runtime::CONSTRUCT_MAP, loc, 6, descriptor, count, + entry_size, val_offset, val_size, ventries); + return map_ctor->get_tree(context); } // Export an array construction. @@ -13589,7 +13100,7 @@ Composite_literal_expression::do_lower(Gogo* gogo, Named_object* function, } if (is_pointer) - ret = Expression::make_heap_composite(ret, this->location()); + ret = Expression::make_heap_expression(ret, this->location()); return ret; } @@ -14031,8 +13542,7 @@ Composite_literal_expression::make_array( return new Fixed_array_construction_expression(type, indexes, vals, location); else - return new Open_array_construction_expression(type, indexes, vals, - location); + return new Slice_construction_expression(type, indexes, vals, location); } // Lower a map composite literal. @@ -14112,7 +13622,7 @@ Expression::is_composite_literal() const case EXPRESSION_COMPOSITE_LITERAL: case EXPRESSION_STRUCT_CONSTRUCTION: case EXPRESSION_FIXED_ARRAY_CONSTRUCTION: - case EXPRESSION_OPEN_ARRAY_CONSTRUCTION: + case EXPRESSION_SLICE_CONSTRUCTION: case EXPRESSION_MAP_CONSTRUCTION: return true; default: @@ -14140,10 +13650,10 @@ Expression::is_nonconstant_composite_literal() const static_cast<const Fixed_array_construction_expression*>(this); return !pace->is_constant_array(); } - case EXPRESSION_OPEN_ARRAY_CONSTRUCTION: + case EXPRESSION_SLICE_CONSTRUCTION: { - const Open_array_construction_expression *pace = - static_cast<const Open_array_construction_expression*>(this); + const Slice_construction_expression *pace = + static_cast<const Slice_construction_expression*>(this); return !pace->is_constant_array(); } case EXPRESSION_MAP_CONSTRUCTION: @@ -14195,6 +13705,21 @@ Type_guard_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +Expression* +Type_guard_expression::do_flatten(Gogo*, Named_object*, + Statement_inserter* inserter) +{ + if (!this->expr_->is_variable()) + { + Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_, + this->location()); + inserter->insert(temp); + this->expr_ = + Expression::make_temporary_reference(temp, this->location()); + } + return this; +} + // Check types of a type guard expression. The expression must have // an interface type, but the actual type conversion is checked at run // time. @@ -14236,24 +13761,23 @@ Type_guard_expression::do_check_types(Gogo*) tree Type_guard_expression::do_get_tree(Translate_context* context) { - tree expr_tree = this->expr_->get_tree(context); - if (expr_tree == error_mark_node) - return error_mark_node; + Expression* conversion; if (this->type_->interface_type() != NULL) - return Expression::convert_interface_to_interface(context, this->type_, - this->expr_->type(), - expr_tree, true, - this->location()); + conversion = + Expression::convert_interface_to_interface(this->type_, this->expr_, + true, this->location()); else - return Expression::convert_for_assignment(context, this->type_, - this->expr_->type(), expr_tree, - this->location()); + conversion = + Expression::convert_for_assignment(context->gogo(), this->type_, + this->expr_, this->location()); + + return conversion->get_tree(context); } // Dump ast representation for a type guard expression. void -Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context) +Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const { this->expr_->dump_expression(ast_dump_context); @@ -14270,16 +13794,16 @@ Expression::make_type_guard(Expression* expr, Type* type, return new Type_guard_expression(expr, type, location); } -// Class Heap_composite_expression. +// Class Heap_expression. -// When you take the address of a composite literal, it is allocated +// When you take the address of an escaping expression, it is allocated // on the heap. This class implements that. -class Heap_composite_expression : public Expression +class Heap_expression : public Expression { public: - Heap_composite_expression(Expression* expr, Location location) - : Expression(EXPRESSION_HEAP_COMPOSITE, location), + Heap_expression(Expression* expr, Location location) + : Expression(EXPRESSION_HEAP, location), expr_(expr) { } @@ -14299,8 +13823,8 @@ class Heap_composite_expression : public Expression Expression* do_copy() { - return Expression::make_heap_composite(this->expr_->copy(), - this->location()); + return Expression::make_heap_expression(this->expr_->copy(), + this->location()); } tree @@ -14316,38 +13840,45 @@ class Heap_composite_expression : public Expression do_dump_expression(Ast_dump_context*) const; private: - // The composite literal which is being put on the heap. + // The expression which is being put on the heap. Expression* expr_; }; -// Return a tree which allocates a composite literal on the heap. +// Return a tree which allocates an expression on the heap. tree -Heap_composite_expression::do_get_tree(Translate_context* context) +Heap_expression::do_get_tree(Translate_context* context) { tree expr_tree = this->expr_->get_tree(context); if (expr_tree == error_mark_node || TREE_TYPE(expr_tree) == error_mark_node) return error_mark_node; - tree expr_size = TYPE_SIZE_UNIT(TREE_TYPE(expr_tree)); - go_assert(TREE_CODE(expr_size) == INTEGER_CST); - tree space = context->gogo()->allocate_memory(this->expr_->type(), - expr_size, this->location()); - space = fold_convert(build_pointer_type(TREE_TYPE(expr_tree)), space); + + Expression* alloc = + Expression::make_allocation(this->expr_->type(), this->location()); + + Gogo* gogo = context->gogo(); + Btype* btype = this->expr_->type()->get_backend(gogo); + size_t expr_size = gogo->backend()->type_size(btype); + tree space = alloc->get_tree(context); + if (expr_size == 0) + return space; + space = save_expr(space); tree ref = build_fold_indirect_ref_loc(this->location().gcc_location(), space); TREE_THIS_NOTRAP(ref) = 1; - tree ret = build2(COMPOUND_EXPR, TREE_TYPE(space), + tree ret = build2(COMPOUND_EXPR, + type_to_tree(this->type()->get_backend(gogo)), build2(MODIFY_EXPR, void_type_node, ref, expr_tree), space); SET_EXPR_LOCATION(ret, this->location().gcc_location()); return ret; } -// Dump ast representation for a heap composite expression. +// Dump ast representation for a heap expression. void -Heap_composite_expression::do_dump_expression( +Heap_expression::do_dump_expression( Ast_dump_context* ast_dump_context) const { ast_dump_context->ostream() << "&("; @@ -14355,12 +13886,12 @@ Heap_composite_expression::do_dump_expression( ast_dump_context->ostream() << ")"; } -// Allocate a composite literal on the heap. +// Allocate an expression on the heap. Expression* -Expression::make_heap_composite(Expression* expr, Location location) +Expression::make_heap_expression(Expression* expr, Location location) { - return new Heap_composite_expression(expr, location); + return new Heap_expression(expr, location); } // Class Receive_expression. @@ -14399,6 +13930,32 @@ Receive_expression::do_check_types(Gogo*) } } +// Flattening for receive expressions creates a temporary variable to store +// received data in for receives. + +Expression* +Receive_expression::do_flatten(Gogo*, Named_object*, + Statement_inserter* inserter) +{ + Channel_type* channel_type = this->channel_->type()->channel_type(); + if (channel_type == NULL) + { + go_assert(saw_errors()); + return this; + } + + Type* element_type = channel_type->element_type(); + if (this->temp_receiver_ == NULL) + { + this->temp_receiver_ = Statement::make_temporary(element_type, NULL, + this->location()); + this->temp_receiver_->set_is_address_taken(); + inserter->insert(this->temp_receiver_); + } + + return this; +} + // Get a tree for a receive expression. tree @@ -14412,19 +13969,18 @@ Receive_expression::do_get_tree(Translate_context* context) go_assert(this->channel_->type()->is_error()); return error_mark_node; } - Expression* td = Expression::make_type_descriptor(channel_type, loc); - tree td_tree = td->get_tree(context); - - Type* element_type = channel_type->element_type(); - Btype* element_type_btype = element_type->get_backend(context->gogo()); - tree element_type_tree = type_to_tree(element_type_btype); - - tree channel = this->channel_->get_tree(context); - if (element_type_tree == error_mark_node || channel == error_mark_node) - return error_mark_node; - return Gogo::receive_from_channel(element_type_tree, td_tree, channel, loc); + Expression* recv_ref = + Expression::make_temporary_reference(this->temp_receiver_, loc); + Expression* recv_addr = + Expression::make_temporary_reference(this->temp_receiver_, loc); + recv_addr = Expression::make_unary(OPERATOR_AND, recv_addr, loc); + Expression* recv = + Runtime::make_call(Runtime::RECEIVE, loc, 3, + td, this->channel_, recv_addr); + recv = Expression::make_compound(recv, recv_ref, loc); + return recv->get_tree(context); } // Dump ast representation for a receive expression. @@ -14725,6 +14281,101 @@ Expression::make_slice_info(Expression* slice, Slice_info slice_info, return new Slice_info_expression(slice, slice_info, location); } +// An expression that represents a slice value: a struct with value pointer, +// length, and capacity fields. + +class Slice_value_expression : public Expression +{ + public: + Slice_value_expression(Type* type, Expression* valptr, Expression* len, + Expression* cap, Location location) + : Expression(EXPRESSION_SLICE_VALUE, location), + type_(type), valptr_(valptr), len_(len), cap_(cap) + { } + + protected: + int + do_traverse(Traverse*); + + Type* + do_type() + { return this->type_; } + + void + do_determine_type(const Type_context*) + { go_unreachable(); } + + Expression* + do_copy() + { + return new Slice_value_expression(this->type_, this->valptr_->copy(), + this->len_->copy(), this->cap_->copy(), + this->location()); + } + + tree + do_get_tree(Translate_context* context); + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The type of the slice value. + Type* type_; + // The pointer to the values in the slice. + Expression* valptr_; + // The length of the slice. + Expression* len_; + // The capacity of the slice. + Expression* cap_; +}; + +int +Slice_value_expression::do_traverse(Traverse* traverse) +{ + if (Expression::traverse(&this->valptr_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->len_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->cap_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + return TRAVERSE_CONTINUE; +} + +tree +Slice_value_expression::do_get_tree(Translate_context* context) +{ + std::vector<Bexpression*> vals(3); + vals[0] = tree_to_expr(this->valptr_->get_tree(context)); + vals[1] = tree_to_expr(this->len_->get_tree(context)); + vals[2] = tree_to_expr(this->cap_->get_tree(context)); + + Gogo* gogo = context->gogo(); + Btype* btype = this->type_->get_backend(gogo); + Bexpression* ret = + gogo->backend()->constructor_expression(btype, vals, this->location()); + return expr_to_tree(ret); +} + +void +Slice_value_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "slicevalue("; + ast_dump_context->ostream() << "values: "; + this->valptr_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ", length: "; + this->len_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ", capacity: "; + this->cap_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ")"; +} + +Expression* +Expression::make_slice_value(Type* at, Expression* valptr, Expression* len, + Expression* cap, Location location) +{ + go_assert(at->is_slice_type()); + return new Slice_value_expression(at, valptr, len, cap, location); +} // An expression that evaluates to some characteristic of a non-empty interface. // This is used to access the method table or underlying object of an interface. @@ -14733,7 +14384,7 @@ class Interface_info_expression : public Expression { public: Interface_info_expression(Expression* iface, Interface_info iface_info, - Location location) + Location location) : Expression(EXPRESSION_INTERFACE_INFO, location), iface_(iface), iface_info_(iface_info) { } @@ -14779,9 +14430,12 @@ Interface_info_expression::do_type() { case INTERFACE_INFO_METHODS: { + Type* pdt = Type::make_type_descriptor_ptr_type(); + if (this->iface_->type()->interface_type()->is_empty()) + return pdt; + Location loc = this->location(); Struct_field_list* sfl = new Struct_field_list(); - Type* pdt = Type::make_type_descriptor_ptr_type(); sfl->push_back( Struct_field(Typed_identifier("__type_descriptor", pdt, loc))); @@ -14855,11 +14509,13 @@ void Interface_info_expression::do_dump_expression( Ast_dump_context* ast_dump_context) const { + bool is_empty = this->iface_->type()->interface_type()->is_empty(); ast_dump_context->ostream() << "interfaceinfo("; this->iface_->dump_expression(ast_dump_context); ast_dump_context->ostream() << ","; ast_dump_context->ostream() << - (this->iface_info_ == INTERFACE_INFO_METHODS ? "methods" + (this->iface_info_ == INTERFACE_INFO_METHODS && !is_empty ? "methods" + : this->iface_info_ == INTERFACE_INFO_TYPE_DESCRIPTOR ? "type_descriptor" : this->iface_info_ == INTERFACE_INFO_OBJECT ? "object" : "unknown"); ast_dump_context->ostream() << ")"; @@ -14874,6 +14530,303 @@ Expression::make_interface_info(Expression* iface, Interface_info iface_info, return new Interface_info_expression(iface, iface_info, location); } +// An expression that represents an interface value. The first field is either +// a type descriptor for an empty interface or a pointer to the interface method +// table for a non-empty interface. The second field is always the object. + +class Interface_value_expression : public Expression +{ + public: + Interface_value_expression(Type* type, Expression* first_field, + Expression* obj, Location location) + : Expression(EXPRESSION_INTERFACE_VALUE, location), + type_(type), first_field_(first_field), obj_(obj) + { } + + protected: + int + do_traverse(Traverse*); + + Type* + do_type() + { return this->type_; } + + void + do_determine_type(const Type_context*) + { go_unreachable(); } + + Expression* + do_copy() + { + return new Interface_value_expression(this->type_, + this->first_field_->copy(), + this->obj_->copy(), this->location()); + } + + tree + do_get_tree(Translate_context* context); + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The type of the interface value. + Type* type_; + // The first field of the interface (either a type descriptor or a pointer + // to the method table. + Expression* first_field_; + // The underlying object of the interface. + Expression* obj_; +}; + +int +Interface_value_expression::do_traverse(Traverse* traverse) +{ + if (Expression::traverse(&this->first_field_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->obj_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + return TRAVERSE_CONTINUE; +} + +tree +Interface_value_expression::do_get_tree(Translate_context* context) +{ + std::vector<Bexpression*> vals(2); + vals[0] = tree_to_expr(this->first_field_->get_tree(context)); + vals[1] = tree_to_expr(this->obj_->get_tree(context)); + + Gogo* gogo = context->gogo(); + Btype* btype = this->type_->get_backend(gogo); + Bexpression* ret = + gogo->backend()->constructor_expression(btype, vals, this->location()); + return expr_to_tree(ret); +} + +void +Interface_value_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "interfacevalue("; + ast_dump_context->ostream() << + (this->type_->interface_type()->is_empty() + ? "type_descriptor: " + : "methods: "); + this->first_field_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ", object: "; + this->obj_->dump_expression(ast_dump_context); + ast_dump_context->ostream() << ")"; +} + +Expression* +Expression::make_interface_value(Type* type, Expression* first_value, + Expression* object, Location location) +{ + return new Interface_value_expression(type, first_value, object, location); +} + +// An interface method table for a pair of types: an interface type and a type +// that implements that interface. + +class Interface_mtable_expression : public Expression +{ + public: + Interface_mtable_expression(Interface_type* itype, Type* type, + bool is_pointer, Location location) + : Expression(EXPRESSION_INTERFACE_MTABLE, location), + itype_(itype), type_(type), is_pointer_(is_pointer), + method_table_type_(NULL), bvar_(NULL) + { } + + protected: + int + do_traverse(Traverse*); + + Type* + do_type(); + + bool + is_immutable() const + { return true; } + + void + do_determine_type(const Type_context*) + { go_unreachable(); } + + Expression* + do_copy() + { + return new Interface_mtable_expression(this->itype_, this->type_, + this->is_pointer_, this->location()); + } + + bool + do_is_addressable() const + { return true; } + + tree + do_get_tree(Translate_context* context); + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The interface type for which the methods are defined. + Interface_type* itype_; + // The type to construct the interface method table for. + Type* type_; + // Whether this table contains the method set for the receiver type or the + // pointer receiver type. + bool is_pointer_; + // The type of the method table. + Type* method_table_type_; + // The backend variable that refers to the interface method table. + Bvariable* bvar_; +}; + +int +Interface_mtable_expression::do_traverse(Traverse* traverse) +{ + if (Type::traverse(this->itype_, traverse) == TRAVERSE_EXIT + || Type::traverse(this->type_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + return TRAVERSE_CONTINUE; +} + +Type* +Interface_mtable_expression::do_type() +{ + if (this->method_table_type_ != NULL) + return this->method_table_type_; + + const Typed_identifier_list* interface_methods = this->itype_->methods(); + go_assert(!interface_methods->empty()); + + Struct_field_list* sfl = new Struct_field_list; + Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(), + this->location()); + sfl->push_back(Struct_field(tid)); + for (Typed_identifier_list::const_iterator p = interface_methods->begin(); + p != interface_methods->end(); + ++p) + sfl->push_back(Struct_field(*p)); + this->method_table_type_ = Type::make_struct_type(sfl, this->location()); + return this->method_table_type_; +} + +tree +Interface_mtable_expression::do_get_tree(Translate_context* context) +{ + Gogo* gogo = context->gogo(); + Bexpression* ret; + Location loc = Linemap::predeclared_location(); + if (this->bvar_ != NULL) + { + ret = gogo->backend()->var_expression(this->bvar_, this->location()); + return expr_to_tree(ret); + } + + const Typed_identifier_list* interface_methods = this->itype_->methods(); + go_assert(!interface_methods->empty()); + + std::string mangled_name = ((this->is_pointer_ ? "__go_pimt__" : "__go_imt_") + + this->itype_->mangled_name(gogo) + + "__" + + this->type_->mangled_name(gogo)); + + // See whether this interface has any hidden methods. + bool has_hidden_methods = false; + for (Typed_identifier_list::const_iterator p = interface_methods->begin(); + p != interface_methods->end(); + ++p) + { + if (Gogo::is_hidden_name(p->name())) + { + has_hidden_methods = true; + break; + } + } + + // We already know that the named type is convertible to the + // interface. If the interface has hidden methods, and the named + // type is defined in a different package, then the interface + // conversion table will be defined by that other package. + if (has_hidden_methods + && this->type_->named_type() != NULL + && this->type_->named_type()->named_object()->package() != NULL) + { + Btype* btype = this->type()->get_backend(gogo); + this->bvar_ = + gogo->backend()->immutable_struct_reference(mangled_name, btype, loc); + ret = gogo->backend()->var_expression(this->bvar_, this->location()); + return expr_to_tree(ret); + } + + // The first element is the type descriptor. + Type* td_type; + if (!this->is_pointer_) + td_type = this->type_; + else + td_type = Type::make_pointer_type(this->type_); + + // Build an interface method table for a type: a type descriptor followed by a + // list of function pointers, one for each interface method. This is used for + // interfaces. + Expression_list* svals = new Expression_list(); + svals->push_back(Expression::make_type_descriptor(td_type, loc)); + + Named_type* nt = this->type_->named_type(); + Struct_type* st = this->type_->struct_type(); + go_assert(nt != NULL || st != NULL); + + for (Typed_identifier_list::const_iterator p = interface_methods->begin(); + p != interface_methods->end(); + ++p) + { + bool is_ambiguous; + Method* m; + if (nt != NULL) + m = nt->method_function(p->name(), &is_ambiguous); + else + m = st->method_function(p->name(), &is_ambiguous); + go_assert(m != NULL); + Named_object* no = m->named_object(); + + go_assert(no->is_function() || no->is_function_declaration()); + svals->push_back(Expression::make_func_code_reference(no, loc)); + } + + Btype* btype = this->type()->get_backend(gogo); + Expression* mtable = Expression::make_struct_composite_literal(this->type(), + svals, loc); + Bexpression* ctor = tree_to_expr(mtable->get_tree(context)); + + bool is_public = has_hidden_methods && this->type_->named_type() != NULL; + this->bvar_ = gogo->backend()->immutable_struct(mangled_name, false, + !is_public, btype, loc); + gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false, + !is_public, btype, loc, ctor); + ret = gogo->backend()->var_expression(this->bvar_, loc); + return expr_to_tree(ret); +} + +void +Interface_mtable_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "__go_" + << (this->is_pointer_ ? "pimt__" : "imt_"); + ast_dump_context->dump_type(this->itype_); + ast_dump_context->ostream() << "__"; + ast_dump_context->dump_type(this->type_); +} + +Expression* +Expression::make_interface_mtable_ref(Interface_type* itype, Type* type, + bool is_pointer, Location location) +{ + return new Interface_mtable_expression(itype, type, is_pointer, location); +} + // An expression which evaluates to the offset of a field within a // struct. This, like Type_info_expression, q.v., is only used to // initialize fields of a type descriptor. @@ -15082,12 +15035,14 @@ class Conditional_expression : public Expression {} protected: + int + do_traverse(Traverse*); + Type* do_type(); void - do_determine_type(const Type_context*) - { } + do_determine_type(const Type_context*); Expression* do_copy() @@ -15111,13 +15066,26 @@ class Conditional_expression : public Expression Expression* else_; }; +// Traversal. + +int +Conditional_expression::do_traverse(Traverse* traverse) +{ + if (Expression::traverse(&this->cond_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->then_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->else_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + return TRAVERSE_CONTINUE; +} + // Return the type of the conditional expression. Type* Conditional_expression::do_type() { Type* result_type = Type::make_void_type(); - if (this->then_->type() == this->else_->type()) + if (Type::are_identical(this->then_->type(), this->else_->type(), false, + NULL)) result_type = this->then_->type(); else if (this->then_->is_nil_expression() || this->else_->is_nil_expression()) @@ -15127,6 +15095,16 @@ Conditional_expression::do_type() return result_type; } +// Determine type for a conditional expression. + +void +Conditional_expression::do_determine_type(const Type_context* context) +{ + this->cond_->determine_type_no_context(); + this->then_->determine_type(context); + this->else_->determine_type(context); +} + // Get the backend representation of a conditional expression. tree @@ -15167,6 +15145,108 @@ Expression::make_conditional(Expression* cond, Expression* then, return new Conditional_expression(cond, then, else_expr, location); } +// Compound expressions. + +class Compound_expression : public Expression +{ + public: + Compound_expression(Expression* init, Expression* expr, Location location) + : Expression(EXPRESSION_COMPOUND, location), init_(init), expr_(expr) + {} + + protected: + int + do_traverse(Traverse*); + + Type* + do_type(); + + void + do_determine_type(const Type_context*); + + Expression* + do_copy() + { + return new Compound_expression(this->init_->copy(), this->expr_->copy(), + this->location()); + } + + tree + do_get_tree(Translate_context* context); + + void + do_dump_expression(Ast_dump_context*) const; + + private: + // The expression that is evaluated first and discarded. + Expression* init_; + // The expression that is evaluated and returned. + Expression* expr_; +}; + +// Traversal. + +int +Compound_expression::do_traverse(Traverse* traverse) +{ + if (Expression::traverse(&this->init_, traverse) == TRAVERSE_EXIT + || Expression::traverse(&this->expr_, traverse) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + return TRAVERSE_CONTINUE; +} + +// Return the type of the compound expression. + +Type* +Compound_expression::do_type() +{ + return this->expr_->type(); +} + +// Determine type for a compound expression. + +void +Compound_expression::do_determine_type(const Type_context* context) +{ + this->init_->determine_type_no_context(); + this->expr_->determine_type(context); +} + +// Get the backend representation of a compound expression. + +tree +Compound_expression::do_get_tree(Translate_context* context) +{ + Gogo* gogo = context->gogo(); + Bexpression* binit = tree_to_expr(this->init_->get_tree(context)); + Bstatement* init_stmt = gogo->backend()->expression_statement(binit); + Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context)); + Bexpression* ret = gogo->backend()->compound_expression(init_stmt, bexpr, + this->location()); + return expr_to_tree(ret); +} + +// Dump ast representation of a conditional expression. + +void +Compound_expression::do_dump_expression( + Ast_dump_context* ast_dump_context) const +{ + ast_dump_context->ostream() << "("; + ast_dump_context->dump_expression(this->init_); + ast_dump_context->ostream() << ","; + ast_dump_context->dump_expression(this->expr_); + ast_dump_context->ostream() << ") "; +} + +// Make a compound expression. + +Expression* +Expression::make_compound(Expression* init, Expression* expr, Location location) +{ + return new Compound_expression(init, expr, location); +} + // Import an expression. This comes at the end in order to see the // various class definitions. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 99a0d0720eb..dc9ad71c820 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -74,6 +74,7 @@ class Expression EXPRESSION_UNKNOWN_REFERENCE, EXPRESSION_BOOLEAN, EXPRESSION_STRING, + EXPRESSION_STRING_INFO, EXPRESSION_INTEGER, EXPRESSION_FLOAT, EXPRESSION_COMPLEX, @@ -95,19 +96,23 @@ class Expression EXPRESSION_UNSAFE_CONVERSION, EXPRESSION_STRUCT_CONSTRUCTION, EXPRESSION_FIXED_ARRAY_CONSTRUCTION, - EXPRESSION_OPEN_ARRAY_CONSTRUCTION, + EXPRESSION_SLICE_CONSTRUCTION, EXPRESSION_MAP_CONSTRUCTION, EXPRESSION_COMPOSITE_LITERAL, - EXPRESSION_HEAP_COMPOSITE, + EXPRESSION_HEAP, EXPRESSION_RECEIVE, EXPRESSION_TYPE_DESCRIPTOR, EXPRESSION_TYPE_INFO, EXPRESSION_SLICE_INFO, + EXPRESSION_SLICE_VALUE, EXPRESSION_INTERFACE_INFO, + EXPRESSION_INTERFACE_VALUE, + EXPRESSION_INTERFACE_MTABLE, EXPRESSION_STRUCT_FIELD_OFFSET, EXPRESSION_MAP_DESCRIPTOR, EXPRESSION_LABEL_ADDR, - EXPRESSION_CONDITIONAL + EXPRESSION_CONDITIONAL, + EXPRESSION_COMPOUND }; Expression(Expression_classification, Location); @@ -188,6 +193,20 @@ class Expression static Expression* make_string(const std::string&, Location); + // Make an expression that evaluates to some characteristic of an string. + // For simplicity, the enum values must match the field indexes in the + // underlying struct. + enum String_info + { + // The underlying data in the string. + STRING_INFO_DATA, + // The length of the string. + STRING_INFO_LENGTH + }; + + static Expression* + make_string_info(Expression* string, String_info, Location); + // Make a character constant expression. TYPE should be NULL for an // abstract type. static Expression* @@ -312,9 +331,9 @@ class Expression static Expression* make_slice_composite_literal(Type*, Expression_list*, Location); - // Take a composite literal and allocate it on the heap. + // Take an expression and allocate it on the heap. static Expression* - make_heap_composite(Expression*, Location); + make_heap_expression(Expression*, Location); // Make a receive expression. VAL is NULL for a unary receive. static Receive_expression* @@ -358,14 +377,20 @@ class Expression static Expression* make_slice_info(Expression* slice, Slice_info, Location); + // Make an expression for a slice value. + static Expression* + make_slice_value(Type*, Expression* valptr, Expression* len, Expression* cap, + Location); - // Make an expression that evaluates to some characteristic of a + // Make an expression that evaluates to some characteristic of an // interface. For simplicity, the enum values must match the field indexes - // of a non-empty interface in the underlying struct. + // in the underlying struct. enum Interface_info { + // The type descriptor of an empty interface. + INTERFACE_INFO_TYPE_DESCRIPTOR = 0, // The methods of an interface. - INTERFACE_INFO_METHODS, + INTERFACE_INFO_METHODS = 0, // The first argument to pass to an interface method. INTERFACE_INFO_OBJECT }; @@ -373,6 +398,17 @@ class Expression static Expression* make_interface_info(Expression* iface, Interface_info, Location); + // Make an expression for an interface value. + static Expression* + make_interface_value(Type*, Expression*, Expression*, Location); + + // Make an expression that builds a reference to the interface method table + // for TYPE that satisfies interface ITYPE. IS_POINTER is true if this is a + // reference to the interface method table for the pointer receiver type. + static Expression* + make_interface_mtable_ref(Interface_type* itype, Type* type, + bool is_pointer, Location); + // Make an expression which evaluates to the offset of a field in a // struct. This is only used for type descriptors, so there is no // location parameter. @@ -393,6 +429,10 @@ class Expression static Expression* make_conditional(Expression*, Expression*, Expression*, Location); + // Make a compound expression. + static Expression* + make_compound(Expression*, Expression*, Location); + // Return the expression classification. Expression_classification classification() const @@ -700,19 +740,19 @@ class Expression tree get_tree(Translate_context*); - // Return a tree handling any conversions which must be done during + // Return an expression handling any conversions which must be done during // assignment. - static tree - convert_for_assignment(Translate_context*, Type* lhs_type, Type* rhs_type, - tree rhs_tree, Location location); + static Expression* + convert_for_assignment(Gogo*, Type* lhs_type, Expression* rhs, + Location location); - // Return a tree converting a value of one interface type to another + // Return an expression converting a value of one interface type to another // interface type. If FOR_TYPE_GUARD is true this is for a type // assertion. - static tree - convert_interface_to_interface(Translate_context*, Type* lhs_type, - Type* rhs_type, tree rhs_tree, - bool for_type_guard, Location); + static Expression* + convert_interface_to_interface(Type* lhs_type, + Expression* rhs, bool for_type_guard, + Location); // Return a backend expression implementing the comparison LEFT OP RIGHT. // TYPE is the type of both sides. @@ -736,12 +776,10 @@ class Expression static Expression* import_expression(Import*); - // Return a tree which checks that VAL, of arbitrary integer type, - // is non-negative and is not more than the maximum value of - // BOUND_TYPE. If SOFAR is not NULL, it is or'red into the result. - // The return value may be NULL if SOFAR is NULL. - static tree - check_bounds(tree val, tree bound_type, tree sofar, Location); + // Return an expression which checks that VAL, of arbitrary integer type, + // is non-negative and is not more than the maximum integer value. + static Expression* + check_bounds(Expression* val, Location); // Dump an expression to a dump constext. void @@ -881,17 +919,14 @@ class Expression : NULL); } - static tree - convert_type_to_interface(Translate_context*, Type*, Type*, tree, - Location); + static Expression* + convert_type_to_interface(Type*, Expression*, Location); - static tree - get_interface_type_descriptor(Translate_context*, Type*, tree, - Location); + static Expression* + get_interface_type_descriptor(Expression*); - static tree - convert_interface_to_type(Translate_context*, Type*, Type*, tree, - Location); + static Expression* + convert_interface_to_type(Type*, Expression*, Location); // The expression classification. Expression_classification classification_; @@ -1408,8 +1443,8 @@ class Call_expression : public Expression Call_expression(Expression* fn, Expression_list* args, bool is_varargs, Location location) : Expression(EXPRESSION_CALL, location), - fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL), - is_varargs_(is_varargs), are_hidden_fields_ok_(false), + fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL), + call_temp_(NULL), is_varargs_(is_varargs), are_hidden_fields_ok_(false), varargs_are_lowered_(false), types_are_determined_(false), is_deferred_(false), issued_error_(false) { } @@ -1489,6 +1524,9 @@ class Call_expression : public Expression virtual Expression* do_lower(Gogo*, Named_object*, Statement_inserter*, int); + virtual Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + bool do_discarding_value() { return true; } @@ -1550,8 +1588,8 @@ class Call_expression : public Expression interface_method_function(Interface_field_reference_expression*, Expression**); - tree - set_results(Translate_context*, tree); + Bexpression* + set_results(Translate_context*, Bexpression*); // The function to call. Expression* fn_; @@ -1563,8 +1601,10 @@ class Call_expression : public Expression // The list of temporaries which will hold the results if the // function returns a tuple. std::vector<Temporary_statement*>* results_; - // The tree for the call, used for a call which returns a tuple. - tree tree_; + // The backend expression for the call, used for a call which returns a tuple. + Bexpression* call_; + // A temporary variable to store this call if the function returns a tuple. + Temporary_statement* call_temp_; // True if the last argument is a varargs argument (f(a...)). bool is_varargs_; // True if this statement may pass hidden fields in the arguments. @@ -1838,7 +1878,7 @@ class Map_index_expression : public Expression Location location) : Expression(EXPRESSION_MAP_INDEX, location), map_(map), index_(index), is_lvalue_(false), - is_in_tuple_assignment_(false) + is_in_tuple_assignment_(false), value_pointer_(NULL) { } // Return the map. @@ -1881,18 +1921,21 @@ class Map_index_expression : public Expression set_is_in_tuple_assignment() { this->is_in_tuple_assignment_ = true; } - // Return a tree for the map index. This returns a tree which + // Return an expression for the map index. This returns an expression which // evaluates to a pointer to a value in the map. If INSERT is true, // the key will be inserted if not present, and the value pointer // will be zero initialized. If INSERT is false, and the key is not // present in the map, the pointer will be NULL. - tree - get_value_pointer(Translate_context*, bool insert); + Expression* + get_value_pointer(bool insert); protected: int do_traverse(Traverse*); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + Type* do_type(); @@ -1934,6 +1977,8 @@ class Map_index_expression : public Expression bool is_lvalue_; // Whether this is in a tuple assignment to a pair of values. bool is_in_tuple_assignment_; + // A pointer to the value at this index. + Expression* value_pointer_; }; // An expression which represents a method bound to its first @@ -2230,6 +2275,9 @@ class Type_guard_expression : public Expression int do_traverse(Traverse* traverse); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + Type* do_type() { return this->type_; } @@ -2268,7 +2316,7 @@ class Receive_expression : public Expression public: Receive_expression(Expression* channel, Location location) : Expression(EXPRESSION_RECEIVE, location), - channel_(channel) + channel_(channel), temp_receiver_(NULL) { } // Return the channel. @@ -2288,6 +2336,9 @@ class Receive_expression : public Expression Type* do_type(); + Expression* + do_flatten(Gogo*, Named_object*, Statement_inserter*); + void do_determine_type(const Type_context*) { this->channel_->determine_type_no_context(); } @@ -2314,6 +2365,8 @@ class Receive_expression : public Expression private: // The channel from which we are receiving. Expression* channel_; + // A temporary reference to the variable storing the received data. + Temporary_statement* temp_receiver_; }; // A numeric constant. This is used both for untyped constants and diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc index 1950090b9e0..e92acae7af4 100644 --- a/gcc/go/gofrontend/gogo-tree.cc +++ b/gcc/go/gofrontend/gogo-tree.cc @@ -636,10 +636,10 @@ class Var_init { public: Var_init() - : var_(NULL), init_(NULL_TREE) + : var_(NULL), init_(NULL) { } - Var_init(Named_object* var, tree init) + Var_init(Named_object* var, Bstatement* init) : var_(var), init_(init) { } @@ -649,15 +649,15 @@ class Var_init { return this->var_; } // Return the initialization expression. - tree + Bstatement* init() const { return this->init_; } private: // The variable being initialized. Named_object* var_; - // The initialization expression to run. - tree init_; + // The initialization statement. + Bstatement* init_; }; typedef std::list<Var_init> Var_inits; @@ -868,15 +868,13 @@ Gogo::write_globals() // initializer purely for its side effects. bool is_sink = no->name()[0] == '_' && no->name()[1] == '.'; - tree var_init_tree = NULL_TREE; + Bstatement* var_init_stmt = NULL; if (!no->var_value()->has_pre_init()) { - tree init = no->var_value()->get_init_tree(this, NULL); - if (init == error_mark_node) - go_assert(saw_errors()); - else if (init == NULL_TREE) + Bexpression* var_binit = no->var_value()->get_init(this, NULL); + if (var_binit == NULL) ; - else if (TREE_CONSTANT(init)) + else if (TREE_CONSTANT(expr_to_tree(var_binit))) { if (expression_requires(no->var_value()->init(), NULL, this->var_depends_on(no->var_value()), @@ -885,17 +883,20 @@ Gogo::write_globals() "initialization expression for %qs depends " "upon itself", no->message_name().c_str()); - this->backend()->global_variable_set_init(var, - tree_to_expr(init)); + this->backend()->global_variable_set_init(var, var_binit); } - else if (is_sink - || int_size_in_bytes(TREE_TYPE(init)) == 0 - || int_size_in_bytes(TREE_TYPE(vec[i])) == 0) - var_init_tree = init; + else if (is_sink) + var_init_stmt = + this->backend()->expression_statement(var_binit); else - var_init_tree = fold_build2_loc(no->location().gcc_location(), - MODIFY_EXPR, void_type_node, - vec[i], init); + { + Location loc = no->var_value()->location(); + Bexpression* var_expr = + this->backend()->var_expression(var, loc); + var_init_stmt = + this->backend()->assignment_statement(var_expr, var_binit, + loc); + } } else { @@ -907,19 +908,21 @@ Gogo::write_globals() push_struct_function(init_fndecl); else push_cfun(DECL_STRUCT_FUNCTION(init_fndecl)); - tree var_decl = is_sink ? NULL_TREE : vec[i]; - var_init_tree = no->var_value()->get_init_block(this, NULL, - var_decl); + Bvariable* var_decl = is_sink ? NULL : var; + var_init_stmt = + no->var_value()->get_init_block(this, NULL, var_decl); + pop_cfun(); } - if (var_init_tree != NULL_TREE && var_init_tree != error_mark_node) + if (var_init_stmt != NULL) { if (no->var_value()->init() == NULL && !no->var_value()->has_pre_init()) - append_to_statement_list(var_init_tree, &var_init_stmt_list); + append_to_statement_list(stat_to_tree(var_init_stmt), + &var_init_stmt_list); else - var_inits.push_back(Var_init(no, var_init_tree)); + var_inits.push_back(Var_init(no, var_init_stmt)); } else if (this->var_depends_on(no->var_value()) != NULL) { @@ -927,7 +930,12 @@ Gogo::write_globals() // not in its init or preinit. This variable needs to // participate in dependency analysis sorting, in case // some other variable depends on this one. - var_inits.push_back(Var_init(no, integer_zero_node)); + Btype* int_btype = + Type::lookup_integer_type("int")->get_backend(this); + Bexpression* zero = this->backend()->zero_expression(int_btype); + Bstatement* zero_stmt = + this->backend()->expression_statement(zero); + var_inits.push_back(Var_init(no, zero_stmt)); } if (!is_sink && no->var_value()->type()->has_pointer()) @@ -950,7 +958,7 @@ Gogo::write_globals() for (Var_inits::const_iterator p = var_inits.begin(); p != var_inits.end(); ++p) - append_to_statement_list(p->init(), &init_stmt_list); + append_to_statement_list(stat_to_tree(p->init()), &init_stmt_list); } // After all the variables are initialized, call the "init" @@ -1106,7 +1114,7 @@ Named_object::get_tree(Gogo* gogo, Named_object* function) cfun->function_end_locus = func->block()->end_location().gcc_location(); - func->build_tree(gogo, this); + func->build(gogo, this); gimplify_function_tree(decl); @@ -1139,84 +1147,6 @@ Named_object::get_tree(Gogo* gogo, Named_object* function) return ret; } -// Get the initial value of a variable as a tree. This does not -// consider whether the variable is in the heap--it returns the -// initial value as though it were always stored in the stack. - -tree -Variable::get_init_tree(Gogo* gogo, Named_object* function) -{ - go_assert(this->preinit_ == NULL); - if (this->init_ == NULL) - { - go_assert(!this->is_parameter_); - if (this->is_global_ || this->is_in_heap()) - return NULL; - Btype* btype = this->type_->get_backend(gogo); - return expr_to_tree(gogo->backend()->zero_expression(btype)); - } - else - { - Translate_context context(gogo, function, NULL, NULL); - tree rhs_tree = this->init_->get_tree(&context); - return Expression::convert_for_assignment(&context, this->type(), - this->init_->type(), - rhs_tree, this->location()); - } -} - -// Get the initial value of a variable when a block is required. -// VAR_DECL is the decl to set; it may be NULL for a sink variable. - -tree -Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl) -{ - go_assert(this->preinit_ != NULL); - - // We want to add the variable assignment to the end of the preinit - // block. The preinit block may have a TRY_FINALLY_EXPR and a - // TRY_CATCH_EXPR; if it does, we want to add to the end of the - // regular statements. - - Translate_context context(gogo, function, NULL, NULL); - Bblock* bblock = this->preinit_->get_backend(&context); - tree block_tree = block_to_tree(bblock); - if (block_tree == error_mark_node) - return error_mark_node; - go_assert(TREE_CODE(block_tree) == BIND_EXPR); - tree statements = BIND_EXPR_BODY(block_tree); - while (statements != NULL_TREE - && (TREE_CODE(statements) == TRY_FINALLY_EXPR - || TREE_CODE(statements) == TRY_CATCH_EXPR)) - statements = TREE_OPERAND(statements, 0); - - // It's possible to have pre-init statements without an initializer - // if the pre-init statements set the variable. - if (this->init_ != NULL) - { - tree rhs_tree = this->init_->get_tree(&context); - if (rhs_tree == error_mark_node) - return error_mark_node; - if (var_decl == NULL_TREE) - append_to_statement_list(rhs_tree, &statements); - else - { - tree val = Expression::convert_for_assignment(&context, this->type(), - this->init_->type(), - rhs_tree, - this->location()); - if (val == error_mark_node) - return error_mark_node; - tree set = fold_build2_loc(this->location().gcc_location(), - MODIFY_EXPR, void_type_node, var_decl, - val); - append_to_statement_list(set, &statements); - } - } - - return block_tree; -} - // Get the backend representation. Bfunction* @@ -1272,469 +1202,6 @@ Function::get_decl() const return function_to_tree(this->fndecl_); } -// We always pass the receiver to a method as a pointer. If the -// receiver is actually declared as a non-pointer type, then we copy -// the value into a local variable, so that it has the right type. In -// this function we create the real PARM_DECL to use, and set -// DEC_INITIAL of the var_decl to be the value passed in. - -tree -Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl) -{ - if (var_decl == error_mark_node) - return error_mark_node; - go_assert(TREE_CODE(var_decl) == VAR_DECL); - tree val_type = TREE_TYPE(var_decl); - bool is_in_heap = no->var_value()->is_in_heap(); - if (is_in_heap) - { - go_assert(POINTER_TYPE_P(val_type)); - val_type = TREE_TYPE(val_type); - } - - source_location loc = DECL_SOURCE_LOCATION(var_decl); - std::string name = IDENTIFIER_POINTER(DECL_NAME(var_decl)); - name += ".pointer"; - tree id = get_identifier_from_string(name); - tree parm_decl = build_decl(loc, PARM_DECL, id, build_pointer_type(val_type)); - DECL_CONTEXT(parm_decl) = current_function_decl; - DECL_ARG_TYPE(parm_decl) = TREE_TYPE(parm_decl); - - go_assert(DECL_INITIAL(var_decl) == NULL_TREE); - tree init = build_fold_indirect_ref_loc(loc, parm_decl); - - if (is_in_heap) - { - tree size = TYPE_SIZE_UNIT(val_type); - tree space = gogo->allocate_memory(no->var_value()->type(), size, - no->location()); - space = save_expr(space); - space = fold_convert(build_pointer_type(val_type), space); - tree spaceref = build_fold_indirect_ref_loc(no->location().gcc_location(), - space); - TREE_THIS_NOTRAP(spaceref) = 1; - tree set = fold_build2_loc(loc, MODIFY_EXPR, void_type_node, - spaceref, init); - init = fold_build2_loc(loc, COMPOUND_EXPR, TREE_TYPE(space), set, space); - } - - DECL_INITIAL(var_decl) = init; - - return parm_decl; -} - -// If we take the address of a parameter, then we need to copy it into -// the heap. We will access it as a local variable via an -// indirection. - -tree -Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree var_decl) -{ - if (var_decl == error_mark_node) - return error_mark_node; - go_assert(TREE_CODE(var_decl) == VAR_DECL); - Location loc(DECL_SOURCE_LOCATION(var_decl)); - - std::string name = IDENTIFIER_POINTER(DECL_NAME(var_decl)); - name += ".param"; - tree id = get_identifier_from_string(name); - - tree type = TREE_TYPE(var_decl); - go_assert(POINTER_TYPE_P(type)); - type = TREE_TYPE(type); - - tree parm_decl = build_decl(loc.gcc_location(), PARM_DECL, id, type); - DECL_CONTEXT(parm_decl) = current_function_decl; - DECL_ARG_TYPE(parm_decl) = type; - - tree size = TYPE_SIZE_UNIT(type); - tree space = gogo->allocate_memory(no->var_value()->type(), size, loc); - space = save_expr(space); - space = fold_convert(TREE_TYPE(var_decl), space); - tree spaceref = build_fold_indirect_ref_loc(loc.gcc_location(), space); - TREE_THIS_NOTRAP(spaceref) = 1; - tree init = build2(COMPOUND_EXPR, TREE_TYPE(space), - build2(MODIFY_EXPR, void_type_node, spaceref, parm_decl), - space); - DECL_INITIAL(var_decl) = init; - - return parm_decl; -} - -// Get a tree for function code. - -void -Function::build_tree(Gogo* gogo, Named_object* named_function) -{ - tree fndecl = this->get_decl(); - go_assert(fndecl != NULL_TREE); - - tree params = NULL_TREE; - tree* pp = ¶ms; - - tree declare_vars = NULL_TREE; - for (Bindings::const_definitions_iterator p = - this->block_->bindings()->begin_definitions(); - p != this->block_->bindings()->end_definitions(); - ++p) - { - if ((*p)->is_variable() && (*p)->var_value()->is_parameter()) - { - Bvariable* bvar = (*p)->get_backend_variable(gogo, named_function); - *pp = var_to_tree(bvar); - - // We always pass the receiver to a method as a pointer. If - // the receiver is declared as a non-pointer type, then we - // copy the value into a local variable. - if ((*p)->var_value()->is_receiver() - && (*p)->var_value()->type()->points_to() == NULL) - { - tree parm_decl = this->make_receiver_parm_decl(gogo, *p, *pp); - tree var = *pp; - if (var != error_mark_node) - { - go_assert(TREE_CODE(var) == VAR_DECL); - DECL_CHAIN(var) = declare_vars; - declare_vars = var; - } - *pp = parm_decl; - } - else if ((*p)->var_value()->is_in_heap()) - { - // If we take the address of a parameter, then we need - // to copy it into the heap. - tree parm_decl = this->copy_parm_to_heap(gogo, *p, *pp); - tree var = *pp; - if (var != error_mark_node) - { - go_assert(TREE_CODE(var) == VAR_DECL); - DECL_CHAIN(var) = declare_vars; - declare_vars = var; - } - *pp = parm_decl; - } - - if (*pp != error_mark_node) - { - go_assert(TREE_CODE(*pp) == PARM_DECL); - pp = &DECL_CHAIN(*pp); - } - } - else if ((*p)->is_result_variable()) - { - Bvariable* bvar = (*p)->get_backend_variable(gogo, named_function); - tree var_decl = var_to_tree(bvar); - - Type* type = (*p)->result_var_value()->type(); - tree init; - if (!(*p)->result_var_value()->is_in_heap()) - { - Btype* btype = type->get_backend(gogo); - init = expr_to_tree(gogo->backend()->zero_expression(btype)); - } - else - { - Location loc = (*p)->location(); - tree type_tree = type_to_tree(type->get_backend(gogo)); - tree space = gogo->allocate_memory(type, - TYPE_SIZE_UNIT(type_tree), - loc); - tree ptr_type_tree = build_pointer_type(type_tree); - init = fold_convert_loc(loc.gcc_location(), ptr_type_tree, space); - } - - if (var_decl != error_mark_node) - { - go_assert(TREE_CODE(var_decl) == VAR_DECL); - DECL_INITIAL(var_decl) = init; - DECL_CHAIN(var_decl) = declare_vars; - declare_vars = var_decl; - } - } - } - - *pp = NULL_TREE; - - DECL_ARGUMENTS(fndecl) = params; - - // If we need a closure variable, fetch it by calling a runtime - // function. The caller will have called __go_set_closure before - // the function call. - if (this->closure_var_ != NULL) - { - Bvariable* bvar = - this->closure_var_->get_backend_variable(gogo, named_function); - tree var_decl = var_to_tree(bvar); - if (var_decl != error_mark_node) - { - go_assert(TREE_CODE(var_decl) == VAR_DECL); - static tree get_closure_fndecl; - tree get_closure = Gogo::call_builtin(&get_closure_fndecl, - this->location_, - "__go_get_closure", - 0, - ptr_type_node); - - // Mark the __go_get_closure function as pure, since it - // depends only on the global variable g. - DECL_PURE_P(get_closure_fndecl) = 1; - - get_closure = fold_convert_loc(this->location_.gcc_location(), - TREE_TYPE(var_decl), get_closure); - DECL_INITIAL(var_decl) = get_closure; - DECL_CHAIN(var_decl) = declare_vars; - declare_vars = var_decl; - } - } - - if (this->block_ != NULL) - { - go_assert(DECL_INITIAL(fndecl) == NULL_TREE); - - // Declare variables if necessary. - tree bind = NULL_TREE; - tree defer_init = NULL_TREE; - if (declare_vars != NULL_TREE || this->defer_stack_ != NULL) - { - tree block = make_node(BLOCK); - BLOCK_SUPERCONTEXT(block) = fndecl; - DECL_INITIAL(fndecl) = block; - BLOCK_VARS(block) = declare_vars; - TREE_USED(block) = 1; - - bind = build3(BIND_EXPR, void_type_node, BLOCK_VARS(block), - NULL_TREE, block); - TREE_SIDE_EFFECTS(bind) = 1; - - if (this->defer_stack_ != NULL) - { - Translate_context dcontext(gogo, named_function, this->block_, - tree_to_block(bind)); - Bstatement* bdi = this->defer_stack_->get_backend(&dcontext); - defer_init = stat_to_tree(bdi); - } - } - - // Build the trees for all the statements in the function. - Translate_context context(gogo, named_function, NULL, NULL); - Bblock* bblock = this->block_->get_backend(&context); - tree code = block_to_tree(bblock); - - tree init = NULL_TREE; - tree except = NULL_TREE; - tree fini = NULL_TREE; - - // Initialize variables if necessary. - for (tree v = declare_vars; v != NULL_TREE; v = DECL_CHAIN(v)) - { - tree dv = build1(DECL_EXPR, void_type_node, v); - SET_EXPR_LOCATION(dv, DECL_SOURCE_LOCATION(v)); - append_to_statement_list(dv, &init); - } - - // If we have a defer stack, initialize it at the start of a - // function. - if (defer_init != NULL_TREE && defer_init != error_mark_node) - { - SET_EXPR_LOCATION(defer_init, - this->block_->start_location().gcc_location()); - append_to_statement_list(defer_init, &init); - - // Clean up the defer stack when we leave the function. - this->build_defer_wrapper(gogo, named_function, &except, &fini); - } - - if (code != NULL_TREE && code != error_mark_node) - { - if (init != NULL_TREE) - code = build2(COMPOUND_EXPR, void_type_node, init, code); - if (except != NULL_TREE) - code = build2(TRY_CATCH_EXPR, void_type_node, code, - build2(CATCH_EXPR, void_type_node, NULL, except)); - if (fini != NULL_TREE) - code = build2(TRY_FINALLY_EXPR, void_type_node, code, fini); - } - - // Stick the code into the block we built for the receiver, if - // we built on. - if (bind != NULL_TREE && code != NULL_TREE && code != error_mark_node) - { - BIND_EXPR_BODY(bind) = code; - code = bind; - } - - DECL_SAVED_TREE(fndecl) = code; - } - - // If we created a descriptor for the function, make sure we emit it. - if (this->descriptor_ != NULL) - { - Translate_context context(gogo, NULL, NULL, NULL); - this->descriptor_->get_tree(&context); - } -} - -// Build the wrappers around function code needed if the function has -// any defer statements. This sets *EXCEPT to an exception handler -// and *FINI to a finally handler. - -void -Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function, - tree *except, tree *fini) -{ - Location end_loc = this->block_->end_location(); - - // Add an exception handler. This is used if a panic occurs. Its - // purpose is to stop the stack unwinding if a deferred function - // calls recover. There are more details in - // libgo/runtime/go-unwind.c. - - tree stmt_list = NULL_TREE; - - Expression* call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1, - this->defer_stack(end_loc)); - Translate_context context(gogo, named_function, NULL, NULL); - tree call_tree = call->get_tree(&context); - if (call_tree != error_mark_node) - append_to_statement_list(call_tree, &stmt_list); - - tree retval = this->return_value(gogo, named_function, end_loc, &stmt_list); - tree set; - if (retval == NULL_TREE) - set = NULL_TREE; - else - set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node, - DECL_RESULT(this->get_decl()), retval); - tree ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR, - void_type_node, set); - append_to_statement_list(ret_stmt, &stmt_list); - - go_assert(*except == NULL_TREE); - *except = stmt_list; - - // Add some finally code to run the defer functions. This is used - // both in the normal case, when no panic occurs, and also if a - // panic occurs to run any further defer functions. Of course, it - // is possible for a defer function to call panic which should be - // caught by another defer function. To handle that we use a loop. - // finish: - // try { __go_undefer(); } catch { __go_check_defer(); goto finish; } - // if (return values are named) return named_vals; - - stmt_list = NULL; - - tree label = create_artificial_label(end_loc.gcc_location()); - tree define_label = fold_build1_loc(end_loc.gcc_location(), LABEL_EXPR, - void_type_node, label); - append_to_statement_list(define_label, &stmt_list); - - call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1, - this->defer_stack(end_loc)); - tree undefer = call->get_tree(&context); - - call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1, - this->defer_stack(end_loc)); - tree defer = call->get_tree(&context); - - if (undefer == error_mark_node || defer == error_mark_node) - return; - - tree jump = fold_build1_loc(end_loc.gcc_location(), GOTO_EXPR, void_type_node, - label); - tree catch_body = build2(COMPOUND_EXPR, void_type_node, defer, jump); - catch_body = build2(CATCH_EXPR, void_type_node, NULL, catch_body); - tree try_catch = build2(TRY_CATCH_EXPR, void_type_node, undefer, catch_body); - - append_to_statement_list(try_catch, &stmt_list); - - if (this->type_->results() != NULL - && !this->type_->results()->empty() - && !this->type_->results()->front().name().empty()) - { - // If the result variables are named, and we are returning from - // this function rather than panicing through it, we need to - // return them again, because they might have been changed by a - // defer function. The runtime routines set the defer_stack - // variable to true if we are returning from this function. - retval = this->return_value(gogo, named_function, end_loc, - &stmt_list); - set = fold_build2_loc(end_loc.gcc_location(), MODIFY_EXPR, void_type_node, - DECL_RESULT(this->get_decl()), retval); - ret_stmt = fold_build1_loc(end_loc.gcc_location(), RETURN_EXPR, - void_type_node, set); - - Expression* ref = - Expression::make_temporary_reference(this->defer_stack_, end_loc); - tree tref = ref->get_tree(&context); - tree s = build3_loc(end_loc.gcc_location(), COND_EXPR, void_type_node, - tref, ret_stmt, NULL_TREE); - - append_to_statement_list(s, &stmt_list); - - } - - go_assert(*fini == NULL_TREE); - *fini = stmt_list; -} - -// Return the value to assign to DECL_RESULT(this->get_decl()). This may -// also add statements to STMT_LIST, which need to be executed before -// the assignment. This is used for a return statement with no -// explicit values. - -tree -Function::return_value(Gogo* gogo, Named_object* named_function, - Location location, tree* stmt_list) const -{ - const Typed_identifier_list* results = this->type_->results(); - if (results == NULL || results->empty()) - return NULL_TREE; - - go_assert(this->results_ != NULL); - if (this->results_->size() != results->size()) - { - go_assert(saw_errors()); - return error_mark_node; - } - - tree retval; - if (results->size() == 1) - { - Bvariable* bvar = - this->results_->front()->get_backend_variable(gogo, - named_function); - tree ret = var_to_tree(bvar); - if (this->results_->front()->result_var_value()->is_in_heap()) - ret = build_fold_indirect_ref_loc(location.gcc_location(), ret); - return ret; - } - else - { - tree rettype = TREE_TYPE(DECL_RESULT(this->get_decl())); - retval = create_tmp_var(rettype, "RESULT"); - tree field = TYPE_FIELDS(rettype); - int index = 0; - for (Typed_identifier_list::const_iterator pr = results->begin(); - pr != results->end(); - ++pr, ++index, field = DECL_CHAIN(field)) - { - go_assert(field != NULL); - Named_object* no = (*this->results_)[index]; - Bvariable* bvar = no->get_backend_variable(gogo, named_function); - tree val = var_to_tree(bvar); - if (no->result_var_value()->is_in_heap()) - val = build_fold_indirect_ref_loc(location.gcc_location(), val); - tree set = fold_build2_loc(location.gcc_location(), MODIFY_EXPR, - void_type_node, - build3(COMPONENT_REF, TREE_TYPE(field), - retval, field, NULL_TREE), - val); - append_to_statement_list(set, stmt_list); - } - return retval; - } -} - // Build the descriptor for a function declaration. This won't // necessarily happen if the package has just a declaration for the // function and no other reference to it, but we may still need the @@ -1834,38 +1301,6 @@ go_type_for_mode(enum machine_mode mode, int unsignedp) return NULL_TREE; } -// Return a tree which allocates SIZE bytes which will holds value of -// type TYPE. - -tree -Gogo::allocate_memory(Type* type, tree size, Location location) -{ - // If the package imports unsafe, then it may play games with - // pointers that look like integers. - if (this->imported_unsafe_ || type->has_pointer()) - { - static tree new_fndecl; - return Gogo::call_builtin(&new_fndecl, - location, - "__go_new", - 1, - ptr_type_node, - sizetype, - size); - } - else - { - static tree new_nopointers_fndecl; - return Gogo::call_builtin(&new_nopointers_fndecl, - location, - "__go_new_nopointers", - 1, - ptr_type_node, - sizetype, - size); - } -} - // Build a builtin struct with a list of fields. The name is // STRUCT_NAME. STRUCT_TYPE is NULL_TREE or an empty RECORD_TYPE // node; this exists so that the struct can have fields which point to @@ -1915,94 +1350,6 @@ Gogo::builtin_struct(tree* ptype, const char* struct_name, tree struct_type, return struct_type; } -// Return a type to use for pointer to const char for a string. - -tree -Gogo::const_char_pointer_type_tree() -{ - static tree type; - if (type == NULL_TREE) - { - tree const_char_type = build_qualified_type(unsigned_char_type_node, - TYPE_QUAL_CONST); - type = build_pointer_type(const_char_type); - go_preserve_from_gc(type); - } - return type; -} - -// Return a tree for a string constant. - -tree -Gogo::string_constant_tree(const std::string& val) -{ - tree index_type = build_index_type(size_int(val.length())); - tree const_char_type = build_qualified_type(unsigned_char_type_node, - TYPE_QUAL_CONST); - tree string_type = build_array_type(const_char_type, index_type); - string_type = build_variant_type_copy(string_type); - TYPE_STRING_FLAG(string_type) = 1; - tree string_val = build_string(val.length(), val.data()); - TREE_TYPE(string_val) = string_type; - return string_val; -} - -// Return a tree for a Go string constant. - -tree -Gogo::go_string_constant_tree(const std::string& val) -{ - tree string_type = type_to_tree(Type::make_string_type()->get_backend(this)); - - vec<constructor_elt, va_gc> *init; - vec_alloc(init, 2); - - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = init->quick_push(empty); - tree field = TYPE_FIELDS(string_type); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__data") == 0); - elt->index = field; - tree str = Gogo::string_constant_tree(val); - elt->value = fold_convert(TREE_TYPE(field), - build_fold_addr_expr(str)); - - elt = init->quick_push(empty); - field = DECL_CHAIN(field); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__length") == 0); - elt->index = field; - elt->value = build_int_cst_type(TREE_TYPE(field), val.length()); - - tree constructor = build_constructor(string_type, init); - TREE_READONLY(constructor) = 1; - TREE_CONSTANT(constructor) = 1; - - return constructor; -} - -// Return a tree for a pointer to a Go string constant. This is only -// used for type descriptors, so we return a pointer to a constant -// decl. - -tree -Gogo::ptr_go_string_constant_tree(const std::string& val) -{ - tree pval = this->go_string_constant_tree(val); - - tree decl = build_decl(UNKNOWN_LOCATION, VAR_DECL, - create_tmp_var_name("SP"), TREE_TYPE(pval)); - DECL_EXTERNAL(decl) = 0; - TREE_PUBLIC(decl) = 0; - TREE_USED(decl) = 1; - TREE_READONLY(decl) = 1; - TREE_CONSTANT(decl) = 1; - TREE_STATIC(decl) = 1; - DECL_ARTIFICIAL(decl) = 1; - DECL_INITIAL(decl) = pval; - rest_of_decl_compilation(decl, 1, 0); - - return build_fold_addr_expr(decl); -} - // Build a constructor for a slice. SLICE_TYPE_TREE is the type of // the slice. VALUES is the value pointer and COUNT is the number of // entries. If CAPACITY is not NULL, it is the capacity; otherwise @@ -2048,136 +1395,6 @@ Gogo::slice_constructor(tree slice_type_tree, tree values, tree count, return build_constructor(slice_type_tree, init); } -// Build an interface method table for a type: a list of function -// pointers, one for each interface method. This is used for -// interfaces. - -tree -Gogo::interface_method_table_for_type(const Interface_type* interface, - Type* type, bool is_pointer) -{ - const Typed_identifier_list* interface_methods = interface->methods(); - go_assert(!interface_methods->empty()); - - std::string mangled_name = ((is_pointer ? "__go_pimt__" : "__go_imt_") - + interface->mangled_name(this) - + "__" - + type->mangled_name(this)); - - tree id = get_identifier_from_string(mangled_name); - - // See whether this interface has any hidden methods. - bool has_hidden_methods = false; - for (Typed_identifier_list::const_iterator p = interface_methods->begin(); - p != interface_methods->end(); - ++p) - { - if (Gogo::is_hidden_name(p->name())) - { - has_hidden_methods = true; - break; - } - } - - // We already know that the named type is convertible to the - // interface. If the interface has hidden methods, and the named - // type is defined in a different package, then the interface - // conversion table will be defined by that other package. - if (has_hidden_methods - && type->named_type() != NULL - && type->named_type()->named_object()->package() != NULL) - { - tree array_type = build_array_type(const_ptr_type_node, NULL); - tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL, id, array_type); - TREE_READONLY(decl) = 1; - TREE_CONSTANT(decl) = 1; - TREE_PUBLIC(decl) = 1; - DECL_EXTERNAL(decl) = 1; - go_preserve_from_gc(decl); - return decl; - } - - size_t count = interface_methods->size(); - vec<constructor_elt, va_gc> *pointers; - vec_alloc(pointers, count + 1); - - // The first element is the type descriptor. - constructor_elt empty = {NULL, NULL}; - constructor_elt* elt = pointers->quick_push(empty); - elt->index = size_zero_node; - Type* td_type; - if (!is_pointer) - td_type = type; - else - td_type = Type::make_pointer_type(type); - - Location loc = Linemap::predeclared_location(); - Bexpression* tdp_bexpr = td_type->type_descriptor_pointer(this, loc); - tree tdp = expr_to_tree(tdp_bexpr); - elt->value = fold_convert(const_ptr_type_node, tdp); - - Named_type* nt = type->named_type(); - Struct_type* st = type->struct_type(); - go_assert(nt != NULL || st != NULL); - size_t i = 1; - for (Typed_identifier_list::const_iterator p = interface_methods->begin(); - p != interface_methods->end(); - ++p, ++i) - { - bool is_ambiguous; - Method* m; - if (nt != NULL) - m = nt->method_function(p->name(), &is_ambiguous); - else - m = st->method_function(p->name(), &is_ambiguous); - go_assert(m != NULL); - - Named_object* no = m->named_object(); - Bfunction* bf; - if (no->is_function()) - bf = no->func_value()->get_or_make_decl(this, no); - else if (no->is_function_declaration()) - bf = no->func_declaration_value()->get_or_make_decl(this, no); - else - go_unreachable(); - tree fndecl = build_fold_addr_expr(function_to_tree(bf)); - - elt = pointers->quick_push(empty); - elt->index = size_int(i); - elt->value = fold_convert(const_ptr_type_node, fndecl); - } - go_assert(i == count + 1); - - tree array_type = build_array_type(const_ptr_type_node, - build_index_type(size_int(count))); - tree constructor = build_constructor(array_type, pointers); - - tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL, id, array_type); - TREE_STATIC(decl) = 1; - TREE_USED(decl) = 1; - TREE_READONLY(decl) = 1; - TREE_CONSTANT(decl) = 1; - DECL_INITIAL(decl) = constructor; - - // If the interface type has hidden methods, and the table is for a - // named type, then this is the only definition of the table. - // Otherwise it is a comdat table which may be defined in multiple - // packages. - if (has_hidden_methods && type->named_type() != NULL) - TREE_PUBLIC(decl) = 1; - else - { - make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl)); - resolve_unique_section(decl, 1, 0); - } - - rest_of_decl_compilation(decl, 1, 0); - - go_preserve_from_gc(decl); - - return decl; -} - // Mark a function as a builtin library function. void @@ -2250,70 +1467,3 @@ Gogo::call_builtin(tree* pdecl, Location location, const char* name, return ret; } - -// Return a tree for receiving a value of type TYPE_TREE on CHANNEL. -// TYPE_DESCRIPTOR_TREE is the channel's type descriptor. This does a -// blocking receive and returns the value read from the channel. - -tree -Gogo::receive_from_channel(tree type_tree, tree type_descriptor_tree, - tree channel, Location location) -{ - if (type_tree == error_mark_node || channel == error_mark_node) - return error_mark_node; - - if (int_size_in_bytes(type_tree) <= 8 - && !AGGREGATE_TYPE_P(type_tree) - && !FLOAT_TYPE_P(type_tree)) - { - static tree receive_small_fndecl; - tree call = Gogo::call_builtin(&receive_small_fndecl, - location, - "__go_receive_small", - 2, - uint64_type_node, - TREE_TYPE(type_descriptor_tree), - type_descriptor_tree, - ptr_type_node, - channel); - if (call == error_mark_node) - return error_mark_node; - // This can panic if there are too many operations on a closed - // channel. - TREE_NOTHROW(receive_small_fndecl) = 0; - int bitsize = GET_MODE_BITSIZE(TYPE_MODE(type_tree)); - tree int_type_tree = go_type_for_size(bitsize, 1); - return fold_convert_loc(location.gcc_location(), type_tree, - fold_convert_loc(location.gcc_location(), - int_type_tree, call)); - } - else - { - tree tmp = create_tmp_var(type_tree, get_name(type_tree)); - DECL_IGNORED_P(tmp) = 0; - TREE_ADDRESSABLE(tmp) = 1; - tree make_tmp = build1(DECL_EXPR, void_type_node, tmp); - SET_EXPR_LOCATION(make_tmp, location.gcc_location()); - tree tmpaddr = build_fold_addr_expr(tmp); - tmpaddr = fold_convert(ptr_type_node, tmpaddr); - static tree receive_big_fndecl; - tree call = Gogo::call_builtin(&receive_big_fndecl, - location, - "__go_receive_big", - 3, - void_type_node, - TREE_TYPE(type_descriptor_tree), - type_descriptor_tree, - ptr_type_node, - channel, - ptr_type_node, - tmpaddr); - if (call == error_mark_node) - return error_mark_node; - // This can panic if there are too many operations on a closed - // channel. - TREE_NOTHROW(receive_big_fndecl) = 0; - return build2(COMPOUND_EXPR, type_tree, make_tmp, - build2(COMPOUND_EXPR, type_tree, call, tmp)); - } -} diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 9739f289f4d..6df4b6bf325 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -1005,6 +1005,10 @@ Label* Gogo::add_label_definition(const std::string& label_name, Location location) { + // A label with a blank identifier is never declared or defined. + if (label_name == "_") + return NULL; + go_assert(!this->functions_.empty()); Function* func = this->functions_.back().function->func_value(); Label* label = func->add_label_definition(this, label_name, location); @@ -3330,6 +3334,7 @@ Build_method_tables::type(Type* type) Struct_type* st = type->struct_type(); if (nt != NULL || st != NULL) { + Translate_context context(this->gogo_, NULL, NULL, NULL); for (std::vector<Interface_type*>::const_iterator p = this->interfaces_.begin(); p != this->interfaces_.end(); @@ -3343,8 +3348,8 @@ Build_method_tables::type(Type* type) if ((*p)->implements_interface(Type::make_pointer_type(nt), NULL)) { - nt->interface_method_table(this->gogo_, *p, false); - nt->interface_method_table(this->gogo_, *p, true); + nt->interface_method_table(*p, false)->get_tree(&context); + nt->interface_method_table(*p, true)->get_tree(&context); } } else @@ -3352,8 +3357,8 @@ Build_method_tables::type(Type* type) if ((*p)->implements_interface(Type::make_pointer_type(st), NULL)) { - st->interface_method_table(this->gogo_, *p, false); - st->interface_method_table(this->gogo_, *p, true); + st->interface_method_table(*p, false)->get_tree(&context); + st->interface_method_table(*p, true)->get_tree(&context); } } } @@ -3361,6 +3366,28 @@ Build_method_tables::type(Type* type) return TRAVERSE_CONTINUE; } +// Return an expression which allocates memory to hold values of type TYPE. + +Expression* +Gogo::allocate_memory(Type* type, Location location) +{ + Btype* btype = type->get_backend(this); + size_t size = this->backend()->type_size(btype); + mpz_t size_val; + mpz_init_set_ui(size_val, size); + Type* uintptr = Type::lookup_integer_type("uintptr"); + Expression* size_expr = + Expression::make_integer(&size_val, uintptr, location); + + // If the package imports unsafe, then it may play games with + // pointers that look like integers. + bool use_new_pointers = this->imported_unsafe_ || type->has_pointer(); + return Runtime::make_call((use_new_pointers + ? Runtime::NEW + : Runtime::NEW_NOPOINTERS), + location, 1, size_expr); +} + // Traversal class used to check for return statements. class Check_return_statements_traverse : public Traverse @@ -4111,6 +4138,293 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) return this->fndecl_; } +// Build the backend representation for the function code. + +void +Function::build(Gogo* gogo, Named_object* named_function) +{ + Translate_context context(gogo, named_function, NULL, NULL); + + // A list of parameter variables for this function. + std::vector<Bvariable*> param_vars; + + // Variables that need to be declared for this function and their + // initial values. + std::vector<Bvariable*> vars; + std::vector<Bexpression*> var_inits; + for (Bindings::const_definitions_iterator p = + this->block_->bindings()->begin_definitions(); + p != this->block_->bindings()->end_definitions(); + ++p) + { + Location loc = (*p)->location(); + if ((*p)->is_variable() && (*p)->var_value()->is_parameter()) + { + Bvariable* bvar = (*p)->get_backend_variable(gogo, named_function); + Bvariable* parm_bvar = bvar; + + // We always pass the receiver to a method as a pointer. If + // the receiver is declared as a non-pointer type, then we + // copy the value into a local variable. + if ((*p)->var_value()->is_receiver() + && (*p)->var_value()->type()->points_to() == NULL) + { + std::string name = (*p)->name() + ".pointer"; + Type* var_type = (*p)->var_value()->type(); + Variable* parm_var = + new Variable(Type::make_pointer_type(var_type), NULL, false, + true, false, loc); + Named_object* parm_no = + Named_object::make_variable(name, NULL, parm_var); + parm_bvar = parm_no->get_backend_variable(gogo, named_function); + + vars.push_back(bvar); + Expression* parm_ref = + Expression::make_var_reference(parm_no, loc); + parm_ref = Expression::make_unary(OPERATOR_MULT, parm_ref, loc); + if ((*p)->var_value()->is_in_heap()) + parm_ref = Expression::make_heap_expression(parm_ref, loc); + var_inits.push_back(tree_to_expr(parm_ref->get_tree(&context))); + } + else if ((*p)->var_value()->is_in_heap()) + { + // If we take the address of a parameter, then we need + // to copy it into the heap. + std::string parm_name = (*p)->name() + ".param"; + Variable* parm_var = new Variable((*p)->var_value()->type(), NULL, + false, true, false, loc); + Named_object* parm_no = + Named_object::make_variable(parm_name, NULL, parm_var); + parm_bvar = parm_no->get_backend_variable(gogo, named_function); + + vars.push_back(bvar); + Expression* var_ref = + Expression::make_var_reference(parm_no, loc); + var_ref = Expression::make_heap_expression(var_ref, loc); + var_inits.push_back(tree_to_expr(var_ref->get_tree(&context))); + } + param_vars.push_back(parm_bvar); + } + else if ((*p)->is_result_variable()) + { + Bvariable* bvar = (*p)->get_backend_variable(gogo, named_function); + + Type* type = (*p)->result_var_value()->type(); + Bexpression* init; + if (!(*p)->result_var_value()->is_in_heap()) + { + Btype* btype = type->get_backend(gogo); + init = gogo->backend()->zero_expression(btype); + } + else + { + Expression* alloc = Expression::make_allocation(type, loc); + init = tree_to_expr(alloc->get_tree(&context)); + } + + vars.push_back(bvar); + var_inits.push_back(init); + } + } + if (!gogo->backend()->function_set_parameters(this->fndecl_, param_vars)) + { + go_assert(saw_errors()); + return; + } + + // If we need a closure variable, fetch it by calling a runtime + // function. The caller will have called __go_set_closure before + // the function call. + if (this->closure_var_ != NULL) + { + Bvariable* closure_bvar = + this->closure_var_->get_backend_variable(gogo, named_function); + vars.push_back(closure_bvar); + + Expression* closure = + Runtime::make_call(Runtime::GET_CLOSURE, this->location_, 0); + var_inits.push_back(tree_to_expr(closure->get_tree(&context))); + } + + if (this->block_ != NULL) + { + // Declare variables if necessary. + Bblock* var_decls = NULL; + + Bstatement* defer_init = NULL; + if (!vars.empty() || this->defer_stack_ != NULL) + { + var_decls = + gogo->backend()->block(this->fndecl_, NULL, vars, + this->block_->start_location(), + this->block_->end_location()); + + if (this->defer_stack_ != NULL) + { + Translate_context dcontext(gogo, named_function, this->block_, + var_decls); + defer_init = this->defer_stack_->get_backend(&dcontext); + } + } + + // Build the backend representation for all the statements in the + // function. + Translate_context context(gogo, named_function, NULL, NULL); + Bblock* code_block = this->block_->get_backend(&context); + + // Initialize variables if necessary. + std::vector<Bstatement*> init; + go_assert(vars.size() == var_inits.size()); + for (size_t i = 0; i < vars.size(); ++i) + { + Bstatement* init_stmt = + gogo->backend()->init_statement(vars[i], var_inits[i]); + init.push_back(init_stmt); + } + Bstatement* var_init = gogo->backend()->statement_list(init); + + // Initialize all variables before executing this code block. + Bstatement* code_stmt = gogo->backend()->block_statement(code_block); + code_stmt = gogo->backend()->compound_statement(var_init, code_stmt); + + // If we have a defer stack, initialize it at the start of a + // function. + Bstatement* except = NULL; + Bstatement* fini = NULL; + if (defer_init != NULL) + { + // Clean up the defer stack when we leave the function. + this->build_defer_wrapper(gogo, named_function, &except, &fini); + + // Wrap the code for this function in an exception handler to handle + // defer calls. + code_stmt = + gogo->backend()->exception_handler_statement(code_stmt, + except, fini, + this->location_); + } + + // Stick the code into the block we built for the receiver, if + // we built one. + if (var_decls != NULL) + { + std::vector<Bstatement*> code_stmt_list(1, code_stmt); + gogo->backend()->block_add_statements(var_decls, code_stmt_list); + code_stmt = gogo->backend()->block_statement(var_decls); + } + + if (!gogo->backend()->function_set_body(this->fndecl_, code_stmt)) + { + go_assert(saw_errors()); + return; + } + } + + // If we created a descriptor for the function, make sure we emit it. + if (this->descriptor_ != NULL) + { + Translate_context context(gogo, NULL, NULL, NULL); + this->descriptor_->get_tree(&context); + } +} + +// Build the wrappers around function code needed if the function has +// any defer statements. This sets *EXCEPT to an exception handler +// and *FINI to a finally handler. + +void +Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function, + Bstatement** except, Bstatement** fini) +{ + Location end_loc = this->block_->end_location(); + + // Add an exception handler. This is used if a panic occurs. Its + // purpose is to stop the stack unwinding if a deferred function + // calls recover. There are more details in + // libgo/runtime/go-unwind.c. + + std::vector<Bstatement*> stmts; + Expression* call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1, + this->defer_stack(end_loc)); + Translate_context context(gogo, named_function, NULL, NULL); + Bexpression* defer = tree_to_expr(call->get_tree(&context)); + stmts.push_back(gogo->backend()->expression_statement(defer)); + + Bstatement* ret_bstmt = this->return_value(gogo, named_function, end_loc); + if (ret_bstmt != NULL) + stmts.push_back(ret_bstmt); + + go_assert(*except == NULL); + *except = gogo->backend()->statement_list(stmts); + + call = Runtime::make_call(Runtime::CHECK_DEFER, end_loc, 1, + this->defer_stack(end_loc)); + defer = tree_to_expr(call->get_tree(&context)); + + call = Runtime::make_call(Runtime::UNDEFER, end_loc, 1, + this->defer_stack(end_loc)); + Bexpression* undefer = tree_to_expr(call->get_tree(&context)); + Bstatement* function_defer = + gogo->backend()->function_defer_statement(this->fndecl_, undefer, defer, + end_loc); + stmts = std::vector<Bstatement*>(1, function_defer); + if (this->type_->results() != NULL + && !this->type_->results()->empty() + && !this->type_->results()->front().name().empty()) + { + // If the result variables are named, and we are returning from + // this function rather than panicing through it, we need to + // return them again, because they might have been changed by a + // defer function. The runtime routines set the defer_stack + // variable to true if we are returning from this function. + + ret_bstmt = this->return_value(gogo, named_function, end_loc); + Bexpression* nil = + tree_to_expr(Expression::make_nil(end_loc)->get_tree(&context)); + Bexpression* ret = + gogo->backend()->compound_expression(ret_bstmt, nil, end_loc); + Expression* ref = + Expression::make_temporary_reference(this->defer_stack_, end_loc); + Bexpression* bref = tree_to_expr(ref->get_tree(&context)); + ret = gogo->backend()->conditional_expression(NULL, bref, ret, NULL, + end_loc); + stmts.push_back(gogo->backend()->expression_statement(ret)); + } + + go_assert(*fini == NULL); + *fini = gogo->backend()->statement_list(stmts); +} + +// Return the statement that assigns values to this function's result struct. + +Bstatement* +Function::return_value(Gogo* gogo, Named_object* named_function, + Location location) const +{ + const Typed_identifier_list* results = this->type_->results(); + if (results == NULL || results->empty()) + return NULL; + + go_assert(this->results_ != NULL); + if (this->results_->size() != results->size()) + { + go_assert(saw_errors()); + return gogo->backend()->error_statement(); + } + + std::vector<Bexpression*> vals(results->size()); + for (size_t i = 0; i < vals.size(); ++i) + { + Named_object* no = (*this->results_)[i]; + Bvariable* bvar = no->get_backend_variable(gogo, named_function); + Bexpression* val = gogo->backend()->var_expression(bvar, location); + if (no->result_var_value()->is_in_heap()) + val = gogo->backend()->indirect_expression(val, true, location); + vals[i] = val; + } + return gogo->backend()->return_statement(this->fndecl_, vals, location); +} + // Class Block. Block::Block(Block* enclosing, Location location) @@ -4857,6 +5171,74 @@ Variable::determine_type() } } +// Get the initial value of a variable. This does not +// consider whether the variable is in the heap--it returns the +// initial value as though it were always stored in the stack. + +Bexpression* +Variable::get_init(Gogo* gogo, Named_object* function) +{ + go_assert(this->preinit_ == NULL); + Location loc = this->location(); + if (this->init_ == NULL) + { + go_assert(!this->is_parameter_); + if (this->is_global_ || this->is_in_heap()) + return NULL; + Btype* btype = this->type()->get_backend(gogo); + return gogo->backend()->zero_expression(btype); + } + else + { + Translate_context context(gogo, function, NULL, NULL); + Expression* init = Expression::make_cast(this->type(), this->init_, loc); + return tree_to_expr(init->get_tree(&context)); + } +} + +// Get the initial value of a variable when a block is required. +// VAR_DECL is the decl to set; it may be NULL for a sink variable. + +Bstatement* +Variable::get_init_block(Gogo* gogo, Named_object* function, + Bvariable* var_decl) +{ + go_assert(this->preinit_ != NULL); + + // We want to add the variable assignment to the end of the preinit + // block. + + Translate_context context(gogo, function, NULL, NULL); + Bblock* bblock = this->preinit_->get_backend(&context); + + // It's possible to have pre-init statements without an initializer + // if the pre-init statements set the variable. + Bstatement* decl_init = NULL; + if (this->init_ != NULL) + { + if (var_decl == NULL) + { + Bexpression* init_bexpr = + tree_to_expr(this->init_->get_tree(&context)); + decl_init = gogo->backend()->expression_statement(init_bexpr); + } + else + { + Location loc = this->location(); + Expression* val_expr = + Expression::convert_for_assignment(gogo, this->type(), + this->init_, this->location()); + Bexpression* val = tree_to_expr(val_expr->get_tree(&context)); + Bexpression* var_ref = gogo->backend()->var_expression(var_decl, loc); + decl_init = gogo->backend()->assignment_statement(var_ref, val, loc); + } + } + Bstatement* block_stmt = gogo->backend()->block_statement(bblock); + if (decl_init != NULL) + block_stmt = gogo->backend()->compound_statement(block_stmt, decl_init); + return block_stmt; +} + // Export the variable void diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 3f2808781b7..3dc401d6955 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -612,34 +612,9 @@ class Gogo void build_interface_method_tables(); - // Build an interface method table for a type: a list of function - // pointers, one for each interface method. This returns a decl. - tree - interface_method_table_for_type(const Interface_type*, Type*, - bool is_pointer); - - // Return a tree which allocate SIZE bytes to hold values of type - // TYPE. - tree - allocate_memory(Type *type, tree size, Location); - - // Return a type to use for pointer to const char. - static tree - const_char_pointer_type_tree(); - - // Build a string constant with the right type. - static tree - string_constant_tree(const std::string&); - - // Build a Go string constant. This returns a pointer to the - // constant. - tree - go_string_constant_tree(const std::string&); - - // Receive a value from a channel. - static tree - receive_from_channel(tree type_tree, tree type_descriptor_tree, tree channel, - Location); + // Return an expression which allocates memory to hold values of type TYPE. + Expression* + allocate_memory(Type *type, Location); private: // During parsing, we keep a stack of functions. Each function on @@ -687,11 +662,6 @@ class Gogo void register_gc_vars(const std::vector<Named_object*>&, tree*); - // Build a pointer to a Go string constant. This returns a pointer - // to the pointer. - tree - ptr_go_string_constant_tree(const std::string&); - // Type used to map import names to packages. typedef std::map<std::string, Package*> Imports; @@ -1119,14 +1089,14 @@ class Function tree get_decl() const; - // Set the function decl to hold a tree of the function code. + // Set the function decl to hold a backend representation of the function + // code. void - build_tree(Gogo*, Named_object*); + build(Gogo*, Named_object*); - // Get the value to return when not explicitly specified. May also - // add statements to execute first to STMT_LIST. - tree - return_value(Gogo*, Named_object*, Location, tree* stmt_list) const; + // Get the statement that assigns values to this function's result struct. + Bstatement* + return_value(Gogo*, Named_object*, Location) const; // Get a tree for the variable holding the defer stack. Expression* @@ -1151,14 +1121,8 @@ class Function // Type for mapping from label names to Label objects. typedef Unordered_map(std::string, Label*) Labels; - tree - make_receiver_parm_decl(Gogo*, Named_object*, tree); - - tree - copy_parm_to_heap(Gogo*, Named_object*, tree); - void - build_defer_wrapper(Gogo*, Named_object*, tree*, tree*); + build_defer_wrapper(Gogo*, Named_object*, Bstatement**, Bstatement**); typedef std::vector<std::pair<Named_object*, Location> > Closure_fields; @@ -1531,16 +1495,16 @@ class Variable get_backend_variable(Gogo*, Named_object*, const Package*, const std::string&); - // Get the initial value of the variable as a tree. This may only + // Get the initial value of the variable. This may only // be called if has_pre_init() returns false. - tree - get_init_tree(Gogo*, Named_object* function); + Bexpression* + get_init(Gogo*, Named_object* function); // Return a series of statements which sets the value of the // variable in DECL. This should only be called is has_pre_init() // returns true. DECL may be NULL for a sink variable. - tree - get_init_block(Gogo*, Named_object* function, tree decl); + Bstatement* + get_init_block(Gogo*, Named_object* function, Bvariable* decl); // Export the variable. void diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 7614e6fc795..3d60171dde2 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -2955,7 +2955,7 @@ Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars, Struct_type* st = closure_var->var_value()->type()->deref()->struct_type(); Expression* cv = Expression::make_struct_composite_literal(st, initializer, location); - return Expression::make_heap_composite(cv, location); + return Expression::make_heap_expression(cv, location); } // PrimaryExpr = Operand { Selector | Index | Slice | TypeGuard | Call } . @@ -3538,7 +3538,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit, expr = Expression::make_type(Type::make_pointer_type(expr->type()), location); else if (op == OPERATOR_AND && expr->is_composite_literal()) - expr = Expression::make_heap_composite(expr, location); + expr = Expression::make_heap_expression(expr, location); else if (op != OPERATOR_CHANOP) expr = Expression::make_unary(op, expr, location); else @@ -3765,7 +3765,8 @@ Parse::labeled_stmt(const std::string& label_name, Location location) { // Mark the label as used to avoid a useless error about an // unused label. - label->set_is_used(); + if (label != NULL) + label->set_is_used(); error_at(location, "missing statement after label"); this->unget_token(Token::make_operator_token(OPERATOR_SEMICOLON, diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index a303a50410f..8c6e82b2267 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -142,11 +142,8 @@ DEF_GO_RUNTIME(SEND_SMALL, "__go_send_small", P3(TYPE, CHAN, UINT64), R0()) // Send a big value on a channel. DEF_GO_RUNTIME(SEND_BIG, "__go_send_big", P3(TYPE, CHAN, POINTER), R0()) -// Receive a small value from a channel. -DEF_GO_RUNTIME(RECEIVE_SMALL, "__go_receive_small", P2(TYPE, CHAN), R1(UINT64)) - -// Receive a big value from a channel. -DEF_GO_RUNTIME(RECEIVE_BIG, "__go_receive_big", P3(TYPE, CHAN, POINTER), R0()) +// Receive a value from a channel. +DEF_GO_RUNTIME(RECEIVE, "__go_receive", P3(TYPE, CHAN, POINTER), R0()) // Receive a value from a channel returning whether it is closed. DEF_GO_RUNTIME(CHANRECV2, "runtime.chanrecv2", P3(TYPE, CHAN, POINTER), @@ -208,7 +205,7 @@ DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT32), R0()) // Close. -DEF_GO_RUNTIME(CLOSE, "__go_close", P1(CHAN), R0()) +DEF_GO_RUNTIME(CLOSE, "__go_builtin_close", P1(CHAN), R0()) // Copy. @@ -233,6 +230,11 @@ DEF_GO_RUNTIME(NEW_NOPOINTERS, "__go_new_nopointers", P1(UINTPTR), R1(POINTER)) // Start a new goroutine. DEF_GO_RUNTIME(GO, "__go_go", P2(FUNC_PTR, POINTER), R0()) +// Get the function closure. +DEF_GO_RUNTIME(GET_CLOSURE, "__go_get_closure", P0(), R1(POINTER)) + +// Set the function closure. +DEF_GO_RUNTIME(SET_CLOSURE, "__go_set_closure", P1(POINTER), R0()) // Defer a function. DEF_GO_RUNTIME(DEFER, "__go_defer", P3(BOOLPTR, FUNC_PTR, POINTER), R0()) @@ -270,7 +272,7 @@ DEF_GO_RUNTIME(IFACEI2T2, "runtime.ifaceI2T2", P3(TYPE, IFACE, POINTER), // A type assertion from one interface type to another. This is // used for a type assertion. -DEF_GO_RUNTIME(ASSERT_INTERFACE, "__go_assert_interface", P2(TYPE, TYPE), R0()) +DEF_GO_RUNTIME(ASSERT_INTERFACE, "__go_assert_interface", P2(TYPE, TYPE), R1(POINTER)) // Convert one interface type to another. This is used for an // assignment. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index d195ab9845a..49a864faa44 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -264,8 +264,7 @@ Variable_declaration_statement::do_get_backend(Translate_context* context) Variable* var = this->var_->var_value(); Bvariable* bvar = this->var_->get_backend_variable(context->gogo(), context->function()); - tree init = var->get_init_tree(context->gogo(), context->function()); - Bexpression* binit = init == NULL ? NULL : tree_to_expr(init); + Bexpression* binit = var->get_init(context->gogo(), context->function()); if (!var->is_in_heap()) { @@ -638,13 +637,17 @@ Assignment_statement::do_check_types(Gogo*) Bstatement* Assignment_statement::do_get_backend(Translate_context* context) { - tree rhs_tree = this->rhs_->get_tree(context); if (this->lhs_->is_sink_expression()) - return context->backend()->expression_statement(tree_to_expr(rhs_tree)); + { + tree rhs_tree = this->rhs_->get_tree(context); + return context->backend()->expression_statement(tree_to_expr(rhs_tree)); + } + tree lhs_tree = this->lhs_->get_tree(context); - rhs_tree = Expression::convert_for_assignment(context, this->lhs_->type(), - this->rhs_->type(), rhs_tree, - this->location()); + Expression* rhs = + Expression::convert_for_assignment(context->gogo(), this->lhs_->type(), + this->rhs_, this->location()); + tree rhs_tree = rhs->get_tree(context); return context->backend()->assignment_statement(tree_to_expr(lhs_tree), tree_to_expr(rhs_tree), this->location()); @@ -2187,7 +2190,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function, location); // Allocate the initialized struct on the heap. - constructor = Expression::make_heap_composite(constructor, location); + constructor = Expression::make_heap_expression(constructor, location); // Look up the thunk. Named_object* named_thunk = gogo->lookup(thunk_name, NULL); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 2148a1a43e6..91a535f01c8 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -3075,34 +3075,6 @@ String_type::do_get_backend(Gogo* gogo) return backend_string_type; } -// Return a tree for the length of STRING. - -tree -String_type::length_tree(Gogo*, tree string) -{ - tree string_type = TREE_TYPE(string); - go_assert(TREE_CODE(string_type) == RECORD_TYPE); - tree length_field = DECL_CHAIN(TYPE_FIELDS(string_type)); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(length_field)), - "__length") == 0); - return fold_build3(COMPONENT_REF, TREE_TYPE(length_field), string, - length_field, NULL_TREE); -} - -// Return a tree for a pointer to the bytes of STRING. - -tree -String_type::bytes_tree(Gogo*, tree string) -{ - tree string_type = TREE_TYPE(string); - go_assert(TREE_CODE(string_type) == RECORD_TYPE); - tree bytes_field = TYPE_FIELDS(string_type); - go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(bytes_field)), - "__data") == 0); - return fold_build3(COMPONENT_REF, TREE_TYPE(bytes_field), string, - bytes_field, NULL_TREE); -} - // The type descriptor for the string type. Expression* @@ -4916,9 +4888,8 @@ Struct_type::method_function(const std::string& name, bool* is_ambiguous) const // the interface INTERFACE. IS_POINTER is true if this is for a // pointer to THIS. -tree -Struct_type::interface_method_table(Gogo* gogo, - const Interface_type* interface, +Expression* +Struct_type::interface_method_table(Interface_type* interface, bool is_pointer) { std::pair<Struct_type*, Struct_type::Struct_method_table_pair*> @@ -4937,7 +4908,7 @@ Struct_type::interface_method_table(Gogo* gogo, ins.first->second = smtp; } - return Type::interface_method_table(gogo, this, interface, is_pointer, + return Type::interface_method_table(this, interface, is_pointer, &smtp->first, &smtp->second); } @@ -8198,13 +8169,12 @@ Named_type::method_function(const std::string& name, bool* is_ambiguous) const // the interface INTERFACE. IS_POINTER is true if this is for a // pointer to THIS. -tree -Named_type::interface_method_table(Gogo* gogo, const Interface_type* interface, - bool is_pointer) +Expression* +Named_type::interface_method_table(Interface_type* interface, bool is_pointer) { - return Type::interface_method_table(gogo, this, interface, is_pointer, - &this->interface_method_tables_, - &this->pointer_interface_method_tables_); + return Type::interface_method_table(this, interface, is_pointer, + &this->interface_method_tables_, + &this->pointer_interface_method_tables_); } // Return whether a named type has any hidden fields. @@ -9385,9 +9355,9 @@ Type::method_function(const Methods* methods, const std::string& name, // Return a pointer to the interface method table for TYPE for the // interface INTERFACE. -tree -Type::interface_method_table(Gogo* gogo, Type* type, - const Interface_type *interface, +Expression* +Type::interface_method_table(Type* type, + Interface_type *interface, bool is_pointer, Interface_method_tables** method_tables, Interface_method_tables** pointer_tables) @@ -9399,23 +9369,18 @@ Type::interface_method_table(Gogo* gogo, Type* type, if (*pimt == NULL) *pimt = new Interface_method_tables(5); - std::pair<const Interface_type*, tree> val(interface, NULL_TREE); + std::pair<Interface_type*, Expression*> val(interface, NULL); std::pair<Interface_method_tables::iterator, bool> ins = (*pimt)->insert(val); + Location loc = Linemap::predeclared_location(); if (ins.second) { // This is a new entry in the hash table. - go_assert(ins.first->second == NULL_TREE); - ins.first->second = gogo->interface_method_table_for_type(interface, - type, - is_pointer); + go_assert(ins.first->second == NULL); + ins.first->second = + Expression::make_interface_mtable_ref(interface, type, is_pointer, loc); } - - tree decl = ins.first->second; - if (decl == error_mark_node) - return error_mark_node; - go_assert(decl != NULL_TREE && TREE_CODE(decl) == VAR_DECL); - return build_fold_addr_expr(decl); + return Expression::make_unary(OPERATOR_AND, ins.first->second, loc); } // Look for field or method NAME for TYPE. Return an Expression for diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 5fda4e7285e..d2ca1bf27fb 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -1019,14 +1019,14 @@ class Type // A mapping from interfaces to the associated interface method // tables for this type. This maps to a decl. - typedef Unordered_map_hash(const Interface_type*, tree, Type_hash_identical, + typedef Unordered_map_hash(Interface_type*, Expression*, Type_hash_identical, Type_identical) Interface_method_tables; // Return a pointer to the interface method table for TYPE for the // interface INTERFACE. - static tree - interface_method_table(Gogo* gogo, Type* type, - const Interface_type *interface, bool is_pointer, + static Expression* + interface_method_table(Type* type, + Interface_type *interface, bool is_pointer, Interface_method_tables** method_tables, Interface_method_tables** pointer_tables); @@ -1688,14 +1688,6 @@ class String_type : public Type : Type(TYPE_STRING) { } - // Return a tree for the length of STRING. - static tree - length_tree(Gogo*, tree string); - - // Return a tree which points to the bytes of STRING. - static tree - bytes_tree(Gogo*, tree string); - protected: bool do_has_pointer() const @@ -2205,9 +2197,8 @@ class Struct_type : public Type // the interface INTERFACE. If IS_POINTER is true, set the type // descriptor to a pointer to this type, otherwise set it to this // type. - tree - interface_method_table(Gogo*, const Interface_type* interface, - bool is_pointer); + Expression* + interface_method_table(Interface_type* interface, bool is_pointer); // Traverse just the field types of a struct type. int @@ -2946,9 +2937,8 @@ class Named_type : public Type // the interface INTERFACE. If IS_POINTER is true, set the type // descriptor to a pointer to this type, otherwise set it to this // type. - tree - interface_method_table(Gogo*, const Interface_type* interface, - bool is_pointer); + Expression* + interface_method_table(Interface_type* interface, bool is_pointer); // Whether this type has any hidden fields. bool diff --git a/gcc/godump.c b/gcc/godump.c index dd9e2e9219b..2afd7f171a0 100644 --- a/gcc/godump.c +++ b/gcc/godump.c @@ -578,9 +578,7 @@ go_format_type (struct godump_container *container, tree type, tree name; void **slot; - name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + name = TYPE_IDENTIFIER (type); slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name), NO_INSERT); @@ -685,9 +683,7 @@ go_format_type (struct godump_container *container, tree type, tree name; void **slot; - name = TYPE_NAME (TREE_TYPE (type)); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + name = TYPE_IDENTIFIER (TREE_TYPE (type)); slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name), NO_INSERT); @@ -806,9 +802,7 @@ go_format_type (struct godump_container *container, tree type, tree name; void **slot; - name = TYPE_NAME (TREE_TYPE (field)); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); + name = TYPE_IDENTIFIER (TREE_TYPE (field)); slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name), diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c index 1d7c7485f85..821f0846ef2 100644 --- a/gcc/graphite-scop-detection.c +++ b/gcc/graphite-scop-detection.c @@ -219,7 +219,14 @@ graphite_can_represent_scev (tree scev) switch (TREE_CODE (scev)) { + case NEGATE_EXPR: + case BIT_NOT_EXPR: + CASE_CONVERT: + case NON_LVALUE_EXPR: + return graphite_can_represent_scev (TREE_OPERAND (scev, 0)); + case PLUS_EXPR: + case POINTER_PLUS_EXPR: case MINUS_EXPR: return graphite_can_represent_scev (TREE_OPERAND (scev, 0)) && graphite_can_represent_scev (TREE_OPERAND (scev, 1)); @@ -241,13 +248,15 @@ graphite_can_represent_scev (tree scev) if (!evolution_function_right_is_integer_cst (scev) || !graphite_can_represent_init (scev)) return false; + return graphite_can_represent_scev (CHREC_LEFT (scev)); default: break; } /* Only affine functions can be represented. */ - if (!scev_is_linear_expression (scev)) + if (tree_contains_chrecs (scev, NULL) + || !scev_is_linear_expression (scev)) return false; return true; @@ -346,13 +355,10 @@ stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop, case GIMPLE_COND: { - tree op; - ssa_op_iter op_iter; - enum tree_code code = gimple_cond_code (stmt); - /* We can handle all binary comparisons. Inequalities are also supported as they can be represented with union of polyhedra. */ + enum tree_code code = gimple_cond_code (stmt); if (!(code == LT_EXPR || code == GT_EXPR || code == LE_EXPR @@ -361,11 +367,14 @@ stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop, || code == NE_EXPR)) return false; - FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES) - if (!graphite_can_represent_expr (scop_entry, loop, op) - /* We can not handle REAL_TYPE. Failed for pr39260. */ - || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE) - return false; + for (unsigned i = 0; i < 2; ++i) + { + tree op = gimple_op (stmt, i); + if (!graphite_can_represent_expr (scop_entry, loop, op) + /* We can not handle REAL_TYPE. Failed for pr39260. */ + || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE) + return false; + } return true; } diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 8acbd1b3db0..3ad80410f9f 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -2249,6 +2249,7 @@ rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi) /* Avoid the insertion of code in the loop latch to please the pattern matching of the vectorizer. */ if (TREE_CODE (arg) == SSA_NAME + && !SSA_NAME_IS_DEFAULT_DEF (arg) && e->src == bb->loop_father->latch) insert_out_of_ssa_copy (scop, zero_dim_array, arg, SSA_NAME_DEF_STMT (arg)); diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index e0d467497fa..2d66e5cab6a 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ /* Instruction scheduling pass. This file, along with sched-deps.c, - contains the generic parts. The actual entry point is found for + contains the generic parts. The actual entry point for the normal instruction scheduling pass is found in sched-rgn.c. We compute insn priorities based on data dependencies. Flow @@ -77,12 +77,12 @@ along with GCC; see the file COPYING3. If not see Before reload, an extended analysis of interblock data dependences is required for interblock scheduling. This is performed in - compute_block_backward_dependences (). + compute_block_dependences (). Dependencies set up by memory references are treated in exactly the same way as other dependencies, by using insn backward dependences INSN_BACK_DEPS. INSN_BACK_DEPS are translated into forward dependences - INSN_FORW_DEPS the purpose of forward list scheduling. + INSN_FORW_DEPS for the purpose of forward list scheduling. Having optimized the critical path, we may have also unduly extended the lifetimes of some registers. If an operation requires diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 05de8572492..689378a736f 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -884,8 +884,9 @@ ipcp_verify_propagated_values (void) { if (dump_file) { + dump_symtab (dump_file); fprintf (dump_file, "\nIPA lattices after constant " - "propagation:\n"); + "propagation, before gcc_unreachable:\n"); print_all_lattices (dump_file, true, false); } diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 7fbfbbb61a7..399485e5610 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -162,6 +162,8 @@ struct GTY(()) odr_type_d int id; /* Is it in anonymous namespace? */ bool anonymous_namespace; + /* Do we know about all derivations of given type? */ + bool all_derivations_known; }; @@ -180,6 +182,61 @@ polymorphic_type_binfo_p (tree binfo) return BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo))); } +/* Return TRUE if all derived types of T are known and thus + we may consider the walk of derived type complete. + + This is typically true only for final anonymous namespace types and types + defined within functions (that may be COMDAT and thus shared across units, + but with the same set of derived types). */ + +static bool +type_all_derivations_known_p (tree t) +{ + if (TYPE_FINAL_P (t)) + return true; + if (flag_ltrans) + return false; + if (type_in_anonymous_namespace_p (t)) + return true; + return (decl_function_context (TYPE_NAME (t)) != NULL); +} + +/* Return TURE if type's constructors are all visible. */ + +static bool +type_all_ctors_visible_p (tree t) +{ + return !flag_ltrans + && cgraph_state >= CGRAPH_STATE_CONSTRUCTION + /* We can not always use type_all_derivations_known_p. + For function local types we must assume case where + the function is COMDAT and shared in between units. + + TODO: These cases are quite easy to get, but we need + to keep track of C++ privatizing via -Wno-weak + as well as the IPA privatizing. */ + && type_in_anonymous_namespace_p (t); +} + +/* Return TRUE if type may have instance. */ + +static bool +type_possibly_instantiated_p (tree t) +{ + tree vtable; + varpool_node *vnode; + + /* TODO: Add abstract types here. */ + if (!type_all_ctors_visible_p (t)) + return true; + + vtable = BINFO_VTABLE (TYPE_BINFO (t)); + if (TREE_CODE (vtable) == POINTER_PLUS_EXPR) + vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0); + vnode = varpool_get_node (vtable); + return vnode && vnode->definition; +} + /* One Definition Rule hashtable helpers. */ struct odr_hasher @@ -439,6 +496,7 @@ get_odr_type (tree type, bool insert) val->bases = vNULL; val->derived_types = vNULL; val->anonymous_namespace = type_in_anonymous_namespace_p (type); + val->all_derivations_known = type_all_derivations_known_p (type); *slot = val; for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++) /* For now record only polymorphic types. other are @@ -469,7 +527,8 @@ dump_odr_type (FILE *f, odr_type t, int indent=0) unsigned int i; fprintf (f, "%*s type %i: ", indent * 2, "", t->id); print_generic_expr (f, t->type, TDF_SLIM); - fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":""); + fprintf (f, "%s", t->anonymous_namespace ? " (anonymous namespace)":""); + fprintf (f, "%s\n", t->all_derivations_known ? " (derivations known)":""); if (TYPE_NAME (t->type)) { fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "", @@ -598,6 +657,48 @@ build_type_inheritance_graph (void) timevar_pop (TV_IPA_INHERITANCE); } +/* Return true if N has reference from live virtual table + (and thus can be a destination of polymorphic call). + Be conservatively correct when callgraph is not built or + if the method may be referred externally. */ + +static bool +referenced_from_vtable_p (struct cgraph_node *node) +{ + int i; + struct ipa_ref *ref; + bool found = false; + + if (node->externally_visible + || node->used_from_other_partition) + return true; + + /* Keep this test constant time. + It is unlikely this can happen except for the case where speculative + devirtualization introduced many speculative edges to this node. + In this case the target is very likely alive anyway. */ + if (node->ref_list.referring.length () > 100) + return true; + + /* We need references built. */ + if (cgraph_state <= CGRAPH_STATE_CONSTRUCTION) + return true; + + for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, + i, ref); i++) + + if ((ref->use == IPA_REF_ALIAS + && referenced_from_vtable_p (cgraph (ref->referring))) + || (ref->use == IPA_REF_ADDR + && TREE_CODE (ref->referring->decl) == VAR_DECL + && DECL_VIRTUAL_P (ref->referring->decl))) + { + found = true; + break; + } + return found; +} + /* If TARGET has associated node, record it in the NODES array. CAN_REFER specify if program can refer to the target directly. if TARGET is unknown (NULL) or it can not be inserted (for example because @@ -611,7 +712,12 @@ maybe_record_node (vec <cgraph_node *> &nodes, bool *completep) { struct cgraph_node *target_node; - enum built_in_function fcode; + + /* cxa_pure_virtual and __builtin_unreachable do not need to be added into + list of targets; the runtime effect of calling them is undefined. + Only "real" virtual methods should be accounted. */ + if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE) + return; if (!can_refer) { @@ -619,24 +725,39 @@ maybe_record_node (vec <cgraph_node *> &nodes, is when we completely optimized it out. */ if (flag_ltrans || !target - || !type_in_anonymous_namespace_p (DECL_CONTEXT (target))) + || !type_in_anonymous_namespace_p (DECL_CONTEXT (target))) *completep = false; return; } - if (!target - /* Those are used to mark impossible scenarios. */ - || (fcode = DECL_FUNCTION_CODE (target)) - == BUILT_IN_UNREACHABLE - || fcode == BUILT_IN_TRAP) + if (!target) return; target_node = cgraph_get_node (target); - if (target_node != NULL - && (TREE_PUBLIC (target) - || target_node->definition) - && symtab_real_symbol_p (target_node)) + /* Method can only be called by polymorphic call if any + of vtables refering to it are alive. + + While this holds for non-anonymous functions, too, there are + cases where we want to keep them in the list; for example + inline functions with -fno-weak are static, but we still + may devirtualize them when instance comes from other unit. + The same holds for LTO. + + Currently we ignore these functions in speculative devirtualization. + ??? Maybe it would make sense to be more aggressive for LTO even + eslewhere. */ + if (!flag_ltrans + && type_in_anonymous_namespace_p (DECL_CONTEXT (target)) + && (!target_node + || !referenced_from_vtable_p (target_node))) + ; + /* See if TARGET is useful function we can deal with. */ + else if (target_node != NULL + && (TREE_PUBLIC (target) + || DECL_EXTERNAL (target) + || target_node->definition) + && symtab_real_symbol_p (target_node)) { gcc_assert (!target_node->global.inlined_to); gcc_assert (symtab_real_symbol_p (target_node)); @@ -648,14 +769,16 @@ maybe_record_node (vec <cgraph_node *> &nodes, } } else if (completep - && !type_in_anonymous_namespace_p - (method_class_type (TREE_TYPE (target)))) - *completep = true; + && (!type_in_anonymous_namespace_p + (DECL_CONTEXT (target)) + || flag_ltrans)) + *completep = false; } /* See if BINFO's type match OUTER_TYPE. If so, lookup BINFO of subtype of OTR_TYPE at OFFSET and in that BINFO find - method in vtable and insert method to NODES array. + method in vtable and insert method to NODES array + or BASES_TO_CONSIDER if this array is non-NULL. Otherwise recurse to base BINFOs. This match what get_binfo_at_offset does, but with offset being unknown. @@ -674,6 +797,7 @@ maybe_record_node (vec <cgraph_node *> &nodes, static void record_target_from_binfo (vec <cgraph_node *> &nodes, + vec <tree> *bases_to_consider, tree binfo, tree otr_type, vec <tree> &type_binfos, @@ -733,13 +857,19 @@ record_target_from_binfo (vec <cgraph_node *> &nodes, return; } gcc_assert (inner_binfo); - if (!pointer_set_insert (matched_vtables, BINFO_VTABLE (inner_binfo))) + if (bases_to_consider + ? !pointer_set_contains (matched_vtables, BINFO_VTABLE (inner_binfo)) + : !pointer_set_insert (matched_vtables, BINFO_VTABLE (inner_binfo))) { bool can_refer; tree target = gimple_get_virt_method_for_binfo (otr_token, inner_binfo, &can_refer); - maybe_record_node (nodes, target, inserted, can_refer, completep); + if (!bases_to_consider) + maybe_record_node (nodes, target, inserted, can_refer, completep); + /* Destructors are never called via construction vtables. */ + else if (!target || !DECL_CXX_DESTRUCTOR_P (target)) + bases_to_consider->safe_push (target); } return; } @@ -748,7 +878,7 @@ record_target_from_binfo (vec <cgraph_node *> &nodes, for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) /* Walking bases that have no virtual method is pointless excercise. */ if (polymorphic_type_binfo_p (base_binfo)) - record_target_from_binfo (nodes, base_binfo, otr_type, + record_target_from_binfo (nodes, bases_to_consider, base_binfo, otr_type, type_binfos, otr_token, outer_type, offset, inserted, matched_vtables, anonymous, completep); @@ -760,7 +890,11 @@ record_target_from_binfo (vec <cgraph_node *> &nodes, of TYPE, insert them to NODES, recurse into derived nodes. INSERTED is used to avoid duplicate insertions of methods into NODES. MATCHED_VTABLES are used to avoid duplicate walking vtables. - Clear COMPLETEP if unreferable target is found. */ + Clear COMPLETEP if unreferable target is found. + + If CONSIDER_CONSTURCTION is true, record to BASES_TO_CONSDIER + all cases where BASE_SKIPPED is true (because the base is abstract + class). */ static void possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes, @@ -771,23 +905,39 @@ possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes, HOST_WIDE_INT otr_token, tree outer_type, HOST_WIDE_INT offset, - bool *completep) + bool *completep, + vec <tree> &bases_to_consider, + bool consider_construction) { tree binfo = TYPE_BINFO (type->type); unsigned int i; vec <tree> type_binfos = vNULL; - - record_target_from_binfo (nodes, binfo, otr_type, type_binfos, otr_token, - outer_type, offset, - inserted, matched_vtables, - type->anonymous_namespace, completep); + bool possibly_instantiated = type_possibly_instantiated_p (type->type); + + /* We may need to consider types w/o instances because of possible derived + types using their methods either directly or via construction vtables. + We are safe to skip them when all derivations are known, since we will + handle them later. + This is done by recording them to BASES_TO_CONSIDER array. */ + if (possibly_instantiated || consider_construction) + { + record_target_from_binfo (nodes, + (!possibly_instantiated + && type_all_derivations_known_p (type->type)) + ? &bases_to_consider : NULL, + binfo, otr_type, type_binfos, otr_token, + outer_type, offset, + inserted, matched_vtables, + type->anonymous_namespace, completep); + } type_binfos.release (); for (i = 0; i < type->derived_types.length (); i++) possible_polymorphic_call_targets_1 (nodes, inserted, matched_vtables, otr_type, type->derived_types[i], - otr_token, outer_type, offset, completep); + otr_token, outer_type, offset, completep, + bases_to_consider, consider_construction); } /* Cache of queries for polymorphic call targets. @@ -1170,7 +1320,7 @@ get_polymorphic_call_info (tree fndecl, context->offset = 0; base_pointer = OBJ_TYPE_REF_OBJECT (ref); context->maybe_derived_type = true; - context->maybe_in_construction = false; + context->maybe_in_construction = true; /* Walk SSA for outer object. */ do @@ -1214,7 +1364,13 @@ get_polymorphic_call_info (tree fndecl, not part of outer type. */ if (!contains_type_p (TREE_TYPE (base), context->offset + offset2, *otr_type)) - return base_pointer; + { + /* Use OTR_TOKEN = INT_MAX as a marker of probably type inconsistent + code sequences; we arrange the calls to be builtin_unreachable + later. */ + *otr_token = INT_MAX; + return base_pointer; + } get_polymorphic_call_info_for_decl (context, base, context->offset + offset2); return NULL; @@ -1288,8 +1444,10 @@ get_polymorphic_call_info (tree fndecl, if (!contains_type_p (context->outer_type, context->offset, *otr_type)) { - context->outer_type = NULL; - gcc_unreachable (); + /* Use OTR_TOKEN = INT_MAX as a marker of probably type inconsistent + code sequences; we arrange the calls to be builtin_unreachable + later. */ + *otr_token = INT_MAX; return base_pointer; } context->maybe_derived_type = false; @@ -1363,7 +1521,8 @@ record_targets_from_bases (tree otr_type, tree target = gimple_get_virt_method_for_binfo (otr_token, base_binfo, &can_refer); - maybe_record_node (nodes, target, inserted, can_refer, completep); + if (!target || ! DECL_CXX_DESTRUCTOR_P (target)) + maybe_record_node (nodes, target, inserted, can_refer, completep); pointer_set_insert (matched_vtables, BINFO_VTABLE (base_binfo)); } } @@ -1389,6 +1548,9 @@ devirt_variable_node_removal_hook (varpool_node *n, temporarily change to one of base types. INCLUDE_DERIVER_TYPES make us to walk the inheritance graph for all derivations. + OTR_TOKEN == INT_MAX is used to mark calls that are provably + undefined and should be redirected to unreachable. + If COMPLETEP is non-NULL, store true if the list is complete. CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry in the target cache. If user needs to visit every target list @@ -1414,6 +1576,7 @@ possible_polymorphic_call_targets (tree otr_type, pointer_set_t *inserted; pointer_set_t *matched_vtables; vec <cgraph_node *> nodes = vNULL; + vec <tree> bases_to_consider = vNULL; odr_type type, outer_type; polymorphic_call_target_d key; polymorphic_call_target_d **slot; @@ -1421,7 +1584,9 @@ possible_polymorphic_call_targets (tree otr_type, tree binfo, target; bool complete; bool can_refer; + bool skipped = false; + /* If ODR is not initialized, return empty incomplete list. */ if (!odr_hash.is_created ()) { if (completep) @@ -1431,11 +1596,28 @@ possible_polymorphic_call_targets (tree otr_type, return nodes; } + /* If we hit type inconsistency, just return empty list of targets. */ + if (otr_token == INT_MAX) + { + if (completep) + *completep = true; + if (nonconstruction_targetsp) + *nonconstruction_targetsp = 0; + return nodes; + } + type = get_odr_type (otr_type, true); /* Lookup the outer class type we want to walk. */ - if (context.outer_type) - get_class_context (&context, otr_type); + if (context.outer_type + && !get_class_context (&context, otr_type)) + { + if (completep) + *completep = false; + if (nonconstruction_targetsp) + *nonconstruction_targetsp = 0; + return nodes; + } /* We canonicalize our query, so we do not need extra hashtable entries. */ @@ -1448,9 +1630,6 @@ possible_polymorphic_call_targets (tree otr_type, } /* We need to update our hiearchy if the type does not exist. */ outer_type = get_odr_type (context.outer_type, true); - /* If outer and inner type match, there are no bases to see. */ - if (type == outer_type) - context.maybe_in_construction = false; /* If the type is complete, there are no derivations. */ if (TYPE_FINAL_P (outer_type->type)) context.maybe_derived_type = false; @@ -1511,7 +1690,10 @@ possible_polymorphic_call_targets (tree otr_type, target = NULL; } - maybe_record_node (nodes, target, inserted, can_refer, &complete); + /* Destructors are never called through construction virtual tables, + because the type is always known. */ + if (target && DECL_CXX_DESTRUCTOR_P (target)) + context.maybe_in_construction = false; if (target) { @@ -1520,8 +1702,15 @@ possible_polymorphic_call_targets (tree otr_type, if (DECL_FINAL_P (target)) context.maybe_derived_type = false; } + + /* If OUTER_TYPE is abstract, we know we are not seeing its instance. */ + if (type_possibly_instantiated_p (outer_type->type)) + maybe_record_node (nodes, target, inserted, can_refer, &complete); else - gcc_assert (!complete); + { + skipped = true; + gcc_assert (in_lto_p || context.maybe_derived_type); + } pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo)); @@ -1530,7 +1719,7 @@ possible_polymorphic_call_targets (tree otr_type, { /* For anonymous namespace types we can attempt to build full type. All derivations must be in this unit (unless we see partial unit). */ - if (!type->anonymous_namespace || flag_ltrans) + if (!type->all_derivations_known) complete = false; for (i = 0; i < outer_type->derived_types.length(); i++) possible_polymorphic_call_targets_1 (nodes, inserted, @@ -1538,15 +1727,36 @@ possible_polymorphic_call_targets (tree otr_type, otr_type, outer_type->derived_types[i], otr_token, outer_type->type, - context.offset, &complete); + context.offset, &complete, + bases_to_consider, + context.maybe_in_construction); } /* Finally walk bases, if asked to. */ (*slot)->nonconstruction_targets = nodes.length(); + + /* Destructors are never called through construction virtual tables, + because the type is always known. One of entries may be cxa_pure_virtual + so look to at least two of them. */ if (context.maybe_in_construction) - record_targets_from_bases (otr_type, otr_token, outer_type->type, - context.offset, nodes, inserted, - matched_vtables, &complete); + for (i =0 ; i < MIN (nodes.length (), 2); i++) + if (DECL_CXX_DESTRUCTOR_P (nodes[i]->decl)) + context.maybe_in_construction = false; + if (context.maybe_in_construction) + { + if (type != outer_type + && (!skipped + || (context.maybe_derived_type + && !type_all_derivations_known_p (outer_type->type)))) + record_targets_from_bases (otr_type, otr_token, outer_type->type, + context.offset, nodes, inserted, + matched_vtables, &complete); + if (skipped) + maybe_record_node (nodes, target, inserted, can_refer, &complete); + for (i = 0; i < bases_to_consider.length(); i++) + maybe_record_node (nodes, bases_to_consider[i], inserted, can_refer, &complete); + } + bases_to_consider.release(); (*slot)->targets = nodes; (*slot)->complete = complete; @@ -1694,6 +1904,12 @@ likely_target_p (struct cgraph_node *n) return false; if (n->frequency < NODE_FREQUENCY_NORMAL) return false; + /* If there are no virtual tables refering the target alive, + the only way the target can be called is an instance comming from other + compilation unit; speculative devirtualization is build around an + assumption that won't happen. */ + if (!referenced_from_vtable_p (n)) + return false; return true; } diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index b2e0285462c..a45aab118fd 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -184,7 +184,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, freq_scale = e->frequency; n = cgraph_clone_node (e->callee, e->callee->decl, e->count, freq_scale, update_original, - vNULL, true, inlining_into); + vNULL, true, inlining_into, NULL); cgraph_redirect_edge_callee (e, n); } } diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 1e1e1183b86..40518194040 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1383,7 +1383,7 @@ recursive_inlining (struct cgraph_edge *edge, /* We need original clone to copy around. */ master_clone = cgraph_clone_node (node, node->decl, node->count, CGRAPH_FREQ_BASE, - false, vNULL, true, NULL); + false, vNULL, true, NULL, NULL); for (e = master_clone->callees; e; e = e->next_callee) if (!e->inline_failed) clone_inlined_nodes (e, true, false, NULL, CGRAPH_FREQ_BASE); diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index dccecb16a5b..8e7c7cb5ebe 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -660,6 +660,14 @@ ipa_merge_profiles (struct cgraph_node *dst, if (dst->tp_first_run > src->tp_first_run && src->tp_first_run) dst->tp_first_run = src->tp_first_run; + if (src->profile_id) + { + if (!dst->profile_id) + dst->profile_id = src->profile_id; + else + gcc_assert (src->profile_id == dst->profile_id); + } + if (!dst->count) return; if (cgraph_dump_file) diff --git a/gcc/ipa.c b/gcc/ipa.c index d23031286f2..3d82a39286c 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -139,7 +139,10 @@ process_references (struct ipa_ref_list *list, if (node->definition && !node->in_other_partition && ((!DECL_EXTERNAL (node->decl) || node->alias) - || (before_inlining_p + || (((before_inlining_p + && (cgraph_state < CGRAPH_STATE_IPA_SSA + || !lookup_attribute ("always_inline", + DECL_ATTRIBUTES (node->decl))))) /* We use variable constructors during late complation for constant folding. Keep references alive so partitioning knows about potential references. */ @@ -191,7 +194,10 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, /* Prior inlining, keep alive bodies of possible targets for devirtualization. */ if (n->definition - && before_inlining_p) + && (before_inlining_p + && (cgraph_state < CGRAPH_STATE_IPA_SSA + || !lookup_attribute ("always_inline", + DECL_ATTRIBUTES (n->decl))))) pointer_set_insert (reachable, n); /* Even after inlining we want to keep the possible targets in the @@ -409,7 +415,18 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) || !DECL_EXTERNAL (e->callee->decl) || e->callee->alias || before_inlining_p)) - pointer_set_insert (reachable, e->callee); + { + /* Be sure that we will not optimize out alias target + body. */ + if (DECL_EXTERNAL (e->callee->decl) + && e->callee->alias + && before_inlining_p) + { + pointer_set_insert (reachable, + cgraph_function_node (e->callee)); + } + pointer_set_insert (reachable, e->callee); + } enqueue_node (e->callee, &first, reachable); } @@ -469,7 +486,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (!node->aux) { if (file) - fprintf (file, " %s", node->name ()); + fprintf (file, " %s/%i", node->name (), node->order); cgraph_remove_node (node); changed = true; } @@ -483,7 +500,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) if (node->definition) { if (file) - fprintf (file, " %s", node->name ()); + fprintf (file, " %s/%i", node->name (), node->order); node->body_removed = true; node->analyzed = false; node->definition = false; @@ -491,6 +508,12 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) node->alias = false; node->thunk.thunk_p = false; node->weakref = false; + /* After early inlining we drop always_inline attributes on + bodies of functions that are still referenced (have their + address taken). */ + DECL_ATTRIBUTES (node->decl) + = remove_attribute ("always_inline", + DECL_ATTRIBUTES (node->decl)); if (!node->in_other_partition) node->local.local = false; cgraph_node_remove_callees (node); @@ -531,7 +554,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl))) { if (file) - fprintf (file, " %s", vnode->name ()); + fprintf (file, " %s/%i", vnode->name (), vnode->order); varpool_remove_node (vnode); changed = true; } @@ -1020,6 +1043,7 @@ function_and_variable_visibility (bool whole_program) == DECL_COMDAT_GROUP (decl_node->decl)); gcc_checking_assert (node->same_comdat_group); } + node->forced_by_abi = decl_node->forced_by_abi; if (DECL_EXTERNAL (decl_node->decl)) DECL_EXTERNAL (node->decl) = 1; } diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index cfc3d7eaaee..aac50876d21 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -1747,12 +1747,27 @@ process_alt_operands (int only_alternative) [GET_MODE (*curr_id->operand_loc[m])]); } - /* We prefer no matching alternatives because - it gives more freedom in RA. */ - if (operand_reg[nop] == NULL_RTX - || (find_regno_note (curr_insn, REG_DEAD, - REGNO (operand_reg[nop])) - == NULL_RTX)) + /* Prefer matching earlyclobber alternative as + it results in less hard regs required for + the insn than a non-matching earlyclobber + alternative. */ + if (curr_static_id->operand[m].early_clobber) + { + if (lra_dump_file != NULL) + fprintf + (lra_dump_file, + " %d Matching earlyclobber alt:" + " reject--\n", + nop); + reject--; + } + /* Otherwise we prefer no matching + alternatives because it gives more freedom + in RA. */ + else if (operand_reg[nop] == NULL_RTX + || (find_regno_note (curr_insn, REG_DEAD, + REGNO (operand_reg[nop])) + == NULL_RTX)) { if (lra_dump_file != NULL) fprintf @@ -2143,7 +2158,7 @@ process_alt_operands (int only_alternative) } /* If the operand is dying, has a matching constraint, and satisfies constraints of the matched operand - which failed to satisfy the own constraints, probably + which failed to satisfy the own constraints, most probably the reload for this operand will be gone. */ if (this_alternative_matches >= 0 && !curr_alt_win[this_alternative_matches] diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 60ae1320843..173067f65cf 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -1001,6 +1001,9 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->thunk.thunk_p = bp_unpack_value (bp, 1); node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN); + gcc_assert (flag_ltrans + || (!node->in_other_partition + && !node->used_from_other_partition)); } /* Return string alias is alias of. */ @@ -1042,7 +1045,7 @@ input_node (struct lto_file_decl_data *file_data, { node = cgraph_clone_node (cgraph (nodes[clone_ref]), fn_decl, 0, CGRAPH_FREQ_BASE, false, - vNULL, false, NULL); + vNULL, false, NULL, NULL); } else { @@ -1169,6 +1172,9 @@ input_varpool_node (struct lto_file_decl_data *file_data, node->same_comdat_group = (symtab_node *) (intptr_t) ref; node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN); + gcc_assert (flag_ltrans + || (!node->in_other_partition + && !node->used_from_other_partition)); return node; } diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 8e2af837465..d0c86626c66 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -727,7 +727,8 @@ input_cfg (struct lto_input_block *ib, struct data_in *data_in, /* Read OMP SIMD related info. */ loop->safelen = streamer_read_hwi (ib); - loop->force_vect = streamer_read_hwi (ib); + loop->dont_vectorize = streamer_read_hwi (ib); + loop->force_vectorize = streamer_read_hwi (ib); loop->simduid = stream_read_tree (ib, data_in); place_new_loop (fn, loop); @@ -893,7 +894,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in, fn->has_nonlocal_label = bp_unpack_value (&bp, 1); fn->calls_alloca = bp_unpack_value (&bp, 1); fn->calls_setjmp = bp_unpack_value (&bp, 1); - fn->has_force_vect_loops = bp_unpack_value (&bp, 1); + fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1); fn->has_simduid_loops = bp_unpack_value (&bp, 1); fn->va_list_fpr_size = bp_unpack_value (&bp, 8); fn->va_list_gpr_size = bp_unpack_value (&bp, 8); @@ -1380,8 +1381,7 @@ lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings, data_in->strings = strings; data_in->strings_len = len; data_in->globals_resolution = resolutions; - data_in->reader_cache = streamer_tree_cache_create (false, false); - + data_in->reader_cache = streamer_tree_cache_create (false, false, true); return data_in; } diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 23217daed46..ec6b4e53c50 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -79,7 +79,7 @@ create_output_block (enum lto_section_type section_type) ob->decl_state = lto_get_out_decl_state (); ob->main_stream = XCNEW (struct lto_output_stream); ob->string_stream = XCNEW (struct lto_output_stream); - ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true); + ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true, false); if (section_type == LTO_section_function_body) ob->cfg_stream = XCNEW (struct lto_output_stream); @@ -1280,7 +1280,6 @@ DFS_write_tree (struct output_block *ob, sccs *from_state, ??? We still wrap these in LTO_tree_scc so at the input side we can properly identify the tree we want to ultimatively return. */ - size_t old_len = ob->writer_cache->nodes.length (); if (size == 1) lto_output_tree_1 (ob, expr, scc_hash, ref_p, this_ref_p); else @@ -1318,7 +1317,6 @@ DFS_write_tree (struct output_block *ob, sccs *from_state, streamer_write_zero (ob); } } - gcc_assert (old_len + size == ob->writer_cache->nodes.length ()); /* Finally truncate the vector. */ sccstack.truncate (first); @@ -1707,7 +1705,8 @@ output_cfg (struct output_block *ob, struct function *fn) /* Write OMP SIMD related info. */ streamer_write_hwi (ob, loop->safelen); - streamer_write_hwi (ob, loop->force_vect); + streamer_write_hwi (ob, loop->dont_vectorize); + streamer_write_hwi (ob, loop->force_vectorize); stream_write_tree (ob, loop->simduid, true); } @@ -1802,7 +1801,7 @@ output_struct_function_base (struct output_block *ob, struct function *fn) bp_pack_value (&bp, fn->has_nonlocal_label, 1); bp_pack_value (&bp, fn->calls_alloca, 1); bp_pack_value (&bp, fn->calls_setjmp, 1); - bp_pack_value (&bp, fn->has_force_vect_loops, 1); + bp_pack_value (&bp, fn->has_force_vectorize_loops, 1); bp_pack_value (&bp, fn->has_simduid_loops, 1); bp_pack_value (&bp, fn->va_list_fpr_size, 8); bp_pack_value (&bp, fn->va_list_gpr_size, 8); @@ -2036,6 +2035,29 @@ copy_function (struct cgraph_node *node) lto_end_section (); } +/* Wrap symbol references in *TP inside a type-preserving MEM_REF. */ + +static tree +wrap_refs (tree *tp, int *ws, void *) +{ + tree t = *tp; + if (handled_component_p (t) + && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL) + { + tree decl = TREE_OPERAND (t, 0); + tree ptrtype = build_pointer_type (TREE_TYPE (decl)); + TREE_OPERAND (t, 0) = build2 (MEM_REF, TREE_TYPE (decl), + build1 (ADDR_EXPR, ptrtype, decl), + build_int_cst (ptrtype, 0)); + TREE_THIS_VOLATILE (TREE_OPERAND (t, 0)) = TREE_THIS_VOLATILE (decl); + *ws = 0; + } + else if (TREE_CODE (t) == CONSTRUCTOR) + ; + else if (!EXPR_P (t)) + *ws = 0; + return NULL_TREE; +} /* Main entry point from the pass manager. */ @@ -2057,24 +2079,33 @@ lto_output (void) for (i = 0; i < n_nodes; i++) { symtab_node *snode = lto_symtab_encoder_deref (encoder, i); - cgraph_node *node = dyn_cast <cgraph_node> (snode); - if (node - && lto_symtab_encoder_encode_body_p (encoder, node) - && !node->alias) + if (cgraph_node *node = dyn_cast <cgraph_node> (snode)) { + if (lto_symtab_encoder_encode_body_p (encoder, node) + && !node->alias) + { #ifdef ENABLE_CHECKING - gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl))); - bitmap_set_bit (output, DECL_UID (node->decl)); + gcc_assert (!bitmap_bit_p (output, DECL_UID (node->decl))); + bitmap_set_bit (output, DECL_UID (node->decl)); #endif - decl_state = lto_new_out_decl_state (); - lto_push_out_decl_state (decl_state); - if (gimple_has_body_p (node->decl) || !flag_wpa) - output_function (node); - else - copy_function (node); - gcc_assert (lto_get_out_decl_state () == decl_state); - lto_pop_out_decl_state (); - lto_record_function_out_decl_state (node->decl, decl_state); + decl_state = lto_new_out_decl_state (); + lto_push_out_decl_state (decl_state); + if (gimple_has_body_p (node->decl) || !flag_wpa) + output_function (node); + else + copy_function (node); + gcc_assert (lto_get_out_decl_state () == decl_state); + lto_pop_out_decl_state (); + lto_record_function_out_decl_state (node->decl, decl_state); + } + } + else if (varpool_node *node = dyn_cast <varpool_node> (snode)) + { + /* Wrap symbol references inside the ctor in a type + preserving MEM_REF. */ + tree ctor = DECL_INITIAL (node->decl); + if (ctor && !in_lto_p) + walk_tree (&ctor, wrap_refs, NULL, NULL); } } @@ -2435,10 +2466,18 @@ produce_asm_for_decls (void) gcc_assert (!alias_pairs); - /* Write the global symbols. */ + /* Get rid of the global decl state hash tables to save some memory. */ out_state = lto_get_out_decl_state (); - num_fns = lto_function_decl_states.length (); + for (int i = 0; i < LTO_N_DECL_STREAMS; i++) + if (out_state->streams[i].tree_hash_table) + { + delete out_state->streams[i].tree_hash_table; + out_state->streams[i].tree_hash_table = NULL; + } + + /* Write the global symbols. */ lto_output_decl_state_streams (ob, out_state); + num_fns = lto_function_decl_states.length (); for (idx = 0; idx < num_fns; idx++) { fn_out_state = diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 51b1903cc05..be0c782cda7 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -140,7 +140,7 @@ along with GCC; see the file COPYING3. If not see sections a '.' and the section type are appended. */ #define LTO_SECTION_NAME_PREFIX ".gnu.lto_" -#define LTO_major_version 3 +#define LTO_major_version 4 #define LTO_minor_version 0 typedef unsigned char lto_decl_flags_t; diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 1607ab3bff4..fd604b0bdb1 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -657,9 +657,7 @@ run_gcc (unsigned argc, char *argv[]) /* Drop arguments that we want to take from the link line. */ case OPT_flto_: case OPT_flto: - case OPT_flto_partition_none: - case OPT_flto_partition_1to1: - case OPT_flto_partition_balanced: + case OPT_flto_partition_: continue; default: @@ -727,8 +725,9 @@ run_gcc (unsigned argc, char *argv[]) verbose = 1; break; - case OPT_flto_partition_none: - no_partition = true; + case OPT_flto_partition_: + if (strcmp (option->arg, "none") == 0) + no_partition = true; break; case OPT_flto_: diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index ad806db7d76..d0e14c1b2f3 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,22 @@ +2014-04-15 Richard Biener <rguenther@suse.de> + + * lto.c: Include params.h. + (do_whole_program_analysis): Switch on flag_lto_partition value, + add support for LTO_PARTITION_ONE. + * lto-partition.h (lto_balanced_map): Adjust. + * lto-partition.c (lto_balanced_map): Get number of desired + partitions as argument to support -flto-partition=one. + +2014-04-14 Jan Hubicka <hubicka@ucw.cz> + + * lto/lto-symtab.c (lto_cgraph_replace_node): Don't re-merge + tp_first_run. + +2014-03-19 Jan Hubicka <hubicka@ucw.cz> + + * lto.c: Include ipa-inline.h + (do_whole_program_analysis): Free inline summary after partitioning. + 2014-03-19 Richard Biener <rguenther@suse.de> PR middle-end/60553 diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index 1ee5fbb851e..bb594344c29 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -415,7 +415,7 @@ varpool_node_cmp (const void *pa, const void *pb) and in-partition calls was reached. */ void -lto_balanced_map (void) +lto_balanced_map (int n_lto_partitions) { int n_nodes = 0; int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0; @@ -472,7 +472,7 @@ lto_balanced_map (void) } /* Compute partition size and create the first partition. */ - partition_size = total_size / PARAM_VALUE (PARAM_LTO_PARTITIONS); + partition_size = total_size / n_lto_partitions; if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) partition_size = PARAM_VALUE (MIN_PARTITION_SIZE); npartitions = 1; @@ -699,9 +699,8 @@ lto_balanced_map (void) /* Since the size of partitions is just approximate, update the size after we finished current one. */ - if (npartitions < PARAM_VALUE (PARAM_LTO_PARTITIONS)) - partition_size = total_size - / (PARAM_VALUE (PARAM_LTO_PARTITIONS) - npartitions); + if (npartitions < n_lto_partitions) + partition_size = total_size / (n_lto_partitions - npartitions); else partition_size = INT_MAX; diff --git a/gcc/lto/lto-partition.h b/gcc/lto/lto-partition.h index 770111d9b27..8db61b30176 100644 --- a/gcc/lto/lto-partition.h +++ b/gcc/lto/lto-partition.h @@ -34,7 +34,7 @@ extern vec<ltrans_partition> ltrans_partitions; void lto_1_to_1_map (void); void lto_max_map (void); -void lto_balanced_map (void); +void lto_balanced_map (int); void lto_promote_cross_file_statics (void); void free_ltrans_partitions (void); void lto_promote_statics_nonwpa (void); diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index 71242c8926f..8c83d3cf3e4 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -91,12 +91,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, if (node->decl != prevailing_node->decl) cgraph_release_function_body (node); - /* Time profile merging */ - if (node->tp_first_run) - prevailing_node->tp_first_run = prevailing_node->tp_first_run ? - MIN (prevailing_node->tp_first_run, node->tp_first_run) : - node->tp_first_run; - /* Finally remove the replaced node. */ cgraph_remove_node (node); } diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 2fa6d65119a..66e2c88261b 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see #include "data-streamer.h" #include "context.h" #include "pass_manager.h" +#include "ipa-inline.h" +#include "params.h" /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver. */ @@ -3266,12 +3268,20 @@ do_whole_program_analysis (void) timevar_pop (TV_WHOPR_WPA); timevar_push (TV_WHOPR_PARTITIONING); - if (flag_lto_partition_1to1) + if (flag_lto_partition == LTO_PARTITION_1TO1) lto_1_to_1_map (); - else if (flag_lto_partition_max) + else if (flag_lto_partition == LTO_PARTITION_MAX) lto_max_map (); + else if (flag_lto_partition == LTO_PARTITION_ONE) + lto_balanced_map (1); + else if (flag_lto_partition == LTO_PARTITION_BALANCED) + lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS)); else - lto_balanced_map (); + gcc_unreachable (); + + /* Inline summaries are needed for balanced partitioning. Free them now so + the memory can be used for streamer caches. */ + inline_free_summary (); /* AUX pointers are used by partitioning code to bookkeep number of partitions symbol is in. This is no longer needed. */ diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index 316653973a4..2848da34c1f 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -96,12 +96,18 @@ static void make_preds_opaque (basic_block, int); /* This function will allocate a new BBINFO structure, initialized - with the MODE, INSN, and basic block BB parameters. */ + with the MODE, INSN, and basic block BB parameters. + INSN may not be a NOTE_INSN_BASIC_BLOCK, unless it is an empty + basic block; that allows us later to insert instructions in a FIFO-like + manner. */ static struct seginfo * new_seginfo (int mode, rtx insn, int bb, HARD_REG_SET regs_live) { struct seginfo *ptr; + + gcc_assert (!NOTE_INSN_BASIC_BLOCK_P (insn) + || insn == BB_END (NOTE_BASIC_BLOCK (insn))); ptr = XNEW (struct seginfo); ptr->mode = mode; ptr->insn_ptr = insn; @@ -534,7 +540,13 @@ optimize_mode_switching (void) break; if (e) { - ptr = new_seginfo (no_mode, BB_HEAD (bb), bb->index, live_now); + rtx ins_pos = BB_HEAD (bb); + if (LABEL_P (ins_pos)) + ins_pos = NEXT_INSN (ins_pos); + gcc_assert (NOTE_INSN_BASIC_BLOCK_P (ins_pos)); + if (ins_pos != BB_END (bb)) + ins_pos = NEXT_INSN (ins_pos); + ptr = new_seginfo (no_mode, ins_pos, bb->index, live_now); add_seginfo (info + bb->index, ptr); bitmap_clear_bit (transp[bb->index], j); } @@ -733,7 +745,15 @@ optimize_mode_switching (void) { emitted = true; if (NOTE_INSN_BASIC_BLOCK_P (ptr->insn_ptr)) - emit_insn_after (mode_set, ptr->insn_ptr); + /* We need to emit the insns in a FIFO-like manner, + i.e. the first to be emitted at our insertion + point ends up first in the instruction steam. + Because we made sure that NOTE_INSN_BASIC_BLOCK is + only used for initially empty basic blocks, we + can archive this by appending at the end of + the block. */ + emit_insn_after + (mode_set, BB_END (NOTE_BASIC_BLOCK (ptr->insn_ptr))); else emit_insn_before (mode_set, ptr->insn_ptr); } diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog index c4183ea31d2..63b37304887 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,3 +1,8 @@ +2014-04-14 Paolo Carlini <paolo.carlini@oracle.com> + + * objcp-decl.h (OBJC_TYPE_NAME, OBJC_SET_TYPE_NAME): Use + TYPE_IDENTIFIER. + 2014-01-02 Richard Sandiford <rdsandiford@googlemail.com> Update copyright years diff --git a/gcc/objcp/objcp-decl.h b/gcc/objcp/objcp-decl.h index bcfcbdecd24..652f9933895 100644 --- a/gcc/objcp/objcp-decl.h +++ b/gcc/objcp/objcp-decl.h @@ -55,16 +55,9 @@ extern tree objcp_end_compound_stmt (tree, int); objcp_end_compound_stmt (stmt, flags) #undef OBJC_TYPE_NAME -#define OBJC_TYPE_NAME(type) \ - (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL \ - ? DECL_NAME (TYPE_NAME (type)) \ - : TYPE_NAME (type)) +#define OBJC_TYPE_NAME(type) (TYPE_IDENTIFIER (type)) #undef OBJC_SET_TYPE_NAME -#define OBJC_SET_TYPE_NAME(type, name) \ - if(TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) \ - DECL_NAME (TYPE_NAME (type)) = name; \ - else \ - TYPE_NAME (type) = name; +#define OBJC_SET_TYPE_NAME(type, name) (TYPE_IDENTIFIER (type) = (name)) #undef TYPE_OBJC_INFO #define TYPE_OBJC_INFO(TYPE) LANG_TYPE_CLASS_CHECK (TYPE)->objc_info diff --git a/gcc/omp-low.c b/gcc/omp-low.c index c9f6f5eb958..91468e95ab6 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -6841,8 +6841,8 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) && flag_tree_loop_optimize && loop->safelen > 1) { - loop->force_vect = true; - cfun->has_force_vect_loops = true; + loop->force_vectorize = true; + cfun->has_force_vectorize_loops = true; } } } @@ -11485,9 +11485,9 @@ simd_clone_adjust (struct cgraph_node *node) /* Mostly annotate the loop for the vectorizer (the rest is done below). */ struct loop *loop = alloc_loop (); - cfun->has_force_vect_loops = true; + cfun->has_force_vectorize_loops = true; loop->safelen = node->simdclone->simdlen; - loop->force_vect = true; + loop->force_vectorize = true; loop->header = body_bb; add_bb_to_loop (incr_bb, loop); diff --git a/gcc/opts.c b/gcc/opts.c index fdc903f9271..1873b96a028 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -431,8 +431,8 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 }, - { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 }, - { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 }, + { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 }, + { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 }, { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 }, @@ -824,14 +824,6 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, opts->x_flag_fat_lto_objects = 1; } } - if ((opts->x_flag_lto_partition_balanced != 0) + (opts->x_flag_lto_partition_1to1 != 0) - + (opts->x_flag_lto_partition_none != 0) >= 1) - { - if ((opts->x_flag_lto_partition_balanced != 0) - + (opts->x_flag_lto_partition_1to1 != 0) - + (opts->x_flag_lto_partition_none != 0) > 1) - error_at (loc, "only one -flto-partition value can be specified"); - } /* We initialize opts->x_flag_split_stack to -1 so that targets can set a default value if they choose based on other options. */ @@ -1740,7 +1732,7 @@ common_handle_option (struct gcc_options *opts, /* FIXME: Instrumentation we insert makes ipa-reference bitmaps quadratic. Disable the pass until better memory representation is done. */ - if (!opts_set->x_flag_ipa_reference && opts->x_in_lto_p) + if (!opts_set->x_flag_ipa_reference) opts->x_flag_ipa_reference = false; break; diff --git a/gcc/passes.def b/gcc/passes.def index c98b048eafc..1ecfb713226 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -68,10 +68,10 @@ along with GCC; see the file COPYING3. If not see /* After CCP we rewrite no longer addressed locals into SSA form if possible. */ NEXT_PASS (pass_forwprop); + NEXT_PASS (pass_sra_early); /* pass_build_ealias is a dummy pass that ensures that we execute TODO_rebuild_alias at this point. */ NEXT_PASS (pass_build_ealias); - NEXT_PASS (pass_sra_early); NEXT_PASS (pass_fre); NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_merge_phi); diff --git a/gcc/real.c b/gcc/real.c index f8e8d7fdfd9..a5e396e0471 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -1446,7 +1446,7 @@ real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) w = SIGSZ * HOST_BITS_PER_LONG + words * HOST_BITS_PER_WIDE_INT; tmp = real_int::from_array (val, (w + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT, w); - tmp = wi::lrshift (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp); + tmp = wi::lrshift<real_int> (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp); result = wide_int::from (tmp, precision, UNSIGNED); if (r->sign) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index f7d3e79a28a..7c21afa6fe5 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -5384,8 +5384,7 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op, tmp[u] = buf; base += HOST_BITS_PER_WIDE_INT; } - gcc_assert (GET_MODE_PRECISION (outer_submode) - <= MAX_BITSIZE_MODE_ANY_INT); + gcc_assert (GET_MODE_PRECISION (outer_submode) <= MAX_BITSIZE_MODE_ANY_INT); r = wide_int::from_array (tmp, units, GET_MODE_PRECISION (outer_submode)); elems[elem] = immed_wide_int_const (r, outer_submode); @@ -5396,7 +5395,7 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op, case MODE_DECIMAL_FLOAT: { REAL_VALUE_TYPE r; - long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32]; + long tmp[MAX_BITSIZE_MODE_ANY_INT / 32]; /* real_from_target wants its input in words affected by FLOAT_WORDS_BIG_ENDIAN. However, we ignore this, diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 66d3c79e3e8..ebcea9a3934 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1417,6 +1417,10 @@ place_field (record_layout_info rli, tree field) DECL_FIELD_BIT_OFFSET (field) = rli->bitpos; SET_DECL_OFFSET_ALIGN (field, rli->offset_align); + /* Evaluate nonconstant offsets only once, either now or as soon as safe. */ + if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST) + DECL_FIELD_OFFSET (field) = variable_size (DECL_FIELD_OFFSET (field)); + /* If this field ended up more aligned than we thought it would be (we approximate this by seeing if its position changed), lay out the field again; perhaps we can use an integral mode for it now. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9270bd67c85..d27064c78ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,500 @@ +2014-04-17 Jakub Jelinek <jakub@redhat.com> + + PR target/60847 + Forward port from 4.8 branch + 2013-07-19 Kirill Yukhin <kirill.yukhin@intel.com> + + * gcc.target/i386/bmi-1.c: Extend with new instrinsics. + Fix scan patterns. + * gcc.target/i386/bmi-2.c: Ditto. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR middle-end/60849 + * g++.dg/opt/pr60849.C: New testcase. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60836 + * g++.dg/vect/pr60836.cc: New testcase. + +2014-04-17 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60841 + * gcc.dg/vect/pr60841.c: New testcase. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + * g++.dg/ipa/devirt-31.C: New testcase. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + PR lto/60820 + * gcc.dg/lto/pr60820_0.c: New testcase. + * gcc.dg/lto/pr60820_1.c: New testcase. + +2014-04-16 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/60854 + * g++.dg/torture/pr60854.C: New testcase. + +2014-04-16 Catherine Moore <clm@codesourcery.com> + + * gcc.target/mips/umips-store16-2.c: New test. + +2014-04-16 Marc Glisse <marc.glisse@inria.fr> + + * g++.dg/cpp0x/initlist-vect.C: New file. + +2014-04-16 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/uninit-B-O0.c: Remove XFAIL. + * gcc.dg/uninit-I-O0.c: Likewise. + * gcc.dg/uninit-pr19430-O0.c: Remove some XFAILs. + +2014-04-16 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/60844 + * gcc.dg/pr60844.c: New test. + +2014-04-15 Richard Biener <rguenther@suse.de> + + PR rtl-optimization/56965 + * gcc.dg/torture/pr56965-1.c: New testcase. + * gcc.dg/torture/pr56965-2.c: Likewise. + +2014-04-15 Teresa Johnson <tejohnson@google.com> + + * gcc.dg/tree-prof/update-loopch.c: Update expected output. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/vect14.adb: New test. + +2014-04-15 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/vect12.ad[sb]: New test. + * gnat.dg/vect13.ad[sb]: Likewise. + +2014-04-15 Max Ostapenko <m.ostapenko@partner.samsung.com> + + * c-c++-common/asan/null-deref-1.c: Change regexp to pass test + under qemu-arm. + * c-c++-common/ubsan/div-by-zero-1.c: Likewise. + * c-c++-common/ubsan/div-by-zero-2.c: Likewise. + * c-c++-common/ubsan/div-by-zero-3.c: Likewise. + * c-c++-common/ubsan/load-bool-enum.c (foo): Likewise. + * c-c++-common/ubsan/null-1.c: Likewise. + * c-c++-common/ubsan/null-10.c: Likewise. + * c-c++-common/ubsan/null-11.c: Likewise. + * c-c++-common/ubsan/null-2.c: Likewise. + * c-c++-common/ubsan/null-3.c: Likewise. + * c-c++-common/ubsan/null-4.c: Likewise. + * c-c++-common/ubsan/null-5.c: Likewise. + * c-c++-common/ubsan/null-6.c: Likewise. + * c-c++-common/ubsan/null-7.c: Likewise. + * c-c++-common/ubsan/null-8.c: Likewise. + * c-c++-common/ubsan/null-9.c: Likewise. + * c-c++-common/ubsan/overflow-add-2.c: Likewise. + * c-c++-common/ubsan/overflow-int128.c: Likewise. + * c-c++-common/ubsan/overflow-mul-2.c: Likewise. + * c-c++-common/ubsan/overflow-mul-4.c: Likewise. + * c-c++-common/ubsan/overflow-negate-1.c: Likewise. + * c-c++-common/ubsan/overflow-sub-2.c: Likewise. + * c-c++-common/ubsan/pr59333.c: Likewise. + * c-c++-common/ubsan/pr59667.c: Likewise. + * c-c++-common/ubsan/pr60613-2.c: Likewise. + * c-c++-common/ubsan/pr60636.c: Likewise. + * c-c++-common/ubsan/shift-1.c: Likewise. + * c-c++-common/ubsan/shift-2.c: Likewise. + * c-c++-common/ubsan/vla-1.c: Likewise. + +2014-04-14 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/vect11.ad[sb]: New test. + +2014-04-14 Richard Biener <rguenther@suse.de> + + * g++.dg/tree-ssa/forwprop-switch.C: New testcase. + +2014-04-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * gcc.dg/lto/pr55113_0.c: Skip on i?86-*-solaris2.1[0-1]*. + +2014-04-14 Richard Biener <rguenther@suse.de> + Marc Glisse <marc.glisse@inria.fr> + + PR c/60819 + * gcc.target/i386/vec-may_alias.c: New testcase. + +2014-04-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * lib/target-supports.exp + (check_effective_target_vect_widen_mult_si_to_di_pattern): + Initialize et_vect_widen_mult_si_to_di_pattern_saved. + Fix formatting. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR lto/60720 + * gcc.dg/lto/pr60720_0.c: New testcase. + * gcc.dg/lto/pr60720_1.c: Likewise. + +2014-04-14 Christian Bruel <christian.bruel@st.com> + + * gcc.target/sh/memset.c: New test. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR middle-end/55022 + * gcc.dg/graphite/pr55022.c: New testcase. + +2014-04-14 Richard Biener <rguenther@suse.de> + + PR tree-optimization/59817 + PR tree-optimization/60453 + * gfortran.dg/graphite/pr59817.f: New testcase. + * gcc.dg/graphite/pr59817-1.c: Likewise. + * gcc.dg/graphite/pr59817-2.c: Likewise. + +2014-04-14 Jason Merrill <jason@redhat.com> + + Revert: + * lib/gcc-dg.exp (dg-build-dso): New. + (gcc-dg-test-1): Handle dg-do-what "dso". + +2014-04-13 Paul Thomas <pault@gcc.gnu.org> + + PR fortran/60717 + * gfortran.dg/unlimited_polymorphic_17.f90: New test. + + PR fortran/58085 + * gfortran.dg/associate_15.f90: New test. + +2014-04-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/60467 + * c-c++-common/cilk-plus/CK/invalid_spawns.c: Add new invalid + case to check. + +2014-04-12 Igor Zamyatin <igor.zamyatin@intel.com> + + PR middle-end/60469 + * c-c++-common/cilk-plus/CK/pr60469.c: New test. + +2014-04-12 Richard Sandiford <rdsandiford@googlemail.com> + + * gcc.target/mips/umips-store16-1.c: New test. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR c/60194 + * * g++.dg/warn/warn_format_signedness.C: New. + * gcc.dg/format/warn-signedness.c: New. + +2014-04-11 Tobias Burnus <burnus@net-b.de> + + PR fortran/58880 + PR fortran/60495 + * gfortran.dg/finalize_25.f90: New. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.target/epiphany/t1068-2.c: New file. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + * gcc.target/epiphany/btst-1.c: New test. + +2014-04-11 Joern Rennecke <joern.rennecke@embecosm.com> + + PR rtl-optimization/60651 + * gcc.target/epiphany/mode-switch.c: New test. + +2014-04-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58600 + * g++.dg/cpp0x/gen-attrs-58.C: New. + * g++.dg/cpp0x/gen-attrs-59.C: Likewise. + +2014-04-11 Steve Ellcey <sellcey@mips.com> + Jakub Jelinek <jakub@redhat.com> + + PR middle-end/60556 + * gcc.c-torture/compile/pr60556.c: New test. + +2014-04-11 Richard Biener <rguenther@suse.de> + + PR middle-end/60797 + * gcc.dg/pr60797.c: New testcase. + +2014-04-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/htm-nofloat-1.c: Rename to ... + * gcc.target/s390/htm-nofloat-compile-1.c: ... this one. + * gcc.target/s390/htm-nofloat-2.c: Add check for htm target and + rename to ... + * gcc.target/s390/htm-nofloat-1.c: ... this one. + * gcc.target/s390/s390.exp: Make sure the assembler supports htm + instructions as well. + +2014-04-11 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/60663 + * gcc.target/arm/pr60663.c: New test. + +2014-04-10 Jason Merrill <jason@redhat.com> + + * g++.dg/dso/dlclose1.C: Disable for 4.9. + +2014-04-10 Jakub Jelinek <jakub@redhat.com> + + PR lto/60567 + * g++.dg/lto/pr60567_0.C: New test. + +2014-04-10 Bernd Edlinger <bernd.edlinger@hotmail.de> + + * gfortran.dg/class_nameclash.f90: New test. + +2014-04-10 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/52844 + * g++.dg/cpp0x/variadic156.C: New. + +2014-04-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.target/s390/htm-builtins-compile-1.c: Replace long long with + long. + +2014-04-10 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR debug/60655 + * gcc.c-torture/compile/pr60655-2.c: Copy from pr60655-1.c without + -fdata-sections. + +2014-04-09 Steve Ellcey <sellcey@mips.com> + + * gcc.dg/tree-ssa/ssa-ifcombine-13.c: Remove mips*-*-* from option + and scan lists. + +2014-04-09 Cong Hou <congh@google.com> + + PR testsuite/60773 + * lib/target-supports.exp: + (check_effective_target_vect_widen_si_to_di_pattern): New. + * gcc.dg/vect/pr60656.c: Require vect_long effective target. + Use scan-tree-dump-times for vect_widen_mult_si_to_di_pattern + targets only. + (foo): Fix up formatting. + (main): Call check_vect. + +2014-04-08 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/59115 + * g++.dg/template/crash119.C: New. + +2014-04-08 Pat Haugen <pthaugen@us.ibm.com> + + * gcc.target/powerpc/atomic_load_store-p8.c: New. + +2014-04-08 Jason Merrill <jason@redhat.com> + + * lib/gcc-dg.exp (dg-build-dso): Reset dg-do-what-default to + compile. + +2014-04-08 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + PR rtl-optimization/60776 + * gcc.dg/builtin-bswap-6.c: Use -mbranch-cost=0 for s390. + * gcc.dg/builtin-bswap-7.c: Likewise. + * gcc.dg/builtin-bswap-6a.c: New testcase. + * gcc.dg/builtin-bswap-7a.c: New testcase. + + Revert + 2014-04-04 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.dg/builtin-bswap-6.c: Adjust return value to disable GCC + optimization. + * gcc.dg/builtin-bswap-7.c: Likewise. + +2014-04-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60785 + * gcc.dg/graphite/pr60785.c: New testcase. + +2014-04-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR target/60602 + * gcc.c-torture/compile/pr28865.c: XFAIL on sparc*-*-solaris2.9* + with as at -O0. + +2014-04-08 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/warn/Wnvdtor-2.C: Add more cases. + * g++.dg/warn/Wnvdtor-3.C: Likewise. + * g++.dg/warn/Wnvdtor-4.C: Likewise. + +2014-04-07 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/test_raise_from_pure.adb: UnXFAIL for ARM. + +2014-04-07 Charles Baylis <charles.baylis@linaro.org> + + PR target/60609 + * g++.dg/torture/pr60609.C: New test. + +2014-04-07 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60766 + * gcc.dg/torture/pr60766.c: New testcase. + +2014-04-07 Jason Merrill <jason@redhat.com> + + * lib/gcc-dg.exp (dg-build-dso): New. + (gcc-dg-test-1): Handle dg-do-what "dso". + * lib/target-supports.exp (add_options_for_dlopen): New. + (check_effective_target_dlopen): Use it. + +2014-04-07 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + * gcc.target/arm/pr60657.c: Fix missing curly brace. + +2014-04-07 Richard Biener <rguenther@suse.de> + + PR middle-end/60750 + * g++.dg/torture/pr60750.C: New testcase. + * gcc.dg/tree-ssa/20040517-1.c: Adjust. + +2014-04-06 Andreas Schwab <schwab@linux-m68k.org> + + * gcc.c-torture/compile/pr60655-1.c: Use __SIZE_TYPE__ for size_t. + +2014-04-06 John David Anglin <danglin@gcc.gnu.org> + + PR testsuite/60671 + g++.dg/pr49718.C: Adjust scan-assembler-times for hppa*-*-hpux*. + +2014-04-06 John David Anglin <danglin@gcc.gnu.org> + + PR testsuite/60672 + * g++.dg/cpp1y/auto-fn25.C: Require lto. + + * gcc.dg/atomic/stdatomic-flag.c: xfail on hppa*-*-hpux*. + +2014-04-05 Dominique d'Humieres <dominiq@lps.ens.fr> + + * gfortran.dg/warn_conversion_4.f90: Adjust test. + +2014-05-04 Pitchumani Sivanupandi <Pitchumani.S@atmel.com> + + * gcc.target/avr/dev-specific-rmw.c: New test. + +2014-04-04 Cong Hou <congh@google.com> + + PR tree-optimization/60656 + * gcc.dg/vect/pr60656.c: New test. + +2014-04-04 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * gcc.dg/builtin-bswap-6.c: Adjust return value to disable GCC + optimization. + * gcc.dg/builtin-bswap-7.c: Likewise. + +2014-04-04 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/58207 + * g++.dg/cpp0x/constexpr-ice15.C: New. + +2014-04-04 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/59626 + testcase by Richard Biener + * gcc.dg/lto/pr59626_0.c: New testcase. + * gcc.dg/lto/pr59626_1.c: New testcase. + +2014-04-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR debug/60655 + * gcc.c-torture/compile/pr60655-1.c: New test. + +2014-04-04 Martin Jambor <mjambor@suse.cz> + + PR ipa/60640 + * g++.dg/ipa/pr60640-1.C: New test. + * g++.dg/ipa/pr60640-2.C: Likewise. + * g++.dg/ipa/pr60640-3.C: Likewise. + * g++.dg/ipa/pr60640-4.C: Likewise. + +2014-04-04 Jeff Law <law@redhat.com> + + PR target/60657 + * gcc.target/arm/pr60657.c: New test. + +2014-04-04 Richard Biener <rguenther@suse.de> + + PR ipa/60746 + * g++.dg/torture/pr60746.C: New testcase. + +2014-04-04 Fabien Chêne <fabien@gcc.gnu.org> + + * g++.old-deja/g++.robertl/eb121.C: Adjust. + * g++.old-deja/g++.jason/overload21.C: Likewise. + * g++.old-deja/g++.law/init5.C: Likewise. + +2014-04-03 Cong Hou <congh@google.com> + + PR tree-optimization/60505 + * gcc.dg/vect/pr60505.c: New test. + +2014-04-03 Richard Biener <rguenther@suse.de> + + PR tree-optimization/60740 + * gcc.dg/graphite/pr60740.c: New testcase. + +2014-04-03 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/warn/Wnvdtor.C: Add non-polymorphic case. + * g++.dg/warn/Wnvdtor-2.C: New. + * g++.dg/warn/Wnvdtor-3.C: New. + * g++.dg/warn/Wnvdtor-4.C: New. + * g++.dg/warn/Weff1.C: Delete. + * g++.old-deja/g++.benjamin/15309-1.C: Delete. + * g++.old-deja/g++.benjamin/15309-2.C: Delete. + +2014-04-02 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/60659 + * testsuite/g++.dg/torture/pr60659.C: New testcase. + +2014-04-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + PR tree-optimization/60733 + * gcc.dg/torture/pr60733.c: New test. + +2014-04-02 Vladimir Makarov <vmakarov@redhat.com> + + PR rtl-optimization/60650 + * gcc.target/arm/pr60650-2.c: New. + +2014-04-02 Joseph Myers <joseph@codesourcery.cmo> + + * gcc.target/i386/avx2-vpand-3.c, + gcc.target/i386/avx256-unaligned-load-2.c: Use -mno-prefer-avx128. + +2014-04-02 Joseph Myers <joseph@codesourcery.com> + + * gcc.target/i386/funcspec-2.c, gcc.target/i386/funcspec-3.c, + gcc.target/i386/funcspec-9.c, gcc.target/i386/isa-1.c, + gcc.target/i386/memcpy-strategy-1.c, + gcc.target/i386/memcpy-strategy-2.c, + gcc.target/i386/memcpy-vector_loop-1.c, + gcc.target/i386/memcpy-vector_loop-2.c, + gcc.target/i386/memset-vector_loop-1.c, + gcc.target/i386/memset-vector_loop-2.c, + gcc.target/i386/sse2-init-v2di-2.c, gcc.target/i386/ssetype-1.c, + gcc.target/i386/ssetype-2.c, gcc.target/i386/ssetype-5.c: Skip for + -march= options different from those in dg-options. + 2014-04-02 Joseph Myers <joseph@codesourcery.com> * gcc.target/i386/387-3.c, gcc.target/i386/387-4.c, diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c b/gcc/testsuite/c-c++-common/asan/null-deref-1.c index 6aea9d295f3..87c34c4f68b 100644 --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c @@ -18,5 +18,5 @@ int main() /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]* #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c index ba9e6193627..5b43be76010 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c @@ -8,6 +8,7 @@ int main (void) { int x; + _Cilk_spawn foo; /* { dg-error "only function calls can be spawned" } */ _Cilk_spawn x; /* { dg-error "only function calls can be spawned" } */ return x; } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60469.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60469.c new file mode 100644 index 00000000000..ca0cf7f68bc --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60469.c @@ -0,0 +1,15 @@ +/* PR middle-end/60469 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +void foo() {} + +#define ALEN 1024 + +int main(int argc, char* argv[]) +{ + int b[ALEN]; + b[:] = 100; + _Cilk_spawn foo(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c index ec391e40be2..479ced038fb 100644 --- a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c @@ -17,8 +17,8 @@ main (void) return 0; } -/* { dg-output "division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero" } */ +/* { dg-output "division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c index c8820fa9466..d1eb95f4362 100644 --- a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c @@ -16,8 +16,8 @@ main (void) return 0; } -/* { dg-output "division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division by zero" } */ +/* { dg-output "division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division by zero\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c index 399071ee7aa..266423aa49f 100644 --- a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c +++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c @@ -16,6 +16,6 @@ main (void) return 0; } -/* { dg-output "division of -2147483648 by -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'" } */ +/* { dg-output "division of -2147483648 by -1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type 'int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/load-bool-enum.c b/gcc/testsuite/c-c++-common/ubsan/load-bool-enum.c index 96f7984f86a..4ffd6325bc1 100644 --- a/gcc/testsuite/c-c++-common/ubsan/load-bool-enum.c +++ b/gcc/testsuite/c-c++-common/ubsan/load-bool-enum.c @@ -10,8 +10,8 @@ bool b; __attribute__((noinline, noclone)) enum A foo (bool *p) { - *p = b; /* { dg-output "load-bool-enum.c:13:\[^\n\r]*runtime error: load of value 4, which is not a valid value for type '(_B|b)ool'(\n|\r\n|\r)*" } */ - return a; /* { dg-output "\[^\n\r]*load-bool-enum.c:14:\[^\n\r]*runtime error: load of value 9, which is not a valid value for type 'A'(\n|\r\n|\r)*" { target c++ } } */ + *p = b; /* { dg-output "load-bool-enum.c:13:\[^\n\r]*runtime error: \[^\n\r]*load of value 4, which is not a valid value for type '(_B|b)ool'\[^\n\r]*(\n|\r\n|\r)*" } */ + return a; /* { dg-output "\[^\n\r]*load-bool-enum.c:14:\[^\n\r]*runtime error: \[^\n\r]*load of value 9, which is not a valid value for type 'A'\[^\n\r]*(\n|\r\n|\r)*" { target c++ } } */ } int diff --git a/gcc/testsuite/c-c++-common/ubsan/null-1.c b/gcc/testsuite/c-c++-common/ubsan/null-1.c index 08d547f3aae..17f6d19c88b 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-1.c @@ -9,4 +9,4 @@ main (void) return *p; } -/* { dg-output "load of null pointer of type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-10.c b/gcc/testsuite/c-c++-common/ubsan/null-10.c index c3d61a01d5b..8dacf6c06cf 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-10.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-10.c @@ -10,4 +10,4 @@ main (void) return 0; } -/* { dg-output "load of null pointer of type 'short int'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-11.c b/gcc/testsuite/c-c++-common/ubsan/null-11.c index 6645f2acfcb..6aefaab0034 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-11.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-11.c @@ -13,4 +13,4 @@ main (void) return (*s)->i; } -/* { dg-output "load of null pointer of type 'struct S \\*'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'struct S \\*'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-2.c b/gcc/testsuite/c-c++-common/ubsan/null-2.c index cb3907fa5cc..df4901faed8 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-2.c @@ -9,4 +9,4 @@ main (void) return ***ppp; } -/* { dg-output "load of null pointer of type 'int \\*\\*'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'int \\*\\*'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-3.c b/gcc/testsuite/c-c++-common/ubsan/null-3.c index f58562c63b8..b1eb3dbc736 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-3.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-3.c @@ -15,4 +15,4 @@ main (void) return foo (*p); } -/* { dg-output "load of null pointer of type 'int \\*'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'int \\*'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-4.c b/gcc/testsuite/c-c++-common/ubsan/null-4.c index 18506afb3c3..7c0aa2c70aa 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-4.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-4.c @@ -11,4 +11,4 @@ main (void) return 0; } -/* { dg-output "load of null pointer of type 'complex double'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'complex double'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-5.c b/gcc/testsuite/c-c++-common/ubsan/null-5.c index c3c45b7c47e..f7f6b86d317 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-5.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-5.c @@ -13,4 +13,4 @@ main (void) return 0; } -/* { dg-output "load of null pointer of type 'volatile const complex float'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'volatile const complex float'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-6.c b/gcc/testsuite/c-c++-common/ubsan/null-6.c index 63fade5a6e1..6f8ba6bf45d 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-6.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-6.c @@ -10,4 +10,4 @@ main (void) return 0; } -/* { dg-output "store to null pointer of type 'long unsigned int'(\n|\r\n|\r)" } */ +/* { dg-output "store to null pointer of type 'long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-7.c b/gcc/testsuite/c-c++-common/ubsan/null-7.c index bf30a0b9b39..92881d73184 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-7.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-7.c @@ -14,4 +14,4 @@ main (void) return *gao (); } -/* { dg-output "load of null pointer of type 'int'(\n|\r\n|\r)" } */ +/* { dg-output "load of null pointer of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-8.c b/gcc/testsuite/c-c++-common/ubsan/null-8.c index 170377ee4d4..246824197b7 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-8.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-8.c @@ -13,4 +13,4 @@ main (void) return s->i; } -/* { dg-output "member access within null pointer of type 'struct S'(\n|\r\n|\r)" } */ +/* { dg-output "member access within null pointer of type 'struct S'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/null-9.c b/gcc/testsuite/c-c++-common/ubsan/null-9.c index ab43d22a325..88d441c3816 100644 --- a/gcc/testsuite/c-c++-common/ubsan/null-9.c +++ b/gcc/testsuite/c-c++-common/ubsan/null-9.c @@ -13,4 +13,4 @@ main (void) return u->i; } -/* { dg-output "member access within null pointer of type 'union U'(\n|\r\n|\r)" } */ +/* { dg-output "member access within null pointer of type 'union U'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-add-2.c b/gcc/testsuite/c-c++-common/ubsan/overflow-add-2.c index 85499d86c26..61097fa0e0d 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-add-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-add-2.c @@ -44,17 +44,17 @@ main (void) return 0; } -/* { dg-output "signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 1 \\+ 2147483647 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 2147483547 \\+ 1024 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -1 \\+ -2147483648 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147483548 \\+ -1024 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 1 \\+ \[^\n\r]* cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1024 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -1 \\+ -\[^\n\r]* cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1024 cannot be represented in type 'long int'" } */ +/* { dg-output "signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 1 \\+ 2147483647 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 2147483647 \\+ 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 2147483547 \\+ 1024 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -1 \\+ -2147483648 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147483548 \\+ -1024 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 1 \\+ \[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\+ 1024 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -1 \\+ -\[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1024 cannot be represented in type 'long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-int128.c b/gcc/testsuite/c-c++-common/ubsan/overflow-int128.c index 9a850243d3b..125d6bf5232 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-int128.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-int128.c @@ -44,4 +44,4 @@ main (void) /* { dg-output "\[^\n\r]*signed integer overflow: 0x80000000000000000000000000000000 \\+ -1 cannot be represented in type '__int128'(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*signed integer overflow: 0x80000000000000000000000000000064 \\+ -1024 cannot be represented in type '__int128'(\n|\r\n|\r)" } */ /* { dg-output "\[^\n\r]*signed integer overflow: 0x7fffffffffffffffffffffffffffffff \\* 2 cannot be represented in type '__int128'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of 0x80000000000000000000000000000000 cannot be represented in type '__int128'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of 0x80000000000000000000000000000000 cannot be represented in type '__int128'; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-2.c b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-2.c index ece25a354b8..54b382a4180 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-2.c @@ -20,7 +20,7 @@ main (void) return 0; } -/* { dg-output "signed integer overflow: 2147483647 \\* 2 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 2 \\* 2147483647 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\* 2 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 2 \\* \[^\n\r]* cannot be represented in type 'long int'" } */ +/* { dg-output "signed integer overflow: 2147483647 \\* 2 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 2 \\* 2147483647 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: \[^\n\r]* \\* 2 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 2 \\* \[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-4.c b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-4.c index 82e114001b4..834eda67306 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-mul-4.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-mul-4.c @@ -52,35 +52,35 @@ main () return 0; } -/* { dg-output "overflow-mul-4.c:20:\[^\n\r]*signed integer overflow: 1537228672809129302 \\* 6 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:21:\[^\n\r]*signed integer overflow: -1537228672809129302 \\* -6 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:22:\[^\n\r]*signed integer overflow: 1537228672809129302 \\* -6 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:23:\[^\n\r]*signed integer overflow: -1537228672809129302 \\* 6 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:24:\[^\n\r]*signed integer overflow: 2166572392 \\* 4257126175 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:25:\[^\n\r]*signed integer overflow: -2166572392 \\* -4257126175 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:26:\[^\n\r]*signed integer overflow: 2166572392 \\* -4257126175 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:27:\[^\n\r]*signed integer overflow: -2166572392 \\* 4257126175 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:28:\[^\n\r]*signed integer overflow: 1537228672809129301 \\* 7 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:29:\[^\n\r]*signed integer overflow: -1537228672809129301 \\* -7 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:30:\[^\n\r]*signed integer overflow: 1537228672809129301 \\* -7 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:31:\[^\n\r]*signed integer overflow: -1537228672809129301 \\* 7 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:32:\[^\n\r]*signed integer overflow: 2166572391 \\* 4257126176 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:33:\[^\n\r]*signed integer overflow: -2166572391 \\* -4257126176 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:34:\[^\n\r]*signed integer overflow: 2166572391 \\* -4257126176 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:35:\[^\n\r]*signed integer overflow: -2166572391 \\* 4257126176 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:36:\[^\n\r]*signed integer overflow: 6 \\* 1537228672809129302 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:37:\[^\n\r]*signed integer overflow: -6 \\* -1537228672809129302 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:38:\[^\n\r]*signed integer overflow: -6 \\* 1537228672809129302 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:39:\[^\n\r]*signed integer overflow: 6 \\* -1537228672809129302 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:40:\[^\n\r]*signed integer overflow: 4257126175 \\* 2166572392 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:41:\[^\n\r]*signed integer overflow: -4257126175 \\* -2166572392 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:42:\[^\n\r]*signed integer overflow: -4257126175 \\* 2166572392 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:43:\[^\n\r]*signed integer overflow: 4257126175 \\* -2166572392 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:44:\[^\n\r]*signed integer overflow: 7 \\* 1537228672809129301 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:45:\[^\n\r]*signed integer overflow: -7 \\* -1537228672809129301 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:46:\[^\n\r]*signed integer overflow: -7 \\* 1537228672809129301 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:47:\[^\n\r]*signed integer overflow: 7 \\* -1537228672809129301 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:48:\[^\n\r]*signed integer overflow: 4257126176 \\* 2166572391 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:49:\[^\n\r]*signed integer overflow: -4257126176 \\* -2166572391 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:50:\[^\n\r]*signed integer overflow: -4257126176 \\* 2166572391 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*overflow-mul-4.c:51:\[^\n\r]*signed integer overflow: 4257126176 \\* -2166572391 cannot be represented in type 'long long int'" } */ +/* { dg-output "overflow-mul-4.c:20:\[^\n\r]*signed integer overflow: 1537228672809129302 \\* 6 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:21:\[^\n\r]*signed integer overflow: -1537228672809129302 \\* -6 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:22:\[^\n\r]*signed integer overflow: 1537228672809129302 \\* -6 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:23:\[^\n\r]*signed integer overflow: -1537228672809129302 \\* 6 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:24:\[^\n\r]*signed integer overflow: 2166572392 \\* 4257126175 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:25:\[^\n\r]*signed integer overflow: -2166572392 \\* -4257126175 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:26:\[^\n\r]*signed integer overflow: 2166572392 \\* -4257126175 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:27:\[^\n\r]*signed integer overflow: -2166572392 \\* 4257126175 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:28:\[^\n\r]*signed integer overflow: 1537228672809129301 \\* 7 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:29:\[^\n\r]*signed integer overflow: -1537228672809129301 \\* -7 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:30:\[^\n\r]*signed integer overflow: 1537228672809129301 \\* -7 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:31:\[^\n\r]*signed integer overflow: -1537228672809129301 \\* 7 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:32:\[^\n\r]*signed integer overflow: 2166572391 \\* 4257126176 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:33:\[^\n\r]*signed integer overflow: -2166572391 \\* -4257126176 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:34:\[^\n\r]*signed integer overflow: 2166572391 \\* -4257126176 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:35:\[^\n\r]*signed integer overflow: -2166572391 \\* 4257126176 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:36:\[^\n\r]*signed integer overflow: 6 \\* 1537228672809129302 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:37:\[^\n\r]*signed integer overflow: -6 \\* -1537228672809129302 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:38:\[^\n\r]*signed integer overflow: -6 \\* 1537228672809129302 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:39:\[^\n\r]*signed integer overflow: 6 \\* -1537228672809129302 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:40:\[^\n\r]*signed integer overflow: 4257126175 \\* 2166572392 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:41:\[^\n\r]*signed integer overflow: -4257126175 \\* -2166572392 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:42:\[^\n\r]*signed integer overflow: -4257126175 \\* 2166572392 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:43:\[^\n\r]*signed integer overflow: 4257126175 \\* -2166572392 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:44:\[^\n\r]*signed integer overflow: 7 \\* 1537228672809129301 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:45:\[^\n\r]*signed integer overflow: -7 \\* -1537228672809129301 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:46:\[^\n\r]*signed integer overflow: -7 \\* 1537228672809129301 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:47:\[^\n\r]*signed integer overflow: 7 \\* -1537228672809129301 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:48:\[^\n\r]*signed integer overflow: 4257126176 \\* 2166572391 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:49:\[^\n\r]*signed integer overflow: -4257126176 \\* -2166572391 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:50:\[^\n\r]*signed integer overflow: -4257126176 \\* 2166572391 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*overflow-mul-4.c:51:\[^\n\r]*signed integer overflow: 4257126176 \\* -2166572391 cannot be represented in type 'long long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-1.c b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-1.c index 85f81d8b547..35fa482c61b 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-1.c @@ -27,12 +27,12 @@ main (void) return 0; } -/* { dg-output "negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself" } */ +/* { dg-output "negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -\[^\n\r]* cannot be represented in type 'long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c b/gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c index 6476b65d2a0..daf6a54666a 100644 --- a/gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/overflow-sub-2.c @@ -42,13 +42,13 @@ main (void) return 0; } -/* { dg-output "signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147483548 \\+ -1024 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -2147482648 \\+ -1048576 cannot be represented in type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* - 1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1024 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1048576 cannot be represented in type 'long int'" } */ +/* { dg-output "signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147483548 \\+ -1024 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147483648 \\+ -1 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -2147482648 \\+ -1048576 cannot be represented in type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* - 1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1024 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1 cannot be represented in type 'long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: -\[^\n\r]* \\+ -1048576 cannot be represented in type 'long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59333.c b/gcc/testsuite/c-c++-common/ubsan/pr59333.c index b68775702be..35504750979 100644 --- a/gcc/testsuite/c-c++-common/ubsan/pr59333.c +++ b/gcc/testsuite/c-c++-common/ubsan/pr59333.c @@ -15,4 +15,4 @@ main (void) return 0; } -/* { dg-output "signed integer overflow: 2 \\+ 9223372036854775807 cannot be represented in type 'long long int'" } */ +/* { dg-output "signed integer overflow: 2 \\+ 9223372036854775807 cannot be represented in type 'long long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr59667.c b/gcc/testsuite/c-c++-common/ubsan/pr59667.c index 7fad7029907..c76c9de9802 100644 --- a/gcc/testsuite/c-c++-common/ubsan/pr59667.c +++ b/gcc/testsuite/c-c++-common/ubsan/pr59667.c @@ -11,4 +11,4 @@ main (void) return 0; } -/* { dg-output "store to null pointer of type 'float'(\n|\r\n|\r)" } */ +/* { dg-output "store to null pointer of type 'float'\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr60613-2.c b/gcc/testsuite/c-c++-common/ubsan/pr60613-2.c index 92c2de81eb8..af6917e6b75 100644 --- a/gcc/testsuite/c-c++-common/ubsan/pr60613-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/pr60613-2.c @@ -32,5 +32,5 @@ main () return 0; } -/* { dg-output "signed integer overflow: 8 \\- -9223372036854775801 cannot be represented in type 'long long int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*signed integer overflow: 8 \\- -9223372036854775802 cannot be represented in type 'long long int'" } */ +/* { dg-output "signed integer overflow: 8 \\- -9223372036854775801 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*signed integer overflow: 8 \\- -9223372036854775802 cannot be represented in type 'long long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr60636.c b/gcc/testsuite/c-c++-common/ubsan/pr60636.c index 41643413755..d6749ab678d 100644 --- a/gcc/testsuite/c-c++-common/ubsan/pr60636.c +++ b/gcc/testsuite/c-c++-common/ubsan/pr60636.c @@ -12,4 +12,4 @@ main () return 0; } -/* { dg-output "negation of -9223372036854775808 cannot be represented in type 'long long int'" } */ +/* { dg-output "negation of -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-1.c b/gcc/testsuite/c-c++-common/ubsan/shift-1.c index d2538802aab..d5c70baa815 100644 --- a/gcc/testsuite/c-c++-common/ubsan/shift-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/shift-1.c @@ -23,9 +23,9 @@ main (void) return 0; } -/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 154 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 524 is too large for \[^\n\r]*-bit type 'long long unsigned int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 370 is too large for \[^\n\r]*-bit type 'int'(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent 402 is too large for \[^\n\r]*-bit type 'long int'" } */ +/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 154 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 524 is too large for \[^\n\r]*-bit type 'long long unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 370 is too large for \[^\n\r]*-bit type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent 402 is too large for \[^\n\r]*-bit type 'long int'\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-2.c b/gcc/testsuite/c-c++-common/ubsan/shift-2.c index aaaeb6fcc09..426ec093706 100644 --- a/gcc/testsuite/c-c++-common/ubsan/shift-2.c +++ b/gcc/testsuite/c-c++-common/ubsan/shift-2.c @@ -16,8 +16,8 @@ main (void) return 0; } -/* { dg-output "shift exponent -3 is negative(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent -4 is negative(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent -5 is negative(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent -6 is negative(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*shift exponent -11 is negative" } */ +/* { dg-output "shift exponent -3 is negative\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent -4 is negative\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent -5 is negative\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent -6 is negative\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*shift exponent -11 is negative\[^\n\r]*" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/vla-1.c b/gcc/testsuite/c-c++-common/ubsan/vla-1.c index 0fecfa2a3d5..14122032410 100644 --- a/gcc/testsuite/c-c++-common/ubsan/vla-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/vla-1.c @@ -102,18 +102,18 @@ main (void) return 0; } -/* { dg-output "variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -5(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -3(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value 0(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value 0(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -6(\n|\r\n|\r)" } */ -/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -4" } */ +/* { dg-output "variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -5\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -3\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value 0\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value 0\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -1\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -6\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*variable length array bound evaluates to non-positive value -4\[^\n\r]*" } */ diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice15.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice15.C new file mode 100644 index 00000000000..576fd415085 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice15.C @@ -0,0 +1,12 @@ +// PR c++/58207 +// { dg-do compile { target c++11 } } + +struct A +{ + virtual bool foo (); +}; + +struct B : public A +{ + constexpr B () : A (&::n) {} // { dg-error "declared" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C index 2aae9cae00b..131af368a21 100644 --- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36-1.C @@ -6,6 +6,6 @@ typedef int (*F [[gnu::warn_unused_result]]) (int); typedef int (*F2 [[gnu::warn_unused_result]]) (int); -typedef int (S::*F3 [[gnu::warn_unused_result]]) (int); // { dg-warning "only applies to function types" } +typedef int (S::*F3 [[gnu::warn_unused_result]]) (int); typedef int [[gnu::warn_unused_result]] (*F5) (int); // { dg-warning "ignored" } diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C new file mode 100644 index 00000000000..f760f560828 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-58.C @@ -0,0 +1,5 @@ +// PR c++/58600 +// { dg-do compile { target c++11 } } + +namespace N { int i; } +using namespace N alignas(int); // { dg-warning "ignored" } diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C new file mode 100644 index 00000000000..c7839fefed9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-59.C @@ -0,0 +1,5 @@ +// PR c++/58600 +// { dg-do compile { target c++11 } } + +namespace N {} +using namespace N alignas(X); // { dg-error "declared" } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-vect.C b/gcc/testsuite/g++.dg/cpp0x/initlist-vect.C new file mode 100644 index 00000000000..80a2fbb63fa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-vect.C @@ -0,0 +1,6 @@ +// { dg-do compile { target c++11 } } + +typedef float X __attribute__ ((vector_size (4 * sizeof (float)))); + +X x; +X x2{x}; diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist83.C b/gcc/testsuite/g++.dg/cpp0x/initlist83.C new file mode 100644 index 00000000000..4a5eeb6d08f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist83.C @@ -0,0 +1,7 @@ +// DR 1467, c++/51747 +// { dg-do compile { target c++11 } } + +struct X { }; + +X x; +X x2{x}; diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic156.C b/gcc/testsuite/g++.dg/cpp0x/variadic156.C new file mode 100644 index 00000000000..7d3c97d6890 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic156.C @@ -0,0 +1,6 @@ +// PR c++/52844 +// { dg-do compile { target c++11 } } + +template < class > struct V { }; +template < int...Is > void f ( V < Is...>) { } // { dg-error "mismatch|type" } +auto g ( ) -> decltype ( f ( V < long > ( ) ) ) ; // { dg-error "matching" } diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn25.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn25.C index 628a685f722..24680f16d05 100644 --- a/gcc/testsuite/g++.dg/cpp1y/auto-fn25.C +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn25.C @@ -1,6 +1,7 @@ // PR c++/60574 -// { dg-options "-flto" } // { dg-do compile { target c++1y } } +// { dg-require-effective-target lto } +// { dg-options "-flto" } struct A { diff --git a/gcc/testsuite/g++.dg/ext/atomic-2.C b/gcc/testsuite/g++.dg/ext/atomic-2.C new file mode 100644 index 00000000000..ac363eb16da --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/atomic-2.C @@ -0,0 +1,14 @@ +// PR c++/57926 + +long Mutex[1]; + +int AcquireLogMutex(void) +{ + return __atomic_exchange_n(Mutex, 1, __ATOMIC_SEQ_CST); +} + +void ReleaseLogMutex(void) +{ + long i = 0; + __atomic_store(Mutex, &i, __ATOMIC_SEQ_CST); +} diff --git a/gcc/testsuite/g++.dg/ext/attrib49.C b/gcc/testsuite/g++.dg/ext/attrib49.C new file mode 100644 index 00000000000..99c6154f1a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib49.C @@ -0,0 +1,20 @@ +// PR c++/60765 +// { dg-options "-Wall -Wunused-parameter" } + +struct foo +{ +} x; + +void (foo::*g) (int *) __attribute__ ((nonnull (2))); + +void +fun1 (void (foo::*f) (int *) __attribute__ ((nonnull (2)))) +{ + (x.*f) ((int *) 0); // { dg-warning "null argument" } +} + +void +fun2 (void (foo::*f) () __attribute__ ((nonnull, unused))) // { dg-bogus "unused" } +{ + (x.*g) ((int *) 0); // { dg-warning "null argument" } +} diff --git a/gcc/testsuite/g++.dg/ext/vla14.C b/gcc/testsuite/g++.dg/ext/vla14.C new file mode 100644 index 00000000000..278cb63b938 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla14.C @@ -0,0 +1,23 @@ +// PR c++/21113 +// { dg-options "" } + +void +f (int n) +{ + goto label; // { dg-error "from here" } + int a[n]; // { dg-error "crosses initialization" } +label: // { dg-error "jump to label" } + ; +} + +void +g (int n) +{ + switch (1) + { + case 1: + int (*a)[n]; // { dg-error "crosses initialization" } + default: // { dg-error "jump to case label" } + ; + } +} diff --git a/gcc/testsuite/g++.dg/ext/vla15.C b/gcc/testsuite/g++.dg/ext/vla15.C new file mode 100644 index 00000000000..feeb49ff280 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla15.C @@ -0,0 +1,20 @@ +// PR c++/44613 +// { dg-do run } +// { dg-options "" } + +void *volatile p; + +int +main (void) +{ + int n = 0; + lab:; + int x[n % 1000 + 1]; + x[0] = 1; + x[n % 1000] = 2; + p = x; + n++; + if (n < 1000000) + goto lab; + return 0; +} diff --git a/gcc/testsuite/g++.dg/init/aggr4.C b/gcc/testsuite/g++.dg/init/aggr4.C index 7120e68cd7e..b0eae2ef3d0 100644 --- a/gcc/testsuite/g++.dg/init/aggr4.C +++ b/gcc/testsuite/g++.dg/init/aggr4.C @@ -4,4 +4,4 @@ struct A }; A a1 = { 1 }; // ok -A a2 = { a1 }; // { dg-error "cannot convert" } +A a2 = { a1 }; // { dg-error "cannot convert" "" { target { ! c++11 } } } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-31.C b/gcc/testsuite/g++.dg/ipa/devirt-31.C new file mode 100644 index 00000000000..49ad33e3e6b --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-31.C @@ -0,0 +1,16 @@ +// { dg-options "-O3 -fdump-tree-ssa" } +inline void t() +{ + struct A {virtual void q() {}}; + static struct A *a; + if (!a) + a = new(A); + a->q(); +}; +void +m() +{ + t(); +} +// { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "ssa" } } +// { dg-final { cleanup-tree-dump "ssa" } } diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-1.C b/gcc/testsuite/g++.dg/ipa/pr60640-1.C new file mode 100644 index 00000000000..7a0b91893f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60640-1.C @@ -0,0 +1,50 @@ +// { dg-do compile } +// { dg-options "-O3" } + +class ASN1Object +{ +public: + virtual ~ASN1Object (); +}; +class A +{ + virtual unsigned m_fn1 () const; +}; +class B +{ +public: + ASN1Object Element; + virtual unsigned m_fn1 (bool) const; +}; +template <class BASE> class C : public BASE +{ +}; + +class D : ASN1Object, public B +{ +}; +class G : public D +{ + unsigned m_fn1 (bool) const {} +}; +class F : A +{ +public: + F (A); + unsigned m_fn1 () const + { + int a; + a = m_fn2 ().m_fn1 (0); + return a; + } + const B &m_fn2 () const { return m_groupParameters; } + C<G> m_groupParameters; +}; +template <class D> void BenchMarkKeyAgreement (int *, int *, int) +{ + A f; + D d (f); +} + +void BenchmarkAll2 () { BenchMarkKeyAgreement<F>(0, 0, 0); } + diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-2.C b/gcc/testsuite/g++.dg/ipa/pr60640-2.C new file mode 100644 index 00000000000..c6e614cc004 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60640-2.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-options "-O3" } + +struct B { virtual unsigned f () const; }; +struct C { virtual void f (); }; +struct F { virtual unsigned f (bool) const; ~F (); }; +struct J : C, F {}; +struct G : J { unsigned f (bool) const { return 0; } }; +struct H : B +{ + H (int); + unsigned f () const { return ((const F &) h).f (0); } + G h; +}; +H h (0); diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-3.C b/gcc/testsuite/g++.dg/ipa/pr60640-3.C new file mode 100644 index 00000000000..21b1f58a040 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60640-3.C @@ -0,0 +1,81 @@ +// { dg-do run } +// { dg-options "-O3" } + +struct Distraction +{ + char fc[8]; + virtual Distraction * return_self () + { return this; } +}; + +namespace { + +struct A; +static A * __attribute__ ((noinline, noclone)) get_an_A (); + +static int go; + +struct A +{ + int fi; + + A () : fi(777) {} + A (int pi) : fi (pi) {} + virtual A * foo (int p) = 0; +}; + +struct B; +static B * __attribute__ ((noinline, noclone)) get_a_B (); + +struct B : public Distraction, A +{ + B () : Distraction(), A() { } + B (int pi) : Distraction (), A (pi) {} + virtual B * foo (int p) + { + int o = fi; + for (int i = 0; i < p; i++) + o += i + i * i; + go = o; + + return get_a_B (); + } +}; + + +struct B gb1 (1111), gb2 (2); +static B * __attribute__ ((noinline, noclone)) +get_a_B () +{ + return &gb1; +} + +static A * __attribute__ ((noinline, noclone)) +get_an_A () +{ + return &gb2; +} + +} + +static int __attribute__ ((noinline, noclone)) +get_a_number () +{ + return 5; +} + +extern "C" void abort (void); + +int main (int argc, char *argv[]) +{ + for (int i = 0; i < get_a_number (); i++) + { + struct A *p = get_an_A (); + struct A *r = p->foo (4); + if (r->fi != 1111) + abort (); + if (go != 22) + abort (); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/ipa/pr60640-4.C b/gcc/testsuite/g++.dg/ipa/pr60640-4.C new file mode 100644 index 00000000000..eb9eb627f85 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60640-4.C @@ -0,0 +1,85 @@ +// { dg-do run } +// { dg-options "-O3 -fdump-ipa-cp" } + +struct Distraction +{ + char fc[8]; + virtual Distraction * return_self () + { return this; } +}; + +namespace { + +struct A; +static A * __attribute__ ((noinline, noclone)) get_an_A (); + +static int go; + +struct A +{ + int fi; + + A () : fi(777) {} + A (int pi) : fi (pi) {} + virtual void foo (int p) = 0; +}; + +struct B : public Distraction, A +{ + B () : Distraction(), A() { } + B (int pi) : Distraction (), A (pi) {} + virtual void foo (int p) + { + int o = fi; + for (int i = 0; i < p; i++) + o += i + i * i; + go = o; + } +}; + + +struct B gb (2); +static A * __attribute__ ((noinline, noclone)) +get_an_A () +{ + return &gb; +} + +} + +static int __attribute__ ((noinline, noclone)) +get_a_number () +{ + return 5; +} + +extern "C" void abort (void); + +static void __attribute__ ((noinline, noclone)) +bar () +{ + for (int i = 0; i < get_a_number (); i++) + { + struct A *p = get_an_A (); + p->foo (4); + if (go != 22) + abort (); + } +} + +int main (int argc, char *argv[]) +{ + for (int i = 0; i < get_a_number (); i++) + { + struct A *p = get_an_A (); + p->foo (4); + if (go != 22) + abort (); + } + + bar (); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Thunk fixed offset" 2 "cp"} } */ +/* { dg-final { cleanup-ipa-dump "cp" } } */ diff --git a/gcc/testsuite/g++.dg/lto/pr60567_0.C b/gcc/testsuite/g++.dg/lto/pr60567_0.C new file mode 100644 index 00000000000..966a3c3bc74 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr60567_0.C @@ -0,0 +1,23 @@ +// PR lto/60567 +// { dg-lto-do link } +// { dg-lto-options { { -flto -fno-use-linker-plugin } } } +// { dg-extra-ld-options "-r -nostdlib" } + +#pragma implementation +struct S {}; + +#pragma interface +struct T +{ + virtual void foo (const S &) = 0; +}; + +struct U +{ + virtual void bar (const S &) = 0; +}; + +struct V : public T, public U +{ + virtual void bar (const S &) {} +}; diff --git a/gcc/testsuite/g++.dg/opt/pr60849.C b/gcc/testsuite/g++.dg/opt/pr60849.C new file mode 100644 index 00000000000..52d8826b0c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr60849.C @@ -0,0 +1,13 @@ +// { dg-do compile } +// { dg-options "-O2" } + +int g; + +extern "C" int isnan (); + +void foo(float a) { + int (*xx)(...); + xx = isnan; + if (xx(a)) + g++; +} diff --git a/gcc/testsuite/g++.dg/pr49718.C b/gcc/testsuite/g++.dg/pr49718.C index d7f2710a994..b1cc5deb7ac 100644 --- a/gcc/testsuite/g++.dg/pr49718.C +++ b/gcc/testsuite/g++.dg/pr49718.C @@ -2,7 +2,8 @@ /* { dg-options "-O2 -finstrument-functions" } */ /* { dg-additional-options "-mno-explicit-relocs" { target alpha*-*-* } } */ /* { dg-additional-options "-mno-relax-pic-calls" { target mips*-*-* } } */ -/* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 1} } */ +/* { dg-final { scan-assembler-times "__cyg_profile_func_enter" 1 { target { ! { hppa*-*-hpux* } } } } } */ +/* { dg-final { scan-assembler-times "__cyg_profile_func_enter,%r" 1 { target hppa*-*-hpux* } } } */ #define NOINSTR __attribute__((no_instrument_function)) diff --git a/gcc/testsuite/g++.dg/template/crash119.C b/gcc/testsuite/g++.dg/template/crash119.C new file mode 100644 index 00000000000..95d80a8ffc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash119.C @@ -0,0 +1,8 @@ +// PR c++/59115 + +template<typename T, float, int, typename U> void foo(T, U) {} // { dg-error "valid type" } + +void bar() +{ + foo(0, 0); // { dg-error "matching" } +} diff --git a/gcc/testsuite/g++.dg/torture/pr60609.C b/gcc/testsuite/g++.dg/torture/pr60609.C new file mode 100644 index 00000000000..9ddec0b601d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60609.C @@ -0,0 +1,252 @@ +/* { dg-do assemble } */ + +class exception +{ +}; +class bad_alloc:exception +{ +}; +class logic_error:exception +{ +}; +class domain_error:logic_error +{ +}; +class invalid_argument:logic_error +{ +}; +class length_error:logic_error +{ +}; +class overflow_error:exception +{ +}; +typedef int mpz_t[]; +template < class > class __gmp_expr; +template <> class __gmp_expr < mpz_t > +{ + ~__gmp_expr (); +}; + +class PIP_Solution_Node; +class internal_exception +{ + ~internal_exception (); +}; +class not_an_integer:internal_exception +{ +}; +class not_a_variable:internal_exception +{ +}; +class not_an_optimization_mode:internal_exception +{ +}; +class not_a_bounded_integer_type_width:internal_exception +{ +}; +class not_a_bounded_integer_type_representation:internal_exception +{ +}; +class not_a_bounded_integer_type_overflow:internal_exception +{ +}; +class not_a_complexity_class:internal_exception +{ +}; +class not_a_control_parameter_name:internal_exception +{ +}; +class not_a_control_parameter_value:internal_exception +{ +}; +class not_a_pip_problem_control_parameter_name:internal_exception +{ +}; +class not_a_pip_problem_control_parameter_value:internal_exception +{ +}; +class not_a_relation:internal_exception +{ +}; +class ppl_handle_mismatch:internal_exception +{ +}; +class timeout_exception +{ + ~timeout_exception (); +}; +class deterministic_timeout_exception:timeout_exception +{ +}; +void __assert_fail (const char *, const char *, int, int *) +__attribute__ ((__noreturn__)); +void PL_get_pointer (void *); +int Prolog_is_address (); +inline int +Prolog_get_address (void **p1) +{ + Prolog_is_address ()? static_cast < + void >(0) : __assert_fail ("Prolog_is_address", "./swi_cfli.hh", 0, 0); + PL_get_pointer (p1); + return 0; +} + +class non_linear:internal_exception +{ +}; +class not_unsigned_integer:internal_exception +{ +}; +class not_universe_or_empty:internal_exception +{ +}; +class not_a_nil_terminated_list:internal_exception +{ +}; +class PPL_integer_out_of_range +{ + __gmp_expr < mpz_t > n; +}; +void handle_exception (); +template < typename T > T * term_to_handle (int, const char *) +{ + if (Prolog_is_address ()) + { + void *p; + Prolog_get_address (&p); + return static_cast < T * >(0); + } + throw; +} + +void +ppl_new_MIP_Problem_from_MIP_Problem () +try +{ + term_to_handle < int >(0, "ppl_new_MIP_Problem_from_MIP_Problem/2"); +} + +catch (exception &) +{ +} + +int +ppl_PIP_Tree_Node_parametric_values () +{ + try + { + PIP_Solution_Node *a = term_to_handle < PIP_Solution_Node > (0, 0); + (void)a; + return 1; + } + catch (internal_exception &) + { + } + catch (not_unsigned_integer &) + { + handle_exception (); + } + catch (non_linear &) + { + handle_exception (); + } + catch (not_a_variable &) + { + handle_exception (); + } + catch (not_an_integer &) + { + handle_exception (); + } + catch (ppl_handle_mismatch &) + { + handle_exception (); + } + catch (not_an_optimization_mode &) + { + handle_exception (); + } + catch (not_a_complexity_class &) + { + handle_exception (); + } + catch (not_a_bounded_integer_type_width &) + { + handle_exception (); + } + catch (not_a_bounded_integer_type_representation &) + { + handle_exception (); + } + catch (not_a_bounded_integer_type_overflow &) + { + handle_exception (); + } + catch (not_a_control_parameter_name &) + { + handle_exception (); + } + catch (not_a_control_parameter_value &) + { + handle_exception (); + } + catch (not_a_pip_problem_control_parameter_name &) + { + handle_exception (); + } + catch (not_a_pip_problem_control_parameter_value &) + { + handle_exception (); + } + catch (not_universe_or_empty &) + { + handle_exception (); + } + catch (not_a_relation &) + { + handle_exception (); + } + catch (not_a_nil_terminated_list &) + { + handle_exception (); + } + catch (PPL_integer_out_of_range &) + { + handle_exception (); + } + catch (int &) + { + } catch (timeout_exception &) + { + handle_exception (); + } catch (deterministic_timeout_exception &) + { + handle_exception (); + } catch (overflow_error &) + { + handle_exception (); + } catch (domain_error &) + { + handle_exception (); + } catch (length_error &) + { + handle_exception (); + } catch (invalid_argument &) + { + handle_exception (); + } catch (logic_error &) + { + handle_exception (); + } catch (bad_alloc &) + { + handle_exception (); + } catch (exception &) + { + handle_exception (); + } catch ( ...) + { + handle_exception (); + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/pr60659.C b/gcc/testsuite/g++.dg/torture/pr60659.C new file mode 100644 index 00000000000..f0158a5220a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60659.C @@ -0,0 +1,58 @@ +// { dg-do compile } +template <typename _InputIterator> void __distance (_InputIterator); +template <typename _InputIterator> +void distance (_InputIterator, _InputIterator p2) +{ + __distance (p2); +} + +namespace boost +{ +template <class Iterator> struct A +{ + typedef typename Iterator::difference_type type; +}; +template <class T> typename T::const_iterator end (T &); +template <class T> typename T::const_iterator begin (T &); +template <class T> struct D : A<typename T::const_iterator> +{ +}; +template <class T> typename D<T>::type distance (const T &p1) +{ + distance (boost::begin (p1), boost::end (p1)); + return 0; +} +template <class IteratorT> class B +{ +public: + typedef B type; + typedef IteratorT const_iterator; +}; +} + +typedef int storage_t[]; +struct F; +template <template <typename> class> struct G +{ + G (const G &p1) { p1.m_fn1 ().m_fn1 (0); } + const F &m_fn1 () const + { + const void *a; + a = &data_m; + return *static_cast<const F *>(a); + } + storage_t *data_m; +}; + +struct F +{ + virtual F *m_fn1 (void *) const; +}; +template <typename> struct H; +struct C : G<H> +{ + typedef int difference_type; +}; +boost::B<C> AllTransVideos (); +int b = boost::distance (AllTransVideos ()); + diff --git a/gcc/testsuite/g++.dg/torture/pr60746.C b/gcc/testsuite/g++.dg/torture/pr60746.C new file mode 100644 index 00000000000..7ce6ebe6bc0 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60746.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +class One +{ +public: + virtual unsigned long getSize () const; +}; + +class Two +{ + virtual int run (); +}; + +int +Two::run () +{ + One list_arry[5][2]; + int orig = 0; + if (list_arry[3][orig].getSize () > 0 + || list_arry[4][orig].getSize () > 0) + { + } +} diff --git a/gcc/testsuite/g++.dg/torture/pr60750.C b/gcc/testsuite/g++.dg/torture/pr60750.C new file mode 100644 index 00000000000..a344bd764a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60750.C @@ -0,0 +1,21 @@ +// { dg-do run } +// { dg-options "-std=c++11" } + +#include <string> +#include <stdexcept> + +const std::string err_prefix = "Problem: "; +void thrower (std::string msg) +{ + throw std::runtime_error(err_prefix + std::move(msg)); +} + +int main(int argc, char **argv) +{ + try { + std::string base = "hello"; + thrower(std::move(base)); + } catch (const std::runtime_error &e) { + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/torture/pr60854.C b/gcc/testsuite/g++.dg/torture/pr60854.C new file mode 100644 index 00000000000..fa4b2e71ab7 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60854.C @@ -0,0 +1,13 @@ +template <typename T> +class MyClass +{ +public: + __attribute__ ((__always_inline__)) inline MyClass () { ; } +}; + +extern template class MyClass<double>; + +void Func() +{ + MyClass<double> x; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/forwprop-switch.C b/gcc/testsuite/g++.dg/tree-ssa/forwprop-switch.C new file mode 100644 index 00000000000..c3f12ac45ae --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/forwprop-switch.C @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-O -fdump-tree-cddce1" } + +enum Scale { E1, E2, E3, E4, E5, E6, E7, E8 }; + +int Test(Scale s) +{ + switch(s) + { + case E1: return 12; + case E2: return 17; + case E3: return 22; + case E4: return 42; + default: break; + } + return 0; +} + +// tree forwprop should have eliminated the (int) s cast for the +// switch value and directly switch on the 's' parameter + +// { dg-final { scan-tree-dump-not "\\\(int\\\)" "cddce1" } } +// { dg-final { scan-tree-dump "switch \\\(s_.\\\(D\\\)\\\)" "cddce1" } } +// { dg-final { cleanup-tree-dump "cddce1" } } diff --git a/gcc/testsuite/g++.dg/vect/pr60836.cc b/gcc/testsuite/g++.dg/vect/pr60836.cc new file mode 100644 index 00000000000..83bb1837531 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr60836.cc @@ -0,0 +1,39 @@ +// { dg-do compile } + +int a, b; +typedef double (*NormFunc) (const int &); +int & +max (int &p1, int &p2) +{ + if (p1 < p2) + return p2; + return p1; +} + +struct A +{ + int operator () (int p1, int p2) + { + return max (p1, p2); + } +}; +template < class, class > double +norm_ (const int &) +{ + char c, d; + A e; + for (; a; a++) + { + b = e (b, d); + b = e (b, c); + } +} + +void +norm () +{ + static NormFunc f = norm_ < int, A >; + f = 0; +} + +// { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/g++.dg/warn/Weff1.C b/gcc/testsuite/g++.dg/warn/Weff1.C deleted file mode 100644 index a00dc29bf5f..00000000000 --- a/gcc/testsuite/g++.dg/warn/Weff1.C +++ /dev/null @@ -1,5 +0,0 @@ -// { dg-options "-Weffc++" } - -struct S {}; -/* Base classes should have virtual destructors. */ -struct T : public S {}; // { dg-warning "" } diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C index d40de3d7c1a..9f2e4bea43b 100644 --- a/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-2.C @@ -6,18 +6,18 @@ // destructor, in which case it would be possible but unsafe to delete // an instance of a derived class through a pointer to the base class. -struct A // { dg-bogus "non-virtual destructor" } +struct A { protected: - ~A(); + ~A(); // inaccessible - no warning public: virtual void f() = 0; }; -struct B // { dg-bogus "non-virtual destructor" } +struct B { private: - ~B(); + ~B(); // inaccessible - no warning public: virtual void f() = 0; }; @@ -52,3 +52,25 @@ private: public: virtual void f() = 0; }; + +struct H {}; + +struct I1 : H +{}; +struct I2 : private H +{}; + +struct J1 : H +{ virtual ~J1 ();}; +struct J2 : private H +{ virtual ~J2 ();}; + +struct K // { dg-warning "accessible non-virtual destructor" } +{ + virtual void k (); +}; + +struct L1 : K // { dg-warning "accessible non-virtual destructor" } +{virtual ~L1 ();}; +struct L2 : private K +{virtual ~L2 ();}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C new file mode 100644 index 00000000000..e83134b062b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-3.C @@ -0,0 +1,75 @@ +// { dg-do compile } +// { dg-options "-Weffc++" } + +// Warn when a class has virtual functions and accessible non-virtual +// destructor, in which case it would be possible but unsafe to delete +// an instance of a derived class through a pointer to the base class. + +struct A +{ +protected: + ~A(); // inaccessible - no warning +public: + virtual void f() = 0; +}; + +struct B +{ +private: + ~B(); // inaccessible - no warning +public: + virtual void f() = 0; +}; + +struct C // { dg-warning "non-virtual destructor" } +{ + virtual void f() = 0; +}; + +struct D // { dg-warning "non-virtual destructor" } +{ + ~D(); + virtual void f() = 0; +}; + +struct E; + +struct F // { dg-warning "non-virtual destructor" } +{ +protected: + friend class E; + ~F(); +public: + virtual void f() = 0; +}; + +struct G // { dg-warning "non-virtual destructor" } +{ +private: + friend class E; + ~G(); +public: + virtual void f() = 0; +}; + +struct H {}; + +struct I1 : H +{}; +struct I2 : private H +{}; + +struct J1 : H // { dg-warning "accessible non-virtual destructor" } +{ virtual ~J1 ();}; +struct J2 : private H +{ virtual ~J2 ();}; + +struct K // { dg-warning "accessible non-virtual destructor" } +{ + virtual void k (); +}; + +struct L1 : K // { dg-warning "accessible non-virtual destructor" } +{virtual ~L1 ();}; +struct L2 : private K +{virtual ~L2 ();}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C b/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C new file mode 100644 index 00000000000..dd6d9d7689e --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor-4.C @@ -0,0 +1,75 @@ +// { dg-do compile } +// { dg-options "-Weffc++ -Wno-non-virtual-dtor" } + +// Warn when a class has virtual functions and accessible non-virtual +// destructor, in which case it would be possible but unsafe to delete +// an instance of a derived class through a pointer to the base class. + +struct A +{ +protected: + ~A(); +public: + virtual void f() = 0; +}; + +struct B +{ +private: + ~B(); +public: + virtual void f() = 0; +}; + +struct C +{ + virtual void f() = 0; +}; + +struct D +{ + ~D(); + virtual void f() = 0; +}; + +struct E; + +struct F +{ +protected: + friend class E; + ~F(); +public: + virtual void f() = 0; +}; + +struct G +{ +private: + friend class E; + ~G(); +public: + virtual void f() = 0; +}; + +struct H {}; + +struct I1 : H +{}; +struct I2 : private H +{}; + +struct J1 : H +{ virtual ~J1 ();}; +struct J2 : private H +{ virtual ~J2 ();}; + +struct K +{ + virtual void k (); +}; + +struct L1 : K +{virtual ~L1 ();}; +struct L2 : private K +{virtual ~L2 ();}; diff --git a/gcc/testsuite/g++.dg/warn/Wnvdtor.C b/gcc/testsuite/g++.dg/warn/Wnvdtor.C index b04fdcbe6b1..f03cff5b31c 100644 --- a/gcc/testsuite/g++.dg/warn/Wnvdtor.C +++ b/gcc/testsuite/g++.dg/warn/Wnvdtor.C @@ -8,3 +8,4 @@ extern "Java" virtual void bar( void); }; } + diff --git a/gcc/testsuite/g++.dg/warn/nonnull2.C b/gcc/testsuite/g++.dg/warn/nonnull2.C new file mode 100644 index 00000000000..10515a47405 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/nonnull2.C @@ -0,0 +1,10 @@ +// PR c++/60764 +// { dg-options "-Wall" } + +struct foo +{ + foo () __attribute__ ((nonnull (1))); +}; + +const foo &x = foo (); // { dg-bogus "null argument" } +foo y = foo (); // { dg-bogus "null argument" } diff --git a/gcc/testsuite/g++.dg/warn/warn_format_signedness.C b/gcc/testsuite/g++.dg/warn/warn_format_signedness.C new file mode 100644 index 00000000000..473d522c8a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/warn_format_signedness.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Wformat -Wformat-signedness" } */ + +/* PR c/60194 */ + +void foo(unsigned u, int i, unsigned char uc, signed char sc) { + __builtin_printf("%d\n", u); /* { dg-warning "expects argument of type 'int', but argument 2 has type 'unsigned int'" } */ + __builtin_printf("%u\n", i); /* { dg-warning "expects argument of type 'unsigned int', but argument 2 has type 'int'" } */ + __builtin_printf("%c\n", sc); + __builtin_printf("%c\n", uc); +} diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C b/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C deleted file mode 100644 index aa5530fff7f..00000000000 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-1.C +++ /dev/null @@ -1,21 +0,0 @@ -// { dg-do assemble } -// { dg-options "-Wnon-virtual-dtor -Weffc++" } -// 981203 bkoz -// g++/15309 - -class bahamian { -public: - bahamian (); - ~bahamian (); -}; - -class miami : public bahamian // { dg-warning "" } // WARNING - -{ -public: - miami (); - ~miami (); -}; - - - - diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C b/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C deleted file mode 100644 index 28317973127..00000000000 --- a/gcc/testsuite/g++.old-deja/g++.benjamin/15309-2.C +++ /dev/null @@ -1,10 +0,0 @@ -// { dg-do assemble } -// { dg-options "-Wnon-virtual-dtor -Weffc++" } -// 981203 bkoz -// g++/15309 - -class bermuda { // { dg-warning "" } // WARNING - -public: - virtual int func1(int); - ~bermuda(); -}; diff --git a/gcc/testsuite/g++.old-deja/g++.jason/overload21.C b/gcc/testsuite/g++.old-deja/g++.jason/overload21.C index 72397930367..125aee0dbfc 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/overload21.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/overload21.C @@ -1,6 +1,6 @@ // { dg-do assemble } struct X { - void f (int = 4, char = 'r'); // { dg-error "previous specification" } + void f (int = 4, char = 'r'); // { dg-message "previous specification" } void g (int = 4, char = 'r'); // { dg-message "previous specification" } }; diff --git a/gcc/testsuite/g++.old-deja/g++.law/init5.C b/gcc/testsuite/g++.old-deja/g++.law/init5.C index c1d647b1b05..7ed89e21924 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/init5.C +++ b/gcc/testsuite/g++.old-deja/g++.law/init5.C @@ -11,8 +11,8 @@ extern int fred( int); class X { public : - void f( int = fred( 0) ) ; // { dg-error "" } previous spec + void f( int = fred( 0) ) ; // { dg-message "previous spec" } } ; -void X::f( int x = fred( 0) ) {// { dg-error "" } .* +void X::f( int x = fred( 0) ) { // { dg-error "default argument" } } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb121.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb121.C index e01d7478838..036c8d5152a 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb121.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb121.C @@ -3,7 +3,7 @@ class A { private: int i1_; public: - void f(int const i1 = 1); // { dg-error "previous specification" } + void f(int const i1 = 1); // { dg-message "previous specification" } }; void diff --git a/gcc/testsuite/gcc.c-torture/compile/pr28865.c b/gcc/testsuite/gcc.c-torture/compile/pr28865.c index aa6ae078aca..4ad0f5c4306 100644 --- a/gcc/testsuite/gcc.c-torture/compile/pr28865.c +++ b/gcc/testsuite/gcc.c-torture/compile/pr28865.c @@ -1,3 +1,5 @@ +/* { dg-xfail-if "PR target/60602" { sparc*-*-solaris2.9* && { ! gas } } { "-O0" } } */ + struct var_len { int field1; diff --git a/gcc/testsuite/gcc.c-torture/compile/pr60556.c b/gcc/testsuite/gcc.c-torture/compile/pr60556.c new file mode 100644 index 00000000000..c775432f8bb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr60556.c @@ -0,0 +1,8 @@ +/* PR middle-end/60556 */ + +int g (int); + +unsigned long long f (void) +{ + return (unsigned long long)(long)&g; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr60655-1.c b/gcc/testsuite/gcc.c-torture/compile/pr60655-1.c new file mode 100644 index 00000000000..6f84f6e4ea0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr60655-1.c @@ -0,0 +1,31 @@ +/* { dg-options "-fdata-sections" } */ + +typedef unsigned char unit; +typedef unit *unitptr; +extern short global_precision; +typedef __SIZE_TYPE__ size_t; +extern void *memcpy (void *dest, const void *src, size_t n); + +short mp_compare(const unit* r1, const unit* r2) +{ + register short precision; + precision = global_precision; + (r1) = ((r1)+(precision)-1); + (r2) = ((r2)+(precision)-1); + do + { if (*r1 < *r2) + return(-1); + if (*((r1)--) > *((r2)--)) + return(1); + } while (--precision); +} + +static unit modulus[((1280+(2*8))/8)]; +static unit d_data[((1280+(2*8))/8)*2]; + +int upton_modmult (unitptr prod, unitptr multiplicand, unitptr multiplier) +{ + unitptr d = d_data; + while (mp_compare(d,modulus) > 0) + memcpy((void*)(prod), (const void*)(d), (global_precision)); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr60655-2.c b/gcc/testsuite/gcc.c-torture/compile/pr60655-2.c new file mode 100644 index 00000000000..f33db643f72 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr60655-2.c @@ -0,0 +1,30 @@ + +typedef unsigned char unit; +typedef unit *unitptr; +extern short global_precision; +typedef __SIZE_TYPE__ size_t; +extern void *memcpy (void *dest, const void *src, size_t n); + +short mp_compare(const unit* r1, const unit* r2) +{ + register short precision; + precision = global_precision; + (r1) = ((r1)+(precision)-1); + (r2) = ((r2)+(precision)-1); + do + { if (*r1 < *r2) + return(-1); + if (*((r1)--) > *((r2)--)) + return(1); + } while (--precision); +} + +static unit modulus[((1280+(2*8))/8)]; +static unit d_data[((1280+(2*8))/8)*2]; + +int upton_modmult (unitptr prod, unitptr multiplicand, unitptr multiplier) +{ + unitptr d = d_data; + while (mp_compare(d,modulus) > 0) + memcpy((void*)(prod), (const void*)(d), (global_precision)); +} diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c index 32f9e9bb631..c1a63f1b3aa 100644 --- a/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-flag.c @@ -1,5 +1,5 @@ /* Test atomic_flag routines for existence and execution. */ -/* { dg-do run } */ +/* { dg-do run { xfail hppa*-*-hpux* } } */ /* { dg-options "-std=c11 -pedantic-errors" } */ #include <stdatomic.h> diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-6.c b/gcc/testsuite/gcc.dg/builtin-bswap-6.c index 024ebf1edf6..efda8706e63 100644 --- a/gcc/testsuite/gcc.dg/builtin-bswap-6.c +++ b/gcc/testsuite/gcc.dg/builtin-bswap-6.c @@ -1,7 +1,10 @@ /* { dg-do compile { target arm*-*-* alpha*-*-* i?86-*-* powerpc*-*-* rs6000-*-* x86_64-*-* s390*-*-* } } */ /* { dg-require-effective-target stdint_types } */ /* { dg-options "-O -fdump-rtl-combine" } */ -/* { dg-options "-O -fdump-rtl-combine -march=z900" { target s390-*-* } } */ + +/* The branch cost setting prevents the return value from being + calculated with arithmetic instead of doing a compare. */ +/* { dg-additional-options "-march=z900 -mbranch-cost=0" { target s390*-*-* } } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-6a.c b/gcc/testsuite/gcc.dg/builtin-bswap-6a.c new file mode 100644 index 00000000000..f93bcde1027 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-bswap-6a.c @@ -0,0 +1,44 @@ +/* { dg-do compile { target arm*-*-* alpha*-*-* i?86-*-* powerpc*-*-* rs6000-*-* x86_64-*-* s390*-*-* } } */ +/* { dg-require-effective-target stdint_types } */ +/* { dg-options "-O2 -fdump-rtl-combine" } */ +/* { dg-additional-options "-march=z900" { target s390-*-* } } */ + +/* The test is similiar to builtin-bswap-6.c but returns 1/2 instead + of 0/1 to prevent GCC from calculating the return value with + arithmetic instead of a comparison. This requires the optimization + level to be bumped up to -O2 at least for x86_64. */ + +#include <stdint.h> + +#define BS(X) __builtin_bswap32(X) + +int foo1 (uint32_t a) +{ + if (BS (a) == 0xA0000) + return 1; + return 2; +} + +int foo2 (uint32_t a) +{ + if (BS (a) != 0xA0000) + return 1; + return 2; +} + +int foo3 (uint32_t a, uint32_t b) +{ + if (BS (a) == BS (b)) + return 1; + return 2; +} + +int foo4 (uint32_t a, uint32_t b) +{ + if (BS (a) != BS (b)) + return 1; + return 2; +} + +/* { dg-final { scan-rtl-dump-not "bswapsi" "combine" } } */ +/* { dg-final { cleanup-rtl-dump "combine" } } */ diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-7.c b/gcc/testsuite/gcc.dg/builtin-bswap-7.c index 399b825ac43..035c7368ad0 100644 --- a/gcc/testsuite/gcc.dg/builtin-bswap-7.c +++ b/gcc/testsuite/gcc.dg/builtin-bswap-7.c @@ -3,6 +3,10 @@ /* { dg-require-effective-target lp64 } */ /* { dg-options "-O -fdump-rtl-combine" } */ +/* The branch cost setting prevents the return value from being + calculated with arithmetic instead of doing a compare. */ +/* { dg-additional-options "-mbranch-cost=0" { target s390x-*-* } } */ + #include <stdint.h> #define BS(X) __builtin_bswap64(X) diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-7a.c b/gcc/testsuite/gcc.dg/builtin-bswap-7a.c new file mode 100644 index 00000000000..d77bd478366 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-bswap-7a.c @@ -0,0 +1,44 @@ +/* { dg-do compile { target arm*-*-* alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* powerpc*-*-* rs6000-*-* } } */ +/* { dg-require-effective-target stdint_types } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2 -fdump-rtl-combine" } */ + +/* The test is similiar to builtin-bswap-7.c but returns 1/2 instead + of 0/1 to prevent GCC from calculating the return value with + arithmetic instead of a comparison. This requires the optimization + level to be bumped up to -O2 at least for x86_64. */ + +#include <stdint.h> + +#define BS(X) __builtin_bswap64(X) + +int foo1 (uint64_t a) +{ + if (BS (a) == 0xA00000000) + return 1; + return 2; +} + +int foo2 (uint64_t a) +{ + if (BS (a) != 0xA00000000) + return 1; + return 2; +} + +int foo3 (uint64_t a, uint64_t b) +{ + if (BS (a) == BS (b)) + return 1; + return 2; +} + +int foo4 (uint64_t a, uint64_t b) +{ + if (BS (a) != BS (b)) + return 1; + return 2; +} + +/* { dg-final { scan-rtl-dump-not "bswapdi" "combine" } } */ +/* { dg-final { cleanup-rtl-dump "combine" } } */ diff --git a/gcc/testsuite/gcc.dg/format/warn-signedness.c b/gcc/testsuite/gcc.dg/format/warn-signedness.c new file mode 100644 index 00000000000..473d522c8a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/warn-signedness.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-Wformat -Wformat-signedness" } */ + +/* PR c/60194 */ + +void foo(unsigned u, int i, unsigned char uc, signed char sc) { + __builtin_printf("%d\n", u); /* { dg-warning "expects argument of type 'int', but argument 2 has type 'unsigned int'" } */ + __builtin_printf("%u\n", i); /* { dg-warning "expects argument of type 'unsigned int', but argument 2 has type 'int'" } */ + __builtin_printf("%c\n", sc); + __builtin_printf("%c\n", uc); +} diff --git a/gcc/testsuite/gcc.dg/graphite/pr55022.c b/gcc/testsuite/gcc.dg/graphite/pr55022.c new file mode 100644 index 00000000000..c631c0e23e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr55022.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fgraphite-identity" } */ + +extern void abort (void); + +void __attribute__((noinline,noclone)) +f(int *limit, int minLen, int maxLen) +{ + int i; + + for (i = minLen; i <= maxLen; i++) { + limit[i] = i; + } +} + +int main() +{ + int limit[256], i; + f (limit, 0, 255); + for (i = 0; i < 256; ++i) + { + if (limit[i] != i) + abort (); + __asm__ volatile ("" : : : "memory"); + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/graphite/pr59817-1.c b/gcc/testsuite/gcc.dg/graphite/pr59817-1.c new file mode 100644 index 00000000000..175fa16fd71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr59817-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -floop-interchange" } */ + +int kd; + +void +n2(void) +{ + static int so; + static short int i5; + int wj; + int *il; + int *nk = &so; + for (wj = 0; wj < 2; ++wj) + *nk = ((i5 += *il) || kd ); +} diff --git a/gcc/testsuite/gcc.dg/graphite/pr59817-2.c b/gcc/testsuite/gcc.dg/graphite/pr59817-2.c new file mode 100644 index 00000000000..13950076814 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr59817-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -floop-interchange" } */ + +void +xl(void) +{ + static int j3; + for (j3 = 0; j3 < 1; ++j3) { + static int f2; + static int w7; + short int b5; + int ok; + f2 = (b5 += ok) ? (w7 = 0): (w7 ? 0 : (f2 = ok)); + } +} diff --git a/gcc/testsuite/gcc.dg/graphite/pr60740.c b/gcc/testsuite/gcc.dg/graphite/pr60740.c new file mode 100644 index 00000000000..5b7c1802236 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr60740.c @@ -0,0 +1,16 @@ +/* { dg-options "-O2 -floop-interchange" } */ + +int **db6 = 0; + +void +k26(void) +{ + static int geb = 0; + int *a22 = &geb; + int **l30 = &a22; + int *c4b; + int ndf; + for (ndf = 0; ndf <= 1; ++ndf) + *c4b = (db6 == l30) && (*a22)--; +} + diff --git a/gcc/testsuite/gcc.dg/graphite/pr60785.c b/gcc/testsuite/gcc.dg/graphite/pr60785.c new file mode 100644 index 00000000000..87c1c685b0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr60785.c @@ -0,0 +1,27 @@ +/* { dg-options "-O2 -floop-interchange" } */ + +static int +aqc(void) +{ + return 1; +} + +void +gkd(void) +{ + int wu0; + static int b1y; + static int gw2; + static int *ydw = &gw2; + static int **m3l = &ydw; + **m3l = 0; + for (b1y = 0; b1y < 1; ++b1y) + { + int *cpj = &gw2; + if (*ydw |= aqc()) + { + *cpj = 0; + *ydw = wu0; + } + } +} diff --git a/gcc/testsuite/gcc.dg/lto/pr55113_0.c b/gcc/testsuite/gcc.dg/lto/pr55113_0.c index 0477fe41bc8..8c309761bce 100644 --- a/gcc/testsuite/gcc.dg/lto/pr55113_0.c +++ b/gcc/testsuite/gcc.dg/lto/pr55113_0.c @@ -2,6 +2,7 @@ /* { dg-lto-do link } */ /* { dg-lto-options { { -flto -fshort-double -O0 } } }*/ /* { dg-skip-if "PR60410" { x86_64-*-* || { i?86-*-* && lp64 } } } */ +/* { dg-skip-if "PR60410" { i?86-*-solaris2.1[0-9]* } } */ int main(void) diff --git a/gcc/testsuite/gcc.dg/lto/pr59626_0.c b/gcc/testsuite/gcc.dg/lto/pr59626_0.c new file mode 100644 index 00000000000..752982fb506 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr59626_0.c @@ -0,0 +1,15 @@ +/* { dg-lto-do run } */ + +int __atoi (const char *) __asm__("atoi"); +extern inline __attribute__((always_inline,gnu_inline)) +int atoi (const char *x) +{ + return __atoi (x); +} + +int bar (int (*)(const char *)); + +int main() +{ + return bar (atoi); +} diff --git a/gcc/testsuite/gcc.dg/lto/pr59626_1.c b/gcc/testsuite/gcc.dg/lto/pr59626_1.c new file mode 100644 index 00000000000..9b3fa1d2e36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr59626_1.c @@ -0,0 +1,4 @@ +int bar (int (*fn)(const char *)) +{ + return fn ("0"); +} diff --git a/gcc/testsuite/gcc.dg/lto/pr60720_0.c b/gcc/testsuite/gcc.dg/lto/pr60720_0.c new file mode 100644 index 00000000000..79cef5dad1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60720_0.c @@ -0,0 +1,15 @@ +/* { dg-lto-do run } */ +/* { dg-extra-ld-options { -w } } */ + +/* ??? lto.exp does not allow to scan for + :1:12: warning: type of 'x' does not match original declaration + extern int x[]; + ^ + :1:5: note: previously declared here + int x; + ^ */ + +extern int x[]; +int *foo[] = { &x[0] }; + +int main() { return *foo[0]; } diff --git a/gcc/testsuite/gcc.dg/lto/pr60720_1.c b/gcc/testsuite/gcc.dg/lto/pr60720_1.c new file mode 100644 index 00000000000..6d1a0d47b7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60720_1.c @@ -0,0 +1 @@ +int x; diff --git a/gcc/testsuite/gcc.dg/lto/pr60820_0.c b/gcc/testsuite/gcc.dg/lto/pr60820_0.c new file mode 100644 index 00000000000..349cf6a02f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60820_0.c @@ -0,0 +1,13 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options {{-flto -r -nostdlib -O2}} } */ +#include <stdio.h> +struct in6_addr {int bah;}; +extern const struct in6_addr in6addr_any; +static const struct in6_addr local_in6addr_any = {1}; +#pragma weak in6addr_any = local_in6addr_any + +__attribute__ ((used)) +void foo2() +{ + fprintf (stderr, "v1: %p, v2: %p\n", &local_in6addr_any, &in6addr_any); +} diff --git a/gcc/testsuite/gcc.dg/lto/pr60820_1.c b/gcc/testsuite/gcc.dg/lto/pr60820_1.c new file mode 100644 index 00000000000..16009e424f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr60820_1.c @@ -0,0 +1,11 @@ +#include <stdio.h> +struct in6_addr {int bah;}; +extern const struct in6_addr in6addr_any; +static const struct in6_addr local_in6addr_any = {1}; +#pragma weak in6addr_any = local_in6addr_any + +__attribute__ ((used)) +void foo() +{ + fprintf (stderr, "v1: %p, v2: %p\n", &local_in6addr_any, &in6addr_any); +} diff --git a/gcc/testsuite/gcc.dg/pr60797.c b/gcc/testsuite/gcc.dg/pr60797.c new file mode 100644 index 00000000000..45090bae502 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr60797.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { alias } } */ + +extern int foo __attribute__((alias("bar"))); /* { dg-error "supported" } */ +int main() +{ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr60844.c b/gcc/testsuite/gcc.dg/pr60844.c new file mode 100644 index 00000000000..16ed243d74c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr60844.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/60844 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ +/* { dg-additional-options "-mtune=atom" { target { i?86-*-* x86_64-*-* } } } */ + +void +foo (int *x, int y, int z) +{ + int b, c = x[0], d = x[1]; + for (b = 0; b < 1; b++) + { + int e = (y ? 1 : 0) | (d ? 2 : 0) | (z ? 1 : 0); + e |= (c ? 2 : 0) | ((1 >> b) ? 1 : 0); + x[2 + b] = e; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr56965-1.c b/gcc/testsuite/gcc.dg/torture/pr56965-1.c new file mode 100644 index 00000000000..2512db3965d --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr56965-1.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-options "-fschedule-insns" { target scheduling } } */ + +extern void abort (void); + +struct S { + int i; + int j; +}; + +struct U { + struct S s; +} __attribute__((may_alias)); + +int __attribute__((noinline,noclone)) +foo (struct U *p, struct U *q) +{ + int i; + q->s.j = 1; + i = p->s.i; + return i; +} + +int main() +{ + int a[3]; + int *p = a; + p[1] = 0; + if (foo ((struct U *)(p + 1), (struct U *)p) != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr56965-2.c b/gcc/testsuite/gcc.dg/torture/pr56965-2.c new file mode 100644 index 00000000000..04f55914e9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr56965-2.c @@ -0,0 +1,34 @@ +extern void abort (void); + +struct S { int i; int j; }; +struct X { struct S s; int k; }; +struct Y { int k; struct S s; }; +union U { struct X x; struct Y y; } __attribute__((may_alias)); + +int __attribute__((noinline)) +foo (union U *p, union U *q) +{ + p->x.s.j = 1; + q->y.s.i = 0; + return p->x.s.j; +} + +struct R { int i; int j; } __attribute__((may_alias)); + +int __attribute__((noinline)) +bar (struct R *p, struct R *q) +{ + p->i = 1; + q->j = 0; + return p->i; +} + +int main() +{ + int a[3]; + if (foo ((union U *)&a[0], (union U *)&a[0]) != 0) + abort (); + if (bar ((struct R *)&a[1], (struct R *)&a[0]) != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr60733.c b/gcc/testsuite/gcc.dg/torture/pr60733.c new file mode 100644 index 00000000000..49cc59ea33a --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr60733.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +int a, d, e, f, g, h, i, j, k; +unsigned short b; + +short +fn1 (int p1, int p2) +{ + return p1 * p2; +} + +int +main () +{ + for (; a; a--) + { + int l = 0; + if (f >= 0) + { + for (; h;) + e = 0; + for (; l != -6; l--) + { + j = fn1 (b--, d); + for (g = 0; g; g = 1) + ; + k = e ? 2 : 0; + } + i = 0; + for (;;) + ; + } + } + d = 0; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr60766.c b/gcc/testsuite/gcc.dg/torture/pr60766.c new file mode 100644 index 00000000000..6f16e3b7408 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr60766.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ + +int m = 9; + +int main() +{ + int n, x; + + n = m; + for (x = 0; x <= n; x++) + if (n == x + (x + 1) + (x + 2)) + return 0; + + __builtin_abort(); +} diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c b/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c index 5297098fc91..85a4b2a840c 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c +++ b/gcc/testsuite/gcc.dg/tree-prof/update-loopch.c @@ -15,8 +15,9 @@ main () is once reached directly from entry point of function, rest via loopback edge. */ /* { dg-final-use { scan-ipa-dump "loop depth 1, count 33334" "profile"} } */ -/* { dg-final-use { scan-tree-dump "loop depth 1, count 33332" "optimized"} } */ -/* { dg-final-use { scan-tree-dump-times "Removing basic block \[^\r\n\]*\[\\r\\n\]+\[^\r\n\]*\[\\r\\n\]+Invalid sum of\[^\r\n\]*\[\\r\\n\]+Invalid sum of" 1 "optimized"} } */ -/* { dg-final-use { scan-tree-dump-times "Invalid sum of" 2 "optimized"} } */ +/* { dg-final-use { scan-tree-dump "loop depth 1, count 33333" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "loop depth 1, count 33332" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "Removing basic block" "optimized"} } */ +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { cleanup-ipa-dump "profile" } } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c index 99b27ce02f1..b49cf648c7d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c @@ -16,6 +16,7 @@ void bar (void) /* We used to treat malloc functions like pure and const functions, but malloc functions may clobber global memory. Only the function result does not alias any other pointer. - Hence, we must have a VDEF for a before and after the call to foo(). */ -/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias"} } */ + Hence, we must have a VDEF for a before and after the call to foo(). + And one after the call to abort(). */ +/* { dg-final { scan-tree-dump-times "VDEF" 3 "alias"} } */ /* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-13.c index 19f892eaa85..43b92c11569 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-13.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-13.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1 -fdump-tree-optimized" } */ -/* { dg-additional-options "-mbranch-cost=2" { target { i?86-*-* x86_64-*-* mips*-*-* s390*-*-* avr*-*-* } } } */ +/* { dg-additional-options "-mbranch-cost=2" { target { i?86-*-* x86_64-*-* s390*-*-* avr*-*-* } } } */ _Bool f1(_Bool a, _Bool b) { @@ -17,5 +17,5 @@ _Bool f1(_Bool a, _Bool b) /* For LOGICAL_OP_NON_SHORT_CIRCUIT, this should be optimized into return a & b;, with no ifs. */ -/* { dg-final { scan-tree-dump-not "if" "optimized" { target { i?86-*-* x86_64-*-* mips*-*-* s390*-*-* avr*-*-* } } } } */ +/* { dg-final { scan-tree-dump-not "if" "optimized" { target { i?86-*-* x86_64-*-* s390*-*-* avr*-*-* } } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/uninit-B-O0.c b/gcc/testsuite/gcc.dg/uninit-B-O0.c index e2883a38ea8..5557ace6f8d 100644 --- a/gcc/testsuite/gcc.dg/uninit-B-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-B-O0.c @@ -9,7 +9,7 @@ void baz (void) { int i; - if (i) /* { dg-warning "uninit" "uninit i warning" { xfail *-*-* } } */ + if (i) /* { dg-warning "'i' is used uninitialized in this function" } */ bar (i); foo (&i); } diff --git a/gcc/testsuite/gcc.dg/uninit-I-O0.c b/gcc/testsuite/gcc.dg/uninit-I-O0.c index 655f5489279..761f65b485b 100644 --- a/gcc/testsuite/gcc.dg/uninit-I-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-I-O0.c @@ -3,6 +3,6 @@ int sys_msgctl (void) { - struct { int mode; } setbuf; /* { dg-warning "'setbuf\.mode' is used" {} { xfail *-*-* } } */ - return setbuf.mode; + struct { int mode; } setbuf; + return setbuf.mode; /* { dg-warning "'setbuf\.mode' is used uninitialized in this function" } */ } diff --git a/gcc/testsuite/gcc.dg/uninit-pr19430-O0.c b/gcc/testsuite/gcc.dg/uninit-pr19430-O0.c index 4ce258653d6..63f0b2b44f3 100644 --- a/gcc/testsuite/gcc.dg/uninit-pr19430-O0.c +++ b/gcc/testsuite/gcc.dg/uninit-pr19430-O0.c @@ -16,10 +16,9 @@ foo (int i) return j; } - int foo2( void ) { - int rc; /* { dg-warning "'rc' is used uninitialized in this function" "uninitialized" { xfail *-*-* } 21 } */ - return rc; + int rc; + return rc; /* { dg-warning "'rc' is used uninitialized in this function" } */ *&rc = 0; } @@ -29,7 +28,7 @@ void frob(int *pi); int main(void) { int i; - printf("i = %d\n", i); /* { dg-warning "'i' is used uninitialized in this function" "uninitialized" { xfail *-*-* } 32 } */ + printf("i = %d\n", i); /* { dg-warning "'i' is used uninitialized in this function" } */ frob(&i); return 0; @@ -38,6 +37,6 @@ int main(void) void foo3(int*); void bar3(void) { int x; - if(x) /* { dg-warning "'x' is used uninitialized in this function" "uninitialized" { xfail *-*-* } 41 } */ + if(x) /* { dg-warning "'x' is used uninitialized in this function" } */ foo3(&x); } diff --git a/gcc/testsuite/gcc.dg/vect/pr60505.c b/gcc/testsuite/gcc.dg/vect/pr60505.c new file mode 100644 index 00000000000..694051320ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr60505.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Wall -Werror" } */ + +void foo(char *in, char *out, int num) +{ + int i; + char ovec[16] = {0}; + + for(i = 0; i < num ; ++i) + out[i] = (ovec[i] = in[i]); + out[num] = ovec[num/2]; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr60656.c b/gcc/testsuite/gcc.dg/vect/pr60656.c new file mode 100644 index 00000000000..4950275fb87 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr60656.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_long } */ + +#include "tree-vect.h" + +__attribute__ ((noinline)) long +foo () +{ + int v[] = {5000, 5001, 5002, 5003}; + long s = 0; + int i; + + for(i = 0; i < 4; ++i) + { + long P = v[i]; + s += P * P * P; + } + return s; +} + +long +bar () +{ + int v[] = {5000, 5001, 5002, 5003}; + long s = 0; + int i; + + for(i = 0; i < 4; ++i) + { + long P = v[i]; + s += P * P * P; + __asm__ volatile (""); + } + return s; +} + +int main() +{ + check_vect (); + + if (foo () != bar ()) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_si_to_di_pattern } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr60841.c b/gcc/testsuite/gcc.dg/vect/pr60841.c new file mode 100644 index 00000000000..44b5d019169 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr60841.c @@ -0,0 +1,183 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math" } */ + +/* This testcase shouldn't consume much memory or produce a 1GB vectorizer + dump file due to SLP tree explosion. */ + +struct S { int f1, f2, f3, f4; } a; +struct T { short f3, f2, f1, f4; }; +int b, c, d, e, f, g; +unsigned long z; + +void +foo (struct T *p, struct T *q, int x, int w) +{ + for (; x; x++) + { + struct S h; + int i; + struct T j; + struct T *r; + h = a; + g = 0; + r = p + 2 * (c + 4) + 1; + j = *r; + r = p; + f = r->f1 - 1; + b = +1.0 + f * f; + i = (r->f2 + j.f2) / 2; + f = r->f3 - 1; + b += 1.0 - i * f * f; + f = r->f4 - 1; + if (b) + b += -1.0 - i * f; + if (b / w) + { + h.f1 += 8.0 * r->f1; + h.f2 += 8.0 * r->f2; + h.f3 += 8.0 * r->f3; + h.f4 += 8.0 * r->f4; + g = 1; + } + r++; + f = r->f1; + i = (r->f2 + j.f2) / 2; + f = r->f3 - 1; + b += 1.0 - i * f * f; + i = (r->f4); + if (b * 65535UL / w) + { + h.f1 += 10.0 * r->f1; + h.f2 += 10.0 * r->f2; + h.f3 += 10.0 * r->f3; + h.f4 += 10.0 * r->f4; + g += 10.0; + } + r++; + f = r->f1; + z = 5UL * i; + f = r->f2; + i = (r->f3 + j.f3) / 2; + b = -i * f * f; + i = (r->f4 + j.f4) / 2; + if (b * 65535UL / 25.0f) + { + h.f1 += 8.0 * r->f1; + h.f2 += 8.0 * r->f2; + h.f3 += 8.0 * r->f3; + h.f4 += 8.0 * r->f4; + g += 8.0; + } + r++; + f = r->f1 - j.f1; + b = 1 * 2.0 * i * f * f; + f = r->f2; + b += 4.0 * f; + i = r->f3 / 2; + f = r->f4 - 1; + if (b * 1) + { + h.f1 += 8.0 * r->f1; + h.f2 += 8.0 * r->f2; + h.f3 += 8.0 * r->f3; + h.f4 += 8.0 * r->f4; + g += 8.0; + } + b = 4.0 * 1 * f; + if (b * 65535UL / 25.0f) + { + h.f1 += 20.0 * r->f1; + h.f2 += 20.0 * r->f2; + h.f3 += 20.0 * r->f3; + h.f4 += 20.0 * r->f4; + g += 20.0; + } + b = 5 * (0.0 - i); + if (b < 0) + { + h.f1 += 8.0 * r->f1; + h.f2 += 8.0 * r->f2; + h.f3 += 8.0 * r->f3; + h.f4 += 8.0 * r->f4; + g += 8.0; + } + r = p + 2 * (c + 4); + i = (r->f1 + j.f1); + b = 1 * 2.0 * i * 1; + f = r->f2 - 1; + i = (r->f3 + j.f3) / 2; + b = 5 * (0.0 - i) * f * f; + i = (r->f4 + j.f4) / 2; + if (b * 65535UL / 25.0f) + { + h.f1 += 10.0 * r->f1; + h.f2 += 10.0 * r->f2; + h.f3 += 10.0 * r->f3; + h.f4 += 10.0 * r->f4; + g += 10.0; + } + r++; + f = r->f1; + b = 5UL * i * f; + i = (r->f2 + j.f2) / 2; + f = r->f3 - 1; + b = 5 * (0.0 - i) * f * f; + f = r->f4 - 1; + if (b * 65535UL / 25.0f) + { + h.f1 += 40.0 * r->f1; + h.f2 += 40.0 * r->f2; + h.f3 += 40.0 * r->f3; + h.f4 += 40.0 * r->f4; + g += 40.0; + } + r++; + i = (r->f1 + j.f1); + b = 5 * i * f; + f = r->f2; + b = 4.0 * f * f; + f = r->f3; + i = (r->f4 + j.f4) / 2; + b = 5 * (0.0 - i) * f * f; + if (b * 25.0f) + { + h.f1 += 8.0 * r->f1; + h.f2 += 8.0 * r->f2; + h.f3 += 8.0 * r->f3; + h.f4 += 8.0 * r->f4; + g += 8.0; + } + r = p + 4 * (c + 4); + i = r->f1 / 2; + b = 5 * (1.0 + i); + i = r->f2 + j.f2; + f = r->f3 - 1; + b = 5 * (0.0 - i) * f * f; + i = (r->f4 + j.f4) / 2; + if (b * 65535UL / 25.0f) + { + h.f1 += 5.0 * r->f1; + h.f2 += 5.0 * r->f2; + h.f3 += 5.0 * r->f3; + h.f4 += 5.0 * r->f4; + g += 5.0; + } + b = 5 * (1.0 + i); + if (b < 0) + { + h.f1 += 5.0 * r->f1; + h.f2 += 5.0 * r->f2; + h.f3 += 5.0 * r->f3; + h.f4 += 5.0 * r->f4; + g += 5.0; + } + q->f1 = (h.f1 + g / 2 - 1) / g; + q->f2 = (h.f2 + g / 2 - 1) / g; + q->f3 = (h.f3 + g / 2 - 1) / g; + q->f4 = (h.f4 + g / 2 - 1) / g; + p++; + q++; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr60650-2.c b/gcc/testsuite/gcc.target/arm/pr60650-2.c new file mode 100644 index 00000000000..19467607b6e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr60650-2.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -march=armv7-a" } */ + +int a, h, j; +long long d, e, i; +int f; +fn1 (void *p1, int p2) +{ + switch (p2) + case 8: +{ + register b = *(long long *) p1, c asm ("r2"); + asm ("%0": "=r" (a), "=r" (c):"r" (b), "r" (0)); + *(long long *) p1 = c; + } +} + +fn2 () +{ + int k; + k = f; + while (1) + { + fn1 (&i, sizeof i); + e = d + k; + switch (d) + case 0: + ( + { + register l asm ("r4"); + register m asm ("r0"); + asm (" .err .endif\n\t": "=r" (h), "=r" (j):"r" (m), + "r" + (l));; + }); + } +} diff --git a/gcc/testsuite/gcc.target/arm/pr60657.c b/gcc/testsuite/gcc.target/arm/pr60657.c new file mode 100644 index 00000000000..66355c39a94 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr60657.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv7-a" } */ + + +void foo (void); + +void +bar (int x, int y) +{ + y = 9999; + if (x & (1 << y)) + foo (); +} diff --git a/gcc/testsuite/gcc.target/arm/pr60663.c b/gcc/testsuite/gcc.target/arm/pr60663.c new file mode 100644 index 00000000000..b79b830e1a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr60663.c @@ -0,0 +1,11 @@ +/* PR rtl-optimization/60663 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv7-a" } */ + +int +foo (void) +{ + unsigned i, j; + asm ("%0 %1" : "=r" (i), "=r" (j)); + return i; +} diff --git a/gcc/testsuite/gcc.target/avr/dev-specific-rmw.c b/gcc/testsuite/gcc.target/avr/dev-specific-rmw.c new file mode 100644 index 00000000000..0a8393e4966 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/dev-specific-rmw.c @@ -0,0 +1,13 @@ +/* Verify that rmw instructions supported */ +/* { dg-do assemble } */ + +int main() +{ + #ifdef __AVR_ISA_RMW__ + __asm("xch Z, r12"); + __asm("las Z, r12"); + __asm("lac Z, r12"); + __asm("lat Z, r12"); + #endif + return 0; +} diff --git a/gcc/testsuite/gcc.target/epiphany/btst-1.c b/gcc/testsuite/gcc.target/epiphany/btst-1.c new file mode 100644 index 00000000000..b5667cce74c --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/btst-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-common" } */ +/* { dg-final { scan-assembler-not "movt" } } */ +/* { dg-final { scan-assembler-not "and" } } */ +/* { dg-final { scan-assembler "lsl" } } */ + +int +tst (int i) +{ + return (i & (1<<21)) ? 6 : 9; +} diff --git a/gcc/testsuite/gcc.target/epiphany/mode-switch.c b/gcc/testsuite/gcc.target/epiphany/mode-switch.c new file mode 100644 index 00000000000..d7f80a962fd --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/mode-switch.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "#-917506" } } */ +/* PR 60651 */ + +int a; +int c; + +void __attribute__((interrupt)) +misc_handler (void) { + a*= c; +} diff --git a/gcc/testsuite/gcc.target/epiphany/t1068-2.c b/gcc/testsuite/gcc.target/epiphany/t1068-2.c new file mode 100644 index 00000000000..3baefcb909a --- /dev/null +++ b/gcc/testsuite/gcc.target/epiphany/t1068-2.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-common" } */ +/* ??? we should be able to get down to 4 movt, but first we'll have to + teach mov2add about flag handling. Maybe add the code that was removed in + r144425 from regmove to postreload; epiphany needs tweaks to the addsi3 + expander to generate a CC reg clobber in the pass. */ +/* { dg-final { scan-assembler-times "movt" 6 } } */ + +typedef unsigned int uint32_t; +typedef unsigned int uint16_t; + +struct dma_desc { + uint32_t config; + uint32_t inner_stride; + uint32_t count; + uint32_t outer_stride; + void *src_addr; + void *dst_addr; +}; +typedef struct dma_desc e_dma_desc_t; + +e_dma_desc_t dma; +int a; +int id[8]; +#define NULL ((void *)0) + +static inline void _ez_dma_set(register e_dma_desc_t *dma, + uint32_t config, + e_dma_desc_t *next, + uint16_t inner_src, uint16_t inner_dst, + uint16_t inner_count, uint16_t outer_count, + uint16_t outer_src, uint16_t outer_dst, + void *src, void*dst) { + //register e_dma_desc_t *dmap = dma; + + dma->config = config | (((uint32_t)next)<<16); + dma->inner_stride = (inner_dst << 16) | inner_src; + dma->count = (inner_count << 16) | outer_count; + dma->outer_stride = (outer_dst << 16) | outer_src; + dma->src_addr = src; + dma->dst_addr = dst; +} + +void __attribute__((section(".text.ds1"))) +dmas_inline1(void) { + register e_dma_desc_t *dmap = &dma; + + _ez_dma_set(dmap, 3, NULL, + 1, 2, + 12, 13, + 5, 1, + id, &a); +} diff --git a/gcc/testsuite/gcc.target/i386/avx2-vpand-3.c b/gcc/testsuite/gcc.target/i386/avx2-vpand-3.c index 67ca4a7cda1..8c08bf5ced5 100644 --- a/gcc/testsuite/gcc.target/i386/avx2-vpand-3.c +++ b/gcc/testsuite/gcc.target/i386/avx2-vpand-3.c @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-mavx2 -O2 -ftree-vectorize -save-temps" } */ +/* { dg-options "-mavx2 -mno-prefer-avx128 -O2 -ftree-vectorize -save-temps" } */ /* { dg-require-effective-target avx2 } */ diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c index 933f265eed5..30b42aa38c2 100644 --- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c +++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-2.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { ! ia32 } } } */ -/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-load" } */ +/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-load -mno-prefer-avx128" } */ void avx_test (char **cp, char **ep) diff --git a/gcc/testsuite/gcc.target/i386/bmi-1.c b/gcc/testsuite/gcc.target/i386/bmi-1.c index a05cb275adc..c66a9d83b29 100644 --- a/gcc/testsuite/gcc.target/i386/bmi-1.c +++ b/gcc/testsuite/gcc.target/i386/bmi-1.c @@ -2,10 +2,10 @@ /* { dg-options "-O2 -mbmi " } */ /* { dg-final { scan-assembler "andn\[^\\n]*eax" } } */ /* { dg-final { scan-assembler-times "bextr\[ \\t]+\[^\\n]*eax" 2 } } */ -/* { dg-final { scan-assembler "blsi\[^\\n]*eax" } } */ -/* { dg-final { scan-assembler "blsmsk\[^\\n]*eax" } } */ -/* { dg-final { scan-assembler "blsr\[^\\n]*eax" } } */ -/* { dg-final { scan-assembler "tzcntl\[^\\n]*eax" } } */ +/* { dg-final { scan-assembler-times "blsi\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "blsmsk\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "blsr\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "tzcntl\[^\\n]*eax" 2 } } */ #include <x86intrin.h> @@ -36,19 +36,43 @@ func_blsi32 (unsigned int X) } unsigned int +func_blsi32_2 (unsigned int X) +{ + return _blsi_u32(X); +} + +unsigned int func_blsmsk32 (unsigned int X) { return __blsmsk_u32(X); } unsigned int +func_blsmsk32_2 (unsigned int X) +{ + return _blsmsk_u32(X); +} + +unsigned int func_blsr32 (unsigned int X) { return __blsr_u32(X); } unsigned int +func_blsr32_2 (unsigned int X) +{ + return _blsr_u32(X); +} + +unsigned int func_tzcnt32 (unsigned int X) { return __tzcnt_u32(X); } + +unsigned int +func_tzcnt32_2 (unsigned int X) +{ + return _tzcnt_u32(X); +} diff --git a/gcc/testsuite/gcc.target/i386/bmi-2.c b/gcc/testsuite/gcc.target/i386/bmi-2.c index 68d06a20540..6eea66aa0f6 100644 --- a/gcc/testsuite/gcc.target/i386/bmi-2.c +++ b/gcc/testsuite/gcc.target/i386/bmi-2.c @@ -2,10 +2,10 @@ /* { dg-options "-O2 -mbmi " } */ /* { dg-final { scan-assembler "andn\[^\\n]*rax" } } */ /* { dg-final { scan-assembler-times "bextr\[ \\t]+\[^\\n]*rax" 2 } } */ -/* { dg-final { scan-assembler "blsi\[^\\n]*rax" } } */ -/* { dg-final { scan-assembler "blsmsk\[^\\n]*rax" } } */ -/* { dg-final { scan-assembler "blsr\[^\\n]*rax" } } */ -/* { dg-final { scan-assembler "tzcntq\[^\\n]*rax" } } */ +/* { dg-final { scan-assembler-times "blsi\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "blsmsk\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "blsr\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "tzcntq\[^\\n]*rax" 2 } } */ #include <x86intrin.h> @@ -36,19 +36,43 @@ func_blsi64 (unsigned long long X) } unsigned long long +func_blsi64_2 (unsigned long long X) +{ + return _blsi_u64 (X); +} + +unsigned long long func_blsmsk64 (unsigned long long X) { return __blsmsk_u64 (X); } unsigned long long +func_blsmsk64_2 (unsigned long long X) +{ + return _blsmsk_u64 (X); +} + +unsigned long long func_blsr64 (unsigned long long X) { return __blsr_u64 (X); } unsigned long long +func_blsr64_2 (unsigned long long X) +{ + return _blsr_u64 (X); +} + +unsigned long long func_tzcnt64 (unsigned long long X) { return __tzcnt_u64 (X); } + +unsigned long long +func_tzcnt64_2 (unsigned long long X) +{ + return _tzcnt_u64 (X); +} diff --git a/gcc/testsuite/gcc.target/i386/funcspec-2.c b/gcc/testsuite/gcc.target/i386/funcspec-2.c index 88c14b29b28..e535586f9b7 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-2.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-2.c @@ -1,5 +1,6 @@ /* Test whether using target specific options, we can generate FMA4 code. */ /* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -march=k8" } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.target/i386/funcspec-3.c b/gcc/testsuite/gcc.target/i386/funcspec-3.c index f3f4db76a84..bac79865d99 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-3.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-3.c @@ -2,6 +2,7 @@ setting the architecture. */ /* { dg-do compile } */ /* { dg-require-effective-target lp64 } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -march=k8 -mno-sse3" } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.target/i386/funcspec-9.c b/gcc/testsuite/gcc.target/i386/funcspec-9.c index 78714e12417..14b7abd2601 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-9.c +++ b/gcc/testsuite/gcc.target/i386/funcspec-9.c @@ -1,5 +1,6 @@ /* Test whether using target specific options, we can generate FMA4 code. */ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -march=k8 -mfpmath=sse -msse2" } */ extern void exit (int); diff --git a/gcc/testsuite/gcc.target/i386/isa-1.c b/gcc/testsuite/gcc.target/i386/isa-1.c index d98c14ffb19..3a4406fc0e4 100644 --- a/gcc/testsuite/gcc.target/i386/isa-1.c +++ b/gcc/testsuite/gcc.target/i386/isa-1.c @@ -1,4 +1,5 @@ /* { dg-do run } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=x86-64" } } */ /* { dg-options "-march=x86-64 -msse4" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c index a2b66d966d0..3117771d431 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 { target { ! { ia32 } } } } } */ /* { dg-final { scan-assembler-times "movdqa" 4 { target { ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c index c2f49f0cc5f..303edca950a 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */ /* { dg-final { scan-assembler-times "movdqa" 8 { target { ! { ia32 } } } } } */ /* { dg-final { scan-assembler-times "movdqa" 4 { target { ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c index c61c067951b..1ea682a1065 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 8 { target { ! { ia32 } } } } } */ /* { dg-final { scan-assembler-times "movdqa" 4 { target { ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c index 8a646d509a1..3befef95d82 100644 --- a/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memcpy-vector_loop-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4} } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c index ad0d130371b..f7e45165c44 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4 } } */ diff --git a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c index f2ceb442c7b..92e61000425 100644 --- a/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c +++ b/gcc/testsuite/gcc.target/i386/memset-vector_loop-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=atom" } } */ /* { dg-options "-O2 -march=atom -minline-all-stringops -mstringop-strategy=vector_loop" } */ /* { dg-final { scan-assembler-times "movdqa" 4} } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2di-2.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-2.c index a2313a4b190..6a50573a55e 100644 --- a/gcc/testsuite/gcc.target/i386/sse2-init-v2di-2.c +++ b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-2.c @@ -1,4 +1,5 @@ /* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=core2" } } */ /* { dg-options "-O2 -msse4 -march=core2 -dp" } */ #include <emmintrin.h> diff --git a/gcc/testsuite/gcc.target/i386/ssetype-1.c b/gcc/testsuite/gcc.target/i386/ssetype-1.c index ef89059b8d8..a8252295587 100644 --- a/gcc/testsuite/gcc.target/i386/ssetype-1.c +++ b/gcc/testsuite/gcc.target/i386/ssetype-1.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* This test checks for absolute memory operands. */ /* { dg-require-effective-target nonpic } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -msse2 -march=k8" } */ /* { dg-final { scan-assembler "andpd\[^\\n\]*magic" } } */ /* { dg-final { scan-assembler "andnpd\[^\\n\]*magic" } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssetype-2.c b/gcc/testsuite/gcc.target/i386/ssetype-2.c index b68a63923fb..37953ca64d0 100644 --- a/gcc/testsuite/gcc.target/i386/ssetype-2.c +++ b/gcc/testsuite/gcc.target/i386/ssetype-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -msse2 -march=k8" } */ /* { dg-final { scan-assembler "andpd" } } */ /* { dg-final { scan-assembler "andnpd" } } */ diff --git a/gcc/testsuite/gcc.target/i386/ssetype-5.c b/gcc/testsuite/gcc.target/i386/ssetype-5.c index 75133e9fa68..4e22e59e556 100644 --- a/gcc/testsuite/gcc.target/i386/ssetype-5.c +++ b/gcc/testsuite/gcc.target/i386/ssetype-5.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* This test checks for absolute memory operands. */ /* { dg-require-effective-target nonpic } */ +/* { dg-skip-if "" { i?86-*-* x86_64-*-* } { "-march=*" } { "-march=k8" } } */ /* { dg-options "-O2 -msse2 -march=k8" } */ /* { dg-final { scan-assembler "pand\[^\\n\]*magic" } } */ /* { dg-final { scan-assembler "pandn\[^\\n\]*magic" } } */ diff --git a/gcc/testsuite/gcc.target/i386/vec-may_alias.c b/gcc/testsuite/gcc.target/i386/vec-may_alias.c new file mode 100644 index 00000000000..e970497454f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/vec-may_alias.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -w -Wno-abi" } */ + +typedef int v2si __attribute__ ((vector_size (8))); +typedef short v4hi __attribute__ ((vector_size (8))); +typedef short v4hia __attribute__ ((vector_size (8), may_alias)); + +__attribute__ ((noinline, noclone)) +int f (v2si A, int N) +{ return ((v4hia)A)[N]; } + +__attribute__ ((noinline, noclone)) +int g (v2si A, int N) +{ return ((v4hi)A)[N]; } + +int main() +{ + v2si x = { 0, 0 }, y = { 1, 1 }; + if (f (x, 0) || f (x, 1) || f (x, 2) || f (x, 3)) + __builtin_abort (); + if (g (y, 0) != 1 || g (y, 1) || g (y, 2) != 1 || g (y, 3)) + __builtin_abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.target/mips/umips-store16-1.c b/gcc/testsuite/gcc.target/mips/umips-store16-1.c new file mode 100644 index 00000000000..6377e8569d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/umips-store16-1.c @@ -0,0 +1,30 @@ +/* { dg-options "(-mmicromips)" } */ +/* { dg-do assemble } */ + +register unsigned int global asm ("$16"); + +extern void exit (int) __attribute__((noreturn)); + +MICROMIPS void +test_sb (unsigned char *ptr, void (*f) (void)) +{ + ptr[0] = global; + f (); + exit (0); +} + +MICROMIPS void +test_sh (unsigned short *ptr, void (*f) (void)) +{ + ptr[0] = global; + f (); + exit (0); +} + +MICROMIPS void +test_sw (unsigned int *ptr, void (*f) (void)) +{ + ptr[0] = global; + f (); + exit (0); +} diff --git a/gcc/testsuite/gcc.target/mips/umips-store16-2.c b/gcc/testsuite/gcc.target/mips/umips-store16-2.c new file mode 100644 index 00000000000..0748edb5692 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/umips-store16-2.c @@ -0,0 +1,22 @@ +/* { dg-options "(-mmicromips) -dp" } */ + +MICROMIPS void +f1 (unsigned char *ptr) +{ + *ptr = 0; +} + +MICROMIPS void +f2 (unsigned short *ptr) +{ + *ptr = 0; +} + +MICROMIPS void +f3 (unsigned int *ptr) +{ + *ptr = 0; +} +/* { dg-final { scan-assembler "\tsb\t\\\$0,0\\(\\\$\[0-9\]+\\)\[^\n\]*length = 2" } } */ +/* { dg-final { scan-assembler "\tsh\t\\\$0,0\\(\\\$\[0-9\]+\\)\[^\n\]*length = 2" } } */ +/* { dg-final { scan-assembler "\tsw\t\\\$0,0\\(\\\$\[0-9\]+\\)\[^\n\]*length = 2" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/atomic_load_store-p8.c b/gcc/testsuite/gcc.target/powerpc/atomic_load_store-p8.c new file mode 100644 index 00000000000..8a5cbfaa36b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/atomic_load_store-p8.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-mcpu=power8 -O2" } */ +/* { dg-final { scan-assembler-times "lq" 1 } } */ +/* { dg-final { scan-assembler-times "stq" 1 } } */ +/* { dg-final { scan-assembler-not "bl __atomic" } } */ +/* { dg-final { scan-assembler-not "lqarx" } } */ +/* { dg-final { scan-assembler-not "stqcx" } } */ + +__int128 +atomic_load_128_relaxed (__int128 *ptr) +{ + return __atomic_load_n (ptr, __ATOMIC_RELAXED); +} + +void +atomic_store_128_relaxed (__int128 *ptr, __int128 val) +{ + __atomic_store_n (ptr, val, __ATOMIC_RELAXED); +} + diff --git a/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c index c1b98e2bba4..982a7483dbe 100644 --- a/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c +++ b/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c @@ -27,8 +27,8 @@ foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) cc = __builtin_tbegin ((void *)0x12345678); cc = __builtin_tbegin (tdb); cc = __builtin_tbegin (&global_tdb); - cc = __builtin_tbegin ((void *)(long long)(reg + 0x12345678)); - cc = __builtin_tbegin ((void *)(long long)(reg)); + cc = __builtin_tbegin ((void *)(long)(reg + 0x12345678)); + cc = __builtin_tbegin ((void *)(long)(reg)); __builtin_tbegin_nofloat ((void *)0); __builtin_tbegin_nofloat ((void *)-99999); @@ -36,8 +36,8 @@ foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) cc = __builtin_tbegin_nofloat ((void *)0x12345678); cc = __builtin_tbegin_nofloat (tdb); cc = __builtin_tbegin_nofloat (&global_tdb); - cc = __builtin_tbegin_nofloat ((void *)(long long)(reg + 0x12345678)); - cc = __builtin_tbegin_nofloat ((void *)(long long)(reg)); + cc = __builtin_tbegin_nofloat ((void *)(long)(reg + 0x12345678)); + cc = __builtin_tbegin_nofloat ((void *)(long)(reg)); __builtin_tbegin_retry ((void *)0, 0); cc = __builtin_tbegin_retry ((void *)0, 1); @@ -50,9 +50,9 @@ foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) cc = __builtin_tbegin_retry (&global_tdb, 42); cc = __builtin_tbegin_retry ((void *)0x12345678, global); cc = __builtin_tbegin_retry ( - (void *)(long long) (reg + 0x12345678), global + 1); + (void *)(long) (reg + 0x12345678), global + 1); cc = __builtin_tbegin_retry ( - (void *)(long long)(reg), global - 1); + (void *)(long)(reg), global - 1); __builtin_tbegin_retry_nofloat ((void *)0, 0); cc = __builtin_tbegin_retry_nofloat ((void *)0, 1); @@ -65,9 +65,9 @@ foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42); cc = __builtin_tbegin_retry_nofloat ((void *)0x12345678, global); cc = __builtin_tbegin_retry_nofloat ( - (void *)(long long) (reg + 0x12345678), global + 1); + (void *)(long) (reg + 0x12345678), global + 1); cc = __builtin_tbegin_retry_nofloat ( - (void *)(long long)(reg), global - 1); + (void *)(long)(reg), global - 1); __builtin_tbeginc (); diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c index df7e2bac874..6022efb97fe 100644 --- a/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c +++ b/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c @@ -1,12 +1,50 @@ -/* { dg-do compile } */ -/* { dg-options "-O3 -march=zEC12 -mzarch" } */ +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch --save-temps" } */ -int -foo () +/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin + instruction does not automatically preserves them. If the + transaction body is fully contained in a function the backend tries + after reload to get rid of the FPR save/restore operations + triggered by the clobbers. This testcase failed since the backend + was able to get rid of all FPR saves/restores and since these were + the only stack operations also of the entire stack space. So even + the save/restore of the stack pointer was omitted in the end. + However, since the frame layout has been fixed before, the prologue + still generated the stack pointer decrement making foo return with + a modified stack pointer. */ + +void abort(void); + +void __attribute__((noinline)) +foo (int a) +{ + if (__builtin_tbegin (0) == 0) + __builtin_tend (); +} + +#ifdef __s390x__ +#define GET_STACK_POINTER(SP) \ + asm volatile ("stg %%r15, %0" : "=QRST" (SP)); +#else +#define GET_STACK_POINTER(SP) \ + asm volatile ("st %%r15, %0" : "=QR" (SP)); +#endif + +int main(void) { - __builtin_tbegin_nofloat (0); - __builtin_tbegin_retry_nofloat (0, 42); + unsigned long new_sp, old_sp; + + GET_STACK_POINTER (old_sp); + foo(42); + GET_STACK_POINTER (new_sp); + + if (old_sp != new_sp) + abort (); + + return 0; } + /* Make sure no FPR saves/restores are emitted. */ -/* { dg-final { scan-assembler-not "std" } } */ -/* { dg-final { scan-assembler-not "ld" } } */ +/* { dg-final { scan-assembler-not "\tstd\t" } } */ +/* { dg-final { scan-assembler-not "\tld\t" } } */ diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c deleted file mode 100644 index 59621a4c19b..00000000000 --- a/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* { dg-do run } */ -/* { dg-options "-O3 -mhtm -Wa,-march=zEC12,-mzarch --save-temps" } */ - -/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin - instruction does not automatically preserves them. If the - transaction body is fully contained in a function the backend tries - after reload to get rid of the FPR save/restore operations - triggered by the clobbers. This testcase failed since the backend - was able to get rid of all FPR saves/restores and since these were - the only stack operations also of the entire stack space. So even - the save/restore of the stack pointer was omitted in the end. - However, since the frame layout has been fixed before, the prologue - still generated the stack pointer decrement making foo return with - a modified stack pointer. */ - -void abort(void); - -void __attribute__((noinline)) -foo (int a) -{ - /* This is just to prevent the tbegin code from actually being - executed. That way the test may even run on machines prior to - zEC12. */ - if (a == 42) - return; - - if (__builtin_tbegin (0) == 0) - __builtin_tend (); -} - -#ifdef __s390x__ -#define GET_STACK_POINTER(SP) \ - asm volatile ("stg %%r15, %0" : "=QRST" (SP)); -#else -#define GET_STACK_POINTER(SP) \ - asm volatile ("st %%r15, %0" : "=QR" (SP)); -#endif - -int main(void) -{ - unsigned long new_sp, old_sp; - - GET_STACK_POINTER (old_sp); - foo(42); - GET_STACK_POINTER (new_sp); - - if (old_sp != new_sp) - abort (); - - return 0; -} - -/* Make sure no FPR saves/restores are emitted. */ -/* { dg-final { scan-assembler-not "\tstd\t" } } */ -/* { dg-final { scan-assembler-not "\tld\t" } } */ diff --git a/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-1.c b/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-1.c new file mode 100644 index 00000000000..df7e2bac874 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +int +foo () +{ + __builtin_tbegin_nofloat (0); + __builtin_tbegin_retry_nofloat (0, 42); +} +/* Make sure no FPR saves/restores are emitted. */ +/* { dg-final { scan-assembler-not "std" } } */ +/* { dg-final { scan-assembler-not "ld" } } */ diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp index 1b6d94a2313..f2ba9298615 100644 --- a/gcc/testsuite/gcc.target/s390/s390.exp +++ b/gcc/testsuite/gcc.target/s390/s390.exp @@ -24,17 +24,17 @@ if ![istarget s390*-*-*] then { # Load support procs. load_lib gcc-dg.exp -# Return 1 if htm (etnd - extract nesting depth) instructions can be -# compiled. +# Return 1 if htm (etnd - extract nesting depth) instructions are +# understood by the assembler and can be executed. proc check_effective_target_htm { } { if { ![check_runtime s390_check_htm [subst { int main (void) { - unsigned int nd = 77; - asm (".insn rre,0xb2ec0000,%0,0" : "=d" (nd)); + unsigned int nd; + asm ("etnd %0" : "=d" (nd)); return nd; } - }]] } { return 0 } else { return 1 } + }] "-march=zEC12 -mzarch" ] } { return 0 } else { return 1 } } # If a testcase doesn't have special options, use these. diff --git a/gcc/testsuite/gcc.target/sh/memset.c b/gcc/testsuite/gcc.target/sh/memset.c new file mode 100644 index 00000000000..4695db3aefa --- /dev/null +++ b/gcc/testsuite/gcc.target/sh/memset.c @@ -0,0 +1,13 @@ +/* Check that the __builtin_memset function is inlined when + optimizing for speed. */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-not "jmp" } } */ + +void +test00(char *dstb) +{ + __builtin_memset (dstb, 0, 15); +} + diff --git a/gcc/testsuite/gfortran.dg/associate_15.f90 b/gcc/testsuite/gfortran.dg/associate_15.f90 new file mode 100644 index 00000000000..7e34eb518e0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/associate_15.f90 @@ -0,0 +1,40 @@ +! { dg-do run } +! Test the fix for PR58085, where the offset for 'x' was set to zero, +! rather than -1. +! +! Contributed by Vladimir Fuka <vladimir.fuka@gmail.com> +! +module foo +contains + function bar (arg) result (res) + integer arg, res(3) + res = [arg, arg+1, arg +2] + end function +end module + use foo + real d(3,3) + integer a,b,c + character(48) line1, line2 + associate (x=>shape(d)) + a = x(1) + b = x(2) + write (line1, *) a, b + write (line2, *) x + if (trim (line1) .ne. trim (line2)) call abort + end associate + associate (x=>[1,2]) + a = x(1) + b = x(2) + write (line1, *) a, b + write (line2, *) x + if (trim (line1) .ne. trim (line2)) call abort + end associate + associate (x=>bar(5)) ! make sure that we haven't broken function association + a = x(1) + b = x(2) + c = x(3) + write (line1, *) a, b, c + write (line2, *) x + if (trim (line1) .ne. trim (line2)) call abort + end associate +end diff --git a/gcc/testsuite/gfortran.dg/class_nameclash.f90 b/gcc/testsuite/gfortran.dg/class_nameclash.f90 new file mode 100644 index 00000000000..227d865962f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/class_nameclash.f90 @@ -0,0 +1,39 @@ +! { dg-do run } +! +! try to provoke class name clashes in gfc_build_class_symbol +! +module test_module + + implicit none + + type, public :: test_p + private + class (test_p), pointer :: next => null() + end type test_p + + type, public :: test +! Error in "call do_it (x)" below: +! Type mismatch in argument 'x' at (1); passed CLASS(test_p) to CLASS(test) + class (test), pointer :: next => null() + end type test + +contains + + subroutine do_it (x) + class (test_p), target :: x + + x%next => x + return + end subroutine do_it + +end module test_module + +use test_module + + implicit none + class (test_p), pointer :: x + + allocate (x) + call do_it (x) + deallocate (x) +end diff --git a/gcc/testsuite/gfortran.dg/finalize_25.f90 b/gcc/testsuite/gfortran.dg/finalize_25.f90 new file mode 100644 index 00000000000..cdbec4caca0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/finalize_25.f90 @@ -0,0 +1,55 @@ +! { dg-do run } +! +! PR fortran/58880 +! PR fortran/60495 +! +! Contributed by Andrew Benson and Janus Weil +! + +module gn + implicit none + type sl + integer, allocatable, dimension(:) :: lv + contains + final :: sld + end type + type :: nde + type(sl) :: r + end type nde + + integer :: cnt = 0 + +contains + + subroutine sld(s) + type(sl) :: s + cnt = cnt + 1 + ! print *,'Finalize sl' + end subroutine + subroutine ndm(s) + type(nde), intent(inout) :: s + type(nde) :: i + i=s + end subroutine ndm +end module + +program main + use gn + type :: nde2 + type(sl) :: r + end type nde2 + type(nde) :: x + + cnt = 0 + call ndm(x) + if (cnt /= 2) call abort() + + cnt = 0 + call ndm2() + if (cnt /= 3) call abort() +contains + subroutine ndm2 + type(nde2) :: s,i + i=s + end subroutine ndm2 +end program main diff --git a/gcc/testsuite/gfortran.dg/graphite/pr59817.f b/gcc/testsuite/gfortran.dg/graphite/pr59817.f new file mode 100644 index 00000000000..a9ee8f19dd7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/pr59817.f @@ -0,0 +1,14 @@ +! { dg-do compile } +! { dg-options "-O2 -floop-interchange" } + SUBROUTINE PREPD(ICAST,ICAS,ICASX,ICAS1,ICAS2,NDET,NM,III,IMP, + * CASMIN) + LOGICAL CASMIN + DIMENSION ICAST(NDET,NM),IMP(NM) + IF(CASMIN) THEN + DO K=1,NDET + DO L=1,NM + IF(L.EQ.K-1) ICAST(K,L) = 1 + END DO + END DO + END IF + END SUBROUTINE diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_17.f90 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_17.f90 new file mode 100644 index 00000000000..0fcff74b910 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_17.f90 @@ -0,0 +1,51 @@ +! { dg-do run } +! Tests fix for PR60717 in which offsets in recursive calls below +! were not being set correctly. +! +! Reported on comp.lang.fortran by Thomas Schnurrenberger +! +module m + implicit none + real :: chksum0 = 0, chksum1 = 0, chksum2 = 0 +contains + recursive subroutine show_real(a) + real, intent(in) :: a(:) + if (size (a) > 0) then + chksum0 = a(1) + chksum0 + call show_real (a(2:)) + end if + return + end subroutine show_real + recursive subroutine show_generic1(a) + class(*), intent(in) :: a(:) + if (size (a) > 0) then + select type (a) + type is (real) + chksum1 = a(1) + chksum1 + end select + call show_generic1 (a(2:)) ! recursive call outside SELECT TYPE + end if + return + end subroutine show_generic1 + recursive subroutine show_generic2(a) + class(*), intent(in) :: a(:) + if (size (a) > 0) then + select type (a) + type is (real) + chksum2 = a(1) + chksum2 + call show_generic2 (a(2:)) ! recursive call inside SELECT TYPE + end select + end if + return + end subroutine show_generic2 +end module m +program test + use :: m + implicit none + real :: array(1:6) = (/ 0, 1, 2, 3, 4, 5 /) + call show_real (array) + call show_generic1 (array) + call show_generic2 (array) + if (chksum0 .ne. chksum1) call abort + if (chksum0 .ne. chksum2) call abort +end program test diff --git a/gcc/testsuite/gfortran.dg/warn_conversion_4.f90 b/gcc/testsuite/gfortran.dg/warn_conversion_4.f90 index f911741f534..3d1b12582b3 100644 --- a/gcc/testsuite/gfortran.dg/warn_conversion_4.f90 +++ b/gcc/testsuite/gfortran.dg/warn_conversion_4.f90 @@ -11,8 +11,8 @@ contains subroutine test integer :: x x = int (abs (cmplx(2.3,0.1))) - x = int (abs (cmplx(2.3_dp,0.1))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might loose precision, consider using the KIND argument" } - x = int (abs (cmplx(2.3,0.1_dp))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might loose precision, consider using the KIND argument" } - x = int (abs (cmplx(2.3_dp,0.1_dp))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might loose precision, consider using the KIND argument" } + x = int (abs (cmplx(2.3_dp,0.1))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might lose precision, consider using the KIND argument" } + x = int (abs (cmplx(2.3,0.1_dp))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might lose precision, consider using the KIND argument" } + x = int (abs (cmplx(2.3_dp,0.1_dp))) ! { dg-warning "Conversion from REAL.8. to default-kind COMPLEX.4. at .1. might lose precision, consider using the KIND argument" } end subroutine test end module fft_mod diff --git a/gcc/testsuite/gnat.dg/test_raise_from_pure.adb b/gcc/testsuite/gnat.dg/test_raise_from_pure.adb index 66db2232e77..8f928c58584 100644 --- a/gcc/testsuite/gnat.dg/test_raise_from_pure.adb +++ b/gcc/testsuite/gnat.dg/test_raise_from_pure.adb @@ -1,4 +1,4 @@ --- { dg-do run { xfail arm*-*-* } } +-- { dg-do run } -- { dg-options "-O2" } -- This is an optimization test and its failure is only a missed optimization. diff --git a/gcc/testsuite/gnat.dg/vect11.adb b/gcc/testsuite/gnat.dg/vect11.adb new file mode 100644 index 00000000000..c8c8a0cb6eb --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect11.adb @@ -0,0 +1,33 @@ +-- { dg-do compile { target i?86-*-* x86_64-*-* } } +-- { dg-options "-O3 -msse2 -fdump-tree-optimized" } + +package body Vect11 is + + function "+" (X, Y : Sarray) return Sarray is + R : Sarray; + begin + for I in Sarray'Range loop + R(I) := X(I) + Y(I); + end loop; + return R; + end; + + procedure Add (X, Y : Sarray; R : out Sarray) is + begin + for I in Sarray'Range loop + R(I) := X(I) + Y(I); + end loop; + end; + + procedure Add (X, Y : not null access Sarray; R : not null access Sarray) is + begin + for I in Sarray'Range loop + pragma Loop_Optimize (Ivdep); + R(I) := X(I) + Y(I); + end loop; + end; + +end Vect11; + +-- { dg-final { scan-tree-dump-not "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/vect11.ads b/gcc/testsuite/gnat.dg/vect11.ads new file mode 100644 index 00000000000..f3ceac111a1 --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect11.ads @@ -0,0 +1,11 @@ +package Vect11 is + + -- Constrained array types are vectorizable + type Sarray is array (1 .. 4) of Float; + for Sarray'Alignment use 16; + + function "+" (X, Y : Sarray) return Sarray; + procedure Add (X, Y : Sarray; R : out Sarray); + procedure Add (X, Y : not null access Sarray; R : not null access Sarray); + +end Vect11; diff --git a/gcc/testsuite/gnat.dg/vect12.adb b/gcc/testsuite/gnat.dg/vect12.adb new file mode 100644 index 00000000000..f493c8bbb0f --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect12.adb @@ -0,0 +1,27 @@ +-- { dg-do compile { target i?86-*-* x86_64-*-* } } +-- { dg-options "-O3 -msse2 -fdump-tree-vect-details" } + +package body Vect12 is + + function "+" (X, Y : Sarray) return Sarray is + R : Sarray; + begin + for I in Sarray'Range loop + pragma Loop_Optimize (No_Vector); + R(I) := X(I) + Y(I); + end loop; + return R; + end; + + procedure Add (X, Y : Sarray; R : out Sarray) is + begin + for I in Sarray'Range loop + pragma Loop_Optimize (No_Vector); + R(I) := X(I) + Y(I); + end loop; + end; + +end Vect12; + +-- { dg-final { scan-tree-dump-not "vectorized 1 loops" "vect" } } +-- { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gnat.dg/vect12.ads b/gcc/testsuite/gnat.dg/vect12.ads new file mode 100644 index 00000000000..a600d0fa5dc --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect12.ads @@ -0,0 +1,10 @@ +package Vect12 is + + -- Constrained array types are vectorizable + type Sarray is array (1 .. 4) of Float; + for Sarray'Alignment use 16; + + function "+" (X, Y : Sarray) return Sarray; + procedure Add (X, Y : Sarray; R : out Sarray); + +end Vect12; diff --git a/gcc/testsuite/gnat.dg/vect13.adb b/gcc/testsuite/gnat.dg/vect13.adb new file mode 100644 index 00000000000..ca765d3b485 --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect13.adb @@ -0,0 +1,27 @@ +-- { dg-do compile { target i?86-*-* x86_64-*-* } } +-- { dg-options "-O3 -msse2 -fdump-tree-vect-details" } + +package body Vect13 is + + function "+" (X, Y : Sarray) return Sarray is + R : Sarray; + begin + for I in Sarray'Range loop + pragma Loop_Optimize (Vector); + R(I) := X(I) + Y(I); + end loop; + return R; + end; + + procedure Add (X, Y : Sarray; R : out Sarray) is + begin + for I in Sarray'Range loop + pragma Loop_Optimize (Vector); + R(I) := X(I) + Y(I); + end loop; + end; + +end Vect13; + +-- { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } +-- { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gnat.dg/vect13.ads b/gcc/testsuite/gnat.dg/vect13.ads new file mode 100644 index 00000000000..7aeac5e527a --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect13.ads @@ -0,0 +1,10 @@ +package Vect13 is + + -- Constrained array types are vectorizable + type Sarray is array (1 .. 4) of Float; + for Sarray'Alignment use 16; + + function "+" (X, Y : Sarray) return Sarray; + procedure Add (X, Y : Sarray; R : out Sarray); + +end Vect13; diff --git a/gcc/testsuite/gnat.dg/vect14.adb b/gcc/testsuite/gnat.dg/vect14.adb new file mode 100644 index 00000000000..adc6ff14b66 --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect14.adb @@ -0,0 +1,25 @@ +-- { dg-do compile { target i?86-*-* x86_64-*-* } } +-- { dg-options "-fdump-tree-optimized" } + +with Interfaces; +with Unchecked_Conversion; + +with GNAT.SSE.Vector_Types; use GNAT.SSE.Vector_Types; + +procedure Vect14 is + + Msk1 : constant := 16#000FFAFFFFFFFB3F#; + Msk2 : constant := 16#000FFDFFFC90FFFD#; + + type Unsigned_64_Array_Type is array (1 .. 2) of Interfaces.Unsigned_64; + + function Convert is new Unchecked_Conversion (Unsigned_64_Array_Type, M128i); + + Sse2_Param_Mask : constant M128i := Convert ((Msk1, Msk2)); + +begin + null; +end; + +-- { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index f9d52bcf63d..a758d4740fd 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -181,6 +181,7 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { lappend options "additional_flags=$extra_tool_flags" } + verbose "$target_compile $prog $output_file $compile_type $options" 4 set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options] # Look for an internal compiler error, which sometimes masks the fact diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 0d2ccd512bc..57b10d0a844 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -746,7 +746,14 @@ proc check_effective_target_mmap {} { # Return 1 if the target supports dlopen, 0 otherwise. proc check_effective_target_dlopen {} { - return [check_function_available "dlopen"] + return [check_no_compiler_messages dlopen executable { + #include <dlfcn.h> + int main(void) { dlopen ("dummy.so", RTLD_NOW); } + } [add_options_for_dlopen ""]] +} + +proc add_options_for_dlopen { flags } { + return "$flags -ldl" } # Return 1 if the target supports clone, 0 otherwise. @@ -3732,6 +3739,28 @@ proc check_effective_target_vect_widen_mult_hi_to_si_pattern { } { } # Return 1 if the target plus current options supports a vector +# widening multiplication of *int* args into *long* result, 0 otherwise. +# +# This won't change for different subtargets so cache the result. + +proc check_effective_target_vect_widen_mult_si_to_di_pattern { } { + global et_vect_widen_mult_si_to_di_pattern + + if [info exists et_vect_widen_mult_si_to_di_pattern_saved] { + verbose "check_effective_target_vect_widen_mult_si_to_di_pattern: using cached result" 2 + } else { + set et_vect_widen_mult_si_to_di_pattern_saved 0 + if {[istarget ia64-*-*] + || [istarget i?86-*-*] + || [istarget x86_64-*-*] } { + set et_vect_widen_mult_si_to_di_pattern_saved 1 + } + } + verbose "check_effective_target_vect_widen_mult_si_to_di_pattern: returning $et_vect_widen_mult_si_to_di_pattern_saved" 2 + return $et_vect_widen_mult_si_to_di_pattern_saved +} + +# Return 1 if the target plus current options supports a vector # widening shift, 0 otherwise. # # This won't change for different subtargets so cache the result. diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index fe6dc2886d6..87a8fd90e3e 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -4914,6 +4914,7 @@ ipa_tm_create_version (struct cgraph_node *old_node) if (DECL_ONE_ONLY (new_decl)) DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl)); + gcc_assert (!old_node->ipa_transforms_to_apply.exists ()); new_node = cgraph_copy_node_for_versioning (old_node, new_decl, vNULL, NULL); new_node->local.local = false; new_node->externally_visible = old_node->externally_visible; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index ede5fdc933f..c4bc86209ec 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -252,9 +252,9 @@ build_gimple_cfg (gimple_seq seq) } -/* Search for ANNOTATE call with annot_expr_ivdep_kind; if found, remove - it and set loop->safelen to INT_MAX. We assume that the annotation - comes immediately before the condition. */ +/* Look for ANNOTATE calls with loop annotation kind; if found, remove + them and propagate the information to the loop. We assume that the + annotations come immediately before the condition of the loop. */ static void replace_loop_annotate () @@ -268,50 +268,62 @@ replace_loop_annotate () { gsi = gsi_last_bb (loop->header); stmt = gsi_stmt (gsi); - if (stmt && gimple_code (stmt) == GIMPLE_COND) + if (!(stmt && gimple_code (stmt) == GIMPLE_COND)) + continue; + for (gsi_prev_nondebug (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi)) { - gsi_prev_nondebug (&gsi); - if (gsi_end_p (gsi)) - continue; stmt = gsi_stmt (gsi); if (gimple_code (stmt) != GIMPLE_CALL) - continue; + break; if (!gimple_call_internal_p (stmt) - || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) - continue; - if ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)) - != annot_expr_ivdep_kind) - continue; + || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) + break; + switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1))) + { + case annot_expr_ivdep_kind: + loop->safelen = INT_MAX; + break; + case annot_expr_no_vector_kind: + loop->dont_vectorize = true; + break; + case annot_expr_vector_kind: + loop->force_vectorize = true; + cfun->has_force_vectorize_loops = true; + break; + default: + gcc_unreachable (); + } stmt = gimple_build_assign (gimple_call_lhs (stmt), gimple_call_arg (stmt, 0)); gsi_replace (&gsi, stmt, true); - loop->safelen = INT_MAX; } } - /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */ + /* Remove IFN_ANNOTATE. Safeguard for the case loop->latch == NULL. */ FOR_EACH_BB_FN (bb, cfun) { - gsi = gsi_last_bb (bb); - stmt = gsi_stmt (gsi); - if (stmt && gimple_code (stmt) == GIMPLE_COND) - gsi_prev_nondebug (&gsi); - if (gsi_end_p (gsi)) - continue; - stmt = gsi_stmt (gsi); - if (gimple_code (stmt) != GIMPLE_CALL) - continue; - if (!gimple_call_internal_p (stmt) - || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) - continue; - if ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)) - != annot_expr_ivdep_kind) - continue; - warning_at (gimple_location (stmt), 0, "ignoring %<GCC ivdep%> " - "annotation"); - stmt = gimple_build_assign (gimple_call_lhs (stmt), - gimple_call_arg (stmt, 0)); - gsi_replace (&gsi, stmt, true); + for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) + { + stmt = gsi_stmt (gsi); + if (gimple_code (stmt) != GIMPLE_CALL) + break; + if (!gimple_call_internal_p (stmt) + || gimple_call_internal_fn (stmt) != IFN_ANNOTATE) + break; + switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1))) + { + case annot_expr_ivdep_kind: + case annot_expr_no_vector_kind: + case annot_expr_vector_kind: + break; + default: + gcc_unreachable (); + } + warning_at (gimple_location (stmt), 0, "ignoring loop annotation"); + stmt = gimple_build_assign (gimple_call_lhs (stmt), + gimple_call_arg (stmt, 0)); + gsi_replace (&gsi, stmt, true); + } } } @@ -1949,7 +1961,7 @@ remove_bb (basic_block bb) fprintf (dump_file, "Removing basic block %d\n", bb->index); if (dump_flags & TDF_DETAILS) { - dump_bb (dump_file, bb, 0, dump_flags); + dump_bb (dump_file, bb, 0, TDF_BLOCKS); fprintf (dump_file, "\n"); } } @@ -6969,7 +6981,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, outer->num_nodes -= num_nodes; loop0->num_nodes -= bbs.length () - num_nodes; - if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vect_loops) + if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vectorize_loops) { struct loop *aloop; for (i = 0; vec_safe_iterate (loops->larray, i, &aloop); i++) @@ -6981,8 +6993,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, d.to_context); dest_cfun->has_simduid_loops = true; } - if (aloop->force_vect) - dest_cfun->has_force_vect_loops = true; + if (aloop->force_vectorize) + dest_cfun->has_force_vectorize_loops = true; } } diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 08401dd2db6..b7882cf6762 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -586,9 +586,6 @@ fixup_noreturn_call (gimple stmt) update_stmt (stmt); changed = true; } - /* Similarly remove VDEF if there is any. */ - else if (gimple_vdef (stmt)) - update_stmt (stmt); return changed; } diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 85d160c2077..72ef8e143a2 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -657,7 +657,10 @@ enum tree_node_kind { }; enum annot_expr_kind { - annot_expr_ivdep_kind + annot_expr_ivdep_kind, + annot_expr_no_vector_kind, + annot_expr_vector_kind, + annot_expr_kind_last }; diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 0dc340f15aa..7ff21329cf1 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -728,7 +728,7 @@ ifcvt_can_use_mask_load_store (gimple stmt) basic_block bb = gimple_bb (stmt); bool is_load; - if (!(flag_tree_loop_vectorize || bb->loop_father->force_vect) + if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize) || bb->loop_father->dont_vectorize || !gimple_assign_single_p (stmt) || gimple_has_volatile_ops (stmt)) @@ -1926,7 +1926,7 @@ version_loop_for_if_conversion (struct loop *loop) if (new_loop == NULL) return false; new_loop->dont_vectorize = true; - new_loop->force_vect = false; + new_loop->force_vectorize = false; gsi = gsi_last_bb (cond_bb); gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num)); gsi_insert_before (&gsi, g, GSI_SAME_STMT); @@ -1950,7 +1950,7 @@ tree_if_conversion (struct loop *loop) goto cleanup; if (any_mask_load_store - && ((!flag_tree_loop_vectorize && !loop->force_vect) + && ((!flag_tree_loop_vectorize && !loop->force_vectorize) || loop->dont_vectorize)) goto cleanup; @@ -1998,7 +1998,7 @@ main_tree_if_conversion (void) FOR_EACH_LOOP (loop, 0) if (flag_tree_loop_if_convert == 1 || flag_tree_loop_if_convert_stores == 1 - || ((flag_tree_loop_vectorize || loop->force_vect) + || ((flag_tree_loop_vectorize || loop->force_vectorize) && !loop->dont_vectorize)) todo |= tree_if_conversion (loop); @@ -2018,7 +2018,7 @@ main_tree_if_conversion (void) static bool gate_tree_if_conversion (void) { - return (((flag_tree_loop_vectorize || cfun->has_force_vect_loops) + return (((flag_tree_loop_vectorize || cfun->has_force_vectorize_loops) && flag_tree_loop_if_convert != 0) || flag_tree_loop_if_convert == 1 || flag_tree_loop_if_convert_stores == 1); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 17c8ccfa452..9b057c3702e 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2347,17 +2347,18 @@ copy_loops (copy_body_data *id, place_new_loop (cfun, dest_loop); flow_loop_tree_node_add (dest_parent, dest_loop); + dest_loop->safelen = src_loop->safelen; + dest_loop->dont_vectorize = src_loop->dont_vectorize; + if (src_loop->force_vectorize) + { + dest_loop->force_vectorize = true; + cfun->has_force_vectorize_loops = true; + } if (src_loop->simduid) { dest_loop->simduid = remap_decl (src_loop->simduid, id); cfun->has_simduid_loops = true; } - if (src_loop->force_vect) - { - dest_loop->force_vect = true; - cfun->has_force_vect_loops = true; - } - dest_loop->safelen = src_loop->safelen; /* Recurse. */ copy_loops (id, dest_loop, src_loop); @@ -5321,18 +5322,6 @@ tree_function_versioning (tree old_decl, tree new_decl, id.dst_node = new_version_node; id.src_cfun = DECL_STRUCT_FUNCTION (old_decl); id.blocks_to_copy = blocks_to_copy; - if (id.src_node->ipa_transforms_to_apply.exists ()) - { - vec<ipa_opt_pass> old_transforms_to_apply - = id.dst_node->ipa_transforms_to_apply; - unsigned int i; - - id.dst_node->ipa_transforms_to_apply - = id.src_node->ipa_transforms_to_apply.copy (); - for (i = 0; i < old_transforms_to_apply.length (); i++) - id.dst_node->ipa_transforms_to_apply.safe_push (old_transforms_to_apply[i]); - old_transforms_to_apply.release (); - } id.copy_decl = copy_decl_no_change; id.transform_call_graph_edges diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index ffaf9b11ff8..d516a9ddaa0 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2119,13 +2119,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, case ANNOTATE_EXPR: pp_string (buffer, "ANNOTATE_EXPR <"); + dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (node, 1))) { case annot_expr_ivdep_kind: - pp_string (buffer, "ivdep, "); + pp_string (buffer, ", ivdep"); + break; + case annot_expr_no_vector_kind: + pp_string (buffer, ", no-vector"); + break; + case annot_expr_vector_kind: + pp_string (buffer, ", vector"); break; + default: + gcc_unreachable (); } - dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (buffer); break; @@ -3479,6 +3487,12 @@ pp_double_int (pretty_printer *pp, double_int d, bool uns) pp_wide_integer (pp, d.low); else if (d.fits_uhwi ()) pp_unsigned_wide_integer (pp, d.low); + else if (HOST_BITS_PER_DOUBLE_INT == HOST_BITS_PER_WIDEST_INT) + pp_scalar (pp, + uns + ? HOST_WIDEST_INT_PRINT_UNSIGNED : HOST_WIDEST_INT_PRINT_DEC, + (HOST_WIDEST_INT) ((((unsigned HOST_WIDEST_INT) d.high << 1) + << (HOST_BITS_PER_WIDE_INT - 1)) | d.low)); else { unsigned HOST_WIDE_INT low = d.low; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index ffef13d16ff..91286b44842 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -4960,6 +4960,14 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node) if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))) return false; + if (DECL_DISREGARD_INLINE_LIMITS (node->decl)) + { + if (dump_file) + fprintf (dump_file, "Always inline function will be inlined " + "anyway. \n"); + return false; + } + return true; } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index fa086b0a793..6aea082a45c 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -858,6 +858,125 @@ may_overlap: return false; } +/* qsort compare function to sort FIELD_DECLs after their + DECL_FIELD_CONTEXT TYPE_UID. */ + +static inline int +ncr_compar (const void *field1_, const void *field2_) +{ + const_tree field1 = *(const_tree *) const_cast <void *>(field1_); + const_tree field2 = *(const_tree *) const_cast <void *>(field2_); + unsigned int uid1 + = TYPE_UID (TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field1))); + unsigned int uid2 + = TYPE_UID (TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field2))); + if (uid1 < uid2) + return -1; + else if (uid1 > uid2) + return 1; + return 0; +} + +/* Return true if we can determine that the fields referenced cannot + overlap for any pair of objects. */ + +static bool +nonoverlapping_component_refs_p (const_tree x, const_tree y) +{ + if (!flag_strict_aliasing + || !x || !y + || TREE_CODE (x) != COMPONENT_REF + || TREE_CODE (y) != COMPONENT_REF) + return false; + + auto_vec<const_tree, 16> fieldsx; + while (TREE_CODE (x) == COMPONENT_REF) + { + tree field = TREE_OPERAND (x, 1); + tree type = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field)); + if (TREE_CODE (type) == RECORD_TYPE) + fieldsx.safe_push (field); + x = TREE_OPERAND (x, 0); + } + if (fieldsx.length () == 0) + return false; + auto_vec<const_tree, 16> fieldsy; + while (TREE_CODE (y) == COMPONENT_REF) + { + tree field = TREE_OPERAND (y, 1); + tree type = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field)); + if (TREE_CODE (type) == RECORD_TYPE) + fieldsy.safe_push (TREE_OPERAND (y, 1)); + y = TREE_OPERAND (y, 0); + } + if (fieldsy.length () == 0) + return false; + + /* Most common case first. */ + if (fieldsx.length () == 1 + && fieldsy.length () == 1) + return ((TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldsx[0])) + == TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldsy[0]))) + && fieldsx[0] != fieldsy[0] + && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0]))); + + if (fieldsx.length () == 2) + { + if (ncr_compar (&fieldsx[0], &fieldsx[1]) == 1) + { + const_tree tem = fieldsx[0]; + fieldsx[0] = fieldsx[1]; + fieldsx[1] = tem; + } + } + else + fieldsx.qsort (ncr_compar); + + if (fieldsy.length () == 2) + { + if (ncr_compar (&fieldsy[0], &fieldsy[1]) == 1) + { + const_tree tem = fieldsy[0]; + fieldsy[0] = fieldsy[1]; + fieldsy[1] = tem; + } + } + else + fieldsy.qsort (ncr_compar); + + unsigned i = 0, j = 0; + do + { + const_tree fieldx = fieldsx[i]; + const_tree fieldy = fieldsy[j]; + tree typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx)); + tree typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy)); + if (typex == typey) + { + /* We're left with accessing different fields of a structure, + no possible overlap, unless they are both bitfields. */ + if (fieldx != fieldy) + return !(DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy)); + } + if (TYPE_UID (typex) < TYPE_UID (typey)) + { + i++; + if (i == fieldsx.length ()) + break; + } + else + { + j++; + if (j == fieldsy.length ()) + break; + } + } + while (1); + + return false; +} + + /* Return true if two memory references based on the variables BASE1 and BASE2 constrained to [OFFSET1, OFFSET1 + MAX_SIZE1) and [OFFSET2, OFFSET2 + MAX_SIZE2) may alias. REF1 and REF2 @@ -1024,6 +1143,10 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1) return ranges_overlap_p (doffset1, max_size1, doffset2, max_size2); + if (ref1 && ref2 + && nonoverlapping_component_refs_p (ref1, ref2)) + return false; + /* Do access-path based disambiguation. */ if (ref1 && ref2 && (handled_component_p (ref1) || handled_component_p (ref2))) @@ -1147,11 +1270,18 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1, && !alias_sets_conflict_p (base1_alias_set, base2_alias_set)) return false; + /* If either reference is view-converted, give up now. */ + if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1 + || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) != 1) + return true; + + if (ref1 && ref2 + && nonoverlapping_component_refs_p (ref1, ref2)) + return false; + /* Do access-path based disambiguation. */ if (ref1 && ref2 - && (handled_component_p (ref1) || handled_component_p (ref2)) - && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1 - && same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1) + && (handled_component_p (ref1) || handled_component_p (ref2))) return aliasing_component_refs_p (ref1, ref1_alias_set, base1_alias_set, offset1, max_size1, diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 0173aada830..f921dc0b151 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1356,43 +1356,38 @@ simplify_gimple_switch_label_vec (gimple stmt, tree index_type) static bool simplify_gimple_switch (gimple stmt) { - tree cond = gimple_switch_index (stmt); - tree def, to, ti; - gimple def_stmt; - /* The optimization that we really care about is removing unnecessary casts. That will let us do much better in propagating the inferred constant at the switch target. */ + tree cond = gimple_switch_index (stmt); if (TREE_CODE (cond) == SSA_NAME) { - def_stmt = SSA_NAME_DEF_STMT (cond); - if (is_gimple_assign (def_stmt)) + gimple def_stmt = SSA_NAME_DEF_STMT (cond); + if (gimple_assign_cast_p (def_stmt)) { - if (gimple_assign_rhs_code (def_stmt) == NOP_EXPR) - { - int need_precision; - bool fail; - - def = gimple_assign_rhs1 (def_stmt); - - to = TREE_TYPE (cond); - ti = TREE_TYPE (def); - - /* If we have an extension that preserves value, then we - can copy the source value into the switch. */ - - need_precision = TYPE_PRECISION (ti); - fail = false; - if (! INTEGRAL_TYPE_P (ti)) - fail = true; - else if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti)) - fail = true; - else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti)) - need_precision += 1; - if (TYPE_PRECISION (to) < need_precision) - fail = true; + tree def = gimple_assign_rhs1 (def_stmt); + if (TREE_CODE (def) != SSA_NAME) + return false; - if (!fail) + /* If we have an extension or sign-change that preserves the + values we check against then we can copy the source value into + the switch. */ + tree ti = TREE_TYPE (def); + if (INTEGRAL_TYPE_P (ti) + && TYPE_PRECISION (ti) <= TYPE_PRECISION (TREE_TYPE (cond))) + { + size_t n = gimple_switch_num_labels (stmt); + tree min = NULL_TREE, max = NULL_TREE; + if (n > 1) + { + min = CASE_LOW (gimple_switch_label (stmt, 1)); + if (CASE_HIGH (gimple_switch_label (stmt, n - 1))) + max = CASE_HIGH (gimple_switch_label (stmt, n - 1)); + else + max = CASE_LOW (gimple_switch_label (stmt, n - 1)); + } + if ((!min || int_fits_type_p (min, ti)) + && (!max || int_fits_type_p (max, ti))) { gimple_switch_set_index (stmt, def); simplify_gimple_switch_label_vec (stmt, ti); diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index a1cb7df8397..7fcff4bdd37 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -1129,7 +1129,7 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer, /* Don't unroll #pragma omp simd loops until the vectorizer attempts to vectorize those. */ - if (loop->force_vect) + if (loop->force_vectorize) return false; /* Try to unroll this loop. */ diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 049da5fcdfa..b0d39271798 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -4363,8 +4363,10 @@ cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter, tree steptype = type; if (POINTER_TYPE_P (type)) steptype = sizetype; + steptype = unsigned_type_for (type); - tree_to_aff_combination (iv->step, steptype, &step); + tree_to_aff_combination (iv->step, TREE_TYPE (iv->step), &step); + aff_combination_convert (&step, steptype); tree_to_aff_combination (niter, TREE_TYPE (niter), &nit); aff_combination_convert (&nit, steptype); aff_combination_mult (&nit, &step, &delta); @@ -4372,6 +4374,8 @@ cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter, aff_combination_add (&delta, &step); tree_to_aff_combination (iv->base, type, val); + if (!POINTER_TYPE_P (type)) + aff_combination_convert (val, steptype); aff_combination_add (val, &delta); } @@ -4750,7 +4754,8 @@ may_eliminate_iv (struct ivopts_data *data, cand_value_at (loop, cand, use->stmt, desc->niter, &bnd); - *bound = aff_combination_to_tree (&bnd); + *bound = fold_convert (TREE_TYPE (cand->iv->base), + aff_combination_to_tree (&bnd)); *comp = iv_elimination_compare (data, use); /* It is unlikely that computing the number of iterations using division diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index e71519acf7b..4008b2bf439 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -157,7 +157,7 @@ tree_loop_vectorize (void) static bool gate_tree_loop_vectorize (void) { - return flag_tree_loop_vectorize || cfun->has_force_vect_loops; + return flag_tree_loop_vectorize || cfun->has_force_vectorize_loops; } namespace { diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 27db5244d96..1210f62295d 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1162,7 +1162,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, if (c_is_int && ((n >= -1 && n <= 2) || (flag_unsafe_math_optimizations - && optimize_insn_for_speed_p () + && optimize_bb_for_speed_p (gsi_bb (*gsi)) && powi_cost (n) <= POWI_MAX_MULTS))) return gimple_expand_builtin_powi (gsi, loc, arg0, n); diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 352ccca4e30..03d3e4d271a 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -166,6 +166,7 @@ create_vop_var (struct function *fn) get_identifier (".MEM"), void_type_node); DECL_ARTIFICIAL (global_var) = 1; + DECL_IGNORED_P (global_var) = 1; TREE_READONLY (global_var) = 0; DECL_EXTERNAL (global_var) = 1; TREE_STATIC (global_var) = 1; @@ -477,9 +478,6 @@ append_use (tree *use_p) static inline void append_vdef (tree var) { - if (!optimize) - return; - gcc_assert ((build_vdef == NULL_TREE || build_vdef == var) && (build_vuse == NULL_TREE @@ -495,9 +493,6 @@ append_vdef (tree var) static inline void append_vuse (tree var) { - if (!optimize) - return; - gcc_assert (build_vuse == NULL_TREE || build_vuse == var); @@ -648,10 +643,8 @@ maybe_add_call_vops (struct function *fn, gimple stmt) call-clobbered. */ if (!(call_flags & ECF_NOVOPS)) { - /* A 'pure' or a 'const' function never call-clobbers anything. - A 'noreturn' function might, but since we don't return anyway - there is no point in recording that. */ - if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN))) + /* A 'pure' or a 'const' function never call-clobbers anything. */ + if (!(call_flags & (ECF_PURE | ECF_CONST))) add_virtual_operand (fn, stmt, opf_def); else if (!(call_flags & ECF_CONST)) add_virtual_operand (fn, stmt, opf_use); diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 95e37f52b80..338e2c1059a 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -350,7 +350,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) if (!do_store_elim) replace_conditional_negation = ((!optimize_size && optimize >= 2) - || (((flag_tree_loop_vectorize || cfun->has_force_vect_loops) + || (((flag_tree_loop_vectorize || cfun->has_force_vectorize_loops) && flag_tree_loop_if_convert != 0) || flag_tree_loop_if_convert == 1 || flag_tree_loop_if_convert_stores == 1)); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 77d05624ff2..3668dbcf2fd 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3013,66 +3013,6 @@ create_expression_by_pieces (basic_block block, pre_expr expr, } -/* Returns true if we want to inhibit the insertions of PHI nodes - for the given EXPR for basic block BB (a member of a loop). - We want to do this, when we fear that the induction variable we - create might inhibit vectorization. */ - -static bool -inhibit_phi_insertion (basic_block bb, pre_expr expr) -{ - vn_reference_t vr = PRE_EXPR_REFERENCE (expr); - vec<vn_reference_op_s> ops = vr->operands; - vn_reference_op_t op; - unsigned i; - - /* If we aren't going to vectorize we don't inhibit anything. */ - if (!flag_tree_loop_vectorize) - return false; - - /* Otherwise we inhibit the insertion when the address of the - memory reference is a simple induction variable. In other - cases the vectorizer won't do anything anyway (either it's - loop invariant or a complicated expression). */ - FOR_EACH_VEC_ELT (ops, i, op) - { - switch (op->opcode) - { - case CALL_EXPR: - /* Calls are not a problem. */ - return false; - - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (TREE_CODE (op->op0) != SSA_NAME) - break; - /* Fallthru. */ - case SSA_NAME: - { - basic_block defbb = gimple_bb (SSA_NAME_DEF_STMT (op->op0)); - affine_iv iv; - /* Default defs are loop invariant. */ - if (!defbb) - break; - /* Defined outside this loop, also loop invariant. */ - if (!flow_bb_inside_loop_p (bb->loop_father, defbb)) - break; - /* If it's a simple induction variable inhibit insertion, - the vectorizer might be interested in this one. */ - if (simple_iv (bb->loop_father, bb->loop_father, - op->op0, &iv, true)) - return true; - /* No simple IV, vectorizer can't do anything, hence no - reason to inhibit the transformation for this operand. */ - break; - } - default: - break; - } - } - return false; -} - /* Insert the to-be-made-available values of expression EXPRNUM for each predecessor, stored in AVAIL, into the predecessors of BLOCK, and merge the result with a phi node, given the same value number as @@ -3106,8 +3046,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, EDGE_PRED (block, 1)->src); /* Induction variables only have one edge inside the loop. */ if ((firstinsideloop ^ secondinsideloop) - && (expr->kind != REFERENCE - || inhibit_phi_insertion (block, expr))) + && expr->kind != REFERENCE) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n"); @@ -4234,6 +4173,56 @@ eliminate_dom_walker::before_dom_children (basic_block b) gcc_assert (sprime != rhs); + /* Inhibit the use of an inserted PHI on a loop header when + the address of the memory reference is a simple induction + variable. In other cases the vectorizer won't do anything + anyway (either it's loop invariant or a complicated + expression). */ + if (flag_tree_loop_vectorize + && gimple_assign_single_p (stmt) + && TREE_CODE (sprime) == SSA_NAME + && loop_outer (b->loop_father)) + { + gimple def_stmt = SSA_NAME_DEF_STMT (sprime); + basic_block def_bb = gimple_bb (def_stmt); + if (gimple_code (def_stmt) == GIMPLE_PHI + && b->loop_father->header == def_bb + && has_zero_uses (sprime)) + { + ssa_op_iter iter; + tree op; + bool found = false; + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + { + affine_iv iv; + def_bb = gimple_bb (SSA_NAME_DEF_STMT (op)); + if (def_bb + && flow_bb_inside_loop_p (b->loop_father, + def_bb) + && simple_iv (b->loop_father, + b->loop_father, op, &iv, true)) + { + found = true; + break; + } + } + if (found) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Not replacing "); + print_gimple_expr (dump_file, stmt, 0, 0); + fprintf (dump_file, " with "); + print_generic_expr (dump_file, sprime, 0); + fprintf (dump_file, " which would add a loop" + " carried dependence to loop %d\n", + b->loop_father->num); + } + continue; + } + } + } + if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Replaced "); diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 840d7e76272..47fd15455b2 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -571,8 +571,14 @@ valid_gimple_rhs_p (tree expr) /* All constants are ok. */ break; - case tcc_binary: case tcc_comparison: + if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) + || (TREE_CODE (TREE_TYPE (expr)) != BOOLEAN_TYPE + && TYPE_PRECISION (TREE_TYPE (expr)) != 1)) + return false; + + /* Fallthru. */ + case tcc_binary: if (!is_gimple_val (TREE_OPERAND (expr, 0)) || !is_gimple_val (TREE_OPERAND (expr, 1))) return false; diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index ab784fab352..4b2b80167c7 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -221,6 +221,35 @@ static struct pointer_map_t *operand_rank; static long get_rank (tree); static bool reassoc_stmt_dominates_stmt_p (gimple, gimple); +/* Wrapper around gsi_remove, which adjusts gimple_uid of debug stmts + possibly added by gsi_remove. */ + +bool +reassoc_remove_stmt (gimple_stmt_iterator *gsi) +{ + gimple stmt = gsi_stmt (*gsi); + + if (!MAY_HAVE_DEBUG_STMTS || gimple_code (stmt) == GIMPLE_PHI) + return gsi_remove (gsi, true); + + gimple_stmt_iterator prev = *gsi; + gsi_prev (&prev); + unsigned uid = gimple_uid (stmt); + basic_block bb = gimple_bb (stmt); + bool ret = gsi_remove (gsi, true); + if (!gsi_end_p (prev)) + gsi_next (&prev); + else + prev = gsi_start_bb (bb); + gimple end_stmt = gsi_stmt (*gsi); + while ((stmt = gsi_stmt (prev)) != end_stmt) + { + gcc_assert (stmt && is_gimple_debug (stmt) && gimple_uid (stmt) == 0); + gimple_set_uid (stmt, uid); + gsi_next (&prev); + } + return ret; +} /* Bias amount for loop-carried phis. We want this to be larger than the depth of any reassociation tree we can see, but not larger than @@ -1123,7 +1152,7 @@ propagate_op_to_single_use (tree op, gimple stmt, tree *def) update_stmt (use_stmt); gsi = gsi_for_stmt (stmt); unlink_stmt_vdef (stmt); - gsi_remove (&gsi, true); + reassoc_remove_stmt (&gsi); release_defs (stmt); } @@ -3072,7 +3101,7 @@ remove_visited_stmt_chain (tree var) { var = gimple_assign_rhs1 (stmt); gsi = gsi_for_stmt (stmt); - gsi_remove (&gsi, true); + reassoc_remove_stmt (&gsi); release_defs (stmt); } else @@ -3494,7 +3523,7 @@ linearize_expr (gimple stmt) update_stmt (stmt); gsi = gsi_for_stmt (oldbinrhs); - gsi_remove (&gsi, true); + reassoc_remove_stmt (&gsi); release_defs (oldbinrhs); gimple_set_visited (stmt, true); @@ -3895,7 +3924,7 @@ repropagate_negates (void) gimple_assign_set_rhs_with_ops (&gsi2, NEGATE_EXPR, x, NULL); user = gsi_stmt (gsi2); update_stmt (user); - gsi_remove (&gsi, true); + reassoc_remove_stmt (&gsi); release_defs (feed); plus_negates.safe_push (gimple_assign_lhs (user)); } @@ -4412,7 +4441,7 @@ reassociate_bb (basic_block bb) reassociations. */ if (has_zero_uses (gimple_get_lhs (stmt))) { - gsi_remove (&gsi, true); + reassoc_remove_stmt (&gsi); release_defs (stmt); /* We might end up removing the last stmt above which places the iterator to the end of the sequence. diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 0fb2cab10f0..59793567994 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4135,7 +4135,7 @@ get_fi_for_callee (gimple call) was handled, otherwise false. */ static bool -find_func_aliases_for_builtin_call (gimple t) +find_func_aliases_for_builtin_call (struct function *fn, gimple t) { tree fndecl = gimple_call_fndecl (t); vec<ce_s> lhsc = vNULL; @@ -4449,7 +4449,7 @@ find_func_aliases_for_builtin_call (gimple t) and otherwise are just all nonlocal variables. */ if (in_ipa_mode) { - fi = lookup_vi_for_tree (cfun->decl); + fi = lookup_vi_for_tree (fn->decl); rhs = get_function_part_constraint (fi, ~0); rhs.type = ADDRESSOF; } @@ -4474,7 +4474,7 @@ find_func_aliases_for_builtin_call (gimple t) { fi = NULL; if (!in_ipa_mode - || !(fi = get_vi_for_tree (cfun->decl))) + || !(fi = get_vi_for_tree (fn->decl))) make_constraint_from (get_varinfo (escaped_id), anything_id); else if (in_ipa_mode && fi != NULL) @@ -4501,7 +4501,7 @@ find_func_aliases_for_builtin_call (gimple t) /* Create constraints for the call T. */ static void -find_func_aliases_for_call (gimple t) +find_func_aliases_for_call (struct function *fn, gimple t) { tree fndecl = gimple_call_fndecl (t); vec<ce_s> lhsc = vNULL; @@ -4510,7 +4510,7 @@ find_func_aliases_for_call (gimple t) if (fndecl != NULL_TREE && DECL_BUILT_IN (fndecl) - && find_func_aliases_for_builtin_call (t)) + && find_func_aliases_for_builtin_call (fn, t)) return; fi = get_fi_for_callee (t); @@ -4620,7 +4620,7 @@ find_func_aliases_for_call (gimple t) when building alias sets and computing alias grouping heuristics. */ static void -find_func_aliases (gimple origt) +find_func_aliases (struct function *fn, gimple origt) { gimple t = origt; vec<ce_s> lhsc = vNULL; @@ -4664,7 +4664,7 @@ find_func_aliases (gimple origt) In non-ipa mode, we need to generate constraints for each pointer passed by address. */ else if (is_gimple_call (t)) - find_func_aliases_for_call (t); + find_func_aliases_for_call (fn, t); /* Otherwise, just a regular assignment statement. Only care about operations with pointer result, others are dealt with as escape @@ -4755,7 +4755,7 @@ find_func_aliases (gimple origt) { fi = NULL; if (!in_ipa_mode - || !(fi = get_vi_for_tree (cfun->decl))) + || !(fi = get_vi_for_tree (fn->decl))) make_escape_constraint (gimple_return_retval (t)); else if (in_ipa_mode && fi != NULL) @@ -4858,7 +4858,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr) IPA constraint builder. */ static void -find_func_clobbers (gimple origt) +find_func_clobbers (struct function *fn, gimple origt) { gimple t = origt; vec<ce_s> lhsc = vNULL; @@ -4876,7 +4876,7 @@ find_func_clobbers (gimple origt) return; /* We'd better have function information for the current function. */ - fi = lookup_vi_for_tree (cfun->decl); + fi = lookup_vi_for_tree (fn->decl); gcc_assert (fi != NULL); /* Account for stores in assignments and calls. */ @@ -4888,12 +4888,12 @@ find_func_clobbers (gimple origt) while (handled_component_p (tem)) tem = TREE_OPERAND (tem, 0); if ((DECL_P (tem) - && !auto_var_in_fn_p (tem, cfun->decl)) + && !auto_var_in_fn_p (tem, fn->decl)) || INDIRECT_REF_P (tem) || (TREE_CODE (tem) == MEM_REF && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR && auto_var_in_fn_p - (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), cfun->decl)))) + (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) { struct constraint_expr lhsc, *rhsp; unsigned i; @@ -4916,12 +4916,12 @@ find_func_clobbers (gimple origt) while (handled_component_p (tem)) tem = TREE_OPERAND (tem, 0); if ((DECL_P (tem) - && !auto_var_in_fn_p (tem, cfun->decl)) + && !auto_var_in_fn_p (tem, fn->decl)) || INDIRECT_REF_P (tem) || (TREE_CODE (tem) == MEM_REF && !(TREE_CODE (TREE_OPERAND (tem, 0)) == ADDR_EXPR && auto_var_in_fn_p - (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), cfun->decl)))) + (TREE_OPERAND (TREE_OPERAND (tem, 0), 0), fn->decl)))) { struct constraint_expr lhs, *rhsp; unsigned i; @@ -5845,14 +5845,14 @@ debug_solution_for_var (unsigned int var) function for intraprocedural mode. */ static void -intra_create_variable_infos (void) +intra_create_variable_infos (struct function *fn) { tree t; /* For each incoming pointer argument arg, create the constraint ARG = NONLOCAL or a dummy variable if it is a restrict qualified passed-by-reference argument. */ - for (t = DECL_ARGUMENTS (current_function_decl); t; t = DECL_CHAIN (t)) + for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t)) { varinfo_t p = get_vi_for_tree (t); @@ -5904,19 +5904,19 @@ intra_create_variable_infos (void) } /* Add a constraint for a result decl that is passed by reference. */ - if (DECL_RESULT (cfun->decl) - && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl))) + if (DECL_RESULT (fn->decl) + && DECL_BY_REFERENCE (DECL_RESULT (fn->decl))) { - varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl)); + varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl)); for (p = result_vi; p; p = vi_next (p)) make_constraint_from (p, nonlocal_id); } /* Add a constraint for the incoming static chain parameter. */ - if (cfun->static_chain_decl != NULL_TREE) + if (fn->static_chain_decl != NULL_TREE) { - varinfo_t p, chain_vi = get_vi_for_tree (cfun->static_chain_decl); + varinfo_t p, chain_vi = get_vi_for_tree (fn->static_chain_decl); for (p = chain_vi; p; p = vi_next (p)) make_constraint_from (p, nonlocal_id); @@ -6801,7 +6801,7 @@ compute_points_to_sets (void) init_alias_vars (); - intra_create_variable_infos (); + intra_create_variable_infos (cfun); /* Now walk all statements and build the constraint set. */ FOR_EACH_BB_FN (bb, cfun) @@ -6813,14 +6813,14 @@ compute_points_to_sets (void) gimple phi = gsi_stmt (gsi); if (! virtual_operand_p (gimple_phi_result (phi))) - find_func_aliases (phi); + find_func_aliases (cfun, phi); } for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - find_func_aliases (stmt); + find_func_aliases (cfun, stmt); } } @@ -7175,7 +7175,7 @@ ipa_pta_execute (void) } func = DECL_STRUCT_FUNCTION (node->decl); - push_cfun (func); + gcc_assert (cfun == NULL); /* For externally visible or attribute used annotated functions use local constraints for their arguments. @@ -7185,7 +7185,7 @@ ipa_pta_execute (void) || node->externally_visible || node->force_output) { - intra_create_variable_infos (); + intra_create_variable_infos (func); /* We also need to make function return values escape. Nothing escapes by returning from main though. */ @@ -7220,20 +7220,18 @@ ipa_pta_execute (void) gimple phi = gsi_stmt (gsi); if (! virtual_operand_p (gimple_phi_result (phi))) - find_func_aliases (phi); + find_func_aliases (func, phi); } for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - find_func_aliases (stmt); - find_func_clobbers (stmt); + find_func_aliases (func, stmt); + find_func_clobbers (func, stmt); } } - pop_cfun (); - if (dump_file) { fprintf (dump_file, "\n"); diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c index 09dc3138a53..78bedfc2e9a 100644 --- a/gcc/tree-ssa-ter.c +++ b/gcc/tree-ssa-ter.c @@ -441,11 +441,6 @@ ter_is_replaceable_p (gimple stmt) || (block1 != NULL_TREE && block1 != block2))) return false; - /* Without alias info we can't move around loads. */ - if (!optimize && gimple_assign_single_p (stmt) - && !is_gimple_val (gimple_assign_rhs1 (stmt))) - return false; - return true; } return false; diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 804b54c098b..d7e8adb5221 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -210,7 +210,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) /* For memory the only cheap thing we can do is see if we have a use of the default def of the virtual operand. - ??? Note that at -O0 we do not have virtual operands. ??? Not so cheap would be to use the alias oracle via walk_aliased_vdefs, if we don't find any aliasing vdef warn as is-used-uninitialized, if we don't find an aliasing diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index bf54f0c610c..f0450561e27 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -144,7 +144,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) /* The node was cleared out when we put it on the free list, so there is no need to do so again here. */ - gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL); + gcc_assert ((*SSANAMES (fn))[SSA_NAME_VERSION (t)] == NULL); (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t; } else diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c index 2d3ba2044a2..5858047b4b5 100644 --- a/gcc/tree-streamer-out.c +++ b/gcc/tree-streamer-out.c @@ -526,13 +526,6 @@ streamer_write_chain (struct output_block *ob, tree t, bool ref_p) { while (t) { - tree saved_chain; - - /* Clear TREE_CHAIN to avoid blindly recursing into the rest - of the list. */ - saved_chain = TREE_CHAIN (t); - TREE_CHAIN (t) = NULL_TREE; - /* We avoid outputting external vars or functions by reference to the global decls section as we do not want to have them enter decl merging. This is, of course, only for the call @@ -544,7 +537,6 @@ streamer_write_chain (struct output_block *ob, tree t, bool ref_p) else stream_write_tree (ob, t, ref_p); - TREE_CHAIN (t) = saved_chain; t = TREE_CHAIN (t); } diff --git a/gcc/tree-streamer.c b/gcc/tree-streamer.c index af9461e7710..517bf77f66b 100644 --- a/gcc/tree-streamer.c +++ b/gcc/tree-streamer.c @@ -101,20 +101,19 @@ static void streamer_tree_cache_add_to_node_array (struct streamer_tree_cache_d *cache, unsigned ix, tree t, hashval_t hash) { - /* Make sure we're either replacing an old element or - appending consecutively. */ - gcc_assert (ix <= cache->nodes.length ()); - - if (ix == cache->nodes.length ()) + /* We're either replacing an old element or appending consecutively. */ + if (cache->nodes.exists ()) { - cache->nodes.safe_push (t); - if (cache->hashes.exists ()) - cache->hashes.safe_push (hash); + if (cache->nodes.length () == ix) + cache->nodes.safe_push (t); + else + cache->nodes[ix] = t; } - else + if (cache->hashes.exists ()) { - cache->nodes[ix] = t; - if (cache->hashes.exists ()) + if (cache->hashes.length () == ix) + cache->hashes.safe_push (hash); + else cache->hashes[ix] = hash; } } @@ -146,7 +145,7 @@ streamer_tree_cache_insert_1 (struct streamer_tree_cache_d *cache, { /* Determine the next slot to use in the cache. */ if (insert_at_next_slot_p) - ix = cache->nodes.length (); + ix = cache->next_idx++; else ix = *ix_p; *slot = ix; @@ -211,7 +210,7 @@ void streamer_tree_cache_append (struct streamer_tree_cache_d *cache, tree t, hashval_t hash) { - unsigned ix = cache->nodes.length (); + unsigned ix = cache->next_idx++; if (!cache->node_map) streamer_tree_cache_add_to_node_array (cache, ix, t, hash); else @@ -326,7 +325,7 @@ preload_common_nodes (struct streamer_tree_cache_d *cache) /* Create a cache of pickled nodes. */ struct streamer_tree_cache_d * -streamer_tree_cache_create (bool with_hashes, bool with_map) +streamer_tree_cache_create (bool with_hashes, bool with_map, bool with_vec) { struct streamer_tree_cache_d *cache; @@ -334,7 +333,9 @@ streamer_tree_cache_create (bool with_hashes, bool with_map) if (with_map) cache->node_map = new pointer_map<unsigned>; - cache->nodes.create (165); + cache->next_idx = 0; + if (with_vec) + cache->nodes.create (165); if (with_hashes) cache->hashes.create (165); diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h index 2aca29a12b9..20dbba024f0 100644 --- a/gcc/tree-streamer.h +++ b/gcc/tree-streamer.h @@ -52,6 +52,9 @@ struct streamer_tree_cache_d vec<tree> nodes; /* The node hashes (if available). */ vec<hashval_t> hashes; + + /* Next index to assign. */ + unsigned next_idx; }; /* Return true if tree node EXPR should be streamed as a builtin. For @@ -97,7 +100,7 @@ void streamer_tree_cache_append (struct streamer_tree_cache_d *, tree, hashval_t); bool streamer_tree_cache_lookup (struct streamer_tree_cache_d *, tree, unsigned *); -struct streamer_tree_cache_d *streamer_tree_cache_create (bool, bool); +struct streamer_tree_cache_d *streamer_tree_cache_create (bool, bool, bool); void streamer_tree_cache_delete (struct streamer_tree_cache_d *); /* Return the tree node at slot IX in CACHE. */ diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 34f4db0708e..aadf9c1b1dd 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -130,21 +130,18 @@ hoist_edge_and_branch_if_true (gimple_stmt_iterator *gsip, This function (and similar RTL-related cost code in e.g. IVOPTS) should be moved to some kind of interface file for GIMPLE/RTL interactions. */ static bool -lshift_cheap_p (void) +lshift_cheap_p (bool speed_p) { /* FIXME: This should be made target dependent via this "this_target" mechanism, similar to e.g. can_copy_init_p in gcse.c. */ static bool init[2] = {false, false}; static bool cheap[2] = {true, true}; - bool speed_p; /* If the targer has no lshift in word_mode, the operation will most probably not be cheap. ??? Does GCC even work for such targets? */ if (optab_handler (ashl_optab, word_mode) == CODE_FOR_nothing) return false; - speed_p = optimize_insn_for_speed_p (); - if (!init[speed_p]) { rtx reg = gen_raw_REG (word_mode, 10000); @@ -165,12 +162,12 @@ lshift_cheap_p (void) static bool expand_switch_using_bit_tests_p (tree range, unsigned int uniq, - unsigned int count) + unsigned int count, bool speed_p) { return (((uniq == 1 && count >= 3) || (uniq == 2 && count >= 5) || (uniq == 3 && count >= 6)) - && lshift_cheap_p () + && lshift_cheap_p (speed_p) && compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0 && compare_tree_int (range, 0) > 0); } @@ -1363,7 +1360,9 @@ process_switch (gimple swtch) if (info.uniq <= MAX_CASE_BIT_TESTS) { if (expand_switch_using_bit_tests_p (info.range_size, - info.uniq, info.count)) + info.uniq, info.count, + optimize_bb_for_speed_p + (gimple_bb (swtch)))) { if (dump_file) fputs (" expanding as bit test is preferable\n", dump_file); diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index d417f0ff6c1..d48e3cdcfca 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3170,7 +3170,7 @@ vect_check_gather (gimple stmt, loop_vec_info loop_vinfo, tree *basep, bool vect_analyze_data_refs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, - int *min_vf) + int *min_vf, unsigned *n_stmts) { struct loop *loop = NULL; basic_block bb = NULL; @@ -3205,6 +3205,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, for (gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + continue; + ++*n_stmts; if (!find_data_references_in_stmt (loop, stmt, &datarefs)) { if (is_gimple_call (stmt) && loop->safelen) @@ -3258,6 +3261,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); + if (is_gimple_debug (stmt)) + continue; + ++*n_stmts; if (!find_data_references_in_stmt (NULL, stmt, &BB_VINFO_DATAREFS (bb_vinfo))) { diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index f959da62320..1f6ac1a348b 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -933,6 +933,7 @@ new_loop_vec_info (struct loop *loop) LOOP_VINFO_NITERS (res) = NULL; LOOP_VINFO_NITERS_UNCHANGED (res) = NULL; LOOP_VINFO_COST_MODEL_MIN_ITERS (res) = 0; + LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0; LOOP_VINFO_VECTORIZABLE_P (res) = 0; LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0; LOOP_VINFO_VECT_FACTOR (res) = 0; @@ -1579,6 +1580,8 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp) || min_profitable_iters > min_scalar_loop_bound)) th = (unsigned) min_profitable_iters; + LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) = th; + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && LOOP_VINFO_INT_NITERS (loop_vinfo) <= th) { @@ -1625,6 +1628,8 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) bool ok, slp = false; int max_vf = MAX_VECTORIZATION_FACTOR; int min_vf = 2; + unsigned int th; + unsigned int n_stmts = 0; /* Find all data references in the loop (which correspond to vdefs/vuses) and analyze their evolution in the loop. Also adjust the minimal @@ -1633,7 +1638,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) FORNOW: Handle only simple, array references, which alignment can be forced, and aligned pointer-references. */ - ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf); + ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf, &n_stmts); if (!ok) { if (dump_enabled_p ()) @@ -1743,7 +1748,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) } /* Check the SLP opportunities in the loop, analyze and build SLP trees. */ - ok = vect_analyze_slp (loop_vinfo, NULL); + ok = vect_analyze_slp (loop_vinfo, NULL, n_stmts); if (ok) { /* Decide which possible SLP instances to SLP. */ @@ -1769,6 +1774,10 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) /* Decide whether we need to create an epilogue loop to handle remaining scalar iterations. */ + th = ((LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo) + 1) + / LOOP_VINFO_VECT_FACTOR (loop_vinfo)) + * LOOP_VINFO_VECT_FACTOR (loop_vinfo); + if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) > 0) { @@ -1779,7 +1788,14 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) } else if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) || (tree_ctz (LOOP_VINFO_NITERS (loop_vinfo)) - < (unsigned)exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo)))) + < (unsigned)exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo)) + /* In case of versioning, check if the maximum number of + iterations is greater than th. If they are identical, + the epilogue is unnecessary. */ + && ((!LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo) + && !LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)) + || (unsigned HOST_WIDE_INT)max_stmt_executions_int + (LOOP_VINFO_LOOP (loop_vinfo)) > th))) LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo) = true; /* If an epilogue loop is required make sure we can create one. */ @@ -2971,7 +2987,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, /* vector version will never be profitable. */ else { - if (LOOP_VINFO_LOOP (loop_vinfo)->force_vect) + if (LOOP_VINFO_LOOP (loop_vinfo)->force_vectorize) warning_at (vect_location, OPT_Wopenmp_simd, "vectorization " "did not happen for a simd loop"); @@ -3936,8 +3952,12 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple stmt, /* Set phi nodes arguments. */ FOR_EACH_VEC_ELT (reduction_phis, i, phi) { - tree vec_init_def = vec_initial_defs[i]; - tree def = vect_defs[i]; + tree vec_init_def, def; + gimple_seq stmts; + vec_init_def = force_gimple_operand (vec_initial_defs[i], &stmts, + true, NULL_TREE); + gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts); + def = vect_defs[i]; for (j = 0; j < ncopies; j++) { /* Set the loop-entry arg of the reduction-phi. */ @@ -5775,9 +5795,7 @@ vect_transform_loop (loop_vec_info loop_vinfo) by our caller. If the threshold makes all loops profitable that run at least the vectorization factor number of times checking is pointless, too. */ - th = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND) - * LOOP_VINFO_VECT_FACTOR (loop_vinfo)) - 1); - th = MAX (th, LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo)); + th = LOOP_VINFO_COST_MODEL_THRESHOLD (loop_vinfo); if (th >= LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 1 && !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) { diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 65f8b022e92..0ab267f7d8e 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -849,9 +849,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, unsigned int *max_nunits, vec<slp_tree> *loads, unsigned int vectorization_factor, - bool *matches, unsigned *npermutes) + bool *matches, unsigned *npermutes, unsigned *tree_size, + unsigned max_tree_size) { - unsigned nops, i, this_npermutes = 0; + unsigned nops, i, this_npermutes = 0, this_tree_size = 0; gimple stmt; if (!matches) @@ -911,6 +912,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, if (oprnd_info->first_dt != vect_internal_def) continue; + if (++this_tree_size > max_tree_size) + { + vect_free_oprnd_info (oprnds_info); + return false; + } + child = vect_create_new_slp_node (oprnd_info->def_stmts); if (!child) { @@ -921,7 +928,8 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, bool *matches = XALLOCAVEC (bool, group_size); if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child, group_size, max_nunits, loads, - vectorization_factor, matches, npermutes)) + vectorization_factor, matches, + npermutes, &this_tree_size, max_tree_size)) { oprnd_info->def_stmts = vNULL; SLP_TREE_CHILDREN (*node).quick_push (child); @@ -961,7 +969,8 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &child, group_size, max_nunits, loads, vectorization_factor, - matches, npermutes)) + matches, npermutes, &this_tree_size, + max_tree_size)) { oprnd_info->def_stmts = vNULL; SLP_TREE_CHILDREN (*node).quick_push (child); @@ -977,6 +986,9 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, return false; } + if (tree_size) + *tree_size += this_tree_size; + vect_free_oprnd_info (oprnds_info); return true; } @@ -1436,7 +1448,7 @@ vect_analyze_slp_cost (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, static bool vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, - gimple stmt) + gimple stmt, unsigned max_tree_size) { slp_instance new_instance; slp_tree node; @@ -1536,7 +1548,8 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, /* Build the tree for the SLP instance. */ if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &node, group_size, &max_nunits, &loads, - vectorization_factor, NULL, NULL)) + vectorization_factor, NULL, NULL, NULL, + max_tree_size)) { /* Calculate the unrolling factor based on the smallest type. */ if (max_nunits > nunits) @@ -1641,7 +1654,8 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, trees of packed scalar stmts if SLP is possible. */ bool -vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) +vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, + unsigned max_tree_size) { unsigned int i; vec<gimple> grouped_stores; @@ -1664,7 +1678,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) /* Find SLP sequences starting from groups of grouped stores. */ FOR_EACH_VEC_ELT (grouped_stores, i, first_element) - if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element)) + if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element, + max_tree_size)) ok = true; if (bb_vinfo && !ok) @@ -1681,7 +1696,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) { /* Find SLP sequences starting from reduction chains. */ FOR_EACH_VEC_ELT (reduc_chains, i, first_element) - if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element)) + if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, first_element, + max_tree_size)) ok = true; else return false; @@ -1693,7 +1709,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) /* Find SLP sequences starting from groups of reductions. */ if (loop_vinfo && LOOP_VINFO_REDUCTIONS (loop_vinfo).length () > 1 - && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, reductions[0])) + && vect_analyze_slp_instance (loop_vinfo, bb_vinfo, reductions[0], + max_tree_size)) ok = true; return true; @@ -2071,12 +2088,13 @@ vect_slp_analyze_bb_1 (basic_block bb) slp_instance instance; int i; int min_vf = 2; + unsigned n_stmts = 0; bb_vinfo = new_bb_vec_info (bb); if (!bb_vinfo) return NULL; - if (!vect_analyze_data_refs (NULL, bb_vinfo, &min_vf)) + if (!vect_analyze_data_refs (NULL, bb_vinfo, &min_vf, &n_stmts)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -2124,7 +2142,7 @@ vect_slp_analyze_bb_1 (basic_block bb) /* Check the SLP opportunities in the basic block, analyze and build SLP trees. */ - if (!vect_analyze_slp (NULL, bb_vinfo)) + if (!vect_analyze_slp (NULL, bb_vinfo, n_stmts)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 0a8f0930b92..b8547cba962 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -7846,7 +7846,21 @@ supportable_widening_operation (enum tree_code code, gimple stmt, stmt, vectype_out, vectype_in, code1, code2, multi_step_cvt, interm_types)) - return true; + { + /* Elements in a vector with vect_used_by_reduction property cannot + be reordered if the use chain with this property does not have the + same operation. One such an example is s += a * b, where elements + in a and b cannot be reordered. Here we check if the vector defined + by STMT is only directly used in the reduction statement. */ + tree lhs = gimple_assign_lhs (stmt); + use_operand_p dummy; + gimple use_stmt; + stmt_vec_info use_stmt_info = NULL; + if (single_imm_use (lhs, &dummy, &use_stmt) + && (use_stmt_info = vinfo_for_stmt (use_stmt)) + && STMT_VINFO_DEF_TYPE (use_stmt_info) == vect_reduction_def) + return true; + } c1 = VEC_WIDEN_MULT_LO_EXPR; c2 = VEC_WIDEN_MULT_HI_EXPR; break; diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index a051dce628e..765e38f689a 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -417,7 +417,7 @@ vectorize_loops (void) any_ifcvt_loops = true; else if ((flag_tree_loop_vectorize && optimize_loop_nest_for_speed_p (loop)) - || loop->force_vect) + || loop->force_vectorize) { loop_vec_info loop_vinfo; vect_location = find_loop_location (loop); @@ -477,7 +477,7 @@ vectorize_loops (void) num_vectorized_loops++; /* Now that the loop has been vectorized, allow it to be unrolled etc. */ - loop->force_vect = false; + loop->force_vectorize = false; if (loop->simduid) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index f8efe471e06..c5cb037042f 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -264,6 +264,11 @@ typedef struct _loop_vec_info { values unknown at compile time. */ int min_profitable_iters; + /* Threshold of number of iterations below which vectorzation will not be + performed. It is calculated from MIN_PROFITABLE_ITERS and + PARAM_MIN_VECT_LOOP_BOUND. */ + unsigned int th; + /* Is the loop vectorizable? */ bool vectorizable; @@ -382,6 +387,7 @@ typedef struct _loop_vec_info { cost model. */ #define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged #define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters +#define LOOP_VINFO_COST_MODEL_THRESHOLD(L) (L)->th #define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable #define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask @@ -952,7 +958,7 @@ known_alignment_for_access_p (struct data_reference *data_ref_info) static inline bool unlimited_cost_model (loop_p loop) { - if (loop != NULL && loop->force_vect + if (loop != NULL && loop->force_vectorize && flag_simd_cost_model != VECT_COST_MODEL_DEFAULT) return flag_simd_cost_model == VECT_COST_MODEL_UNLIMITED; return (flag_vect_cost_model == VECT_COST_MODEL_UNLIMITED); @@ -1051,7 +1057,8 @@ extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info); extern bool vect_prune_runtime_alias_test_list (loop_vec_info); extern tree vect_check_gather (gimple, loop_vec_info, tree *, tree *, int *); -extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *); +extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *, + unsigned *); extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree, tree *, gimple_stmt_iterator *, gimple *, bool, bool *); @@ -1101,7 +1108,7 @@ extern bool vect_transform_slp_perm_load (slp_tree, vec<tree> , slp_instance, bool); extern bool vect_schedule_slp (loop_vec_info, bb_vec_info); extern void vect_update_slp_costs_according_to_vf (loop_vec_info); -extern bool vect_analyze_slp (loop_vec_info, bb_vec_info); +extern bool vect_analyze_slp (loop_vec_info, bb_vec_info, unsigned); extern bool vect_make_slp_decision (loop_vec_info); extern void vect_detect_hybrid_slp (loop_vec_info); extern void vect_get_slp_defs (vec<tree> , slp_tree, diff --git a/gcc/tree.c b/gcc/tree.c index 57efa2ff926..1c440b2217c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7349,7 +7349,7 @@ iterative_hash_expr (const_tree t, hashval_t val) { int i; enum tree_code code; - char tclass; + enum tree_code_class tclass; if (t == NULL_TREE) return iterative_hash_hashval_t (0, val); @@ -7759,20 +7759,9 @@ subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval) || TREE_CODE (base_type) == BOOLEAN_TYPE) && int_size_in_bytes (type) == int_size_in_bytes (base_type) && tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type)) - && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type))) - { - tree type_name = TYPE_NAME (type); - tree base_type_name = TYPE_NAME (base_type); - - if (type_name && TREE_CODE (type_name) == TYPE_DECL) - type_name = DECL_NAME (type_name); - - if (base_type_name && TREE_CODE (base_type_name) == TYPE_DECL) - base_type_name = DECL_NAME (base_type_name); - - if (type_name == base_type_name) - return false; - } + && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type)) + && TYPE_IDENTIFIER (type) == TYPE_IDENTIFIER (base_type)) + return false; if (lowval) *lowval = low; @@ -11127,7 +11116,7 @@ walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data, tree tree_block (tree t) { - char const c = TREE_CODE_CLASS (TREE_CODE (t)); + const enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t)); if (IS_EXPR_CODE_CLASS (c)) return LOCATION_BLOCK (t->exp.locus); @@ -11138,7 +11127,7 @@ tree_block (tree t) void tree_set_block (tree t, tree b) { - char const c = TREE_CODE_CLASS (TREE_CODE (t)); + const enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t)); if (IS_EXPR_CODE_CLASS (c)) { diff --git a/gcc/tree.def b/gcc/tree.def index fa85bf18592..a6247a7e00a 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1291,7 +1291,7 @@ DEFTREECODE (TARGET_OPTION_NODE, "target_option_node", tcc_exceptional, 0) /* ANNOTATE_EXPR. Operand 0 is the expression to be annotated. - Operand 1 is the annotation id. */ + Operand 1 is the annotation kind. */ DEFTREECODE (ANNOTATE_EXPR, "annotate_expr", tcc_expression, 2) /* Cilk spawn statement diff --git a/gcc/tree.h b/gcc/tree.h index 9c95d6f4329..6c4d2478e43 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1909,6 +1909,11 @@ extern void protected_set_expr_location (tree, location_t); It is an IDENTIFIER_NODE. */ #define DECL_NAME(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.name) +/* The IDENTIFIER_NODE associated with the TYPE_NAME field. */ +#define TYPE_IDENTIFIER(NODE) \ + (TYPE_NAME (NODE) && DECL_P (TYPE_NAME (NODE)) \ + ? DECL_NAME (TYPE_NAME (NODE)) : TYPE_NAME (NODE)) + /* Every ..._DECL node gets a unique number. */ #define DECL_UID(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.uid) @@ -4207,7 +4212,7 @@ static inline tree fold_build_pointer_plus_loc (location_t loc, tree ptr, tree off) { return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr), - ptr, fold_convert_loc (loc, sizetype, off)); + ptr, convert_to_ptrofftype_loc (loc, off)); } #define fold_build_pointer_plus(p,o) \ fold_build_pointer_plus_loc (UNKNOWN_LOCATION, p, o) diff --git a/gcc/varasm.c b/gcc/varasm.c index 65283c151f3..796b36d3d58 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5656,6 +5656,7 @@ assemble_alias (tree decl, tree target) # if !defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL) error_at (DECL_SOURCE_LOCATION (decl), "alias definitions not supported in this configuration"); + TREE_ASM_WRITTEN (decl) = 1; return; # else if (!DECL_WEAK (decl)) @@ -5666,6 +5667,7 @@ assemble_alias (tree decl, tree target) else error_at (DECL_SOURCE_LOCATION (decl), "only weak aliases are supported in this configuration"); + TREE_ASM_WRITTEN (decl) = 1; return; } # endif diff --git a/gcc/varpool.c b/gcc/varpool.c index acb522100ea..b5493ab5a84 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -166,7 +166,9 @@ varpool_remove_node (varpool_node *node) /* Because we remove references from external functions before final compilation, we may end up removing useful constructors. FIXME: We probably want to trace boundaries better. */ - if ((init = ctor_for_folding (node->decl)) == error_mark_node) + if (cgraph_state == CGRAPH_LTO_STREAMING) + ; + else if ((init = ctor_for_folding (node->decl)) == error_mark_node) varpool_remove_initializer (node); else DECL_INITIAL (node->decl) = init; diff --git a/libcilkrts/ChangeLog b/libcilkrts/ChangeLog index 80b35c1405d..bb3913b10d9 100644 --- a/libcilkrts/ChangeLog +++ b/libcilkrts/ChangeLog @@ -1,3 +1,12 @@ +2014-04-11 Barry Tannenbaum <barry.m.tannenbaum@intel.com> + + PR other/60644 + * runtime/os-unix.c: Replaced all occurrances of ANDROID with + __ANDROID__. + * runtime/bug.h: Likewise. + * include/cilk/metaprogramming.h: Likewise. + * include/cilk/reducer_min_max.h: Likewise. + 2014-03-26 Tobias Burnus <burnus@net-b.de> * libcilkrts.spec.in: New. diff --git a/libcilkrts/include/cilk/metaprogramming.h b/libcilkrts/include/cilk/metaprogramming.h index 5f6f29df87b..29b0839e788 100644 --- a/libcilkrts/include/cilk/metaprogramming.h +++ b/libcilkrts/include/cilk/metaprogramming.h @@ -468,7 +468,7 @@ inline void* allocate_aligned(std::size_t size, std::size_t alignment) #ifdef _WIN32 return _aligned_malloc(size, alignment); #else -#if defined(ANDROID) || defined(__ANDROID__) +#if defined(__ANDROID__) return memalign(std::max(alignment, sizeof(void*)), size); #else void* ptr; diff --git a/libcilkrts/include/cilk/reducer_min_max.h b/libcilkrts/include/cilk/reducer_min_max.h index 55f068c34a3..7fe09e8d605 100644 --- a/libcilkrts/include/cilk/reducer_min_max.h +++ b/libcilkrts/include/cilk/reducer_min_max.h @@ -3025,7 +3025,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig #include <limits.h> /* Wchar_t min/max constants */ -#if defined(_MSC_VER) || defined(ANDROID) +#if defined(_MSC_VER) || defined(__ANDROID__) # include <wchar.h> #else # include <stdint.h> diff --git a/libcilkrts/runtime/bug.h b/libcilkrts/runtime/bug.h index bb18913787d..1a64bea3a54 100644 --- a/libcilkrts/runtime/bug.h +++ b/libcilkrts/runtime/bug.h @@ -90,7 +90,7 @@ COMMON_PORTABLE extern const char *const __cilkrts_assertion_failed; * GPL V3 licensed. */ COMMON_PORTABLE void cilkbug_assert_no_uncaught_exception(void); -#if defined(_WIN32) || defined(ANDROID) +#if defined(_WIN32) || defined(__ANDROID__) # define CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION() #else # define CILKBUG_ASSERT_NO_UNCAUGHT_EXCEPTION() \ diff --git a/libcilkrts/runtime/os-unix.c b/libcilkrts/runtime/os-unix.c index fafb91d91a1..c9ddbbc5961 100644 --- a/libcilkrts/runtime/os-unix.c +++ b/libcilkrts/runtime/os-unix.c @@ -282,7 +282,7 @@ void __cilkrts_init_tls_variables(void) } #endif -#if defined (__linux__) && ! defined(ANDROID) +#if defined (__linux__) && ! defined(__ANDROID__) /* * Get the thread id, rather than the pid. In the case of MIC offload, it's * possible that we have multiple threads entering Cilk, and each has a @@ -343,7 +343,7 @@ static int linux_get_affinity_count (int tid) return available_procs; #endif } -#endif +#endif // defined (__linux__) && ! defined(__ANDROID__) /* * __cilkrts_hardware_cpu_count @@ -354,7 +354,7 @@ static int linux_get_affinity_count (int tid) COMMON_SYSDEP int __cilkrts_hardware_cpu_count(void) { -#if defined ANDROID || (defined(__sun__) && defined(__svr4__)) +#if defined __ANDROID__ || (defined(__sun__) && defined(__svr4__)) return sysconf (_SC_NPROCESSORS_ONLN); #elif defined __MIC__ /// HACK: Usually, the 3rd and 4th hyperthreads are not beneficial @@ -409,7 +409,7 @@ COMMON_SYSDEP void __cilkrts_yield(void) // giving up the processor and latency starting up when work becomes // available _mm_delay_32(1024); -#elif defined(ANDROID) || (defined(__sun__) && defined(__svr4__)) +#elif defined(__ANDROID__) || (defined(__sun__) && defined(__svr4__)) // On Android and Solaris, call sched_yield to yield quantum. I'm not // sure why we don't do this on Linux also. sched_yield(); diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 6d92f9a655f..7bfdfc439a0 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,8 @@ +2014-04-11 Jerry DeLisle <jvdelisle@gcc.gnu> + + PR libfortran/60810 + io/unit.c (is_trim_ok): If internal unit is array, do not trim. + 2014-03-21 Jerry DeLisle <jvdelisle@gcc.gnu> PR libfortran/60148 diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index e522195e5dd..385818adc1f 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -382,9 +382,7 @@ static bool is_trim_ok (st_parameter_dt *dtp) { /* Check rank and stride. */ - if (dtp->internal_unit_desc - && (GFC_DESCRIPTOR_RANK (dtp->internal_unit_desc) > 1 - || GFC_DESCRIPTOR_STRIDE(dtp->internal_unit_desc, 0) != 1)) + if (dtp->internal_unit_desc) return false; /* Format strings can not have 'BZ' or '/'. */ if (dtp->common.flags & IOPARM_DT_HAS_FORMAT) diff --git a/libgo/config.h.in b/libgo/config.h.in index 73854351c76..ca5dcb22587 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -341,9 +341,6 @@ */ #undef LT_OBJDIR -/* Define if makecontext expects top of stack in uc_stack. */ -#undef MAKECONTEXT_STACK_TOP - /* Name of package */ #undef PACKAGE diff --git a/libgo/configure b/libgo/configure index f4b8c104465..81936a8aa97 100755 --- a/libgo/configure +++ b/libgo/configure @@ -13889,11 +13889,6 @@ case "$target" in # msghdr in <sys/socket.h>. OSCFLAGS="$OSCFLAGS -D_XOPEN_SOURCE=500" ;; - *-*-solaris2.[89]) - # Solaris 8/9 need this so struct msghdr gets the msg_control - # etc. fields in <sys/socket.h> (_XPG4_2). - OSCFLAGS="$OSCFLAGS -D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED -D__EXTENSIONS__" - ;; *-*-solaris2.1[01]) # Solaris 10+ needs this so struct msghdr gets the msg_control # etc. fields in <sys/socket.h> (_XPG4_2). _XOPEN_SOURCE=600 as @@ -15053,20 +15048,6 @@ $as_echo "#define HAVE_STRUCT_EXCEPTION 1" >>confdefs.h fi -case "$target" in - sparc*-*-solaris2.[89]*) - libgo_cv_lib_makecontext_stack_top=yes - ;; - *) - libgo_cv_lib_makecontext_stack_top=no - ;; -esac -if test "$libgo_cv_lib_makecontext_stack_top" = "yes"; then - -$as_echo "#define MAKECONTEXT_STACK_TOP 1" >>confdefs.h - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setcontext clobbers TLS variables" >&5 $as_echo_n "checking whether setcontext clobbers TLS variables... " >&6; } if test "${libgo_cv_lib_setcontext_clobbers_tls+set}" = set; then : diff --git a/libgo/configure.ac b/libgo/configure.ac index 4480261a9c9..6f59c03f876 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -316,11 +316,6 @@ case "$target" in # msghdr in <sys/socket.h>. OSCFLAGS="$OSCFLAGS -D_XOPEN_SOURCE=500" ;; - *-*-solaris2.[[89]]) - # Solaris 8/9 need this so struct msghdr gets the msg_control - # etc. fields in <sys/socket.h> (_XPG4_2). - OSCFLAGS="$OSCFLAGS -D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED -D__EXTENSIONS__" - ;; *-*-solaris2.1[[01]]) # Solaris 10+ needs this so struct msghdr gets the msg_control # etc. fields in <sys/socket.h> (_XPG4_2). _XOPEN_SOURCE=600 as @@ -662,21 +657,6 @@ if test "$libgo_has_struct_exception" = "yes"; then [Define to 1 if <math.h> defines struct exception]) fi -dnl Check if makecontext expects the uc_stack member of ucontext to point -dnl to the top of the stack. -case "$target" in - sparc*-*-solaris2.[[89]]*) - libgo_cv_lib_makecontext_stack_top=yes - ;; - *) - libgo_cv_lib_makecontext_stack_top=no - ;; -esac -if test "$libgo_cv_lib_makecontext_stack_top" = "yes"; then - AC_DEFINE(MAKECONTEXT_STACK_TOP, 1, - [Define if makecontext expects top of stack in uc_stack.]) -fi - dnl See whether setcontext changes the value of TLS variables. AC_CACHE_CHECK([whether setcontext clobbers TLS variables], [libgo_cv_lib_setcontext_clobbers_tls], diff --git a/libgo/go/math/ldexp.go b/libgo/go/math/ldexp.go index 4c63edd7319..2898f5dd498 100644 --- a/libgo/go/math/ldexp.go +++ b/libgo/go/math/ldexp.go @@ -17,16 +17,6 @@ func libc_ldexp(float64, int) float64 func Ldexp(frac float64, exp int) float64 { r := libc_ldexp(frac, exp) - - // Work around a bug in the implementation of ldexp on Solaris - // 9. If multiplying a negative number by 2 raised to a - // negative exponent underflows, we want to return negative - // zero, but the Solaris 9 implementation returns positive - // zero. This workaround can be removed when and if we no - // longer care about Solaris 9. - if r == 0 && frac < 0 && exp < 0 { - r = Copysign(0, frac) - } return r } diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c index 1d9e6681d35..38a2aafc775 100644 --- a/libgo/runtime/chan.c +++ b/libgo/runtime/chan.c @@ -483,31 +483,10 @@ __go_send_big(ChanType *t, Hchan* c, byte* p) runtime_chansend(t, c, p, nil, runtime_getcallerpc(&t)); } -// The compiler generates a call to __go_receive_small to receive a -// value 8 bytes or smaller. -uint64 -__go_receive_small(ChanType *t, Hchan* c) -{ - union { - byte b[sizeof(uint64)]; - uint64 v; - } u; - byte *p; - - u.v = 0; -#ifndef WORDS_BIGENDIAN - p = u.b; -#else - p = u.b + sizeof(uint64) - t->__element_type->__size; -#endif - runtime_chanrecv(t, c, p, nil, nil); - return u.v; -} - -// The compiler generates a call to __go_receive_big to receive a -// value larger than 8 bytes. +// The compiler generates a call to __go_receive to receive a +// value from a channel. void -__go_receive_big(ChanType *t, Hchan* c, byte* p) +__go_receive(ChanType *t, Hchan* c, byte* p) { runtime_chanrecv(t, c, p, nil, nil); } diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 1bc0876d8e6..ed0c1a03ba6 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -1212,9 +1212,6 @@ runtime_newextram(void) // here we need to set up the context for g0. getcontext(&mp->g0->context); mp->g0->context.uc_stack.ss_sp = g0_sp; -#ifdef MAKECONTEXT_STACK_TOP - mp->g0->context.uc_stack.ss_sp += g0_spsize; -#endif mp->g0->context.uc_stack.ss_size = g0_spsize; makecontext(&mp->g0->context, kickoff, 0); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index d3cda25384d..c0f093ff458 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2014-04-02 Richard Henderson <rth@redhat.com> + + * config/linux/futex.h (futex_wait): Get error value from errno. + (futex_wake): Likewise. + 2014-03-25 Jakub Jelinek <jakub@redhat.com> PR c++/60331 diff --git a/libgomp/config/linux/futex.h b/libgomp/config/linux/futex.h index 802abfd24e2..63334c7c916 100644 --- a/libgomp/config/linux/futex.h +++ b/libgomp/config/linux/futex.h @@ -41,8 +41,8 @@ static inline void futex_wait (int *addr, int val) { - long err = syscall (SYS_futex, addr, gomp_futex_wait, val, NULL); - if (__builtin_expect (err == -ENOSYS, 0)) + int err = syscall (SYS_futex, addr, gomp_futex_wait, val, NULL); + if (__builtin_expect (err < 0 && errno == ENOSYS, 0)) { gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; @@ -53,8 +53,8 @@ futex_wait (int *addr, int val) static inline void futex_wake (int *addr, int count) { - long err = syscall (SYS_futex, addr, gomp_futex_wake, count); - if (__builtin_expect (err == -ENOSYS, 0)) + int err = syscall (SYS_futex, addr, gomp_futex_wake, count); + if (__builtin_expect (err < 0 && errno == ENOSYS, 0)) { gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; diff --git a/libitm/ChangeLog b/libitm/ChangeLog index 6aca5d2ac38..62005789c57 100644 --- a/libitm/ChangeLog +++ b/libitm/ChangeLog @@ -1,3 +1,8 @@ +2014-04-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * config/generic/asmcfi.h: Also check for + __GCC_HAVE_DWARF2_CFI_ASM. + 2013-04-02 Richard Henderson <rth@redhat.com> * config/alpha/target.h (PAGE_SIZE, FIXED_PAGE_SIZE): Remove. diff --git a/libitm/config/generic/asmcfi.h b/libitm/config/generic/asmcfi.h index 999409ae96f..398cb4564de 100644 --- a/libitm/config/generic/asmcfi.h +++ b/libitm/config/generic/asmcfi.h @@ -24,7 +24,7 @@ #include "config.h" -#ifdef HAVE_AS_CFI_PSEUDO_OP +#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__GCC_HAVE_DWARF2_CFI_ASM) #define cfi_startproc .cfi_startproc #define cfi_endproc .cfi_endproc @@ -50,4 +50,4 @@ #define cfi_restore(r) #define cfi_undefined(r) -#endif /* HAVE_AS_CFI_PSEUDO_OP */ +#endif /* HAVE_AS_CFI_PSEUDO_OP && __GCC_HAVE_DWARF2_CFI_ASM */ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c65abca0943..4d0e3901a45 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,116 @@ +2014-04-16 Jonathan Wakely <jwakely@redhat.com> + + * include/std/functional (__is_location_invariant): Use __or_ helper. + +2014-04-15 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/60734 + * include/bits/stl_tree.h (_Rb_tree::_M_end): Fix invalid cast. + + PR libstdc++/60695 + * include/std/atomic (atomic<_Tp>): Add static assertion. + * testsuite/29_atomics/atomic/60695.cc: New. + + PR libstdc++/60594 + * include/std/functional (function::_Callable): Exclude own type + from the callable checks. + * testsuite/20_util/function/60594.cc: New. + + * include/bits/atomic_base.h (__atomic_base<_PTp*>::_M_type_size): Add + const to constexpr member functions. + + * include/bits/shared_ptr.h (shared_ptr::shared_ptr(nullptr_t)): Use + delegating constructor. + * include/bits/shared_ptr_base.h + (__shared_ptr::__shared_ptr(nullptr_t)): Likewise + + * include/std/atomic: Uglify parameter names. + + PR c++/60786 + * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/ + 1.cc: Fix invalid explicit instantiations with unqualified names. + * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/ + 2.cc: Likweise. + * testsuite/20_util/tuple/53648.cc: Likweise. + * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc: + Likewise. + * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc: + Likewise. + * testsuite/23_containers/unordered_map/requirements/ + debug_container.cc: Likewise. + * testsuite/23_containers/unordered_map/requirements/ + explicit_instantiation/3.cc: Likewise. + * testsuite/23_containers/unordered_multimap/requirements/debug.cc: + Likewise. + * testsuite/23_containers/unordered_multimap/requirements/ + explicit_instantiation/3.cc: Likewise. + * testsuite/23_containers/unordered_multiset/requirements/debug.cc: + Likewise. + * testsuite/23_containers/unordered_multiset/requirements/ + explicit_instantiation/3.cc: Likewise. + * testsuite/23_containers/unordered_set/requirements/ + debug_container.cc: Likewise. + * testsuite/23_containers/unordered_set/requirements/ + explicit_instantiation/3.cc: Likewise. + + * testsuite/24_iterators/insert_iterator/requirements/container.cc: Do + not use uninitialized members in mem-initializers. + * testsuite/ext/throw_value/cons.cc: Fix most vexing parse. + * testsuite/util/testsuite_common_types.h: Update comment. + + * include/experimental/string_view: Fix inconsistent exception specs. + + * include/bits/shared_ptr.h (shared_ptr::shared_ptr(nullptr_t)): + Remove name of unused parameter. + +2014-04-14 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/stl_vector.h (_Vector_base::_Vector_impl, + _Vector_base::_M_allocate): NullablePointer requirements do not + include initialization from literal zero, use value-initialization. + * include/bits/vector.tcc (vector::_M_insert_aux, + vector::_M_explace_back_aux): Likewise for assignment. + + * include/bits/allocator.h (operator==, operator!=): Add exception + specifications. + + PR libstdc++/60497 + * include/std/tuple (get): Qualify calls to prevent ADL. + * testsuite/20_util/tuple/60497.cc: New. + + * include/std/tuple (tuple_element_t): Define. + * testsuite/20_util/tuple/tuple_element.cc: Change to compile-only + test. + * testsuite/20_util/tuple/tuple_element_t.cc: New. + +2014-04-11 Marc Glisse <marc.glisse@inria.fr> + + PR libstdc++/59434 + * include/bits/stl_iterator.h (move_iterator::reference, + move_iterator::operator*): Implement LWG 2106. + * testsuite/24_iterators/move_iterator/dr2106.cc: New file. + +2014-04-11 Marc Glisse <marc.glisse@inria.fr> + + * include/std/complex (__complex_exp, pow): Specify the template + parameter in calls to std::polar, for expression templates. + +2014-04-10 Andreas Schwab <schwab@suse.de> + + * config/abi/post/alpha-linux-gnu/baseline_symbols.txt: Remove TLS + symbols. + * config/abi/post/m68k-linux-gnu/baseline_symbols.txt: Likewise. + * config/abi/post/mips64-linux-gnu/baseline_symbols.txt: Likewise. + + * config/abi/post/ia64-linux-gnu/baseline_symbols.txt: Update. + +2014-04-07 Jonathan Wakely <jwakely@redhat.com> + + * testsuite/20_util/exchange/1.cc: Add missing return statements. + * testsuite/20_util/pair/40925.cc: Avoid most vexing parse. + * testsuite/22_locale/codecvt_byname/50714.cc: Add missing exception + specifications. + 2014-04-02 Dominique d'Humieres <dominiq@lps.ens.fr> Jack Howarth <howarth@bromo.med.uc.edu> diff --git a/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt index c62f4db8fd9..e518a0a2fb3 100644 --- a/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt @@ -4026,5 +4026,3 @@ OBJECT:96:_ZTVSt12ctype_bynameIcE@@GLIBCXX_3.4 OBJECT:96:_ZTVSt5ctypeIcE@@GLIBCXX_3.4 OBJECT:96:_ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:96:_ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 -TLS:8:_ZSt11__once_call@@GLIBCXX_3.4.11 -TLS:8:_ZSt15__once_callable@@GLIBCXX_3.4.11 diff --git a/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt index 91421b373b5..6ff97c7a6ad 100644 --- a/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt @@ -43,6 +43,10 @@ FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4 FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4 FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4 FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4 +FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17 +FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17 +FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17 +FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base7_M_swapERS0_@@GLIBCXX_3.4.17 FUNC:_ZN14__gnu_parallel9_Settings3getEv@@GLIBCXX_3.4.10 FUNC:_ZN14__gnu_parallel9_Settings3setERS0_@@GLIBCXX_3.4.10 FUNC:_ZN9__gnu_cxx12__atomic_addEPVii@@GLIBCXX_3.4 @@ -143,6 +147,8 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4cendEv@@GLIBCXX_3.4.14 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwmm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4findEPKwm@@GLIBCXX_3.4 @@ -153,12 +159,15 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE4sizeEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv@@GLIBCXX_3.4 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5crendEv@@GLIBCXX_3.4.14 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5emptyEv@@GLIBCXX_3.4 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEPKwmm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindERKS2_m@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE5rfindEwm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6_M_repEv@@GLIBCXX_3.4 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6cbeginEv@@GLIBCXX_3.4.14 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6lengthEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6rbeginEv@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE6substrEmm@@GLIBCXX_3.4 @@ -170,6 +179,7 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmPKw@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmPKwm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmRKS2_@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7compareEmmRKS2_mm@@GLIBCXX_3.4 +FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE7crbeginEv@@GLIBCXX_3.4.14 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_checkEmPKc@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4 FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4 @@ -204,6 +214,8 @@ FUNC:_ZNKSs2atEm@@GLIBCXX_3.4 FUNC:_ZNKSs3endEv@@GLIBCXX_3.4 FUNC:_ZNKSs4_Rep12_M_is_leakedEv@@GLIBCXX_3.4 FUNC:_ZNKSs4_Rep12_M_is_sharedEv@@GLIBCXX_3.4 +FUNC:_ZNKSs4backEv@@GLIBCXX_3.4.15 +FUNC:_ZNKSs4cendEv@@GLIBCXX_3.4.14 FUNC:_ZNKSs4copyEPcmm@@GLIBCXX_3.4 FUNC:_ZNKSs4dataEv@@GLIBCXX_3.4 FUNC:_ZNKSs4findEPKcm@@GLIBCXX_3.4 @@ -214,12 +226,15 @@ FUNC:_ZNKSs4rendEv@@GLIBCXX_3.4 FUNC:_ZNKSs4sizeEv@@GLIBCXX_3.4 FUNC:_ZNKSs5beginEv@@GLIBCXX_3.4 FUNC:_ZNKSs5c_strEv@@GLIBCXX_3.4 +FUNC:_ZNKSs5crendEv@@GLIBCXX_3.4.14 FUNC:_ZNKSs5emptyEv@@GLIBCXX_3.4 +FUNC:_ZNKSs5frontEv@@GLIBCXX_3.4.15 FUNC:_ZNKSs5rfindEPKcm@@GLIBCXX_3.4 FUNC:_ZNKSs5rfindEPKcmm@@GLIBCXX_3.4 FUNC:_ZNKSs5rfindERKSsm@@GLIBCXX_3.4 FUNC:_ZNKSs5rfindEcm@@GLIBCXX_3.4 FUNC:_ZNKSs6_M_repEv@@GLIBCXX_3.4 +FUNC:_ZNKSs6cbeginEv@@GLIBCXX_3.4.14 FUNC:_ZNKSs6lengthEv@@GLIBCXX_3.4 FUNC:_ZNKSs6rbeginEv@@GLIBCXX_3.4 FUNC:_ZNKSs6substrEmm@@GLIBCXX_3.4 @@ -231,6 +246,7 @@ FUNC:_ZNKSs7compareEmmPKc@@GLIBCXX_3.4 FUNC:_ZNKSs7compareEmmPKcm@@GLIBCXX_3.4 FUNC:_ZNKSs7compareEmmRKSs@@GLIBCXX_3.4 FUNC:_ZNKSs7compareEmmRKSsmm@@GLIBCXX_3.4 +FUNC:_ZNKSs7crbeginEv@@GLIBCXX_3.4.14 FUNC:_ZNKSs8_M_checkEmPKc@@GLIBCXX_3.4 FUNC:_ZNKSs8_M_limitEmm@@GLIBCXX_3.4 FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4 @@ -337,6 +353,8 @@ FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw@@GLIBCXX_3.4 FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw@@GLIBCXX_3.4 FUNC:_ZNKSt11logic_error4whatEv@@GLIBCXX_3.4 FUNC:_ZNKSt12__basic_fileIcE7is_openEv@@GLIBCXX_3.4 +FUNC:_ZNKSt12bad_weak_ptr4whatEv@@GLIBCXX_3.4.15 +FUNC:_ZNKSt12future_error4whatEv@@GLIBCXX_3.4.14 FUNC:_ZNKSt12strstreambuf6pcountEv@@GLIBCXX_3.4 FUNC:_ZNKSt13bad_exception4whatEv@@GLIBCXX_3.4.9 FUNC:_ZNKSt13basic_filebufIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 @@ -385,6 +403,8 @@ FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE5pbaseEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_streambufIwSt11char_traitsIwEE6getlocEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt15basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 +FUNC:_ZNKSt16bad_array_length4whatEv@@CXXABI_1.3.8 +FUNC:_ZNKSt17bad_function_call4whatEv@@GLIBCXX_3.4.18 FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt18basic_stringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt18basic_stringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 @@ -397,6 +417,7 @@ FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE5rdbufEv@@GLIBCXX_3.4 FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4 FUNC:_ZNKSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE5rdbufEv@@GLIBCXX_3.4 +FUNC:_ZNKSt20bad_array_new_length4whatEv@@CXXABI_1.3.8 FUNC:_ZNKSt3tr14hashIRKSbIwSt11char_traitsIwESaIwEEEclES6_@@GLIBCXX_3.4.10 FUNC:_ZNKSt3tr14hashIRKSsEclES2_@@GLIBCXX_3.4.10 FUNC:_ZNKSt3tr14hashISbIwSt11char_traitsIwESaIwEEEclES4_@@GLIBCXX_3.4.10 @@ -572,6 +593,8 @@ FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewm@@GLIBCXX_3.4 FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewx@@GLIBCXX_3.4 FUNC:_ZNKSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES3_RSt8ios_basewy@@GLIBCXX_3.4 +FUNC:_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm@@GLIBCXX_3.4.18 +FUNC:_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEmmm@@GLIBCXX_3.4.18 FUNC:_ZNKSt8bad_cast4whatEv@@GLIBCXX_3.4.9 FUNC:_ZNKSt8ios_base7failure4whatEv@@GLIBCXX_3.4 FUNC:_ZNKSt8messagesIcE18_M_convert_to_charERKSs@@GLIBCXX_3.4 @@ -624,6 +647,7 @@ FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE14do_get_week FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE15_M_extract_nameES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4 +FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 @@ -639,6 +663,7 @@ FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE14do_get_week FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE15_M_extract_nameES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_monthnameES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4 +FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14 FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_yearES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4 @@ -719,17 +744,23 @@ FUNC:_ZNSaIwEC2ERKS_@@GLIBCXX_3.4 FUNC:_ZNSaIwEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSaIwED1Ev@@GLIBCXX_3.4 FUNC:_ZNSaIwED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE10_S_compareEmm@@GLIBCXX_3.4.16 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructEmwRKS1_@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iteratorIPwS2_EEEES6_T_S8_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEmmPKwm@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EmwRKS1_@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroyERKS1_@@GLIBCXX_3.4 @@ -744,6 +775,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep26_M_set_length_and_sharableEm@GLIBCXX_ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_m@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEmmRKS1_@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4 @@ -751,12 +783,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5clearEv@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EE@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5eraseEmm@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5frontEv@@GLIBCXX_3.4.15 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEPKwm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendERKS2_mm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE@@GLIBCXX_3.4.11 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6appendEmw@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEOS2_@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignEPKwm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE6assignERKS2_@@GLIBCXX_3.4 @@ -795,10 +829,12 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmRKS2_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmRKS2_mm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7replaceEmmmw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE7reserveEm@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEE8pop_backEv@@GLIBCXX_3.4.17 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@@GLIBCXX_3.4.5 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEmmm@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwmRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4 @@ -811,6 +847,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwmRKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4 @@ -825,6 +862,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPKwEET_S6_RKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2IPwEET_S5_RKS1_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEOS2_@@GLIBCXX_3.4.14 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSEPKw@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSERKS2_@@GLIBCXX_3.4 FUNC:_ZNSbIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE@@GLIBCXX_3.4.11 @@ -943,17 +981,23 @@ FUNC:_ZNSolsEs@@GLIBCXX_3.4 FUNC:_ZNSolsEt@@GLIBCXX_3.4 FUNC:_ZNSolsEx@@GLIBCXX_3.4 FUNC:_ZNSolsEy@@GLIBCXX_3.4 +FUNC:_ZNSs10_S_compareEmm@@GLIBCXX_3.4.16 FUNC:_ZNSs12_Alloc_hiderC1EPcRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSs12_Alloc_hiderC2EPcRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSs12_M_leak_hardEv@@GLIBCXX_3.4 FUNC:_ZNSs12_S_constructEmcRKSaIcE@@GLIBCXX_3.4 +FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 +FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 +FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14 FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4 FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4 FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4 FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4 FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4 +FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14 FUNC:_ZNSs14_M_replace_auxEmmmc@@GLIBCXX_3.4 FUNC:_ZNSs15_M_replace_safeEmmPKcm@@GLIBCXX_3.4 +FUNC:_ZNSs18_S_construct_aux_2EmcRKSaIcE@@GLIBCXX_3.4.14 FUNC:_ZNSs2atEm@@GLIBCXX_3.4 FUNC:_ZNSs3endEv@@GLIBCXX_3.4 FUNC:_ZNSs4_Rep10_M_destroyERKSaIcE@@GLIBCXX_3.4 @@ -968,6 +1012,7 @@ FUNC:_ZNSs4_Rep26_M_set_length_and_sharableEm@GLIBCXX_3.4 FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4 FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEm@@GLIBCXX_3.4 FUNC:_ZNSs4_Rep9_S_createEmmRKSaIcE@@GLIBCXX_3.4 +FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15 FUNC:_ZNSs4rendEv@@GLIBCXX_3.4 FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4 FUNC:_ZNSs5beginEv@@GLIBCXX_3.4 @@ -975,12 +1020,14 @@ FUNC:_ZNSs5clearEv@@GLIBCXX_3.4 FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE@@GLIBCXX_3.4 FUNC:_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEES2_@@GLIBCXX_3.4 FUNC:_ZNSs5eraseEmm@@GLIBCXX_3.4 +FUNC:_ZNSs5frontEv@@GLIBCXX_3.4.15 FUNC:_ZNSs6appendEPKc@@GLIBCXX_3.4 FUNC:_ZNSs6appendEPKcm@@GLIBCXX_3.4 FUNC:_ZNSs6appendERKSs@@GLIBCXX_3.4 FUNC:_ZNSs6appendERKSsmm@@GLIBCXX_3.4 FUNC:_ZNSs6appendESt16initializer_listIcE@@GLIBCXX_3.4.11 FUNC:_ZNSs6appendEmc@@GLIBCXX_3.4 +FUNC:_ZNSs6assignEOSs@@GLIBCXX_3.4.14 FUNC:_ZNSs6assignEPKc@@GLIBCXX_3.4 FUNC:_ZNSs6assignEPKcm@@GLIBCXX_3.4 FUNC:_ZNSs6assignERKSs@@GLIBCXX_3.4 @@ -1019,10 +1066,12 @@ FUNC:_ZNSs7replaceEmmRKSs@@GLIBCXX_3.4 FUNC:_ZNSs7replaceEmmRKSsmm@@GLIBCXX_3.4 FUNC:_ZNSs7replaceEmmmc@@GLIBCXX_3.4 FUNC:_ZNSs7reserveEm@@GLIBCXX_3.4 +FUNC:_ZNSs8pop_backEv@@GLIBCXX_3.4.17 FUNC:_ZNSs9_M_assignEPcmc@@GLIBCXX_3.4.5 FUNC:_ZNSs9_M_assignEPcmc@GLIBCXX_3.4 FUNC:_ZNSs9_M_mutateEmmm@@GLIBCXX_3.4 FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4 +FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14 FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC1EPKcmRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4 @@ -1035,6 +1084,7 @@ FUNC:_ZNSsC1Ev@@GLIBCXX_3.4 FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 +FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15 FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC2EPKcmRKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4 @@ -1049,6 +1099,7 @@ FUNC:_ZNSsC2IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsC2IPcEET_S1_RKSaIcE@@GLIBCXX_3.4 FUNC:_ZNSsD1Ev@@GLIBCXX_3.4 FUNC:_ZNSsD2Ev@@GLIBCXX_3.4 +FUNC:_ZNSsaSEOSs@@GLIBCXX_3.4.14 FUNC:_ZNSsaSEPKc@@GLIBCXX_3.4 FUNC:_ZNSsaSERKSs@@GLIBCXX_3.4 FUNC:_ZNSsaSESt16initializer_listIcE@@GLIBCXX_3.4.11 @@ -1157,6 +1208,12 @@ FUNC:_ZNSt11range_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt11range_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt11range_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt11range_errorD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt11range_errorD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt11regex_errorC1ENSt15regex_constants10error_typeE@@GLIBCXX_3.4.20 +FUNC:_ZNSt11regex_errorD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt11regex_errorD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt11regex_errorD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt11this_thread11__sleep_forENSt6chrono8durationIlSt5ratioILl1ELl1EEEENS1_IlS2_ILl1ELl1000000000EEEE@@GLIBCXX_3.4.18 FUNC:_ZNSt12__basic_fileIcE2fdEv@@GLIBCXX_3.4 FUNC:_ZNSt12__basic_fileIcE4fileEv@@GLIBCXX_3.4.1 FUNC:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei@@GLIBCXX_3.4 @@ -1173,6 +1230,9 @@ FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4 FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4 FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12ctype_bynameIcEC1EPKcm@@GLIBCXX_3.4 FUNC:_ZNSt12ctype_bynameIcEC2EPKcm@@GLIBCXX_3.4 FUNC:_ZNSt12ctype_bynameIcED0Ev@@GLIBCXX_3.4 @@ -1187,14 +1247,20 @@ FUNC:_ZNSt12domain_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12domain_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12domain_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt12domain_errorD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt12domain_errorD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt12future_errorD0Ev@@GLIBCXX_3.4.14 +FUNC:_ZNSt12future_errorD1Ev@@GLIBCXX_3.4.14 +FUNC:_ZNSt12future_errorD2Ev@@GLIBCXX_3.4.14 FUNC:_ZNSt12length_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12length_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12length_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt12length_errorD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt12length_errorD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12out_of_rangeC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12out_of_rangeC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt12out_of_rangeD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt12out_of_rangeD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt12out_of_rangeD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12strstreambuf3strEv@@GLIBCXX_3.4 FUNC:_ZNSt12strstreambuf6freezeEb@@GLIBCXX_3.4 FUNC:_ZNSt12strstreambuf6setbufEPcl@@GLIBCXX_3.4 @@ -1228,10 +1294,22 @@ FUNC:_ZNSt12strstreambufD2Ev@@GLIBCXX_3.4 FUNC:_ZNSt12system_errorD0Ev@@GLIBCXX_3.4.11 FUNC:_ZNSt12system_errorD1Ev@@GLIBCXX_3.4.11 FUNC:_ZNSt12system_errorD2Ev@@GLIBCXX_3.4.11 +FUNC:_ZNSt13__future_base11_State_baseD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base11_State_baseD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base11_State_baseD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base12_Result_baseC1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base12_Result_baseC2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base12_Result_baseD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base12_Result_baseD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base12_Result_baseD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt13__future_base19_Async_state_commonD0Ev@@GLIBCXX_3.4.17 +FUNC:_ZNSt13__future_base19_Async_state_commonD1Ev@@GLIBCXX_3.4.17 +FUNC:_ZNSt13__future_base19_Async_state_commonD2Ev@@GLIBCXX_3.4.17 FUNC:_ZNSt13bad_exceptionD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13bad_exceptionD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13bad_exceptionD2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE13_M_set_bufferEl@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE15_M_create_pbackEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE16_M_destroy_pbackEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE19_M_terminate_outputEv@@GLIBCXX_3.4 @@ -1239,6 +1317,7 @@ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPcl@@GLIB FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEE5imbueERKSt6locale@@GLIBCXX_3.4 @@ -1258,6 +1337,7 @@ FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE13_M_set_bufferEl@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE14_M_get_ext_posER11__mbstate_t@@GLIBCXX_3.4.15 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE15_M_create_pbackEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE16_M_destroy_pbackEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE19_M_terminate_outputEv@@GLIBCXX_3.4 @@ -1265,6 +1345,7 @@ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE22_M_convert_to_externalEPwl@@GLIB FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE26_M_destroy_internal_bufferEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE27_M_allocate_internal_bufferEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEE5imbueERKSt6locale@@GLIBCXX_3.4 @@ -1284,21 +1365,27 @@ FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_filebufIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13basic_fstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 @@ -1405,27 +1492,38 @@ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEs@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEt@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEx@@GLIBCXX_3.4 FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEy@@GLIBCXX_3.4 +FUNC:_ZNSt13random_device14_M_init_pretr1ERKSs@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device16_M_getval_pretr1Ev@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18 +FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18 FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ifstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 @@ -1438,21 +1536,27 @@ FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_iostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE4openERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE5closeEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEE7is_openEv@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2EPKcSt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4.13 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEEC2Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14basic_ofstreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4 @@ -1477,15 +1581,25 @@ FUNC:_ZNSt14collate_bynameIwEC2EPKcm@@GLIBCXX_3.4 FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt14error_categoryC1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt14error_categoryC2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt14error_categoryD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt14error_categoryD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt14error_categoryD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt14overflow_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt14overflow_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt14overflow_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt14overflow_errorD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt14overflow_errorD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 +FUNC:_ZNSt15_List_node_base11_M_transferEPS_S0_@@GLIBCXX_3.4.14 FUNC:_ZNSt15_List_node_base4hookEPS_@@GLIBCXX_3.4 FUNC:_ZNSt15_List_node_base4swapERS_S0_@@GLIBCXX_3.4 FUNC:_ZNSt15_List_node_base6unhookEv@@GLIBCXX_3.4 +FUNC:_ZNSt15_List_node_base7_M_hookEPS_@@GLIBCXX_3.4.14 FUNC:_ZNSt15_List_node_base7reverseEv@@GLIBCXX_3.4 FUNC:_ZNSt15_List_node_base8transferEPS_S0_@@GLIBCXX_3.4 +FUNC:_ZNSt15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 FUNC:_ZNSt15__exception_ptr13exception_ptr4swapERS0_@@CXXABI_1.3.3 FUNC:_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE@@CXXABI_1.3.3 FUNC:_ZNSt15__exception_ptr13exception_ptrC1ERKS0_@@CXXABI_1.3.3 @@ -1500,6 +1614,8 @@ FUNC:_ZNSt15__exception_ptreqERKNS_13exception_ptrES2_@@CXXABI_1.3.3 FUNC:_ZNSt15__exception_ptrneERKNS_13exception_ptrES2_@@CXXABI_1.3.3 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_gbumpEl@@GLIBCXX_3.4.16 +FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE12__safe_pbumpEl@@GLIBCXX_3.4.16 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setgEPcS3_S3_@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4setpEPcS3_@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEE4syncEv@@GLIBCXX_3.4 @@ -1539,6 +1655,8 @@ FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIcSt11char_traitsIcEEaSERKS2_@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE10pubseekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_gbumpEl@@GLIBCXX_3.4.16 +FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE12__safe_pbumpEl@@GLIBCXX_3.4.16 FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setgEPwS3_S3_@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4setpEPwS3_@@GLIBCXX_3.4 FUNC:_ZNSt15basic_streambufIwSt11char_traitsIwEE4syncEv@@GLIBCXX_3.4 @@ -1583,6 +1701,7 @@ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE6setbufEPcl@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7_M_syncEPcmm@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8_M_pbumpEPcS4_l@@GLIBCXX_3.4.16 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9pbackfailEi@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv@@GLIBCXX_3.4.6 @@ -1600,6 +1719,7 @@ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE6setbufEPwl@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7_M_syncEPwmm@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekoffElSt12_Ios_SeekdirSt13_Ios_Openmode@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE7seekposESt4fposI11__mbstate_tESt13_Ios_Openmode@@GLIBCXX_3.4 +FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8_M_pbumpEPwS4_l@@GLIBCXX_3.4.16 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE8overflowEj@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9pbackfailEj@@GLIBCXX_3.4 FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv@@GLIBCXX_3.4.6 @@ -1654,6 +1774,7 @@ FUNC:_ZNSt15underflow_errorC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt15underflow_errorC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt15underflow_errorD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt15underflow_errorD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt15underflow_errorD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt16__numpunct_cacheIcE8_M_cacheERKSt6locale@@GLIBCXX_3.4 FUNC:_ZNSt16__numpunct_cacheIcEC1Em@@GLIBCXX_3.4 FUNC:_ZNSt16__numpunct_cacheIcEC2Em@@GLIBCXX_3.4 @@ -1666,10 +1787,17 @@ FUNC:_ZNSt16__numpunct_cacheIwEC2Em@@GLIBCXX_3.4 FUNC:_ZNSt16__numpunct_cacheIwED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt16__numpunct_cacheIwED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt16__numpunct_cacheIwED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt16bad_array_lengthD0Ev@@CXXABI_1.3.8 +FUNC:_ZNSt16bad_array_lengthD1Ev@@CXXABI_1.3.8 +FUNC:_ZNSt16bad_array_lengthD2Ev@@CXXABI_1.3.8 FUNC:_ZNSt16invalid_argumentC1ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt16invalid_argumentC2ERKSs@@GLIBCXX_3.4 FUNC:_ZNSt16invalid_argumentD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt16invalid_argumentD1Ev@@GLIBCXX_3.4 +FUNC:_ZNSt16invalid_argumentD2Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt16nested_exceptionD0Ev@@CXXABI_1.3.5 +FUNC:_ZNSt16nested_exceptionD1Ev@@CXXABI_1.3.5 +FUNC:_ZNSt16nested_exceptionD2Ev@@CXXABI_1.3.5 FUNC:_ZNSt17__timepunct_cacheIcEC1Em@@GLIBCXX_3.4 FUNC:_ZNSt17__timepunct_cacheIcEC2Em@@GLIBCXX_3.4 FUNC:_ZNSt17__timepunct_cacheIcED0Ev@@GLIBCXX_3.4 @@ -1680,6 +1808,9 @@ FUNC:_ZNSt17__timepunct_cacheIwEC2Em@@GLIBCXX_3.4 FUNC:_ZNSt17__timepunct_cacheIwED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt17__timepunct_cacheIwED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt17__timepunct_cacheIwED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt17bad_function_callD0Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt17bad_function_callD1Ev@@GLIBCXX_3.4.15 +FUNC:_ZNSt17bad_function_callD2Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt17moneypunct_bynameIcLb0EEC1EPKcm@@GLIBCXX_3.4 FUNC:_ZNSt17moneypunct_bynameIcLb0EEC2EPKcm@@GLIBCXX_3.4 FUNC:_ZNSt17moneypunct_bynameIcLb0EED0Ev@@GLIBCXX_3.4 @@ -1783,6 +1914,9 @@ FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@@GLIBCXX_3.4.5 FUNC:_ZNSt19istreambuf_iteratorIcSt11char_traitsIcEEppEv@GLIBCXX_3.4 FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@@GLIBCXX_3.4.5 FUNC:_ZNSt19istreambuf_iteratorIwSt11char_traitsIwEEppEv@GLIBCXX_3.4 +FUNC:_ZNSt20bad_array_new_lengthD0Ev@@CXXABI_1.3.8 +FUNC:_ZNSt20bad_array_new_lengthD1Ev@@CXXABI_1.3.8 +FUNC:_ZNSt20bad_array_new_lengthD2Ev@@CXXABI_1.3.8 FUNC:_ZNSt22condition_variable_anyC1Ev@@GLIBCXX_3.4.11 FUNC:_ZNSt22condition_variable_anyC2Ev@@GLIBCXX_3.4.11 FUNC:_ZNSt22condition_variable_anyD1Ev@@GLIBCXX_3.4.11 @@ -1803,12 +1937,18 @@ FUNC:_ZNSt5ctypeIwEC2Em@@GLIBCXX_3.4 FUNC:_ZNSt5ctypeIwED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt5ctypeIwED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt5ctypeIwED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt6__norm15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 +FUNC:_ZNSt6__norm15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 FUNC:_ZNSt6__norm15_List_node_base4hookEPS0_@@GLIBCXX_3.4.9 FUNC:_ZNSt6__norm15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.9 FUNC:_ZNSt6__norm15_List_node_base6unhookEv@@GLIBCXX_3.4.9 +FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9 FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9 +FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11 +FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19 +FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19 FUNC:_ZNSt6gslice8_IndexerC1EmRKSt8valarrayImES4_@@GLIBCXX_3.4 FUNC:_ZNSt6gslice8_IndexerC2EmRKSt8valarrayImES4_@@GLIBCXX_3.4 FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4 @@ -1852,6 +1992,7 @@ FUNC:_ZNSt6localeD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt6localeD2Ev@@GLIBCXX_3.4 FUNC:_ZNSt6localeaSERKS_@@GLIBCXX_3.4 FUNC:_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE@@GLIBCXX_3.4.11 +FUNC:_ZNSt6thread20hardware_concurrencyEv@@GLIBCXX_3.4.17 FUNC:_ZNSt6thread4joinEv@@GLIBCXX_3.4.11 FUNC:_ZNSt6thread6detachEv@@GLIBCXX_3.4.11 FUNC:_ZNSt7codecvtIcc11__mbstate_tEC1EP15__locale_structm@@GLIBCXX_3.4 @@ -1902,6 +2043,11 @@ FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@@GLIBCXX_3 FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4 FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4 +FUNC:_ZNSt8__detail15_List_node_base10_M_reverseEv@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.15 FUNC:_ZNSt8bad_castD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD2Ev@@GLIBCXX_3.4 @@ -1988,11 +2134,17 @@ FUNC:_ZNSt8valarrayImEC2Em@@GLIBCXX_3.4 FUNC:_ZNSt8valarrayImED1Ev@@GLIBCXX_3.4 FUNC:_ZNSt8valarrayImED2Ev@@GLIBCXX_3.4 FUNC:_ZNSt8valarrayImEixEm@@GLIBCXX_3.4 +FUNC:_ZNSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.14 +FUNC:_ZNSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.14 +FUNC:_ZNSt9__cxx199815_List_node_base10_M_reverseEv@@GLIBCXX_3.4.14 +FUNC:_ZNSt9__cxx199815_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.14 FUNC:_ZNSt9__cxx199815_List_node_base4hookEPS0_@@GLIBCXX_3.4.10 FUNC:_ZNSt9__cxx199815_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.10 FUNC:_ZNSt9__cxx199815_List_node_base6unhookEv@@GLIBCXX_3.4.10 +FUNC:_ZNSt9__cxx199815_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14 FUNC:_ZNSt9__cxx199815_List_node_base7reverseEv@@GLIBCXX_3.4.10 FUNC:_ZNSt9__cxx199815_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.10 +FUNC:_ZNSt9__cxx199815_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14 FUNC:_ZNSt9bad_allocD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt9bad_allocD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt9bad_allocD2Ev@@GLIBCXX_3.4 @@ -2070,11 +2222,17 @@ FUNC:_ZNSt9type_infoD2Ev@@GLIBCXX_3.4 FUNC:_ZNVSt9__atomic011atomic_flag12test_and_setESt12memory_order@@GLIBCXX_3.4.11 FUNC:_ZNVSt9__atomic011atomic_flag5clearESt12memory_order@@GLIBCXX_3.4.11 FUNC:_ZSt10unexpectedv@@GLIBCXX_3.4 +FUNC:_ZSt11_Hash_bytesPKvmm@@CXXABI_1.3.5 +FUNC:_ZSt13get_terminatev@@GLIBCXX_3.4.20 FUNC:_ZSt13set_terminatePFvvE@@GLIBCXX_3.4 FUNC:_ZSt14__convert_to_vIdEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 FUNC:_ZSt14__convert_to_vIeEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 FUNC:_ZSt14__convert_to_vIfEvPKcRT_RSt12_Ios_IostateRKP15__locale_struct@@GLIBCXX_3.4 +FUNC:_ZSt14get_unexpectedv@@GLIBCXX_3.4.20 FUNC:_ZSt14set_unexpectedPFvvE@@GLIBCXX_3.4 +FUNC:_ZSt15_Fnv_hash_bytesPKvmm@@CXXABI_1.3.5 +FUNC:_ZSt15future_categoryv@@GLIBCXX_3.4.15 +FUNC:_ZSt15get_new_handlerv@@GLIBCXX_3.4.20 FUNC:_ZSt15set_new_handlerPFvvE@@GLIBCXX_3.4 FUNC:_ZSt15system_categoryv@@GLIBCXX_3.4.11 FUNC:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l@@GLIBCXX_3.4.9 @@ -2096,9 +2254,11 @@ FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4 FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4 FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4 FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4 +FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15 FUNC:_ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_@@GLIBCXX_3.4 FUNC:_ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_@@GLIBCXX_3.4 FUNC:_ZSt20__throw_domain_errorPKc@@GLIBCXX_3.4 +FUNC:_ZSt20__throw_future_errori@@GLIBCXX_3.4.14 FUNC:_ZSt20__throw_length_errorPKc@@GLIBCXX_3.4 FUNC:_ZSt20__throw_out_of_rangePKc@@GLIBCXX_3.4 FUNC:_ZSt20__throw_system_errori@@GLIBCXX_3.4.11 @@ -2110,6 +2270,8 @@ FUNC:_ZSt21__throw_runtime_errorPKc@@GLIBCXX_3.4 FUNC:_ZSt22__throw_overflow_errorPKc@@GLIBCXX_3.4 FUNC:_ZSt23__throw_underflow_errorPKc@@GLIBCXX_3.4 FUNC:_ZSt24__throw_invalid_argumentPKc@@GLIBCXX_3.4 +FUNC:_ZSt24__throw_out_of_range_fmtPKcz@@GLIBCXX_3.4.20 +FUNC:_ZSt25__throw_bad_function_callv@@GLIBCXX_3.4.14 FUNC:_ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_@@GLIBCXX_3.4 FUNC:_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_@@GLIBCXX_3.4 FUNC:_ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_@@GLIBCXX_3.4 @@ -2309,14 +2471,17 @@ FUNC:_Znwm@@GLIBCXX_3.4 FUNC:_ZnwmRKSt9nothrow_t@@GLIBCXX_3.4 FUNC:__atomic_flag_for_address@@GLIBCXX_3.4.11 FUNC:__atomic_flag_wait_explicit@@GLIBCXX_3.4.11 +FUNC:__cxa_allocate_dependent_exception@@CXXABI_1.3.6 FUNC:__cxa_allocate_exception@@CXXABI_1.3 FUNC:__cxa_bad_cast@@CXXABI_1.3 FUNC:__cxa_bad_typeid@@CXXABI_1.3 FUNC:__cxa_begin_catch@@CXXABI_1.3 FUNC:__cxa_call_unexpected@@CXXABI_1.3 FUNC:__cxa_current_exception_type@@CXXABI_1.3 +FUNC:__cxa_deleted_virtual@@CXXABI_1.3.6 FUNC:__cxa_demangle@@CXXABI_1.3 FUNC:__cxa_end_catch@@CXXABI_1.3 +FUNC:__cxa_free_dependent_exception@@CXXABI_1.3.6 FUNC:__cxa_free_exception@@CXXABI_1.3 FUNC:__cxa_get_exception_ptr@@CXXABI_1.3.1 FUNC:__cxa_get_globals@@CXXABI_1.3 @@ -2326,7 +2491,11 @@ FUNC:__cxa_guard_acquire@@CXXABI_1.3 FUNC:__cxa_guard_release@@CXXABI_1.3 FUNC:__cxa_pure_virtual@@CXXABI_1.3 FUNC:__cxa_rethrow@@CXXABI_1.3 +FUNC:__cxa_thread_atexit@@CXXABI_1.3.7 FUNC:__cxa_throw@@CXXABI_1.3 +FUNC:__cxa_throw_bad_array_length@@CXXABI_1.3.8 +FUNC:__cxa_throw_bad_array_new_length@@CXXABI_1.3.8 +FUNC:__cxa_tm_cleanup@@CXXABI_TM_1 FUNC:__cxa_vec_cctor@@CXXABI_1.3 FUNC:__cxa_vec_cleanup@@CXXABI_1.3 FUNC:__cxa_vec_ctor@@CXXABI_1.3 @@ -2346,11 +2515,26 @@ OBJECT:0:CXXABI_1.3 OBJECT:0:CXXABI_1.3.1 OBJECT:0:CXXABI_1.3.2 OBJECT:0:CXXABI_1.3.3 +OBJECT:0:CXXABI_1.3.4 +OBJECT:0:CXXABI_1.3.5 +OBJECT:0:CXXABI_1.3.6 +OBJECT:0:CXXABI_1.3.7 +OBJECT:0:CXXABI_1.3.8 +OBJECT:0:CXXABI_TM_1 OBJECT:0:GLIBCXX_3.4 OBJECT:0:GLIBCXX_3.4.1 OBJECT:0:GLIBCXX_3.4.10 OBJECT:0:GLIBCXX_3.4.11 +OBJECT:0:GLIBCXX_3.4.12 +OBJECT:0:GLIBCXX_3.4.13 +OBJECT:0:GLIBCXX_3.4.14 +OBJECT:0:GLIBCXX_3.4.15 +OBJECT:0:GLIBCXX_3.4.16 +OBJECT:0:GLIBCXX_3.4.17 +OBJECT:0:GLIBCXX_3.4.18 +OBJECT:0:GLIBCXX_3.4.19 OBJECT:0:GLIBCXX_3.4.2 +OBJECT:0:GLIBCXX_3.4.20 OBJECT:0:GLIBCXX_3.4.3 OBJECT:0:GLIBCXX_3.4.4 OBJECT:0:GLIBCXX_3.4.5 @@ -2428,10 +2612,16 @@ OBJECT:168:_ZTVSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:168:_ZTVSt18basic_stringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 OBJECT:168:_ZTVSt18basic_stringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 OBJECT:168:_ZTVSt9strstream@@GLIBCXX_3.4 +OBJECT:16:_ZTIDd@@CXXABI_1.3.4 +OBJECT:16:_ZTIDe@@CXXABI_1.3.4 +OBJECT:16:_ZTIDf@@CXXABI_1.3.4 OBJECT:16:_ZTIDi@@CXXABI_1.3.3 +OBJECT:16:_ZTIDn@@CXXABI_1.3.5 OBJECT:16:_ZTIDs@@CXXABI_1.3.3 OBJECT:16:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2 OBJECT:16:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2 +OBJECT:16:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 +OBJECT:16:_ZTINSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 OBJECT:16:_ZTINSt6locale5facetE@@GLIBCXX_3.4 OBJECT:16:_ZTISt10ctype_base@@GLIBCXX_3.4 OBJECT:16:_ZTISt10money_base@@GLIBCXX_3.4 @@ -2440,6 +2630,7 @@ OBJECT:16:_ZTISt13messages_base@@GLIBCXX_3.4 OBJECT:16:_ZTISt14error_category@@GLIBCXX_3.4.11 OBJECT:16:_ZTISt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 OBJECT:16:_ZTISt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 +OBJECT:16:_ZTISt16nested_exception@@CXXABI_1.3.5 OBJECT:16:_ZTISt8ios_base@@GLIBCXX_3.4 OBJECT:16:_ZTISt9exception@@GLIBCXX_3.4 OBJECT:16:_ZTISt9time_base@@GLIBCXX_3.4 @@ -2455,6 +2646,8 @@ OBJECT:16:_ZTIi@@CXXABI_1.3 OBJECT:16:_ZTIj@@CXXABI_1.3 OBJECT:16:_ZTIl@@CXXABI_1.3 OBJECT:16:_ZTIm@@CXXABI_1.3 +OBJECT:16:_ZTIn@@CXXABI_1.3.5 +OBJECT:16:_ZTIo@@CXXABI_1.3.5 OBJECT:16:_ZTIs@@CXXABI_1.3 OBJECT:16:_ZTIt@@CXXABI_1.3 OBJECT:16:_ZTIv@@CXXABI_1.3 @@ -2473,6 +2666,7 @@ OBJECT:176:_ZTVSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCX OBJECT:176:_ZTVSt7num_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:17:_ZTSSt12codecvt_base@@GLIBCXX_3.4 OBJECT:17:_ZTSSt12domain_error@@GLIBCXX_3.4 +OBJECT:17:_ZTSSt12future_error@@GLIBCXX_3.4.14 OBJECT:17:_ZTSSt12length_error@@GLIBCXX_3.4 OBJECT:17:_ZTSSt12out_of_range@@GLIBCXX_3.4 OBJECT:17:_ZTSSt12strstreambuf@@GLIBCXX_3.4 @@ -2498,6 +2692,35 @@ OBJECT:1:_ZNSt10moneypunctIcLb0EE4intlE@@GLIBCXX_3.4 OBJECT:1:_ZNSt10moneypunctIcLb1EE4intlE@@GLIBCXX_3.4 OBJECT:1:_ZNSt10moneypunctIwLb0EE4intlE@@GLIBCXX_3.4 OBJECT:1:_ZNSt10moneypunctIwLb1EE4intlE@@GLIBCXX_3.4 +OBJECT:1:_ZNSt12placeholders2_1E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_2E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_3E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_4E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_5E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_6E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_7E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_8E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders2_9E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_10E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_11E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_12E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_13E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_14E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_15E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_16E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_17E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_18E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_19E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_20E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_21E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_22E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_23E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_24E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_25E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_26E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_27E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_28E@@GLIBCXX_3.4.15 +OBJECT:1:_ZNSt12placeholders3_29E@@GLIBCXX_3.4.15 OBJECT:1:_ZNSt14numeric_limitsIDiE10is_boundedE@@GLIBCXX_3.4.11 OBJECT:1:_ZNSt14numeric_limitsIDiE10is_integerE@@GLIBCXX_3.4.11 OBJECT:1:_ZNSt14numeric_limitsIDiE12has_infinityE@@GLIBCXX_3.4.11 @@ -2667,6 +2890,32 @@ OBJECT:1:_ZNSt14numeric_limitsImE8is_exactE@@GLIBCXX_3.4 OBJECT:1:_ZNSt14numeric_limitsImE9is_iec559E@@GLIBCXX_3.4 OBJECT:1:_ZNSt14numeric_limitsImE9is_moduloE@@GLIBCXX_3.4 OBJECT:1:_ZNSt14numeric_limitsImE9is_signedE@@GLIBCXX_3.4 +OBJECT:1:_ZNSt14numeric_limitsInE10is_boundedE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE10is_integerE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE12has_infinityE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE13has_quiet_NaNE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE14is_specializedE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE15has_denorm_lossE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE15tinyness_beforeE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE17has_signaling_NaNE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE5trapsE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE8is_exactE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE9is_iec559E@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE9is_moduloE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsInE9is_signedE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE10is_boundedE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE10is_integerE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE12has_infinityE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE13has_quiet_NaNE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE14is_specializedE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE15has_denorm_lossE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE15tinyness_beforeE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE17has_signaling_NaNE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE5trapsE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE8is_exactE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE9is_iec559E@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE9is_moduloE@@GLIBCXX_3.4.17 +OBJECT:1:_ZNSt14numeric_limitsIoE9is_signedE@@GLIBCXX_3.4.17 OBJECT:1:_ZNSt14numeric_limitsIsE10is_boundedE@@GLIBCXX_3.4 OBJECT:1:_ZNSt14numeric_limitsIsE10is_integerE@@GLIBCXX_3.4 OBJECT:1:_ZNSt14numeric_limitsIsE12has_infinityE@@GLIBCXX_3.4 @@ -2750,6 +2999,8 @@ OBJECT:1:_ZNSt21__numeric_limits_base9is_iec559E@@GLIBCXX_3.4 OBJECT:1:_ZNSt21__numeric_limits_base9is_moduloE@@GLIBCXX_3.4 OBJECT:1:_ZNSt21__numeric_limits_base9is_signedE@@GLIBCXX_3.4 OBJECT:1:_ZNSt6chrono12system_clock12is_monotonicE@@GLIBCXX_3.4.11 +OBJECT:1:_ZNSt6chrono3_V212steady_clock9is_steadyE@@GLIBCXX_3.4.19 +OBJECT:1:_ZNSt6chrono3_V212system_clock9is_steadyE@@GLIBCXX_3.4.19 OBJECT:1:_ZSt10adopt_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt10defer_lock@@GLIBCXX_3.4.11 OBJECT:1:_ZSt11try_to_lock@@GLIBCXX_3.4.11 @@ -2757,6 +3008,7 @@ OBJECT:1:_ZSt7nothrow@@GLIBCXX_3.4 OBJECT:20:_ZTSSt12ctype_bynameIcE@@GLIBCXX_3.4 OBJECT:20:_ZTSSt12ctype_bynameIwE@@GLIBCXX_3.4 OBJECT:20:_ZTSSt15underflow_error@@GLIBCXX_3.4 +OBJECT:21:_ZTSSt16bad_array_length@@CXXABI_1.3.8 OBJECT:21:_ZTSSt16invalid_argument@@GLIBCXX_3.4 OBJECT:224:_ZTVSt7num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:224:_ZTVSt7num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 @@ -2800,6 +3052,7 @@ OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4 +OBJECT:24:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 OBJECT:24:_ZTINSt8ios_base7failureE@@GLIBCXX_3.4 OBJECT:24:_ZTISt10bad_typeid@@GLIBCXX_3.4 OBJECT:24:_ZTISt10istrstream@@GLIBCXX_3.4 @@ -2809,9 +3062,12 @@ OBJECT:24:_ZTISt11__timepunctIcE@@GLIBCXX_3.4 OBJECT:24:_ZTISt11__timepunctIwE@@GLIBCXX_3.4 OBJECT:24:_ZTISt11logic_error@@GLIBCXX_3.4 OBJECT:24:_ZTISt11range_error@@GLIBCXX_3.4 +OBJECT:24:_ZTISt11regex_error@@GLIBCXX_3.4.15 +OBJECT:24:_ZTISt12bad_weak_ptr@@GLIBCXX_3.4.15 OBJECT:24:_ZTISt12ctype_bynameIcE@@GLIBCXX_3.4 OBJECT:24:_ZTISt12ctype_bynameIwE@@GLIBCXX_3.4 OBJECT:24:_ZTISt12domain_error@@GLIBCXX_3.4 +OBJECT:24:_ZTISt12future_error@@GLIBCXX_3.4.14 OBJECT:24:_ZTISt12length_error@@GLIBCXX_3.4 OBJECT:24:_ZTISt12out_of_range@@GLIBCXX_3.4 OBJECT:24:_ZTISt12strstreambuf@@GLIBCXX_3.4 @@ -2842,7 +3098,9 @@ OBJECT:24:_ZTISt15time_get_bynameIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE OBJECT:24:_ZTISt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt15underflow_error@@GLIBCXX_3.4 +OBJECT:24:_ZTISt16bad_array_length@@CXXABI_1.3.8 OBJECT:24:_ZTISt16invalid_argument@@GLIBCXX_3.4 +OBJECT:24:_ZTISt17bad_function_call@@GLIBCXX_3.4.15 OBJECT:24:_ZTISt17moneypunct_bynameIcLb0EE@@GLIBCXX_3.4 OBJECT:24:_ZTISt17moneypunct_bynameIcLb1EE@@GLIBCXX_3.4 OBJECT:24:_ZTISt17moneypunct_bynameIwLb0EE@@GLIBCXX_3.4 @@ -2853,6 +3111,7 @@ OBJECT:24:_ZTISt19basic_istringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt19basic_istringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt19basic_ostringstreamIcSt11char_traitsIcESaIcEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt19basic_ostringstreamIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 +OBJECT:24:_ZTISt20bad_array_new_length@@CXXABI_1.3.8 OBJECT:24:_ZTISt5ctypeIwE@@GLIBCXX_3.4 OBJECT:24:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4 OBJECT:24:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4 @@ -2875,6 +3134,7 @@ OBJECT:24:_ZTISt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBC OBJECT:24:_ZTISt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:24:_ZTISt9strstream@@GLIBCXX_3.4 +OBJECT:25:_ZTSSt20bad_array_new_length@@CXXABI_1.3.8 OBJECT:272:_ZSt4cerr@@GLIBCXX_3.4 OBJECT:272:_ZSt4clog@@GLIBCXX_3.4 OBJECT:272:_ZSt4cout@@GLIBCXX_3.4 @@ -2921,9 +3181,17 @@ OBJECT:2:_ZTSx@@CXXABI_1.3 OBJECT:2:_ZTSy@@CXXABI_1.3 OBJECT:32:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 OBJECT:32:_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4 +OBJECT:32:_ZTIPDd@@CXXABI_1.3.4 +OBJECT:32:_ZTIPDe@@CXXABI_1.3.4 +OBJECT:32:_ZTIPDf@@CXXABI_1.3.4 OBJECT:32:_ZTIPDi@@CXXABI_1.3.3 +OBJECT:32:_ZTIPDn@@CXXABI_1.3.5 OBJECT:32:_ZTIPDs@@CXXABI_1.3.3 +OBJECT:32:_ZTIPKDd@@CXXABI_1.3.4 +OBJECT:32:_ZTIPKDe@@CXXABI_1.3.4 +OBJECT:32:_ZTIPKDf@@CXXABI_1.3.4 OBJECT:32:_ZTIPKDi@@CXXABI_1.3.3 +OBJECT:32:_ZTIPKDn@@CXXABI_1.3.5 OBJECT:32:_ZTIPKDs@@CXXABI_1.3.3 OBJECT:32:_ZTIPKa@@CXXABI_1.3 OBJECT:32:_ZTIPKb@@CXXABI_1.3 @@ -2936,6 +3204,8 @@ OBJECT:32:_ZTIPKi@@CXXABI_1.3 OBJECT:32:_ZTIPKj@@CXXABI_1.3 OBJECT:32:_ZTIPKl@@CXXABI_1.3 OBJECT:32:_ZTIPKm@@CXXABI_1.3 +OBJECT:32:_ZTIPKn@@CXXABI_1.3.5 +OBJECT:32:_ZTIPKo@@CXXABI_1.3.5 OBJECT:32:_ZTIPKs@@CXXABI_1.3 OBJECT:32:_ZTIPKt@@CXXABI_1.3 OBJECT:32:_ZTIPKv@@CXXABI_1.3 @@ -2953,6 +3223,8 @@ OBJECT:32:_ZTIPi@@CXXABI_1.3 OBJECT:32:_ZTIPj@@CXXABI_1.3 OBJECT:32:_ZTIPl@@CXXABI_1.3 OBJECT:32:_ZTIPm@@CXXABI_1.3 +OBJECT:32:_ZTIPn@@CXXABI_1.3.5 +OBJECT:32:_ZTIPo@@CXXABI_1.3.5 OBJECT:32:_ZTIPs@@CXXABI_1.3 OBJECT:32:_ZTIPt@@CXXABI_1.3 OBJECT:32:_ZTIPv@@CXXABI_1.3 @@ -3017,6 +3289,7 @@ OBJECT:40:_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:40:_ZTSSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:40:_ZTSSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4 OBJECT:40:_ZTSSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 +OBJECT:41:_ZTSNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 OBJECT:41:_ZTSSt15basic_streambufIcSt11char_traitsIcEE@@GLIBCXX_3.4 OBJECT:41:_ZTSSt15basic_streambufIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:45:_ZTSSt23__codecvt_abstract_baseIcc11__mbstate_tE@@GLIBCXX_3.4 @@ -3027,6 +3300,7 @@ OBJECT:46:_ZTSSt15basic_stringbufIwSt11char_traitsIwESaIwEE@@GLIBCXX_3.4 OBJECT:48:_ZTVNSt6locale5facetE@@GLIBCXX_3.4 OBJECT:48:_ZTVSt11__timepunctIcE@@GLIBCXX_3.4 OBJECT:48:_ZTVSt11__timepunctIwE@@GLIBCXX_3.4 +OBJECT:48:_ZTVSt16nested_exception@@CXXABI_1.3.5 OBJECT:48:_ZTVSt8ios_base@@GLIBCXX_3.4 OBJECT:48:_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4 OBJECT:48:_ZTVSt9basic_iosIwSt11char_traitsIwEE@@GLIBCXX_3.4 @@ -3038,6 +3312,7 @@ OBJECT:4:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE@@GLIBCXX_3.4 OBJECT:4:_ZNSt10money_base18_S_default_patternE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIDiE10has_denormE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDiE11round_styleE@@GLIBCXX_3.4.11 +OBJECT:4:_ZNSt14numeric_limitsIDiE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIDiE12max_exponentE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDiE12min_exponentE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDiE14max_exponent10E@@GLIBCXX_3.4.11 @@ -3047,6 +3322,7 @@ OBJECT:4:_ZNSt14numeric_limitsIDiE6digitsE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDiE8digits10E@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDsE10has_denormE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDsE11round_styleE@@GLIBCXX_3.4.11 +OBJECT:4:_ZNSt14numeric_limitsIDsE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIDsE12max_exponentE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDsE12min_exponentE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDsE14max_exponent10E@@GLIBCXX_3.4.11 @@ -3056,6 +3332,7 @@ OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11 OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIaE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIaE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIaE14max_exponent10E@@GLIBCXX_3.4 @@ -3065,6 +3342,7 @@ OBJECT:4:_ZNSt14numeric_limitsIaE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIaE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIbE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIbE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIbE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIbE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIbE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIbE14max_exponent10E@@GLIBCXX_3.4 @@ -3074,6 +3352,7 @@ OBJECT:4:_ZNSt14numeric_limitsIbE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIbE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIcE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIcE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIcE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIcE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIcE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIcE14max_exponent10E@@GLIBCXX_3.4 @@ -3083,6 +3362,7 @@ OBJECT:4:_ZNSt14numeric_limitsIcE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIcE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIdE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIdE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIdE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIdE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIdE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIdE14max_exponent10E@@GLIBCXX_3.4 @@ -3092,6 +3372,7 @@ OBJECT:4:_ZNSt14numeric_limitsIdE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIdE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIeE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIeE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIeE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIeE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIeE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIeE14max_exponent10E@@GLIBCXX_3.4 @@ -3101,6 +3382,7 @@ OBJECT:4:_ZNSt14numeric_limitsIeE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIeE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIfE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIfE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIfE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIfE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIfE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIfE14max_exponent10E@@GLIBCXX_3.4 @@ -3110,6 +3392,7 @@ OBJECT:4:_ZNSt14numeric_limitsIfE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIfE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIhE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIhE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIhE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIhE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIhE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIhE14max_exponent10E@@GLIBCXX_3.4 @@ -3119,6 +3402,7 @@ OBJECT:4:_ZNSt14numeric_limitsIhE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIhE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIiE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIiE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIiE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIiE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIiE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIiE14max_exponent10E@@GLIBCXX_3.4 @@ -3128,6 +3412,7 @@ OBJECT:4:_ZNSt14numeric_limitsIiE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIiE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIjE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIjE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIjE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIjE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIjE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIjE14max_exponent10E@@GLIBCXX_3.4 @@ -3137,6 +3422,7 @@ OBJECT:4:_ZNSt14numeric_limitsIjE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIjE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIlE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIlE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIlE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIlE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIlE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIlE14max_exponent10E@@GLIBCXX_3.4 @@ -3146,6 +3432,7 @@ OBJECT:4:_ZNSt14numeric_limitsIlE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIlE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsImE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsImE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE14max_exponent10E@@GLIBCXX_3.4 @@ -3153,8 +3440,29 @@ OBJECT:4:_ZNSt14numeric_limitsImE14min_exponent10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE5radixE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsImE8digits10E@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsInE10has_denormE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE11round_styleE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE12max_digits10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE12max_exponentE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE12min_exponentE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE14max_exponent10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE14min_exponent10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE5radixE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE6digitsE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsInE8digits10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE10has_denormE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE11round_styleE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE12max_digits10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE12max_exponentE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE12min_exponentE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE14max_exponent10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE14min_exponent10E@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE5radixE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE6digitsE@@GLIBCXX_3.4.17 +OBJECT:4:_ZNSt14numeric_limitsIoE8digits10E@@GLIBCXX_3.4.17 OBJECT:4:_ZNSt14numeric_limitsIsE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIsE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIsE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIsE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIsE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIsE14max_exponent10E@@GLIBCXX_3.4 @@ -3164,6 +3472,7 @@ OBJECT:4:_ZNSt14numeric_limitsIsE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIsE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsItE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsItE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsItE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsItE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsItE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsItE14max_exponent10E@@GLIBCXX_3.4 @@ -3173,6 +3482,7 @@ OBJECT:4:_ZNSt14numeric_limitsItE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsItE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIwE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIwE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIwE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIwE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIwE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIwE14max_exponent10E@@GLIBCXX_3.4 @@ -3182,6 +3492,7 @@ OBJECT:4:_ZNSt14numeric_limitsIwE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIwE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIxE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIxE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIxE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIxE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIxE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIxE14max_exponent10E@@GLIBCXX_3.4 @@ -3191,6 +3502,7 @@ OBJECT:4:_ZNSt14numeric_limitsIxE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIxE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIyE10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIyE11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt14numeric_limitsIyE12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt14numeric_limitsIyE12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIyE12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIyE14max_exponent10E@@GLIBCXX_3.4 @@ -3200,6 +3512,7 @@ OBJECT:4:_ZNSt14numeric_limitsIyE6digitsE@@GLIBCXX_3.4 OBJECT:4:_ZNSt14numeric_limitsIyE8digits10E@@GLIBCXX_3.4 OBJECT:4:_ZNSt21__numeric_limits_base10has_denormE@@GLIBCXX_3.4 OBJECT:4:_ZNSt21__numeric_limits_base11round_styleE@@GLIBCXX_3.4 +OBJECT:4:_ZNSt21__numeric_limits_base12max_digits10E@@GLIBCXX_3.4.14 OBJECT:4:_ZNSt21__numeric_limits_base12max_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt21__numeric_limits_base12min_exponentE@@GLIBCXX_3.4 OBJECT:4:_ZNSt21__numeric_limits_base14max_exponent10E@@GLIBCXX_3.4 @@ -3298,12 +3611,18 @@ OBJECT:60:_ZTSSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBC OBJECT:60:_ZTSSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:60:_ZTSSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:60:_ZTSSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 +OBJECT:64:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15 +OBJECT:64:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15 +OBJECT:64:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17 OBJECT:64:_ZTVNSt8ios_base7failureE@@GLIBCXX_3.4 OBJECT:64:_ZTVSt10bad_typeid@@GLIBCXX_3.4 OBJECT:64:_ZTVSt10lock_error@@GLIBCXX_3.4.11 OBJECT:64:_ZTVSt11logic_error@@GLIBCXX_3.4 OBJECT:64:_ZTVSt11range_error@@GLIBCXX_3.4 +OBJECT:64:_ZTVSt11regex_error@@GLIBCXX_3.4.15 +OBJECT:64:_ZTVSt12bad_weak_ptr@@GLIBCXX_3.4.15 OBJECT:64:_ZTVSt12domain_error@@GLIBCXX_3.4 +OBJECT:64:_ZTVSt12future_error@@GLIBCXX_3.4.14 OBJECT:64:_ZTVSt12length_error@@GLIBCXX_3.4 OBJECT:64:_ZTVSt12out_of_range@@GLIBCXX_3.4 OBJECT:64:_ZTVSt12system_error@@GLIBCXX_3.4.11 @@ -3313,7 +3632,10 @@ OBJECT:64:_ZTVSt14overflow_error@@GLIBCXX_3.4 OBJECT:64:_ZTVSt15time_put_bynameIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:64:_ZTVSt15time_put_bynameIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 OBJECT:64:_ZTVSt15underflow_error@@GLIBCXX_3.4 +OBJECT:64:_ZTVSt16bad_array_length@@CXXABI_1.3.8 OBJECT:64:_ZTVSt16invalid_argument@@GLIBCXX_3.4 +OBJECT:64:_ZTVSt17bad_function_call@@GLIBCXX_3.4.15 +OBJECT:64:_ZTVSt20bad_array_new_length@@CXXABI_1.3.8 OBJECT:64:_ZTVSt8bad_cast@@GLIBCXX_3.4 OBJECT:64:_ZTVSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4 OBJECT:64:_ZTVSt8time_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4 @@ -3392,6 +3714,7 @@ OBJECT:8:_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLI OBJECT:8:_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 OBJECT:8:_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4 OBJECT:8:_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4 +OBJECT:8:_ZSt15future_category@@GLIBCXX_3.4.14 OBJECT:96:_ZTVSt14collate_bynameIcE@@GLIBCXX_3.4 OBJECT:96:_ZTVSt14collate_bynameIwE@@GLIBCXX_3.4 OBJECT:96:_ZTVSt15messages_bynameIcE@@GLIBCXX_3.4 diff --git a/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt index e7e2bc56401..ce247a91e13 100644 --- a/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt @@ -3671,5 +3671,3 @@ OBJECT:8:_ZTTSi@@GLIBCXX_3.4 OBJECT:8:_ZTTSo@@GLIBCXX_3.4 OBJECT:8:_ZTTSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:8:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -TLS:4:_ZSt11__once_call@@GLIBCXX_3.4.11 -TLS:4:_ZSt15__once_callable@@GLIBCXX_3.4.11 diff --git a/libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt index 8c1075d95c9..fa2fda345c4 100644 --- a/libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/mips64-linux-gnu/baseline_symbols.txt @@ -3745,5 +3745,3 @@ OBJECT:8:_ZTTSi@@GLIBCXX_3.4 OBJECT:8:_ZTTSo@@GLIBCXX_3.4 OBJECT:8:_ZTTSt13basic_istreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 OBJECT:8:_ZTTSt13basic_ostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4 -TLS:4:_ZSt11__once_call@@GLIBCXX_3.4.11 -TLS:4:_ZSt15__once_callable@@GLIBCXX_3.4.11 diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index e293c545f42..05a06bab847 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -126,21 +126,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _T1, typename _T2> inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) + _GLIBCXX_USE_NOEXCEPT { return true; } template<typename _Tp> inline bool operator==(const allocator<_Tp>&, const allocator<_Tp>&) + _GLIBCXX_USE_NOEXCEPT { return true; } template<typename _T1, typename _T2> inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) + _GLIBCXX_USE_NOEXCEPT { return false; } template<typename _Tp> inline bool operator!=(const allocator<_Tp>&, const allocator<_Tp>&) + _GLIBCXX_USE_NOEXCEPT { return false; } /// @} group allocator diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index 242459ad01e..1fc0ebb7e40 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -675,10 +675,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Factored out to facilitate explicit specialization. constexpr ptrdiff_t - _M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); } + _M_type_size(ptrdiff_t __d) const { return __d * sizeof(_PTp); } constexpr ptrdiff_t - _M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); } + _M_type_size(ptrdiff_t __d) const volatile { return __d * sizeof(_PTp); } public: __atomic_base() noexcept = default; diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index 081d3bd3748..290a0c983a3 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -262,8 +262,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @param __p A null pointer constant. * @post use_count() == 0 && get() == nullptr */ - constexpr shared_ptr(nullptr_t __p) noexcept - : __shared_ptr<_Tp>(__p) { } + constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { } shared_ptr& operator=(const shared_ptr&) noexcept = default; diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 536df017d11..57398af2eb6 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -963,10 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __shared_ptr(std::auto_ptr<_Tp1>&& __r); #endif - /* TODO: use delegating constructor */ - constexpr __shared_ptr(nullptr_t) noexcept - : _M_ptr(0), _M_refcount() - { } + constexpr __shared_ptr(nullptr_t) noexcept : __shared_ptr() { } template<typename _Tp1> __shared_ptr& diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 1d2a52419d9..16f992c7490 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -965,6 +965,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Iterator _M_current; typedef iterator_traits<_Iterator> __traits_type; + typedef typename __traits_type::reference __base_ref; public: typedef _Iterator iterator_type; @@ -973,7 +974,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __traits_type::difference_type difference_type; // NB: DR 680. typedef _Iterator pointer; - typedef value_type&& reference; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2106. move_iterator wrapping iterators returning prvalues + typedef typename conditional<is_reference<__base_ref>::value, + typename remove_reference<__base_ref>::type&&, + __base_ref>::type reference; move_iterator() : _M_current() { } @@ -992,7 +997,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION reference operator*() const - { return std::move(*_M_current); } + { return static_cast<reference>(*_M_current); } pointer operator->() const diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 4bc3c602c20..288c9fa4f1e 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -526,11 +526,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Link_type _M_end() _GLIBCXX_NOEXCEPT - { return static_cast<_Link_type>(&this->_M_impl._M_header); } + { return reinterpret_cast<_Link_type>(&this->_M_impl._M_header); } _Const_Link_type _M_end() const _GLIBCXX_NOEXCEPT - { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + { return reinterpret_cast<_Const_Link_type>(&this->_M_impl._M_header); } static const_reference _S_value(_Const_Link_type __x) diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 7e52fde55b1..3d3a2cf9f8c 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -84,17 +84,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer _M_end_of_storage; _Vector_impl() - : _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) + : _Tp_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() { } _Vector_impl(_Tp_alloc_type const& __a) _GLIBCXX_NOEXCEPT - : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + : _Tp_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() { } #if __cplusplus >= 201103L _Vector_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), - _M_start(0), _M_finish(0), _M_end_of_storage(0) + _M_start(), _M_finish(), _M_end_of_storage() { } #endif @@ -167,7 +167,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_allocate(size_t __n) { typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr; - return __n != 0 ? _Tr::allocate(_M_impl, __n) : 0; + return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer(); } void diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 1eff51447a1..299e6142498 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -362,7 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #else __x); #endif - __new_finish = 0; + __new_finish = pointer(); __new_finish = std::__uninitialized_move_if_noexcept_a @@ -412,7 +412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { _Alloc_traits::construct(this->_M_impl, __new_start + size(), std::forward<_Args>(__args)...); - __new_finish = 0; + __new_finish = pointer(); __new_finish = std::__uninitialized_move_if_noexcept_a @@ -493,7 +493,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::__uninitialized_fill_n_a(__new_start + __elems_before, __n, __x, _M_get_Tp_allocator()); - __new_finish = 0; + __new_finish = pointer(); __new_finish = std::__uninitialized_move_if_noexcept_a diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view index bebeb6b62ea..6b6588b9770 100644 --- a/libstdc++-v3/include/experimental/string_view +++ b/libstdc++-v3/include/experimental/string_view @@ -329,7 +329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(_CharT __c, size_type __pos=0) const noexcept; size_type - find(const _CharT* __str, size_type __pos, size_type __n) const; + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; size_type find(const _CharT* __str, size_type __pos=0) const noexcept @@ -343,7 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION rfind(_CharT __c, size_type __pos = npos) const noexcept; size_type - rfind(const _CharT* __str, size_type __pos, size_type __n) const; + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; size_type rfind(const _CharT* __str, size_type __pos = npos) const noexcept diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index ece75a4e4ba..be7d0be051a 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -163,6 +163,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: _Tp _M_i; + // TODO: static_assert(is_trivially_copyable<_Tp>::value, ""); + + static_assert(sizeof(_Tp) > 0, + "Incomplete or zero-sized types are not supported"); + public: atomic() noexcept = default; ~atomic() noexcept = default; @@ -195,43 +200,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __atomic_is_lock_free(sizeof(_M_i), nullptr); } void - store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept - { __atomic_store(&_M_i, &__i, _m); } + store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept + { __atomic_store(&_M_i, &__i, __m); } void - store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept - { __atomic_store(&_M_i, &__i, _m); } + store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept + { __atomic_store(&_M_i, &__i, __m); } _Tp - load(memory_order _m = memory_order_seq_cst) const noexcept + load(memory_order __m = memory_order_seq_cst) const noexcept { _Tp tmp; - __atomic_load(&_M_i, &tmp, _m); + __atomic_load(&_M_i, &tmp, __m); return tmp; } _Tp - load(memory_order _m = memory_order_seq_cst) const volatile noexcept + load(memory_order __m = memory_order_seq_cst) const volatile noexcept { _Tp tmp; - __atomic_load(&_M_i, &tmp, _m); + __atomic_load(&_M_i, &tmp, __m); return tmp; } _Tp - exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept + exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept { _Tp tmp; - __atomic_exchange(&_M_i, &__i, &tmp, _m); + __atomic_exchange(&_M_i, &__i, &tmp, __m); return tmp; } _Tp exchange(_Tp __i, - memory_order _m = memory_order_seq_cst) volatile noexcept + memory_order __m = memory_order_seq_cst) volatile noexcept { _Tp tmp; - __atomic_exchange(&_M_i, &__i, &tmp, _m); + __atomic_exchange(&_M_i, &__i, &tmp, __m); return tmp; } @@ -239,14 +244,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); + return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); } bool compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); + return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); } bool @@ -265,14 +270,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); + return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); } bool compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, memory_order __f) volatile noexcept { - return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); + return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); } bool diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex index 34fa1ddbcea..5849cd5e806 100644 --- a/libstdc++-v3/include/std/complex +++ b/libstdc++-v3/include/std/complex @@ -735,7 +735,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> inline complex<_Tp> __complex_exp(const complex<_Tp>& __z) - { return std::polar(exp(__z.real()), __z.imag()); } + { return std::polar<_Tp>(exp(__z.real()), __z.imag()); } #if _GLIBCXX_USE_C99_COMPLEX inline __complex__ float @@ -995,7 +995,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return pow(__x.real(), __y); complex<_Tp> __t = std::log(__x); - return std::polar(exp(__y * __t.real()), __y * __t.imag()); + return std::polar<_Tp>(exp(__y * __t.real()), __y * __t.imag()); } template<typename _Tp> @@ -1032,8 +1032,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline complex<_Tp> pow(const _Tp& __x, const complex<_Tp>& __y) { - return __x > _Tp() ? std::polar(pow(__x, __y.real()), - __y.imag() * log(__x)) + return __x > _Tp() ? std::polar<_Tp>(pow(__x, __y.real()), + __y.imag() * log(__x)) : std::pow(complex<_Tp>(__x), __y); } diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 5a987d914b1..295022de8ee 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1747,8 +1747,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) */ template<typename _Tp> struct __is_location_invariant - : integral_constant<bool, (is_pointer<_Tp>::value - || is_member_pointer<_Tp>::value)> + : __or_<is_pointer<_Tp>, is_member_pointer<_Tp>>::type { }; class _Undefined_class; @@ -2149,8 +2148,15 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) using _Invoke = decltype(__callable_functor(std::declval<_Functor&>()) (std::declval<_ArgTypes>()...) ); + // Used so the return type convertibility checks aren't done when + // performing overload resolution for copy construction/assignment. + template<typename _Tp> + using _NotSelf = __not_<is_same<_Tp, function>>; + template<typename _Functor> - using _Callable = __check_func_return_type<_Invoke<_Functor>, _Res>; + using _Callable + = __and_<_NotSelf<_Functor>, + __check_func_return_type<_Invoke<_Functor>, _Res>>; template<typename _Cond, typename _Tp> using _Requires = typename enable_if<_Cond::value, _Tp>::type; @@ -2291,7 +2297,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * reference_wrapper<F>, this function will not throw. */ template<typename _Functor> - _Requires<_Callable<_Functor>, function&> + _Requires<_Callable<typename decay<_Functor>::type>, function&> operator=(_Functor&& __f) { function(std::forward<_Functor>(__f)).swap(*this); diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 92ecdb9bc5b..03d87d77aa0 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -710,6 +710,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION add_cv<typename tuple_element<__i, _Tp>::type>::type type; }; +#if __cplusplus > 201103L + template<std::size_t __i, typename _Tp> + using tuple_element_t = typename tuple_element<__i, _Tp>::type; +#endif + /// Finds the size of a given tuple type. template<typename _Tp> struct tuple_size; @@ -755,14 +760,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename tuple_element<__i, tuple<_Elements...>>::type >::type get(tuple<_Elements...>& __t) noexcept - { return __get_helper<__i>(__t); } + { return std::__get_helper<__i>(__t); } template<std::size_t __i, typename... _Elements> constexpr typename __add_c_ref< typename tuple_element<__i, tuple<_Elements...>>::type >::type get(const tuple<_Elements...>& __t) noexcept - { return __get_helper<__i>(__t); } + { return std::__get_helper<__i>(__t); } template<std::size_t __i, typename... _Elements> constexpr typename __add_r_ref< @@ -786,17 +791,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template <typename _Tp, typename... _Types> constexpr _Tp& get(tuple<_Types...>& __t) noexcept - { return __get_helper2<_Tp>(__t); } + { return std::__get_helper2<_Tp>(__t); } template <typename _Tp, typename... _Types> constexpr _Tp&& get(tuple<_Types...>&& __t) noexcept - { return std::move(__get_helper2<_Tp>(__t)); } + { return std::move(std::__get_helper2<_Tp>(__t)); } template <typename _Tp, typename... _Types> constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept - { return __get_helper2<_Tp>(__t); } + { return std::__get_helper2<_Tp>(__t); } #endif // This class helps construct the various comparison operations on tuples diff --git a/libstdc++-v3/testsuite/20_util/exchange/1.cc b/libstdc++-v3/testsuite/20_util/exchange/1.cc index 923920edda7..2f8825d1eca 100644 --- a/libstdc++-v3/testsuite/20_util/exchange/1.cc +++ b/libstdc++-v3/testsuite/20_util/exchange/1.cc @@ -78,8 +78,8 @@ void test04() To() = default; To(const To&) = default; To(const From&) = delete; - To& operator=(const From&) { value = 1; } - To& operator=(From&&) { value = 2; } + To& operator=(const From&) { value = 1; return *this; } + To& operator=(From&&) { value = 2; return *this; } }; To t; diff --git a/libstdc++-v3/testsuite/20_util/function/60594.cc b/libstdc++-v3/testsuite/20_util/function/60594.cc new file mode 100644 index 00000000000..be80b3f44d0 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function/60594.cc @@ -0,0 +1,36 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2011-2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// libstdc++/60594 + +#include <functional> +#include <type_traits> +struct bar; +using F = std::function<bar()>; +// check for copy constructible and assignable while 'bar' is incomplete +constexpr int c = std::is_copy_constructible<F>::value; +constexpr int a = std::is_copy_assignable<F>::value; +struct bar { }; +bar func(); +void test() +{ + F g{ &func }; + g = func; +} diff --git a/libstdc++-v3/testsuite/20_util/pair/40925.cc b/libstdc++-v3/testsuite/20_util/pair/40925.cc index 599fd3875e5..5b34a626eb1 100644 --- a/libstdc++-v3/testsuite/20_util/pair/40925.cc +++ b/libstdc++-v3/testsuite/20_util/pair/40925.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2009-2014 Free Software Foundation, Inc. @@ -63,5 +63,5 @@ void test01() std::pair<move_only, int*> p15(move_only(), ip); std::pair<move_only, int X::*> p16(move_only(), mp); - std::pair<move_only, move_only> p17(move_only(), move_only()); + std::pair<move_only, move_only> p17{move_only(), move_only()}; } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc index 40ebec09684..0d81481a75b 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2006-2014 Free Software Foundation, Inc. @@ -24,8 +24,7 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::shared_ptr; -template class shared_ptr<int>; -template class shared_ptr<void>; -template class shared_ptr<ClassType>; -template class shared_ptr<IncompleteClass>; +template class std::shared_ptr<int>; +template class std::shared_ptr<void>; +template class std::shared_ptr<ClassType>; +template class std::shared_ptr<IncompleteClass>; diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc index 148375a4ad6..37a0c1d14c0 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/2.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -27,8 +27,7 @@ // library this checks the templates can be instantiated for non-default // lock policy, for a single-threaded lib this is redundant but harmless. using namespace __gnu_test; -using std::__shared_ptr; using std::_S_single; -template class __shared_ptr<int, _S_single>; -template class __shared_ptr<ClassType, _S_single>; -template class __shared_ptr<IncompleteClass, _S_single>; +template class std::__shared_ptr<int, _S_single>; +template class std::__shared_ptr<ClassType, _S_single>; +template class std::__shared_ptr<IncompleteClass, _S_single>; diff --git a/libstdc++-v3/testsuite/20_util/tuple/53648.cc b/libstdc++-v3/testsuite/20_util/tuple/53648.cc index 7bde67e7e1c..fb37638f754 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/53648.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/53648.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2012-2014 Free Software Foundation, Inc. @@ -27,10 +27,10 @@ using std::tuple; struct A { }; -template class tuple<tuple<>>; -template class tuple<tuple<tuple<>>>; -template class tuple<A, tuple<A, tuple<A, tuple<A>>>>; -template class tuple<tuple<tuple<A, A>, A>, A>; +template class std::tuple<tuple<>>; +template class std::tuple<tuple<tuple<>>>; +template class std::tuple<A, tuple<A, tuple<A, tuple<A>>>>; +template class std::tuple<tuple<tuple<A, A>, A>, A>; // Verify the following QoI properties are preserved diff --git a/libstdc++-v3/testsuite/20_util/tuple/60497.cc b/libstdc++-v3/testsuite/20_util/tuple/60497.cc new file mode 100644 index 00000000000..76d4223165f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/60497.cc @@ -0,0 +1,37 @@ +// { dg-options "-std=gnu++14" } +// { dg-do compile } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// libstdc++/60497 + +#include <tuple> + +struct A; +template<typename T> struct B { T t; }; + +using element_type = B<A>*; +using tuple_type = std::tuple<element_type>; + +tuple_type t; +const tuple_type ct; + +auto a = std::get<0>(t); +auto b = std::get<0>(ct); +auto c = std::get<element_type>(t); +auto d = std::get<element_type>(ct); diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc index 0dbdf10fc99..3ff8e824f60 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_element.cc @@ -1,4 +1,5 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } +// { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. // diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc new file mode 100644 index 00000000000..e46af5c305d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/tuple_element_t.cc @@ -0,0 +1,36 @@ +// { dg-options "-std=gnu++14" } +// { dg-do compile } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <tuple> + +using namespace std; + +struct foo +{ }; + +int +main() +{ + // As foo isn't constructible from anything else, this + // lets us check if the alias is returning foo when it should + foo q1; + tuple_element_t<0,tuple<foo,void,int> > q2(q1); + tuple_element_t<2,tuple<void,int,foo> > q3(q1); +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc index c5a30f27272..0a15e46b8b6 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2006-2014 Free Software Foundation, Inc. @@ -24,8 +24,7 @@ #include <testsuite_tr1.h> using namespace __gnu_test; -using std::weak_ptr; -template class weak_ptr<int>; -template class weak_ptr<void>; -template class weak_ptr<ClassType>; -template class weak_ptr<IncompleteClass>; +template class std::weak_ptr<int>; +template class std::weak_ptr<void>; +template class std::weak_ptr<ClassType>; +template class std::weak_ptr<IncompleteClass>; diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc index 5c1e91b7950..c0873a14898 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/2.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -27,9 +27,8 @@ // library this checks the templates can be instantiated for non-default // lock policy, for a single-threaded lib this is redundant but harmless. using namespace __gnu_test; -using std::__weak_ptr; using std::_S_single; -template class __weak_ptr<int, _S_single>; -template class __weak_ptr<void, _S_single>; -template class __weak_ptr<ClassType, _S_single>; -template class __weak_ptr<IncompleteClass, _S_single>; +template class std::__weak_ptr<int, _S_single>; +template class std::__weak_ptr<void, _S_single>; +template class std::__weak_ptr<ClassType, _S_single>; +template class std::__weak_ptr<IncompleteClass, _S_single>; diff --git a/libstdc++-v3/testsuite/22_locale/codecvt_byname/50714.cc b/libstdc++-v3/testsuite/22_locale/codecvt_byname/50714.cc index e40717ba168..d42caa54e05 100644 --- a/libstdc++-v3/testsuite/22_locale/codecvt_byname/50714.cc +++ b/libstdc++-v3/testsuite/22_locale/codecvt_byname/50714.cc @@ -52,12 +52,12 @@ namespace std template<> int - codecvt<mychar, char, mbstate_t>::do_encoding() const + codecvt<mychar, char, mbstate_t>::do_encoding() const throw() { return 0; } template<> bool - codecvt<mychar, char, mbstate_t>::do_always_noconv() const + codecvt<mychar, char, mbstate_t>::do_always_noconv() const throw() { return false; } template<> @@ -69,7 +69,7 @@ namespace std template<> int - codecvt<mychar, char, mbstate_t>::do_max_length() const + codecvt<mychar, char, mbstate_t>::do_max_length() const throw() { return 4; } } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/debug_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/debug_container.cc index abd9d2c0bd0..c4d3442f672 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/debug_container.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/debug_container.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,18 +21,16 @@ #include <string> #include <debug/unordered_map> -using namespace __gnu_debug; - using std::allocator; using std::equal_to; using std::hash; using std::pair; using std::string; -template class unordered_map<string, float>; -template class unordered_map<string, int, - hash<string>, equal_to<string>, - allocator<pair<const string, int> > >; -template class unordered_map<string, float, - hash<string>, equal_to<string>, - allocator<char> >; +template class __gnu_debug::unordered_map<string, float>; +template class __gnu_debug::unordered_map<string, int, + hash<string>, equal_to<string>, + allocator<pair<const string, int>>>; +template class __gnu_debug::unordered_map<string, float, + hash<string>, equal_to<string>, + allocator<char>>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/3.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/3.cc index de46c5ce621..145d23e123f 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/3.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/explicit_instantiation/3.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,4 +21,5 @@ #include <unordered_map> using namespace std; -template class unordered_map<int, int, hash<int>, equal_to<int>, allocator<char>>; +template class std::unordered_map<int, int, hash<int>, equal_to<int>, + allocator<char>>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/debug.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/debug.cc index 488dbe5e9ec..d2d70764f5c 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/debug.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/debug.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,8 +21,6 @@ #include <string> #include <debug/unordered_map> -using namespace __gnu_debug; - using std::string; -template class unordered_multimap<string, float>; +template class __gnu_debug::unordered_multimap<string, float>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/3.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/3.cc index e3d0f47c42c..8640bc320c4 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/3.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/explicit_instantiation/3.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,4 +21,5 @@ #include <unordered_map> using namespace std; -template class unordered_multimap<int, int, hash<int>, equal_to<int>, allocator<char>>; +template class std::unordered_multimap<int, int, hash<int>, equal_to<int>, + allocator<char>>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/debug.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/debug.cc index bc3544119ec..5e916ad7685 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/debug.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/debug.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,6 +21,4 @@ #include <string> #include <debug/unordered_set> -using namespace __gnu_debug; - -template class unordered_multiset<int>; +template class __gnu_debug::unordered_multiset<int>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/3.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/3.cc index 2a81347eed1..c4624b59147 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/3.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/requirements/explicit_instantiation/3.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,4 +21,5 @@ #include <unordered_set> using namespace std; -template class unordered_multiset<int, hash<int>, equal_to<int>, allocator<char>>; +template class std::unordered_multiset<int, hash<int>, equal_to<int>, + allocator<char>>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/debug_container.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/debug_container.cc index 948c66266d3..f6ab58588ca 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/debug_container.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/debug_container.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -20,6 +20,4 @@ #include <debug/unordered_set> -using namespace __gnu_debug; - -template class unordered_set<int>; +template class __gnu_debug::unordered_set<int>; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/3.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/3.cc index 5cdcb3e314d..27be027da6b 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/3.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/requirements/explicit_instantiation/3.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // { dg-do compile } // Copyright (C) 2007-2014 Free Software Foundation, Inc. @@ -21,4 +21,5 @@ #include <unordered_set> using namespace std; -template class unordered_set<int, hash<int>, equal_to<int>, allocator<char>>; +template class std::unordered_set<int, hash<int>, equal_to<int>, + allocator<char>>; diff --git a/libstdc++-v3/testsuite/24_iterators/insert_iterator/requirements/container.cc b/libstdc++-v3/testsuite/24_iterators/insert_iterator/requirements/container.cc index 9aea7c92b26..162a16e2984 100644 --- a/libstdc++-v3/testsuite/24_iterators/insert_iterator/requirements/container.cc +++ b/libstdc++-v3/testsuite/24_iterators/insert_iterator/requirements/container.cc @@ -26,9 +26,9 @@ // Check data member 'container' accessible. class test_dm : public std::insert_iterator<std::list<int> > { - container_type l; - container_type::iterator i; + container_type& l(); + container_type::iterator i(); container_type* p; public: - test_dm(): std::insert_iterator<std::list<int> >(l, i), p(container) { } + test_dm(): std::insert_iterator<std::list<int> >(l(), i()), p(container) { } }; diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc b/libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc new file mode 100644 index 00000000000..fc155620288 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/dr2106.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <type_traits> +#include <vector> + +typedef std::vector<bool> Vec; +typedef Vec::reference Ref; +typedef Vec::const_reference CRef; +typedef Vec::iterator It; +typedef Vec::const_iterator CIt; +typedef std::move_iterator<It> MIt; +typedef std::move_iterator<CIt> MCIt; +static_assert(std::is_same<MIt::reference, Ref>::value,""); +static_assert(std::is_same<MCIt::reference, CRef>::value,""); diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc new file mode 100644 index 00000000000..27c0c8f59a6 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc @@ -0,0 +1,30 @@ +// { dg-require-atomic-builtins "" } +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <atomic> + +// libstdc++/60695 + +struct X { + char stuff[0]; // GNU extension, type has zero size +}; + +std::atomic<X> a; // { dg-error "not supported" "" { target *-*-* } 168 } diff --git a/libstdc++-v3/testsuite/ext/throw_value/cons.cc b/libstdc++-v3/testsuite/ext/throw_value/cons.cc index 40e67a83220..c6689752f65 100644 --- a/libstdc++-v3/testsuite/ext/throw_value/cons.cc +++ b/libstdc++-v3/testsuite/ext/throw_value/cons.cc @@ -1,4 +1,4 @@ -// { dg-options "-std=gnu++0x" } +// { dg-options "-std=gnu++11" } // Copyright (C) 2009-2014 Free Software Foundation, Inc. // @@ -24,8 +24,8 @@ void foo1() { typedef __gnu_cxx::throw_value_limit value_type; value_type v1; - value_type v2(v2); - value_type v3(value_type()); + value_type v2{v1}; + value_type v3{value_type()}; } bool foo2() diff --git a/libstdc++-v3/testsuite/util/testsuite_common_types.h b/libstdc++-v3/testsuite/util/testsuite_common_types.h index 63339ef877b..abf6ea92ba7 100644 --- a/libstdc++-v3/testsuite/util/testsuite_common_types.h +++ b/libstdc++-v3/testsuite/util/testsuite_common_types.h @@ -689,7 +689,8 @@ namespace __gnu_test struct _Concept; // NB: _Tp must be a literal type. - // Have to have user-defined default ctor for this to work. + // Have to have user-defined default ctor for this to work, + // or implicit default ctor must initialize all members. template<typename _Tp> struct _Concept<_Tp, true> { diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog index bc8ec38dc9c..a60e93b709b 100644 --- a/maintainer-scripts/ChangeLog +++ b/maintainer-scripts/ChangeLog @@ -1,3 +1,7 @@ +2014-04-11 Jakub Jelinek <jakub@redhat.com> + + * crontab: Enable snapshots from gcc-4_9-branch. + 2014-02-01 Dmitry Gorbachev <d.g.gorbachev@gmail.com> PR other/56653 diff --git a/maintainer-scripts/crontab b/maintainer-scripts/crontab index 9f644496a89..f254514be85 100644 --- a/maintainer-scripts/crontab +++ b/maintainer-scripts/crontab @@ -1,6 +1,7 @@ 16 0 * * * sh /home/gccadmin/scripts/update_version_svn 50 0 * * * sh /home/gccadmin/scripts/update_web_docs_svn 55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx_svn +32 22 * * 3 sh /home/gccadmin/scripts/gcc_release -s 4.9:branches/gcc-4_9-branch -l -d /sourceware/snapshot-tmp/gcc all 32 22 * * 4 sh /home/gccadmin/scripts/gcc_release -s 4.8:branches/gcc-4_8-branch -l -d /sourceware/snapshot-tmp/gcc all 32 22 * * 6 sh /home/gccadmin/scripts/gcc_release -s 4.7:branches/gcc-4_7-branch -l -d /sourceware/snapshot-tmp/gcc all -32 22 * * 7 sh /home/gccadmin/scripts/gcc_release -s 4.9:trunk -l -d /sourceware/snapshot-tmp/gcc all +32 22 * * 7 sh /home/gccadmin/scripts/gcc_release -s 4.10:trunk -l -d /sourceware/snapshot-tmp/gcc all |