diff options
author | Richard Guenther <rguenther@suse.de> | 2010-06-28 12:53:25 +0000 |
---|---|---|
committer | Richard Guenther <rguenther@suse.de> | 2010-06-28 12:53:25 +0000 |
commit | 8814e660dfe47d2832cd9c3829001f798dd7515e (patch) | |
tree | 8ed1d7cd976dd8b957246ffa40cec9966bb8cd8b | |
parent | 1271357c111ffe419bda75a647c67c09f186c656 (diff) | |
parent | a8d33d41d32ce2bb74ca82a5b66b40b99274f56c (diff) |
2010-06-28 Richard Guenther <rguenther@suse.de>
Merge from trunk r161484.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/mem-ref2@161488 138bc75d-0d04-0410-961f-82ee72b054a4
288 files changed, 12932 insertions, 1232 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dd890761dc..7b5976187e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,372 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * system.h: Poison GCC_EXCEPT_H for front-end files. + + * langhooks.h (struct lang_hooks): Add eh_protect_cleanup_actions + langhook. + * langhooks-def.h (LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS) New. + Define to NULL by default. + * except.h: Define GCC_EXCEPT_H. + (doing_eh): Remove prototype. + (init_eh, init_eh_for_function): Move prototypes to toplev.h. + (lang_protect_cleanup_actions): Remove. + * except.c (lang_protect_cleanup_actions): Remove. + (doing_eh): Remove. + (gen_eh_region): Don't check doing_eh here. + * toplev.h (init_eh, init_eh_for_function_): Moved from except.h. + * tree-eh.c (honor_protect_cleanup_actions): Use new langhook + instead of lang_protect_cleanup_actions. + * omp-low.c (maybe_catch_exception): Likewise. + * Makefile.in: Update dependencies. + +2010-06-28 Bingfeng Mei <bmei@broadcom.com> + + * cgraph.h (struct varpool_node): new used_from_object_file flag. + (struct cgraph_local_info): new used_from_object_file flag. + * cgraph.c (dump_cgraph_node): dump used_from_object_file flag. + (cgraph_clone_node): initialize used_from_object_file. + (cgraph_create_virtual_clone): initialize used_from_object_file. + * lto-symbtab.c (lto_symtab_merge_decls_1): Set + used_from_object_file flags for symbols of LDPR_PREVAILING_DEF + when compiling with -fwhole-program. + (lto_symtab_resolve_symbols) Use LDPR_PREVAILING_DEF_IRONLY for + internal resolver. + * ipa.c (function_and_variable_visibility): Set externally_visible + flag of varpool_node if used_from_object_file flag is set. + (cgraph_externally_visible_p): check used_from_object_file flag. + * doc/invoke.texi (-fwhole-program option): Change description of + externally_visible attribute accordingly. + * doc/extend.texi (externally_visible): Ditto. + +2010-06-27 Jan Hubicka <jh@suse.cz> + + * params.def (max-inline-insns-auto): Default to 40. + * doc/invoke.texi (max-inline-insns-auto): Document the change. + +2010-06-27 Jan Hubicka <jh@suse.cz> + + PR middle-end/44671 + PR middle-end/44686 + * tree.c (build_function_decl_skip_args): Clear DECL_BUILT_IN on signature + change. + * ipa-split.c (split_function): Always clear DECL_BUILT_IN. + * ipa-prop.c (ipa_modify_formal_parameters): Likewise. + +2010-06-27 Anatoly Sokolov <aesok@post.ru> + + * target.h (struct gcc_target): Add register_move_cost field. + * target-def.h (TARGET_REGISTER_MOVE_COST): New. + (TARGET_INITIALIZER): Use TARGET_REGISTER_MOVE_COST. + * targhooks.c (default_register_move_cost): New function. + * targhooks.h (default_register_move_cost): Declare function. + * defaults.h (REGISTER_MOVE_COST): Delete. + * ira-int.h (ira_register_move_cost): Update comment. + * ira.c: (ira_register_move_cost): Update comment. + * reload.h (register_move_cost): Declare. + * reginfo.c (register_move_cost): New function. + (move_cost): Update comment. + (init_move_cost, memory_move_secondary_cost): Replace + REGISTER_MOVE_COST with register_move_cost. + * postreload.c (reload_cse_simplify_set): (Ditto.). + * reload.c (find_valid_class, find_reloads): (Ditto.). + * reload1.c (choose_reload_regs): (Ditto.). + * doc/tm.texi (TARGET_REGISTER_MOVE_COST): New. + (REGISTER_MOVE_COST, TARGET_MEMORY_MOVE_COST): Update documentation. + * doc/md.texi (can_create_pseudo_p): Update documentation. + + * config/i386/i386.h (MEMORY_MOVE_COST): Remove macro. + * config/i386/i386-protos.h (int ix86_memory_move_cost): Remove. + * config/i386/i386.h (ix86_memory_move_cost): Make static. + (TARGET_MEMORY_MOVE_COST): Define. + + * config/ia64/ia64.h (MEMORY_MOVE_COST): Remove macro. + * config/ia64/ia64-protos.h (int ia64_memory_move_cost): Remove. + * config/ia64/ia64.h (ia64_memory_move_cost): Make static. + (TARGET_MEMORY_MOVE_COST): Define. + +2010-06-27 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/44683 + * tree-ssa-dom.c (record_edge_info): Record equivalences for the + false edge from the inverted condition. + +2010-06-27 Richard Guenther <rguenther@suse.de> + + PR middle-end/44684 + * tree-ssa-alias.c (refs_may_alias_p_1): Allow SSA name refs. + (stmt_may_clobber_ref_p_1): Do not bother to call the oracle + for register LHS. Or non-store assignments. + +2010-06-26 Eric Botcazou <ebotcazou@adacore.com> + + * config/sparc/sparc.c (sparc_emit_set_const32): Make static. + (sparc_emit_set_const64): Likewise. Remove disabled code. + * config/sparc/sparc-protos.h (sparc_emit_set_const32): Delete. + (sparc_emit_set_const64): Likewise. + +2010-06-26 Catherine Moore <clm@codesourcery.com> + + * config/mips/mips.md (alu_type): New attribute. + (type): Infer type from alu_type. + (*add<mode>3, *add<mode>3_mips16, *addsi3_extended, + *baddu_si_eb, *baddu_si_el, *baddu_di, sub<mode>3, + *subsi3_extended, negsi2, negdi2, *low<mode>, + *low<mode>_mips16, *ior<mode>3, *ior<mode>3_mips16, + xor<mode>3, *nor<mode>3, + *zero_extend<GPR:mode>_trunc<SHORT:mode>, + *zero_extendhi_truncqi): Set alu_type instead of type. + +2010-06-26 Douglas B Rupp <rupp@gnat.com> + + * config/alpha/alpha.c (alpha_need_linkage): Adjust + splay_tree_new_ggc call. + (alpha_use_linkage): Likewise. + +2010-06-26 Joseph Myers <joseph@codesourcery.com> + + * collect2.c (main): Remove SWITCHES_NEED_SPACES conditional. + * doc/tm.texi (SWITCHES_NEED_SPACES): Don't document. + * gcc.c (SWITCHES_NEED_SPACES, switches_need_spaces): Remove. + (static_specs): Remove switches_need_spaces. + (process_command, do_self_spec): Hardcode handling "-o" instead of + checking switches_need_spaces. + * system.h (SWITCHES_NEED_SPACES): Poison. + +2010-06-26 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/44393 + * tree-loop-distribution.c (generate_loops_for_partition): Fix + stmt removal and VOP renaming. + (generate_memset_zero): Remove redundant stmt updating. + * tree-flow.h (mark_virtual_ops_in_bb): Remove. + * tree-cfg.c (mark_virtual_ops_in_bb): Likewise. + +2010-06-26 Jan Hubicka <jh@suse.cz> + + * ipa-split.c (consider_split): PHI in entry block is OK as long as all + edges comming from header are equivalent. + (visit_bb): Handle PHIs correctly. + * tree-inline.c (copy_phis_for_bb): Be able to copy + PHI from entry edge. + (copy_cfg_body): Produce edge from entry BB before copying + PHIs. + +2010-06-26 Richard Guenther <rguenther@suse.de> + + PR middle-end/44674 + * tree-ssa-alias.c (refs_may_alias_p_1): Allow all kind of + decls. Handle LABEL_DECLs like FUNCTION_DECLs. + +2010-06-26 Joseph Myers <joseph@codesourcery.com> + + * gcc.c (n_switches_alloc, n_infiles_alloc, alloc_infile, + add_infile, alloc_switch): New. + (process_command): Remove variable lang_n_infiles. Process + options in a single pass. Use new functions for allocating + infiles and switches arrays. Properly skip operands of + -Xpreprocessor and -Xassembler. + +2010-06-26 Jan Hubicka <jh@suse.cz> + + PR middle-end/44671 + * cgraphunit.c (cgraph_function_versioning): Remove wrong + cgraph_make_decl_local call; fix typo copying RTL data. + +2010-06-25 DJ Delorie <dj@redhat.com> + + * config/m32c/m32c-protos.h (m32c_note_pragma_address): Declare. + (m32c_output_aligned_common): Likewise. + * config/m32c/m32c.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): New. + (ASM_OUTPUT_ALIGNED_DECL_LOCAL): New. + * config/m32c/m32c-pragma.c (m32c_pragma_address): New. + (m32c_register_pragmas): Register it. + * config/m32c/m32c.c (m32c_get_pragma_address): New. + (m32c_insert_attributes): Set #pragma address decls volatile. + (pragma_entry_eq): New. + (pragma_entry_hash): New. + (m32c_note_pragma_address): New. + (m32c_get_pragma_address): New. + (m32c_output_aligned_common): New. + * doc/extend.texi: Document the new pragma. + + * config/m32c/m32c.c (m32c_illegal_subreg_p): Reject illegal MEMs + also. + * config/m32c/predicates.md (m32c_any_operand): Check the code + instead of memory_operand so as to allow matching volatile MEMs. + (m32c_nonimmediate_operand): Likewise. + (mra_operand): Allow volatiles. + +2010-06-25 Alexandre Oliva <aoliva@redhat.com> + + PR debug/44610 + * simplify-rtx.c (delegitimize_mem_from_attrs): Don't use a base + address if the offset is unknown. + +2010-06-25 Douglas B Rupp <rupp@gnat.com> + + * dwarf2out.c (dwarf2out_vms_debug_main_pointer): New function. + * dwarf2out.h (dwarf2out_vms_debug_main_pointer): Declare new function. + * config/ia64/ia64-protos.h (ia64_start_function): Declare. + * config/ia64/sysv4.h (ASM_DECLARE_FUNCTION_NAME): Move contents + to ia64_start_function. Invoke it. + * config/ia64/ia64.c (ia64_start_function): Call new function + dwarf2out_vms_debug_main_pointer. + +2010-06-25 Sebastian Pop <sebastian.pop@amd.com> + + * tree-if-conv.c (insert_gimplified_predicates): Do not insert + statements computing the true predicate. + +2010-06-25 Sebastian Pop <sebastian.pop@amd.com> + + * tree-if-conv.c (init_bb_predicate): Initialize the predicate + to boolean_true_node. + (reset_bb_predicate): New. + (predicate_bbs): Call reset_bb_predicate. + +2010-06-25 Sebastian Pop <sebastian.pop@amd.com> + + * tree-if-conv.c (combine_blocks): Remove FIXME comment. + (tree_if_conversion): Returns true when something has been changed. + (main_tree_if_conversion): Return TODO_cleanup_cfg when if-conversion + changed something. + +2010-06-25 Sebastian Pop <sebastian.pop@amd.com> + + * Makefile.in (tree-if-conv.o): Depends on DBGCNT_H. + * dbgcnt.def (if_conversion_tree): New DEBUG_COUNTER. + * tree-if-conv.c: Include dbgcnt.h. + (tree_if_conversion): Use if_conversion_tree to count the number of + if-convertible loops. + +2010-06-25 Changpeng Fang <changpeng.fang@amd.com> + + * common.opt (fprefetch-loop-arrays): Re-define + -fprefetch-loop-arrays as a tri-state option with the initial + value of -1. + * tree-ssa-loop.c (gate_tree_ssa_loop_prefetch): Invoke prefetch + pass only when flag_prefetch_loop_arrays > 0. + * toplev.c (process_options): Note that, with tri-states, + flag_prefetch_loop_arrays>0 means prefetching is enabled. + * config/i386/i386.c (override_options): Enable prefetching at -O3 + for a set of CPUs that sw prefetching is helpful. + (software_prefetching_beneficial_p): New. Return TRUE if software + prefetching is beneficial for the given CPU. + +2010-06-25 H.J. Lu <hongjiu.lu@intel.com> + + PR rtl-optimization/44326 + * implicit-zee.c (find_removable_zero_extends): Replace + INSN_P with NONDEBUG_INSN_P. + +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.h (struct ipa_param_descriptor): Removed the modified flag. + (struct ipa_node_params): Removed the modification_analysis_done flag. + (ipa_is_param_modified): Removed. + (ipa_analyze_node): Declare. + (ipa_compute_jump_functions): Remove declaration. + (ipa_count_arguments): Likewise. + (ipa_detect_param_modifications): Likewise. + (ipa_analyze_params_uses): Likewise. + * ipa-prop.c (struct param_analysis_info): New type. + (visit_store_addr_for_mod_analysis): Removed. + (visit_load_for_mod_analysis): Renamed to visit_ref_for_mod_analysis, + moved down in the file. + (ipa_detect_param_modifications): Merged into ipa_analyze_params_uses. + (ipa_count_arguments): Made static. + (mark_modified): New function. + (is_parm_modified_before_call): New function. + (compute_pass_through_member_ptrs): New parameter parms_info, call + is_parm_modified_before_call instead of ipa_is_param_modified. + (ipa_compute_jump_functions_for_edge): New parameter parms_info, pass + it to compute_pass_through_member_ptrs. + (ipa_compute_jump_functions): New parameter parms_info, pass it to + ipa_compute_jump_functions_for_edge. Call ipa_initialize_node_params + on the callee if it is analyzed. Made static. + (ipa_analyze_indirect_call_uses): New parameter parms_info, call + is_parm_modified_before_call instead of ipa_is_param_modified. + (ipa_analyze_call_uses): New parameter parms_info, pass it to + ipa_analyze_indirect_call_uses. + (ipa_analyze_stmt_uses): New parameter parms_info, pass it to + ipa_analyze_call_uses. + (ipa_analyze_params_uses): New parameter parms_info, pass it to + ipa_analyze_stmt_uses. Also perform the used analysis. Made static. + (ipa_analyze_node): New function. + (ipa_print_node_params): Do not dump the modified flag. + (ipa_write_node_info): Assert uses_analysis_done rather than streaming + it. Do not stream the modified parameter flag. + (ipa_read_node_info): Set uses_analysis_done to 1 instead of streaming + it. Do not stream the modified parameter flag. + * ipa-cp.c (ipcp_analyze_node): Removed. + (ipcp_init_stage): Iterate only once over the nodes, analyze each one + with only a call to ipa_analyze_node. + * ipa-inline.c (inline_indirect_intraprocedural_analysis): Analyze the + node with only a call to ipa_analyze_node. + +2010-06-25 Manuel López-Ibáñez <manu@gcc.gnu.org> + + * doc/invoke.texi (-Wsuggest-attribute): Add item for noreturn. + +2010-06-25 Jan Hubicka <jh@suse.cz> + + * tree-pass.h (pass_split_functions): Declare. + * opts.c (decode_options): Enable function splitting at -O2 + * timevar.def (TV_IPA_FNSPLIT): New macro. + * ipa-split.c: New file. + * common.opt (-fpartial-inlining): New flag. + * Makefile.in (ipa-split.o): New object file. + * passes.c (init_optimization_passes): Add ipa-split. + * params.def (partial-inlining-entry-probability): New parameters. + * doc/invoke.texi (-fpartial-inlining): New. + +2010-06-25 Manuel López-Ibáñez <manu@gcc.gnu.org> + + PR 44665 + * tree-inline.c (gimple_expand_calls_inline): Fix typo in comment. + * gimplify.c (is_gimple_reg_rhs_or_call): Likewise. + (gimplify_expr): Likewise. + +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * ipa-prop.c (determine_cst_member_ptr): Ignore non-clobbering + statements instead of bailing out on them. + (ipa_analyze_indirect_call_uses): Do not require that loads from the + parameter are in the same BB as the condition. Update comments. + +2010-06-25 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/43866 + * tree-ssa-loop-unswitch.c (tree_may_unswitch_on): If stmt is always + true or always false, return NULL_TREE. + (tree_unswitch_single_loop): Optimize conditions even when reaching + max-unswitch-level parameter. If num > 0, optimize first all conditions + using entry checks, then do still reachable block discovery and consider + only conditions in still reachable basic blocks in the loop. + + PR tree-optimization/44539 + * tree-cfgcleanup.c (fixup_noreturn_call): Call update_stmt even when + the call doesn't have LHS, but has VDEF. + +2010-06-25 Joseph Myers <joseph@codesourcery.com> + + * config/pa/pa.h (MODIFY_TARGET_NAME): Remove. + * doc/tm.texi (MODIFY_TARGET_NAME): Don't document. + * gcc.c (enum add_del, struct modify_target, modify_target): + Remove. + (process_command): Remove code conditional on MODIFY_TARGET_NAME. + * system.h (MODIFY_TARGET_NAME): Poison. + +2010-06-25 Alan Modra <amodra@gmail.com> + + * doc/invoke.texi: Delete mcmodel=medium from powerpc options. + * config/rs6000/rs6000.h (enum rs6000_cmodel): Delete CMODEL_MEDIUM. + * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Set + CMODEL_LARGE as default. + * config/rs6000/rs6000.c (rs6000_handle_option): Remove mcmodel=medium. + (offsettable_ok_by_alignment): Delete. + (rs6000_emit_move): Remove mcmodel=medium optimization. + 2010-06-25 Bernd Schmidt <bernds@codesourcery.com> With large parts from Jim Wilson: diff --git a/gcc/ChangeLog.mem-ref2 b/gcc/ChangeLog.mem-ref2 index 8729d53a94f..afa0da8979f 100644 --- a/gcc/ChangeLog.mem-ref2 +++ b/gcc/ChangeLog.mem-ref2 @@ -1,3 +1,7 @@ +2010-06-28 Richard Guenther <rguenther@suse.de> + + Merge from trunk r161484. + 2010-06-25 Richard Guenther <rguenther@suse.de> * config/i386/i386.c (ix86_canonical_va_list_type): Replace diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index dff9214b7fb..67fef635adf 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20100625 +20100628 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 997c9a14d4d..723c295814b 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1441,6 +1441,7 @@ OBJS-archive = \ cppdefault.o \ incpath.o \ ipa-cp.o \ + ipa-split.o \ ipa-inline.o \ ipa-prop.o \ ipa-pure-const.o \ @@ -2080,7 +2081,7 @@ c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ c-family/c-cppbuiltin.o : c-family/c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) \ - $(FLAGS_H) $(TOPLEV_H) output.h $(EXCEPT_H) $(TREE_H) $(TARGET_H) \ + $(FLAGS_H) $(TOPLEV_H) output.h $(TREE_H) $(TARGET_H) \ $(TM_P_H) $(BASEVER) debug.h $(CPP_ID_DATA_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION) @@ -2282,26 +2283,26 @@ lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) \ $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_CORE_H) \ - except.h $(TIMEVAR_H) output.h pointer-set.h $(LTO_STREAMER_H) $(GCOV_IO_H) + $(EXCEPT_H) $(TIMEVAR_H) output.h pointer-set.h $(LTO_STREAMER_H) $(GCOV_IO_H) lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(CGRAPH_H) \ $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) libfuncs.h $(EXCEPT_H) debug.h \ - $(TIMEVAR_H) output.h $(IPA_UTILS_H) $(LTO_STREAMER_H) + $(TIMEVAR_H) output.h $(IPA_UTILS_H) $(LTO_STREAMER_H) toplev.h lto-streamer-out.o : lto-streamer-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ $(HASHTAB_H) $(BASIC_BLOCK_H) tree-iterator.h \ $(TREE_FLOW_H) $(TREE_PASS_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) \ - $(DIAGNOSTIC_CORE_H) except.h $(LTO_STREAMER_H) $(TOPLEV_H) + $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(LTO_STREAMER_H) $(TOPLEV_H) lto-section-in.o: lto-section-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \ $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) \ - $(GGC_H) $(DIAGNOSTIC_CORE_H) except.h $(TIMEVAR_H) output.h \ + $(GGC_H) $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(TIMEVAR_H) output.h \ $(LTO_STREAMER_H) lto-compress.h lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(PARAMS_H) input.h \ $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \ - $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) except.h pointer-set.h \ + $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(EXCEPT_H) pointer-set.h \ $(BITMAP_H) langhooks.h $(LTO_STREAMER_H) lto-compress.h lto-symtab.o: lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ toplev.h $(TREE_H) $(GIMPLE_H) $(GGC_H) $(LAMBDA_H) $(HASHTAB_H) \ @@ -2500,7 +2501,7 @@ tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \ tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \ $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) \ - $(TREE_DUMP_H) tree-pretty-print.h gimple-pretty-print.h + $(TREE_DUMP_H) $(DBGCNT_H) tree-pretty-print.h gimple-pretty-print.h tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ coretypes.h $(GGC_H) tree-iterator.h $(GIMPLE_H) gt-tree-iterator.h tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ @@ -3003,6 +3004,10 @@ ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ $(TREE_PASS_H) $(FLAGS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \ $(TREE_INLINE_H) $(FIBHEAP_H) $(PARAMS_H) tree-pretty-print.h +ipa-split.o : ipa-split.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \ + $(TREE_PASS_H) $(FLAGS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \ + $(TREE_INLINE_H) $(FIBHEAP_H) $(PARAMS_H) matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(RTL_H) $(TREE_INLINE_H) $(TREE_FLOW_H) \ tree-flow-inline.h langhooks.h $(HASHTAB_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \ @@ -4414,7 +4419,7 @@ PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(host_xm_file_list) $(host_xm_include_list) $(xm_include_list) \ intl.h $(PLUGIN_VERSION_H) $(DIAGNOSTIC_H) $(C_COMMON_H) $(C_PRETTY_PRINT_H) \ tree-iterator.h $(PLUGIN_H) $(TREE_FLOW_H) langhooks.h incpath.h debug.h \ - except.h tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) \ + $(EXCEPT_H) tree-ssa-sccvn.h real.h output.h $(IPA_UTILS_H) \ $(C_PRAGMA_H) $(CPPLIB_H) $(FUNCTION_H) \ cppdefault.h flags.h $(MD5_H) params.def params.h prefix.h tree-inline.h \ $(IPA_PROP_H) $(RTL_H) $(TM_P_H) $(CFGLOOP_H) $(EMIT_RTL_H) version.h diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 56f0a06a50f..4046a3a1e89 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,17 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * gcc-interface/misc.c: Do not include except.h. + * gcc-interface/Make-lang.in: Update dependencies. + +2010-06-27 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/trans.c: Include tree-flow.h. + (gnu_switch_label_stack): Delete. + (Case_Statement_to_gnu): Do not emit the goto at the end of a case if + its associated block cannot fall through. Do not emit the final label + if no cases branch to it. + * gcc-interface/Make-lang.in (ada/trans.o): Add $(TREE_FLOW_H). + 2010-06-23 Thomas Quinot <quinot@adacore.com> * exp_attr.adb (Expand_Access_To_Protected_Op): When rewriting a diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 9bf7a47453f..095ae08bbad 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -1244,7 +1244,7 @@ ada/decl.o : ada/gcc-interface/decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TARGET_H) $(FUNCTION_H) \ - $(FLAGS_H) debug.h toplev.h $(EXCEPT_H) langhooks.h \ + $(FLAGS_H) debug.h toplev.h langhooks.h \ $(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) $(PLUGIN_H) \ ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \ ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \ @@ -1260,7 +1260,7 @@ ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@ ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h \ + $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h $(TREE_FLOW_H) \ $(GIMPLE_H) ada/gcc-interface/ada.h ada/adadecode.h ada/types.h \ ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \ ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \ diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 3716f1a631f..4033173d782 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -25,7 +25,7 @@ /* This file contains parts of the compiler that are required for interfacing with GCC but otherwise do nothing and parts of Gigi that need to know - about RTL. */ + about GIMPLE. */ #include "config.h" #include "system.h" @@ -44,7 +44,6 @@ #include "options.h" #include "plugin.h" #include "function.h" /* For pass_by_reference. */ -#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */ #include "ada.h" #include "adadecode.h" diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index aec94b03c4c..30b5c72493f 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -33,6 +33,7 @@ #include "output.h" #include "libfuncs.h" /* For set_stack_check_libfunc. */ #include "tree-iterator.h" +#include "tree-flow.h" #include "gimple.h" #include "ada.h" @@ -168,9 +169,6 @@ static GTY(()) VEC(tree,gc) *gnu_return_label_stack; /* Stack of LOOP_STMT nodes. */ static GTY(()) VEC(tree,gc) *gnu_loop_label_stack; -/* Stack of labels for switch statements. */ -static GTY(()) VEC(tree,gc) *gnu_switch_label_stack; - /* The stacks for N_{Push,Pop}_*_Label. */ static GTY(()) VEC(tree,gc) *gnu_constraint_error_label_stack; static GTY(()) VEC(tree,gc) *gnu_storage_error_label_stack; @@ -1908,9 +1906,9 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) static tree Case_Statement_to_gnu (Node_Id gnat_node) { - tree gnu_result; - tree gnu_expr; + tree gnu_result, gnu_expr, gnu_label; Node_Id gnat_when; + bool may_fallthru = false; gnu_expr = gnat_to_gnu (Expression (gnat_node)); gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr); @@ -1933,8 +1931,7 @@ Case_Statement_to_gnu (Node_Id gnat_node) /* We build a SWITCH_EXPR that contains the code with interspersed CASE_LABEL_EXPRs for each label. */ - VEC_safe_push (tree, gc, gnu_switch_label_stack, - create_artificial_label (input_location)); + gnu_label = create_artificial_label (input_location); start_stmt_group (); for (gnat_when = First_Non_Pragma (Alternatives (gnat_node)); @@ -2014,18 +2011,22 @@ Case_Statement_to_gnu (Node_Id gnat_node) containing the Case statement. */ if (choices_added_p) { - add_stmt (build_stmt_group (Statements (gnat_when), true)); - add_stmt (build1 (GOTO_EXPR, void_type_node, - VEC_last (tree, gnu_switch_label_stack))); + tree group = build_stmt_group (Statements (gnat_when), true); + bool group_may_fallthru = block_may_fallthru (group); + add_stmt (group); + if (group_may_fallthru) + { + add_stmt (build1 (GOTO_EXPR, void_type_node, gnu_label)); + may_fallthru = true; + } } } - /* Now emit a definition of the label all the cases branched to. */ - add_stmt (build1 (LABEL_EXPR, void_type_node, - VEC_last (tree, gnu_switch_label_stack))); + /* Now emit a definition of the label the cases branch to, if any. */ + if (may_fallthru) + add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label)); gnu_result = build3 (SWITCH_EXPR, TREE_TYPE (gnu_expr), gnu_expr, end_stmt_group (), NULL_TREE); - VEC_pop (tree, gnu_switch_label_stack); return gnu_result; } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 0d54b2d01fc..5b575ee1b3d 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * c-cppbuiltin.c: Do not include except.h. + 2010-06-24 Andi Kleen <ak@linux.intel.com> * c-common.c (warn_for_omitted_condop): New. diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 1105ce59f81..fbace227195 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see #include "c-common.h" #include "c-pragma.h" #include "output.h" -#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */ #include "debug.h" /* For dwarf2out_do_cfi_asm. */ #include "toplev.h" #include "tm_p.h" /* For TARGET_CPU_CPP_BUILTINS & friends. */ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 557c205e3d1..b63bf314a12 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1825,6 +1825,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) fprintf (f, " local"); if (node->local.externally_visible) fprintf (f, " externally_visible"); + if (node->local.used_from_object_file) + fprintf (f, " used_from_object_file"); if (node->local.finalized) fprintf (f, " finalized"); if (node->local.disregard_inline_limits) @@ -2075,6 +2077,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, new_node->analyzed = n->analyzed; new_node->local = n->local; new_node->local.externally_visible = false; + new_node->local.used_from_object_file = false; new_node->local.local = true; new_node->local.vtable_method = false; new_node->global = n->global; @@ -2266,6 +2269,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, else new_node->clone.combined_args_to_skip = args_to_skip; new_node->local.externally_visible = 0; + new_node->local.used_from_object_file = 0; new_node->local.local = 1; new_node->lowered = true; new_node->reachable = true; diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 2c7ddbf123c..ef556b9cd7f 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -102,6 +102,9 @@ struct GTY(()) cgraph_local_info { /* Set when function is visible by other units. */ unsigned externally_visible : 1; + /* Set when resolver determines that function is visible by other units. */ + unsigned used_from_object_file : 1; + /* Set once it has been finalized so we consider it to be output. */ unsigned finalized : 1; @@ -487,6 +490,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) varpool_node { unsigned output : 1; /* Set when function is visible by other units. */ unsigned externally_visible : 1; + /* Set when resolver determines that variable is visible by other units. */ + unsigned used_from_object_file : 1; /* Set for aliases once they got through assemble_alias. Also set for extra name aliases in varpool_extra_name_alias. */ unsigned alias : 1; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 3eb06fe96be..5a69afa5286 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2125,7 +2125,7 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version, new_version->local.local = true; new_version->local.vtable_method = false; new_version->global = old_version->global; - new_version->rtl = new_version->rtl; + new_version->rtl = old_version->rtl; new_version->reachable = true; new_version->count = old_version->count; @@ -2193,7 +2193,6 @@ cgraph_function_versioning (struct cgraph_node *old_version_node, else new_decl = build_function_decl_skip_args (old_decl, args_to_skip); - cgraph_make_decl_local (new_decl); /* Generate a new name for the new version. */ DECL_NAME (new_decl) = clone_function_name (old_decl, clone_name); SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl)); diff --git a/gcc/collect2.c b/gcc/collect2.c index b5421179fd2..b26aaf31485 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -1535,12 +1535,7 @@ main (int argc, char **argv) case 'o': if (arg[2] == '\0') output_file = *ld1++ = *ld2++ = *++argv; - else if (1 -#ifdef SWITCHES_NEED_SPACES - && ! strchr (SWITCHES_NEED_SPACES, arg[1]) -#endif - ) - + else output_file = &arg[2]; break; diff --git a/gcc/common.opt b/gcc/common.opt index 968663a43e4..6ca787a4b5f 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -884,6 +884,10 @@ foptimize-sibling-calls Common Report Var(flag_optimize_sibling_calls) Optimization Optimize sibling and tail recursive calls +fpartial-inlining +Common Report Var(flag_partial_inlining) +Perform partial inlining + fpre-ipa-mem-report Common Report Var(pre_ipa_mem_report) Report on memory allocation before interprocedural optimization @@ -945,7 +949,7 @@ Common Report Var(flag_predictive_commoning) Optimization Run predictive commoning optimization. fprefetch-loop-arrays -Common Report Var(flag_prefetch_loop_arrays) Optimization +Common Report Var(flag_prefetch_loop_arrays) Init(-1) Optimization Generate prefetch instructions, if available, for arrays in loops fprofile diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 35ad72f4398..33a472ffa16 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -9900,8 +9900,11 @@ alpha_need_linkage (const char *name, int is_local) struct alpha_funcs *cfaf; if (!alpha_funcs_tree) - alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn) - splay_tree_compare_pointers); + alpha_funcs_tree = splay_tree_new_ggc + (splay_tree_compare_pointers, + ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s, + ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s); + cfaf = ggc_alloc_alpha_funcs (); @@ -9937,7 +9940,10 @@ alpha_need_linkage (const char *name, int is_local) } } else - alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp); + alpha_links_tree = splay_tree_new_ggc + ((splay_tree_compare_fn) strcmp, + ggc_alloc_splay_tree_str_alpha_links_splay_tree_s, + ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s); al = ggc_alloc_alpha_links (); name = ggc_strdup (name); @@ -9995,7 +10001,10 @@ alpha_use_linkage (rtx func, tree cfundecl, int lflag, int rflag) al = (struct alpha_links *) lnode->value; } else - cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp); + cfaf->links = splay_tree_new_ggc + ((splay_tree_compare_fn) strcmp, + ggc_alloc_splay_tree_str_alpha_links_splay_tree_s, + ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s); if (!al) { diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 5bd8749645e..308f9eef5e8 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -149,8 +149,6 @@ extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx, rtx); extern bool ix86_hard_regno_mode_ok (int, enum machine_mode); extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode); -extern int ix86_register_move_cost (enum machine_mode, enum reg_class, - enum reg_class); extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class, enum machine_mode, int); extern bool ix86_cannot_change_mode_class (enum machine_mode, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c56a212dbe4..9c308acf888 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2691,6 +2691,26 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune, return ret; } +/* Return TRUE if software prefetching is beneficial for the + given CPU. */ + +static bool +software_prefetching_beneficial_p (void) +{ + switch (ix86_tune) + { + case PROCESSOR_GEODE: + case PROCESSOR_K6: + case PROCESSOR_ATHLON: + case PROCESSOR_K8: + case PROCESSOR_AMDFAM10: + return true; + + default: + return false; + } +} + /* Function that is callable from the debugger to print the current options. */ void @@ -3535,6 +3555,13 @@ override_options (bool main_args_p) if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE)) set_param_value ("l2-cache-size", ix86_cost->l2_cache_size); + /* Enable sw prefetching at -O3 for CPUS that prefetching is helpful. */ + if (flag_prefetch_loop_arrays < 0 + && HAVE_prefetch + && optimize >= 3 + && software_prefetching_beneficial_p ()) + flag_prefetch_loop_arrays = 1; + /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0) can be optimized to ap = __builtin_next_arg (0). */ if (!TARGET_64BIT) @@ -25635,7 +25662,7 @@ ix86_memory_move_cost (enum machine_mode mode, enum reg_class regclass, on some machines it is expensive to move between registers if they are not general registers. */ -int +static int ix86_register_move_cost (enum machine_mode mode, enum reg_class class1, enum reg_class class2) { @@ -30809,6 +30836,8 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree) #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION ix86_handle_option +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST ix86_register_move_cost #undef TARGET_MEMORY_MOVE_COST #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost #undef TARGET_RTX_COSTS diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 226f7849829..67f1f60f3a1 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1891,17 +1891,6 @@ do { \ so give the MEM rtx a byte's mode. */ #define FUNCTION_MODE QImode -/* A C expression for the cost of moving data from a register in class FROM to - one in class TO. The classes are expressed using the enumeration values - such as `GENERAL_REGS'. A value of 2 is the default; other values are - interpreted relative to that. - - It is not required that the cost always equal 2 when FROM is the same as TO; - on some machines it is expensive to move between registers if they are not - general registers. */ - -#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \ - ix86_register_move_cost ((MODE), (CLASS1), (CLASS2)) /* A C expression for the cost of a branch instruction. A value of 1 is the default; other values are interpreted relative to that. */ diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 43d58641b9a..a5914b1a5ac 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler for IA-64. - Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -79,10 +79,9 @@ extern void ia64_vms_output_aligned_decl_common (FILE *, tree, const char *, unsigned HOST_WIDE_INT, unsigned int); extern void ia64_vms_elf_asm_named_section (const char *, unsigned int, tree); +extern void ia64_start_function (FILE *, const char *, tree); #endif /* TREE_CODE */ -extern int ia64_register_move_cost (enum machine_mode, enum reg_class, - enum reg_class); extern int ia64_epilogue_uses (int); extern int ia64_eh_uses (int); extern void emit_safe_across_calls (void); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 9e2aa7ab50d..d40747a7f1c 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -210,6 +210,8 @@ static bool ia64_return_in_memory (const_tree, const_tree); static rtx ia64_function_value (const_tree, const_tree, bool); static rtx ia64_libcall_value (enum machine_mode, const_rtx); static bool ia64_function_value_regno_p (const unsigned int); +static int ia64_register_move_cost (enum machine_mode, enum reg_class, + enum reg_class); static bool ia64_rtx_costs (rtx, int, int, int *, bool); static int ia64_unspec_may_trap_p (const_rtx, unsigned); static void fix_range (const char *); @@ -454,6 +456,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_ASM_GLOBALIZE_DECL_NAME #define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST ia64_register_move_cost #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS ia64_rtx_costs #undef TARGET_ADDRESS_COST @@ -3423,6 +3427,29 @@ ia64_expand_prologue (void) finish_spill_pointers (); } +/* Output the textual info surrounding the prologue. */ + +void +ia64_start_function (FILE *file, const char *fnname, + tree decl ATTRIBUTE_UNUSED) +{ +#if VMS_DEBUGGING_INFO + if (vms_debug_main + && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0) + { + targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER); + ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname); + dwarf2out_vms_debug_main_pointer (); + vms_debug_main = 0; + } +#endif + + fputs ("\t.proc ", file); + assemble_name (file, fnname); + fputc ('\n', file); + ASM_OUTPUT_LABEL (file, fnname); +} + /* Called after register allocation to add any instructions needed for the epilogue. Using an epilogue insn is favored compared to putting all of the instructions in output_function_prologue(), since it allows the scheduler @@ -5179,7 +5206,7 @@ ia64_rtx_costs (rtx x, int code, int outer_code, int *total, /* Calculate the cost of moving data from a register in class FROM to one in class TO, using MODE. */ -int +static int ia64_register_move_cost (enum machine_mode mode, enum reg_class from, enum reg_class to) { diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 8192b9fb522..bf24f73f04e 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1310,11 +1310,6 @@ do { \ /* Describing Relative Costs of Operations */ -/* A C expression for the cost of moving data from a register in class FROM to - one in class TO, using MODE. */ - -#define REGISTER_MOVE_COST ia64_register_move_cost - /* A C expression for the cost of moving data of mode M between a register and memory. */ #define MEMORY_MOVE_COST(MODE,CLASS,IN) \ diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h index 678a81ec628..0d760731b46 100644 --- a/gcc/config/ia64/sysv4.h +++ b/gcc/config/ia64/sysv4.h @@ -1,7 +1,7 @@ /* Override definitions in elfos.h/svr4.h to be correct for IA64. Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, -2007 Free Software Foundation, Inc. +2007, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -127,12 +127,7 @@ do { \ #undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ -do { \ - fputs ("\t.proc ", FILE); \ - assemble_name (FILE, NAME); \ - fputc ('\n', FILE); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ -} while (0) + ia64_start_function(FILE,NAME,DECL) /* We redefine this to use the ia64 .endp pseudo-op. */ diff --git a/gcc/config/m32c/m32c-pragma.c b/gcc/config/m32c/m32c-pragma.c index 49fe0238597..b57615265a2 100644 --- a/gcc/config/m32c/m32c-pragma.c +++ b/gcc/config/m32c/m32c-pragma.c @@ -87,9 +87,47 @@ m32c_pragma_memregs (cpp_reader * reader ATTRIBUTE_UNUSED) error ("#pragma GCC memregs takes a number [0..16]"); } +/* Implements the "pragma ADDRESS" pragma. This pragma takes a + variable name and an address, and arranges for that variable to be + "at" that address. The variable is also made volatile. */ +static void +m32c_pragma_address (cpp_reader * reader ATTRIBUTE_UNUSED) +{ + /* on off */ + tree var, addr; + enum cpp_ttype type; + const char *var_str; + + type = pragma_lex (&var); + if (type == CPP_NAME) + { + var_str = IDENTIFIER_POINTER (var); + + type = pragma_lex (&addr); + if (type == CPP_NUMBER) + { + if (var != error_mark_node) + { + unsigned uaddr = tree_low_cst (addr, 1); + m32c_note_pragma_address (IDENTIFIER_POINTER (var), uaddr); + } + + type = pragma_lex (&var); + if (type != CPP_EOF) + { + error ("junk at end of #pragma ADDRESS"); + } + return; + } + } + error ("malformed #pragma ADDRESS variable address"); +} + /* Implements REGISTER_TARGET_PRAGMAS. */ void m32c_register_pragmas (void) { c_register_pragma ("GCC", "memregs", m32c_pragma_memregs); + c_register_pragma (NULL, "ADDRESS", m32c_pragma_address); + c_register_pragma (NULL, "address", m32c_pragma_address); } diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h index 42b92feb506..89231fc2d5d 100644 --- a/gcc/config/m32c/m32c-protos.h +++ b/gcc/config/m32c/m32c-protos.h @@ -42,6 +42,7 @@ int m32c_print_operand_punct_valid_p (int); int m32c_push_rounding (int); int m32c_reg_class_from_constraint (char, const char *); void m32c_register_pragmas (void); +void m32c_note_pragma_address (const char *, unsigned); int m32c_regno_ok_for_base_p (int); int m32c_trampoline_alignment (void); int m32c_trampoline_size (void); @@ -104,6 +105,8 @@ tree m32c_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); void m32c_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); bool m32c_promote_function_return (const_tree); int m32c_special_page_vector_p (tree); +void m32c_output_aligned_common (FILE *, tree, const char *, + int, int, int); #endif diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 3280d14e78e..443325f8dd9 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -83,6 +83,9 @@ static int need_to_save (int); static rtx m32c_function_value (const_tree, const_tree, bool); static rtx m32c_libcall_value (enum machine_mode, const_rtx); +/* Returns true if an address is specified, else false. */ +static bool m32c_get_pragma_address (const char *varname, unsigned *addr); + int current_function_special_page_vector (rtx); #define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0) @@ -2929,7 +2932,107 @@ static void m32c_insert_attributes (tree node ATTRIBUTE_UNUSED, tree * attr_ptr ATTRIBUTE_UNUSED) { - /* Nothing to do here. */ + unsigned addr; + /* See if we need to make #pragma address variables volatile. */ + + if (TREE_CODE (node) == VAR_DECL) + { + char *name = IDENTIFIER_POINTER (DECL_NAME (node)); + if (m32c_get_pragma_address (name, &addr)) + { + TREE_THIS_VOLATILE (node) = true; + } + } +} + + +struct GTY(()) pragma_entry { + const char *varname; + unsigned address; +}; +typedef struct pragma_entry pragma_entry; + +/* Hash table of pragma info. */ +static GTY((param_is (pragma_entry))) htab_t pragma_htab; + +static int +pragma_entry_eq (const void *p1, const void *p2) +{ + const pragma_entry *old = (const pragma_entry *) p1; + const char *new_name = (const char *) p2; + + return strcmp (old->varname, new_name) == 0; +} + +static hashval_t +pragma_entry_hash (const void *p) +{ + const pragma_entry *old = (const pragma_entry *) p; + return htab_hash_string (old->varname); +} + +void +m32c_note_pragma_address (const char *varname, unsigned address) +{ + pragma_entry **slot; + + if (!pragma_htab) + pragma_htab = htab_create_ggc (31, pragma_entry_hash, + pragma_entry_eq, NULL); + + slot = (pragma_entry **) + htab_find_slot_with_hash (pragma_htab, varname, + htab_hash_string (varname), INSERT); + + if (!*slot) + { + *slot = ggc_alloc_pragma_entry (); + (*slot)->varname = ggc_strdup (varname); + } + (*slot)->address = address; +} + +static bool +m32c_get_pragma_address (const char *varname, unsigned *address) +{ + pragma_entry **slot; + + if (!pragma_htab) + return false; + + slot = (pragma_entry **) + htab_find_slot_with_hash (pragma_htab, varname, + htab_hash_string (varname), NO_INSERT); + if (slot && *slot) + { + *address = (*slot)->address; + return true; + } + return false; +} + +void +m32c_output_aligned_common (FILE *stream, tree decl, const char *name, + int size, int align, int global) +{ + unsigned address; + + if (m32c_get_pragma_address (name, &address)) + { + /* We never output these as global. */ + assemble_name (stream, name); + fprintf (stream, " = 0x%04x\n", address); + return; + } + if (!global) + { + fprintf (stream, "\t.local\t"); + assemble_name (stream, name); + fprintf (stream, "\n"); + } + fprintf (stream, "\t.comm\t"); + assemble_name (stream, name); + fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT); } /* Predicates */ @@ -2960,7 +3063,7 @@ static const struct { }; /* Returns TRUE if OP is a subreg of a hard reg which we don't - support. */ + support. We also bail on MEMs with illegal addresses. */ bool m32c_illegal_subreg_p (rtx op) { @@ -2968,6 +3071,12 @@ m32c_illegal_subreg_p (rtx op) unsigned int i; int src_mode, dest_mode; + if (GET_CODE (op) == MEM + && ! m32c_legitimate_address_p (Pmode, XEXP (op, 0), false)) + { + return true; + } + if (GET_CODE (op) != SUBREG) return false; diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h index 85dc2d1dce2..a98005c78c1 100644 --- a/gcc/config/m32c/m32c.h +++ b/gcc/config/m32c/m32c.h @@ -644,6 +644,13 @@ typedef struct m32c_cumulative_args #define ASM_OUTPUT_REG_PUSH(S,R) m32c_output_reg_push (S, R) #define ASM_OUTPUT_REG_POP(S,R) m32c_output_reg_pop (S, R) +#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGNMENT) \ + m32c_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 1) + +#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) \ + m32c_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 0) + + /* Output of Dispatch Tables */ #define ASM_OUTPUT_ADDR_VEC_ELT(S,V) \ diff --git a/gcc/config/m32c/predicates.md b/gcc/config/m32c/predicates.md index 321debfd2ca..98a1c16e7c5 100644 --- a/gcc/config/m32c/predicates.md +++ b/gcc/config/m32c/predicates.md @@ -26,7 +26,7 @@ (define_predicate "m32c_any_operand" (ior (match_operand 0 "general_operand") - (match_operand 1 "memory_operand")) + (match_code "mem,const_int,const_double")) { return ! m32c_illegal_subreg_p (op); } @@ -36,7 +36,11 @@ (define_predicate "m32c_nonimmediate_operand" (ior (match_operand 0 "nonimmediate_operand") - (match_operand 1 "memory_operand"))) + (match_code "mem")) + { + return ! m32c_illegal_subreg_p (op); + } +) ; TRUE if the operand is a pseudo-register. (define_predicate "m32c_pseudo" @@ -135,7 +139,7 @@ ; Likewise, plus TRUE for memory references. (define_predicate "mra_operand" - (and (and (match_operand 0 "nonimmediate_operand" "") + (and (and (match_operand 0 "m32c_nonimmediate_operand" "") (not (match_operand 1 "cr_operand" ""))) (not (match_operand 2 "m32c_wide_subreg" "")))) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 0ad21bd1783..9b09344d9c9 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -199,6 +199,9 @@ shift_shift,lui_movf" (const_string "unknown")) +(define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor" + (const_string "unknown")) + ;; Main data type used by the insn (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW" (const_string "unknown")) @@ -275,6 +278,10 @@ (cond [(eq_attr "jal" "!unset") (const_string "call") (eq_attr "got" "load") (const_string "load") + (eq_attr "alu_type" "add,sub") (const_string "arith") + + (eq_attr "alu_type" "not,nor,and,or,xor") (const_string "logical") + ;; If a doubleword move uses these expensive instructions, ;; it is usually better to schedule them in the same way ;; as the singleword form, rather than as "multi". @@ -978,7 +985,7 @@ "@ <d>addu\t%0,%1,%2 <d>addiu\t%0,%1,%2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "<MODE>")]) (define_insn "*add<mode>3_mips16" @@ -992,7 +999,7 @@ <d>addiu\t%0,%2 <d>addiu\t%0,%1,%2 <d>addu\t%0,%1,%2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "<MODE>") (set_attr_alternative "length" [(if_then_else (match_operand 2 "m16_simm8_8") @@ -1130,7 +1137,7 @@ "@ addu\t%0,%1,%2 addiu\t%0,%1,%2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "SI")]) ;; Split this insn so that the addiu splitters can have a crack at it. @@ -1145,7 +1152,7 @@ "&& reload_completed" [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))] { operands[3] = gen_lowpart (SImode, operands[0]); } - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "SI") (set_attr "extended_mips16" "yes")]) @@ -1159,7 +1166,7 @@ (match_operand:SI 2 "register_operand" "d")) 3)))] "ISA_HAS_BADDU && BYTES_BIG_ENDIAN" "baddu\\t%0,%1,%2" - [(set_attr "type" "arith")]) + [(set_attr "alu_type" "add")]) (define_insn "*baddu_si_el" [(set (match_operand:SI 0 "register_operand" "=d") @@ -1169,7 +1176,7 @@ (match_operand:SI 2 "register_operand" "d")) 0)))] "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN" "baddu\\t%0,%1,%2" - [(set_attr "type" "arith")]) + [(set_attr "alu_type" "add")]) (define_insn "*baddu_di<mode>" [(set (match_operand:GPR 0 "register_operand" "=d") @@ -1179,7 +1186,7 @@ (match_operand:DI 2 "register_operand" "d")))))] "ISA_HAS_BADDU && TARGET_64BIT" "baddu\\t%0,%1,%2" - [(set_attr "type" "arith")]) + [(set_attr "alu_type" "add")]) ;; ;; .................... @@ -1204,7 +1211,7 @@ (match_operand:GPR 2 "register_operand" "d")))] "" "<d>subu\t%0,%1,%2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "sub") (set_attr "mode" "<MODE>")]) (define_insn "*subsi3_extended" @@ -1214,7 +1221,7 @@ (match_operand:SI 2 "register_operand" "d"))))] "TARGET_64BIT" "subu\t%0,%1,%2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "sub") (set_attr "mode" "DI")]) ;; @@ -2483,7 +2490,7 @@ else return "subu\t%0,%.,%1"; } - [(set_attr "type" "arith") + [(set_attr "alu_type" "sub") (set_attr "mode" "SI")]) (define_insn "negdi2" @@ -2491,7 +2498,7 @@ (neg:DI (match_operand:DI 1 "register_operand" "d")))] "TARGET_64BIT && !TARGET_MIPS16" "dsubu\t%0,%.,%1" - [(set_attr "type" "arith") + [(set_attr "alu_type" "sub") (set_attr "mode" "DI")]) ;; neg.fmt is an arithmetic instruction and treats all NaN inputs as @@ -2516,7 +2523,7 @@ else return "nor\t%0,%.,%1"; } - [(set_attr "type" "logical") + [(set_attr "alu_type" "not") (set_attr "mode" "<MODE>")]) ;; @@ -2638,7 +2645,7 @@ "@ or\t%0,%1,%2 ori\t%0,%1,%x2" - [(set_attr "type" "logical") + [(set_attr "alu_type" "or") (set_attr "mode" "<MODE>")]) (define_insn "*ior<mode>3_mips16" @@ -2647,7 +2654,7 @@ (match_operand:GPR 2 "register_operand" "d")))] "TARGET_MIPS16" "or\t%0,%2" - [(set_attr "type" "logical") + [(set_attr "alu_type" "or") (set_attr "mode" "<MODE>")]) (define_expand "xor<mode>3" @@ -2665,7 +2672,7 @@ "@ xor\t%0,%1,%2 xori\t%0,%1,%x2" - [(set_attr "type" "logical") + [(set_attr "alu_type" "xor") (set_attr "mode" "<MODE>")]) (define_insn "" @@ -2677,7 +2684,7 @@ xor\t%0,%2 cmpi\t%1,%2 cmp\t%1,%2" - [(set_attr "type" "logical,arith,arith") + [(set_attr "alu_type" "xor") (set_attr "mode" "<MODE>") (set_attr_alternative "length" [(const_int 4) @@ -2692,7 +2699,7 @@ (not:GPR (match_operand:GPR 2 "register_operand" "d"))))] "!TARGET_MIPS16" "nor\t%0,%1,%2" - [(set_attr "type" "logical") + [(set_attr "alu_type" "nor") (set_attr "mode" "<MODE>")]) ;; @@ -2910,7 +2917,7 @@ operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode)); return "andi\t%0,%1,%x2"; } - [(set_attr "type" "logical") + [(set_attr "alu_type" "and") (set_attr "mode" "<GPR:MODE>")]) (define_insn "*zero_extendhi_truncqi" @@ -2919,7 +2926,7 @@ (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] "TARGET_64BIT && !TARGET_MIPS16" "andi\t%0,%1,0xff" - [(set_attr "type" "logical") + [(set_attr "alu_type" "and") (set_attr "mode" "HI")]) ;; @@ -3851,7 +3858,7 @@ (match_operand:P 2 "immediate_operand" "")))] "!TARGET_MIPS16" "<d>addiu\t%0,%1,%R2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "<MODE>")]) (define_insn "*low<mode>_mips16" @@ -3860,7 +3867,7 @@ (match_operand:P 2 "immediate_operand" "")))] "TARGET_MIPS16" "<d>addiu\t%0,%R2" - [(set_attr "type" "arith") + [(set_attr "alu_type" "add") (set_attr "mode" "<MODE>") (set_attr "extended_mips16" "yes")]) diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 4b10a0a3b9b..8a18289b0d2 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for the HP Spectrum. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) of Cygnus Support and Tim Moore (moore@defmacro.cs.utah.edu) of the Center for @@ -222,15 +222,6 @@ do { \ #define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" #endif -/* This macro defines command-line switches that modify the default - target name. - - The definition is be an initializer for an array of structures. Each - array element has have three elements: the switch name, one of the - enumeration codes ADD or DELETE to indicate whether the string should be - inserted or deleted, and the string to be inserted or deleted. */ -#define MODIFY_TARGET_NAME {{"-32", DELETE, "64"}, {"-64", ADD, "64"}} - /* Make gcc agree with <machine/ansi.h> */ #define SIZE_TYPE "unsigned int" diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index c4e365174ce..900570f2ea1 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -134,7 +134,7 @@ extern enum rs6000_cmodel cmodel; else \ { \ if (!rs6000_explicit_options.cmodel) \ - SET_CMODEL (CMODEL_MEDIUM); \ + SET_CMODEL (CMODEL_LARGE); \ if (cmodel != CMODEL_SMALL) \ { \ TARGET_NO_FP_IN_TOC = 0; \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 59e53b94a75..9b0bc50b168 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3653,8 +3653,6 @@ rs6000_handle_option (size_t code, const char *arg, int value) case OPT_mcmodel_: if (strcmp (arg, "small") == 0) cmodel = CMODEL_SMALL; - else if (strcmp (arg, "medium") == 0) - cmodel = CMODEL_MEDIUM; else if (strcmp (arg, "large") == 0) cmodel = CMODEL_LARGE; else @@ -6636,36 +6634,6 @@ rs6000_eliminate_indexed_memrefs (rtx operands[2]) copy_addr_to_reg (XEXP (operands[1], 0))); } -/* Return true if memory accesses to DECL are known to never straddle - a 32k boundary. */ - -static bool -offsettable_ok_by_alignment (tree decl) -{ - unsigned HOST_WIDE_INT dsize; - - /* Presume any compiler generated symbol_ref is suitably aligned. */ - if (!decl) - return true; - - if (TREE_CODE (decl) != VAR_DECL - && TREE_CODE (decl) != PARM_DECL - && TREE_CODE (decl) != RESULT_DECL - && TREE_CODE (decl) != FIELD_DECL) - return true; - - if (!host_integerp (DECL_SIZE_UNIT (decl), 1)) - return false; - - dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1); - if (dsize <= 1) - return true; - if (dsize > 32768) - return false; - - return DECL_ALIGN_UNIT (decl) >= dsize; -} - /* Emit a move from SOURCE to DEST in mode MODE. */ void rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) @@ -6979,16 +6947,11 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) /* If this is a SYMBOL_REF that refers to a constant pool entry, and we have put it in the TOC, we just need to make a TOC-relative reference to it. */ - if ((TARGET_TOC - && GET_CODE (operands[1]) == SYMBOL_REF - && constant_pool_expr_p (operands[1]) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), - get_pool_mode (operands[1]))) - || (TARGET_CMODEL == CMODEL_MEDIUM - && GET_CODE (operands[1]) == SYMBOL_REF - && !CONSTANT_POOL_ADDRESS_P (operands[1]) - && SYMBOL_REF_LOCAL_P (operands[1]) - && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1])))) + if (TARGET_TOC + && GET_CODE (operands[1]) == SYMBOL_REF + && constant_pool_expr_p (operands[1]) + && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]), + get_pool_mode (operands[1]))) { rtx reg = NULL_RTX; if (TARGET_CMODEL != CMODEL_SMALL) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index cd7b9281bef..a6248ecc1e6 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -295,11 +295,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); /* Code model for 64-bit linux. small: 16-bit toc offsets. - medium: 32-bit toc offsets, static data and code within 2G of TOC pointer. - large: 32-bit toc offsets, no limit on static data and code. */ + large: 32-bit toc offsets. */ enum rs6000_cmodel { CMODEL_SMALL, - CMODEL_MEDIUM, CMODEL_LARGE }; diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index fd602ccd200..cc51280596c 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -66,8 +66,6 @@ extern bool legitimate_pic_operand_p (rtx); extern void sparc_emit_call_insn (rtx, rtx); extern void sparc_defer_case_vector (rtx, rtx, int); extern bool sparc_expand_move (enum machine_mode, rtx *); -extern void sparc_emit_set_const32 (rtx, rtx); -extern void sparc_emit_set_const64 (rtx, rtx); extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx); extern int sparc_splitdi_legitimate (rtx, rtx); extern int sparc_absnegfloat_split_legitimate (rtx, rtx); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 8b44dbeb80d..412f27c3066 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -354,6 +354,8 @@ static int function_arg_slotno (const CUMULATIVE_ARGS *, enum machine_mode, static int supersparc_adjust_cost (rtx, rtx, rtx, int); static int hypersparc_adjust_cost (rtx, rtx, rtx, int); +static void sparc_emit_set_const32 (rtx, rtx); +static void sparc_emit_set_const64 (rtx, rtx); static void sparc_output_addr_vec (rtx); static void sparc_output_addr_diff_vec (rtx); static void sparc_output_deferred_case_vectors (void); @@ -1111,7 +1113,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) We know it can't be done in one insn when we get here, the move expander guarantees this. */ -void +static void sparc_emit_set_const32 (rtx op0, rtx op1) { enum machine_mode mode = GET_MODE (op0); @@ -1353,7 +1355,7 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp) } #if HOST_BITS_PER_WIDE_INT == 32 -void +static void sparc_emit_set_const64 (rtx op0 ATTRIBUTE_UNUSED, rtx op1 ATTRIBUTE_UNUSED) { gcc_unreachable (); @@ -1710,7 +1712,7 @@ create_simple_focus_bits (unsigned HOST_WIDE_INT high_bits, being loaded into a register. Emit the most efficient insn sequence possible. Detection of all the 1-insn cases has been done already. */ -void +static void sparc_emit_set_const64 (rtx op0, rtx op1) { unsigned HOST_WIDE_INT high_bits, low_bits; @@ -1936,10 +1938,6 @@ sparc_emit_set_const64 (rtx op0, rtx op1) } /* The easiest way when all else fails, is full decomposition. */ -#if 0 - printf ("sparc_emit_set_const64: Hard constant [%08lx%08lx] neg[%08lx%08lx]\n", - high_bits, low_bits, ~high_bits, ~low_bits); -#endif sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits); } #endif /* HOST_BITS_PER_WIDE_INT == 32 */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3093f0d9c9a..3b5f1bd82de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * init.c: Do not include except.h. + * decl.c: Likewise. + * expr.c: Likewise. + * cp-lang.c: Likewise. + * pt.c: Likewise. + * semantics.c: Likewise. + * decl2.c: Likewise. + * except.c: Likewise. + (init_exception_processing): Do not set the removed + lang_protect_cleanup_actions here. + (cp_protect_cleanup_actions): Make non-static and remove prototype. + (doing_eh): New, moved from except.c but removed the do_warning flag. + (expand_start_catch_block): Update doing_eh call. + (expand_end_catch_block): Likewise. + (build_throw): Likewise. + * cp-tree.h: Prototype cp_protect_cleanup_actions. + * cp-objcp-common.h: Set LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS to + cp_protect_cleanup_actions. + * Make-lang.in: Update dependencies. + +2010-06-26 Jason Merrill <jason@redhat.com> + + * call.c (add_function_candidate): Set LOOKUP_COPY_PARM for any + constructor called with a single argument that takes a reference + to the constructor's class. + (BAD_CONVERSION_RANK): New. + (compare_ics): Use it to compare bad ICSes. + 2010-06-25 Joseph Myers <joseph@codesourcery.com> * lang-specs.h: Remove +e handling. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index bfccd72d5d8..f664c78f12f 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -249,14 +249,14 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \ $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h gt-cp-cp-lang.h \ - cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H) + cp/cp-objcp-common.h $(EXPR_H) cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \ - output.h $(EXCEPT_H) toplev.h $(HASHTAB_H) $(RTL_H) \ + output.h toplev.h $(HASHTAB_H) $(RTL_H) \ cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \ debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H) $(PLUGIN_H) \ intl.h tree-iterator.h $(SPLAY_TREE_H) cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \ - output.h $(EXCEPT_H) toplev.h $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \ + output.h toplev.h $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \ $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H) $(POINTER_SET_H) \ $(SPLAY_TREE_H) c-family/c-ada-spec.h cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \ @@ -288,19 +288,17 @@ cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H) cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h convert.h \ $(TARGET_H) $(C_PRAGMA_H) gt-cp-rtti.h intl.h -cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(EXCEPT_H) \ +cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ toplev.h cp/cfns.h $(TREE_INLINE_H) $(TARGET_H) -cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ - toplev.h $(EXCEPT_H) $(TM_P_H) +cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(TM_P_H) cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/cp-objcp-common.h \ - toplev.h $(EXCEPT_H) $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h \ - vecprim.h intl.h + toplev.h $(TREE_INLINE_H) pointer-set.h gt-cp-pt.h vecprim.h intl.h cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \ $(FLAGS_H) $(REAL_H) $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H) \ tree-diagnostic.h tree-pretty-print.h cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) \ gt-cp-repo.h -cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) $(EXCEPT_H) toplev.h \ +cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) toplev.h \ $(FLAGS_H) output.h $(RTL_H) $(TIMEVAR_H) \ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H) \ bitmap.h gt-cp-semantics.h diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 55089edbf1d..faaab1027f5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -122,6 +122,11 @@ struct conversion { : (NODE)->user_conv_p ? cr_user \ : (NODE)->rank) +#define BAD_CONVERSION_RANK(NODE) \ + ((NODE)->ellipsis_p ? cr_ellipsis \ + : (NODE)->user_conv_p ? cr_user \ + : (NODE)->rank) + static struct obstack conversion_obstack; static bool conversion_obstack_initialized; @@ -1386,9 +1391,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conversion operator). */ flags |= LOOKUP_NO_TEMP_BIND; - /* Temporaries are copy-initialized, except for this hack to allow - explicit conversion ops to the copy ctor. See also - add_function_candidate. */ + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So don't set LOOKUP_ONLYCONVERTING in that case. */ if (!(flags & LOOKUP_COPY_PARM)) flags |= LOOKUP_ONLYCONVERTING; @@ -1618,6 +1626,8 @@ add_function_candidate (struct z_candidate **candidates, tree parmtype = TREE_VALUE (parmnode); int lflags = flags; + parmnode = TREE_CHAIN (parmnode); + /* The type of the implicit object parameter ('this') for overload resolution is not always the same as for the function itself; conversion functions are considered to @@ -1634,13 +1644,25 @@ add_function_candidate (struct z_candidate **candidates, parmtype = build_pointer_type (parmtype); } - if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn) - && (len-skip == 1)) + /* Core issue 899: When [copy-]initializing a temporary to be bound + to the first parameter of a copy constructor (12.8) called with + a single argument in the context of direct-initialization, + explicit conversion functions are also considered. + + So set LOOKUP_COPY_PARM to let reference_binding know that + it's being called in that context. We generalize the above + to handle move constructors and template constructors as well; + the standardese should soon be updated similarly. */ + if (ctype && i == 0 && (len-skip == 1) + && !(flags & LOOKUP_ONLYCONVERTING) + && DECL_CONSTRUCTOR_P (fn) + && parmtype != error_mark_node + && (same_type_ignoring_top_level_qualifiers_p + (non_reference (parmtype), ctype))) { - /* Hack: Direct-initialize copy parm (i.e. suppress - LOOKUP_ONLYCONVERTING) to make explicit conversion ops - work. See also reference_binding. */ lflags |= LOOKUP_COPY_PARM; + /* We allow user-defined conversions within init-lists, but + not for the copy constructor. */ if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION) lflags |= LOOKUP_NO_CONVERSION; } @@ -1668,9 +1690,6 @@ add_function_candidate (struct z_candidate **candidates, if (t->bad_p) viable = -1; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); } out: @@ -6741,14 +6760,16 @@ compare_ics (conversion *ics1, conversion *ics2) if (rank1 == cr_bad) { - /* XXX Isn't this an extension? */ - /* Both ICS are bad. We try to make a decision based on what - would have happened if they'd been good. */ - if (ics1->user_conv_p > ics2->user_conv_p - || ics1->rank > ics2->rank) + /* Both ICS are bad. We try to make a decision based on what would + have happened if they'd been good. This is not an extension, + we'll still give an error when we build up the call; this just + helps us give a more helpful error message. */ + rank1 = BAD_CONVERSION_RANK (ics1); + rank2 = BAD_CONVERSION_RANK (ics2); + + if (rank1 > rank2) return -1; - else if (ics1->user_conv_p < ics2->user_conv_p - || ics1->rank < ics2->rank) + else if (rank1 < rank2) return 1; /* We couldn't make up our minds; try to figure it out below. */ diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 541e9adcdeb..fb687b81685 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -32,7 +32,6 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "cp-objcp-common.h" #include "hashtab.h" -#include "except.h" enum c_language_kind c_language = clk_cxx; static void cp_init_ts (void); diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 1a97ad2b119..f2d4aa1cceb 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -143,4 +143,7 @@ extern bool cp_function_decl_explicit_p (tree decl); #undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP true +#undef LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS +#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS cp_protect_cleanup_actions + #endif /* GCC_CP_OBJCP_COMMON */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f63ec2e795c..285dac73c81 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4855,6 +4855,7 @@ extern tree eh_type_info (tree); extern tree begin_eh_spec_block (void); extern void finish_eh_spec_block (tree, tree); extern tree build_eh_type_type (tree); +extern tree cp_protect_cleanup_actions (void); /* in expr.c */ extern tree cplus_expand_constant (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9541252125a..48d2b690752 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -40,7 +40,6 @@ along with GCC; see the file COPYING3. If not see #include "decl.h" #include "intl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "hashtab.h" #include "tm_p.h" diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 691c1dbc0f3..1e088e0464a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "decl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "timevar.h" #include "cpplib.h" diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 64f417154ce..79bab76cc5a 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -31,7 +31,6 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "flags.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "tree-inline.h" #include "tree-iterator.h" @@ -50,7 +49,6 @@ static tree wrap_cleanups_r (tree *, int *, void *); static int complete_ptr_ref_or_void_ptr_p (tree, tree); static bool is_admissible_throw_operand (tree); static int can_convert_eh (tree, tree); -static tree cp_protect_cleanup_actions (void); /* Sets up all the global eh stuff that needs to be initialized at the start of compilation. */ @@ -72,14 +70,12 @@ init_exception_processing (void) tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); call_unexpected_node = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); - - lang_protect_cleanup_actions = &cp_protect_cleanup_actions; } /* Returns an expression to be executed if an unhandled exception is propagated out of a cleanup region. */ -static tree +tree cp_protect_cleanup_actions (void) { /* [except.terminate] @@ -407,6 +403,30 @@ initialize_handler_parm (tree decl, tree exp) LOOKUP_ONLYCONVERTING|DIRECT_BIND); } + +/* Routine to see if exception handling is turned on. + DO_WARN is nonzero if we want to inform the user that exception + handling is turned off. + + This is used to ensure that -fexceptions has been specified if the + compiler tries to use any exception-specific functions. */ + +static inline int +doing_eh (void) +{ + if (! flag_exceptions) + { + static int warned = 0; + if (! warned) + { + error ("exception handling disabled, use -fexceptions to enable"); + warned = 1; + } + return 0; + } + return 1; +} + /* Call this to start a catch block. DECL is the catch parameter. */ tree @@ -415,7 +435,7 @@ expand_start_catch_block (tree decl) tree exp; tree type, init; - if (! doing_eh (1)) + if (! doing_eh ()) return NULL_TREE; /* Make sure this declaration is reasonable. */ @@ -494,7 +514,7 @@ expand_start_catch_block (tree decl) void expand_end_catch_block (void) { - if (! doing_eh (1)) + if (! doing_eh ()) return; /* The exception being handled is rethrown if control reaches the end of @@ -641,7 +661,7 @@ build_throw (tree exp) return error_mark_node; } - if (! doing_eh (1)) + if (! doing_eh ()) return error_mark_node; if (exp && decl_is_java_type (TREE_TYPE (exp), 1)) diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 0a0ba534063..681834d9a37 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -28,7 +28,6 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "cp-tree.h" #include "toplev.h" -#include "except.h" #include "tm_p.h" /* Expand C++-specific constants. Currently, this means PTRMEM_CST. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 84e486cea46..30808b233ce 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "flags.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "target.h" diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b97d3f5cc09..863218d68a9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -40,7 +40,6 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "decl.h" #include "output.h" -#include "except.h" #include "toplev.h" #include "timevar.h" #include "tree-iterator.h" diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4869cfc47e9..e750937dfe1 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -33,7 +33,6 @@ along with GCC; see the file COPYING3. If not see #include "c-family/c-common.h" #include "tree-inline.h" #include "tree-mudflap.h" -#include "except.h" #include "toplev.h" #include "flags.h" #include "output.h" diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def index 33afb0b0e84..0d73d942073 100644 --- a/gcc/dbgcnt.def +++ b/gcc/dbgcnt.def @@ -160,6 +160,7 @@ DEBUG_COUNTER (global_alloc_at_reg) DEBUG_COUNTER (hoist) DEBUG_COUNTER (ia64_sched2) DEBUG_COUNTER (if_conversion) +DEBUG_COUNTER (if_conversion_tree) DEBUG_COUNTER (if_after_combine) DEBUG_COUNTER (if_after_reload) DEBUG_COUNTER (local_alloc_for_sched) diff --git a/gcc/defaults.h b/gcc/defaults.h index c4809c97b20..eb74033657b 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -981,10 +981,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif /* old constraint mechanism in use */ -#ifndef REGISTER_MOVE_COST -#define REGISTER_MOVE_COST(m, x, y) 2 -#endif - /* Determine whether the entire c99 runtime is present in the runtime library. */ #ifndef TARGET_C99_FUNCTIONS diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 795b6bf7a34..b967e798b32 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2296,7 +2296,7 @@ attribute is present. @cindex @code{externally_visible} attribute. This attribute, attached to a global variable or function, nullifies the effect of the @option{-fwhole-program} command-line option, so the -object remains visible outside the current compilation unit. +object remains visible outside the current compilation unit. If @option{-fwhole-program} is used together with @option{-flto} and @command{gold} is used as the linker plugin, @code{externally_visible} attributes are automatically added to functions (not variable yet due to a current @command{gold} issue) that are accessed outside of LTO objects according to resolution file produced by @command{gold}. For other linkers that cannot generate resolution file, explicit @code{externally_visible} attributes are still necessary. @item far @cindex functions which handle memory bank switching @@ -12266,7 +12266,7 @@ subsequent functions. @subsection M32C Pragmas @table @code -@item memregs @var{number} +@item GCC memregs @var{number} @cindex pragma, memregs Overrides the command-line option @code{-memregs=} for the current file. Use with care! This pragma must be before any function in the @@ -12275,6 +12275,21 @@ make them incompatible. This pragma is useful when a performance-critical function uses a memreg for temporary values, as it may allow you to reduce the number of memregs used. +@item ADDRESS @var{name} @var{address} +@cindex pragma, address +For any declared symbols matching @var{name}, this does three things +to that symbol: it forces the symbol to be located at the given +address (a number), it forces the symbol to be volatile, and it +changes the symbol's scope to be static. This pragma exists for +compatibility with other compilers, but note that the common +@code{1234H} numeric syntax is not supported (use @code{0x1234} +instead). Example: + +@example +#pragma ADDRESS port3 0x103 +char port3; +@end example + @end table @node MeP Pragmas diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7aa4e518713..48716c5283e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -258,7 +258,7 @@ Objective-C and Objective-C++ Dialects}. -Wsign-compare -Wsign-conversion -Wstack-protector @gol -Wstrict-aliasing -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol --Wsuggest-attribute=@r{[}const@r{|}pure@r{]} @gol +-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{]} @gol -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized @gol -Wunknown-pragmas -Wno-pragmas @gol @@ -362,7 +362,7 @@ Objective-C and Objective-C++ Dialects}. -fno-sched-interblock -fno-sched-spec -fno-signed-zeros @gol -fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss @gol -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls @gol --fpeel-loops -fpredictive-commoning -fprefetch-loop-arrays @gol +-fpartial-inlining -fpeel-loops -fpredictive-commoning -fprefetch-loop-arrays @gol -fprofile-correction -fprofile-dir=@var{path} -fprofile-generate @gol -fprofile-generate=@var{path} @gol -fprofile-use -fprofile-use=@var{path} -fprofile-values @gol @@ -3669,7 +3669,7 @@ comparisons, so this warning level will give a very large number of false positives. @end table -@item -Wsuggest-attribute=@r{[}const@r{|}pure@r{|}noreturn@r{]} +@item -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{]} @opindex Wsuggest-attribute= @opindex Wno-suggest-attribute= Warn for cases where adding an attribute may be beneficial. The @@ -3678,6 +3678,7 @@ attributes currently supported are listed below. @table @gcctabopt @item -Wsuggest-attribute=pure @itemx -Wsuggest-attribute=const +@itemx -Wsuggest-attribute=noreturn @opindex Wsuggest-attribute=pure @opindex Wno-suggest-attribute=pure @opindex Wsuggest-attribute=const @@ -5870,6 +5871,7 @@ also turns on the following optimization flags: -findirect-inlining @gol -fipa-sra @gol -foptimize-sibling-calls @gol +-fpartial-inlining @gol -fpeephole2 @gol -fregmove @gol -freorder-blocks -freorder-functions @gol @@ -7027,6 +7029,14 @@ This optimization is enabled by default. With this option, the compiler will create multiple copies of some local variables when unrolling a loop which can result in superior code. +@item -fpartial-inlining +@opindex fpartial-inlining +Inline parts of functions. This option has any effect only +when inlining itself is turned on by the @option{-finline-functions} +or @option{-finline-small-functions} options. + +Enabled at level @option{-O2}. + @item -fpredictive-commoning @opindex fpredictive-commoning Perform predictive commoning optimization, i.e., reusing computations @@ -7300,7 +7310,7 @@ Enabled by default with @option{-funroll-loops}. Assume that the current compilation unit represents the whole program being compiled. All public functions and variables with the exception of @code{main} and those merged by attribute @code{externally_visible} become static functions -and in effect are optimized more aggressively by interprocedural optimizers. +and in effect are optimized more aggressively by interprocedural optimizers. If @command{gold} is used as the linker plugin, @code{externally_visible} attributes are automatically added to functions (not variable yet due to a current @command{gold} issue) that are accessed outside of LTO objects according to resolution file produced by @command{gold}. For other linkers that cannot generate resolution file, explicit @code{externally_visible} attributes are still necessary. While this option is equivalent to proper use of the @code{static} keyword for programs consisting of a single file, in combination with option @option{-combine}, @option{-flto} or @option{-fwhopr} this flag can be used to @@ -8115,7 +8125,7 @@ a lot of functions that would otherwise not be considered for inlining by the compiler will be investigated. To those functions, a different (more restrictive) limit compared to functions declared inline can be applied. -The default value is 50. +The default value is 40. @item large-function-insns The limit specifying really large functions. For functions larger than this @@ -14987,11 +14997,6 @@ scheduling parameters set by @option{-mtune}. Generate PowerPC64 code for the small model: The TOC is limited to 64k. -@item -mcmodel=medium -@opindex mcmodel=medium -Generate PowerPC64 code for the medium model: The TOC and other static -data may be up to a total of 4G in size. - @item -mcmodel=large @opindex mcmodel=large Generate PowerPC64 code for the large model: The TOC may be up to 4G diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 46bd4f61112..211fdcb8635 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -3763,7 +3763,8 @@ it is unsafe to call @code{gen_reg_rtx} to allocate a new pseudo. The constraints on a @samp{mov@var{m}} must permit moving any hard register to any other hard register provided that @code{HARD_REGNO_MODE_OK} permits mode @var{m} in both registers and -@code{REGISTER_MOVE_COST} applied to their classes returns a value of 2. +@code{TARGET_REGISTER_MOVE_COST} applied to their classes returns a value +of 2. It is obligatory to support floating point @samp{mov@var{m}} instructions into and out of any registers that can hold fixed point diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b118c657391..637dd50444d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -141,13 +141,6 @@ should call @code{DEFAULT_SWITCH_CURTAILS_COMPILATION} and then check for additional options. @end defmac -@defmac SWITCHES_NEED_SPACES -A string-valued C expression which enumerates the options for which -the linker needs a space between the option and its argument. - -If this macro is not defined, the default value is @code{""}. -@end defmac - @defmac TARGET_OPTION_TRANSLATE_TABLE If defined, a list of pairs of strings, the first of which is a potential command line target to the @file{gcc} driver program, and the @@ -523,31 +516,6 @@ Cross compilers do not search either @file{/usr/local/include} or its replacement. @end defmac -@defmac MODIFY_TARGET_NAME -Define this macro if you wish to define command-line switches that -modify the default target name. - -For each switch, you can include a string to be appended to the first -part of the configuration name or a string to be deleted from the -configuration name, if present. The definition should be an initializer -for an array of structures. Each array element should have three -elements: the switch name (a string constant, including the initial -dash), one of the enumeration codes @code{ADD} or @code{DELETE} to -indicate whether the string should be inserted or deleted, and the string -to be inserted or deleted (a string constant). - -For example, on a machine where @samp{64} at the end of the -configuration name denotes a 64-bit target and you want the @option{-32} -and @option{-64} switches to select between 32- and 64-bit targets, you would -code - -@smallexample -#define MODIFY_TARGET_NAME \ - @{ @{ "-32", DELETE, "64"@}, \ - @{"-64", ADD, "64"@}@} -@end smallexample -@end defmac - @defmac SYSTEM_INCLUDE_DIR Define this macro as a C string constant if you wish to specify a system-specific directory to search for header files before the standard @@ -6148,8 +6116,32 @@ classes returns a value of 2, reload does not check to ensure that the constraints of the insn are met. Setting a cost of other than 2 will allow reload to verify that the constraints are met. You should do this if the @samp{mov@var{m}} pattern's constraints do not allow such copying. + +These macros are obsolete, new ports should use the target hook +@code{TARGET_REGISTER_MOVE_COST} instead. @end defmac +@deftypefn {Target Hook} int TARGET_REGISTER_MOVE_COST (enum machine_mode @var{mode}, enum reg_class @var{from}, enum reg_class @var{to}) +This target hook should return the cost of moving data of mode @var{mode} +from a register in class @var{from} to one in class @var{to}. The classes +are expressed using the enumeration values such as @code{GENERAL_REGS}. +A value of 2 is the default; other values are interpreted relative to +that. + +It is not required that the cost always equal 2 when @var{from} is the +same as @var{to}; on some machines it is expensive to move between +registers if they are not general registers. + +If reload sees an insn consisting of a single @code{set} between two +hard registers, and if @code{TARGET_REGISTER_MOVE_COST} applied to their +classes returns a value of 2, reload does not check to ensure that the +constraints of the insn are met. Setting a cost of other than 2 will +allow reload to verify that the constraints are met. You should do this +if the @samp{mov@var{m}} pattern's constraints do not allow such copying. + +The default version of this function returns 2. +@end deftypefn + @defmac MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in}) A C expression for the cost of moving data of mode @var{mode} between a register of class @var{class} and memory; @var{in} is zero if the value @@ -6181,9 +6173,9 @@ These macros are obsolete, new ports should use the target hook This target hook should return the cost of moving data of mode @var{mode} between a register of class @var{class} and memory; @var{in} is @code{false} if the value is to be written to memory, @code{true} if it is to be read in. -This cost is relative to those in @code{REGISTER_MOVE_COST}. If moving -between registers and memory is more expensive than between two registers, -you should add this target hook to express the relative cost. +This cost is relative to those in @code{TARGET_REGISTER_MOVE_COST}. +If moving between registers and memory is more expensive than between two +registers, you should add this target hook to express the relative cost. If you do not add this target hook, GCC uses a default cost of 4 plus the cost of copying via a secondary reload register, if one is diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e1ff0d30f09..7e168e27061 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -17419,6 +17419,39 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) #endif } +#ifdef VMS_DEBUGGING_INFO + +/* Output the debug main pointer die for VMS */ + +void +dwarf2out_vms_debug_main_pointer (void) +{ + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + dw_die_ref die; + + /* Allocate the VMS debug main subprogram die. */ + die = ggc_alloc_cleared_die_node (); + die->die_tag = DW_TAG_subprogram; + add_name_attribute (die, VMS_DEBUG_MAIN_POINTER); + ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL, + current_function_funcdef_no); + add_AT_lbl_id (die, DW_AT_entry_pc, label); + + /* Make it the first child of comp_unit_die. */ + die->die_parent = comp_unit_die; + if (comp_unit_die->die_child) + { + die->die_sib = comp_unit_die->die_child->die_sib; + comp_unit_die->die_child->die_sib = die; + } + else + { + die->die_sib = die; + comp_unit_die->die_child = die; + } +} +#endif + /* Push a new declaration scope. */ static void diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index 21d87cbfb6e..d70b26f6ffd 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -27,6 +27,9 @@ extern void debug_dwarf (void); struct die_struct; extern void debug_dwarf_die (struct die_struct *); extern void dwarf2out_set_demangle_name_func (const char *(*) (const char *)); +#ifdef VMS_DEBUGGING_INFO +extern void dwarf2out_vms_debug_main_pointer (void); +#endif struct array_descr_info { diff --git a/gcc/except.c b/gcc/except.c index 16a02473a12..285d4a657e8 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see During pass_lower_eh (tree-eh.c) we record the nested structure of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE. - We expand the lang_protect_cleanup_actions hook into MUST_NOT_THROW + We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW regions at this time. We can then flatten the statements within the TRY nodes to straight-line code. Statements that had been within TRY nodes that can throw are recorded within CFUN->EH->THROW_STMT_TABLE, @@ -150,10 +150,6 @@ along with GCC; see the file COPYING3. If not see #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM #endif -/* Protect cleanup actions with must-not-throw regions, with a call - to the given failure handler. */ -tree (*lang_protect_cleanup_actions) (void); - static GTY(()) int call_site_base; static GTY ((param_is (union tree_node))) htab_t type_to_runtime_map; @@ -203,30 +199,6 @@ static void dw2_output_call_site_table (int, int); static void sjlj_output_call_site_table (void); -/* Routine to see if exception handling is turned on. - DO_WARN is nonzero if we want to inform the user that exception - handling is turned off. - - This is used to ensure that -fexceptions has been specified if the - compiler tries to use any exception-specific functions. */ - -int -doing_eh (int do_warn) -{ - if (! flag_exceptions) - { - static int warned = 0; - if (! warned && do_warn) - { - error ("exception handling disabled, use -fexceptions to enable"); - warned = 1; - } - return 0; - } - return 1; -} - - void init_eh (void) { @@ -345,10 +317,6 @@ gen_eh_region (enum eh_region_type type, eh_region outer) { eh_region new_eh; -#ifdef ENABLE_CHECKING - gcc_assert (doing_eh (0)); -#endif - /* Insert a new blank region as a leaf in the tree. */ new_eh = ggc_alloc_cleared_eh_region_d (); new_eh->type = type; diff --git a/gcc/except.h b/gcc/except.h index 068a444c9b1..72fd76ef646 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -19,6 +19,13 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +/* No include guards here, but define an include file marker anyway, so + that the compiler can keep track of where this file is included. This + is e.g. used to avoid including this file in front-end specific files. */ +#ifndef GCC_EXCEPT_H +# define GCC_EXCEPT_H +#endif + #include "hashtab.h" #include "vecprim.h" #include "vecir.h" @@ -222,14 +229,10 @@ struct GTY(()) eh_status }; -/* Test: is exception handling turned on? */ -extern int doing_eh (int); - /* Invokes CALLBACK for every exception handler label. Only used by old loop hackery; should not be used by new code. */ extern void for_each_eh_label (void (*) (rtx)); -extern void init_eh (void); extern void init_eh_for_function (void); extern void remove_eh_landing_pad (eh_landing_pad); @@ -287,14 +290,6 @@ extern void assign_filter_values (void); extern eh_region get_eh_region_from_rtx (const_rtx); extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx); -/* If non-NULL, this is a function that returns a function decl to be - executed if an unhandled exception is propagated out of a cleanup - region. For example, in C++, an exception thrown by a destructor - during stack unwinding is required to result in a call to - `std::terminate', so the C++ version of this function returns a - FUNCTION_DECL for `std::terminate'. */ -extern tree (*lang_protect_cleanup_actions) (void); - struct GTY(()) throw_stmt_node { gimple stmt; int lp_nr; diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e887e6f7491..fc8445c784d 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,70 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * Make-lang.in: Update dependencies. + +2010-06-27 Nathan Froyd <froydnj@codesourcery.com> + + * gfortran.h (gfc_code): Split backend_decl field into cycle_label + and exit_label fields. + * trans-openmp.c (gfc_trans_omp_do): Assign to new fields + individually. + * trans-stmt.c (gfc_trans_simple_do): Likewise. + (gfc_trans_do): Likewise. + (gfc_trans_do_while): Likewise. + (gfc_trans_cycle): Use cycle_label directly. + (gfc_trans_exit): Use exit_label directly. + +2010-06-27 Daniel Kraft <d@domob.eu> + + * dump-parse-tree.c (show_symbol): Dump target-expression for + associate names. + (show_code_node): Make distinction between BLOCK and ASSOCIATE. + (show_namespace): Use show_level for correct indentation of + "inner namespaces" (contained procedures or BLOCK). + +2010-06-27 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/44678 + * dump-parse-tree.c (show_code_node): Show namespace for + EXEC_BLOCK. + +2010-06-26 Tobias Burnus <burnus@net-b.de> + + * decl.c (gfc_match_decl_type_spec): Support + TYPE(intrinsic-type-spec). + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * intrinsic.h (gfc_check_selected_real_kind, + gfc_simplify_selected_real_kind): Update prototypes. + * intrinsic.c (add_functions): Add radix support to + selected_real_kind. + * check.c (gfc_check_selected_real_kind): Ditto. + * simplify.c (gfc_simplify_selected_real_kind): Ditto. + * trans-decl.c (gfc_build_intrinsic_function_decls): + Change call from selected_real_kind to selected_real_kind2008. + * intrinsic.texi (SELECTED_REAL_KIND): Update for radix. + (PRECISION, RANGE, RADIX): Add cross @refs. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * decl.c (gfc_match_entry): Mark ENTRY as GFC_STD_F2008_OBS. + * gfortran.texi (_gfortran_set_options): Update for + GFC_STD_F2008_OBS addition. + * libgfortran.h: Add GFC_STD_F2008_OBS. + * options.c (set_default_std_flags, gfc_handle_option): Handle + GFC_STD_F2008_OBS. + io.c (check_format): Fix allow_std check. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * decl.c (gfc_match_entry): Allow END besides + END SUBROUTINE/END FUNCTION for contained procedures. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * parse.c (next_free, next_fixed): Allow ";" as first character. + 2010-06-24 Tobias Burnus <burnus@net-b.de> PR fortran/44614 diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index b74f9e99d0b..2a8c791c445 100644 --- a/gcc/fortran/Make-lang.in +++ b/gcc/fortran/Make-lang.in @@ -336,7 +336,7 @@ GFORTRAN_TRANS_DEPS = fortran/gfortran.h fortran/libgfortran.h \ fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \ gt-fortran-f95-lang.h gtype-fortran.h $(CGRAPH_H) $(TARGET_H) fortran/cpp.h \ $(BUILTINS_DEF) fortran/types.def \ - libfuncs.h expr.h except.h + libfuncs.h expr.h fortran/scanner.o: toplev.h fortran/cpp.h fortran/convert.o: $(GFORTRAN_TRANS_DEPS) fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 81f3e24847b..34527172431 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -2920,15 +2920,13 @@ gfc_check_selected_int_kind (gfc_expr *r) gfc_try -gfc_check_selected_real_kind (gfc_expr *p, gfc_expr *r) +gfc_check_selected_real_kind (gfc_expr *p, gfc_expr *r, gfc_expr *radix) { - if (p == NULL && r == NULL) - { - gfc_error ("Missing arguments to %s intrinsic at %L", - gfc_current_intrinsic, gfc_current_intrinsic_where); - - return FAILURE; - } + if (p == NULL && r == NULL + && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: SELECTED_REAL_KIND with" + " neither 'P' nor 'R' argument at %L", + gfc_current_intrinsic_where) == FAILURE) + return FAILURE; if (p) { @@ -2948,6 +2946,20 @@ gfc_check_selected_real_kind (gfc_expr *p, gfc_expr *r) return FAILURE; } + if (radix) + { + if (type_check (radix, 1, BT_INTEGER) == FAILURE) + return FAILURE; + + if (scalar_check (radix, 1) == FAILURE) + return FAILURE; + + if (gfc_notify_std (GFC_STD_F2008, "Fortran 2008: '%s' intrinsic with " + "RADIX argument at %L", gfc_current_intrinsic, + &radix->where) == FAILURE) + return FAILURE; + } + return SUCCESS; } diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index aa7a2668fce..07c3acb9467 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -2342,7 +2342,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) gfc_symbol *sym; match m; char c; - bool seen_deferred_kind; + bool seen_deferred_kind, matched_type; /* A belt and braces check that the typespec is correctly being treated as a deferred characteristic association. */ @@ -2374,47 +2374,88 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_YES; } - if (gfc_match (" integer") == MATCH_YES) + + m = gfc_match (" type ( %n", name); + matched_type = (m == MATCH_YES); + + if ((matched_type && strcmp ("integer", name) == 0) + || (!matched_type && gfc_match (" integer") == MATCH_YES)) { ts->type = BT_INTEGER; ts->kind = gfc_default_integer_kind; goto get_kind; } - if (gfc_match (" character") == MATCH_YES) + if ((matched_type && strcmp ("character", name) == 0) + || (!matched_type && gfc_match (" character") == MATCH_YES)) { + if (matched_type + && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: TYPE with " + "intrinsic-type-spec at %C") == FAILURE) + return MATCH_ERROR; + ts->type = BT_CHARACTER; if (implicit_flag == 0) - return gfc_match_char_spec (ts); + m = gfc_match_char_spec (ts); else - return MATCH_YES; + m = MATCH_YES; + + if (matched_type && m == MATCH_YES && gfc_match_char (')') != MATCH_YES) + m = MATCH_ERROR; + + return m; } - if (gfc_match (" real") == MATCH_YES) + if ((matched_type && strcmp ("real", name) == 0) + || (!matched_type && gfc_match (" real") == MATCH_YES)) { ts->type = BT_REAL; ts->kind = gfc_default_real_kind; goto get_kind; } - if (gfc_match (" double precision") == MATCH_YES) + if ((matched_type + && (strcmp ("doubleprecision", name) == 0 + || (strcmp ("double", name) == 0 + && gfc_match (" precision") == MATCH_YES))) + || (!matched_type && gfc_match (" double precision") == MATCH_YES)) { + if (matched_type + && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: TYPE with " + "intrinsic-type-spec at %C") == FAILURE) + return MATCH_ERROR; + if (matched_type && gfc_match_char (')') != MATCH_YES) + return MATCH_ERROR; + ts->type = BT_REAL; ts->kind = gfc_default_double_kind; return MATCH_YES; } - if (gfc_match (" complex") == MATCH_YES) + if ((matched_type && strcmp ("complex", name) == 0) + || (!matched_type && gfc_match (" complex") == MATCH_YES)) { ts->type = BT_COMPLEX; ts->kind = gfc_default_complex_kind; goto get_kind; } - if (gfc_match (" double complex") == MATCH_YES) + if ((matched_type + && (strcmp ("doublecomplex", name) == 0 + || (strcmp ("double", name) == 0 + && gfc_match (" complex") == MATCH_YES))) + || (!matched_type && gfc_match (" double complex") == MATCH_YES)) { - if (gfc_notify_std (GFC_STD_GNU, "DOUBLE COMPLEX at %C does not " - "conform to the Fortran 95 standard") == FAILURE) + if (gfc_notify_std (GFC_STD_GNU, "Extension: DOUBLE COMPLEX at %C") + == FAILURE) + return MATCH_ERROR; + + if (matched_type + && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: TYPE with " + "intrinsic-type-spec at %C") == FAILURE) + return MATCH_ERROR; + + if (matched_type && gfc_match_char (')') != MATCH_YES) return MATCH_ERROR; ts->type = BT_COMPLEX; @@ -2422,14 +2463,17 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_YES; } - if (gfc_match (" logical") == MATCH_YES) + if ((matched_type && strcmp ("logical", name) == 0) + || (!matched_type && gfc_match (" logical") == MATCH_YES)) { ts->type = BT_LOGICAL; ts->kind = gfc_default_logical_kind; goto get_kind; } - m = gfc_match (" type ( %n )", name); + if (matched_type) + m = gfc_match_char (')'); + if (m == MATCH_YES) ts->type = BT_DERIVED; else @@ -2490,23 +2534,43 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag) return MATCH_YES; get_kind: + if (matched_type + && gfc_notify_std (GFC_STD_F2008, "Fortran 2008: TYPE with " + "intrinsic-type-spec at %C") == FAILURE) + return MATCH_ERROR; + /* For all types except double, derived and character, look for an optional kind specifier. MATCH_NO is actually OK at this point. */ if (implicit_flag == 1) - return MATCH_YES; + { + if (matched_type && gfc_match_char (')') != MATCH_YES) + return MATCH_ERROR; + + return MATCH_YES; + } if (gfc_current_form == FORM_FREE) { c = gfc_peek_ascii_char (); if (!gfc_is_whitespace (c) && c != '*' && c != '(' && c != ':' && c != ',') - return MATCH_NO; + { + if (matched_type && c == ')') + { + gfc_next_ascii_char (); + return MATCH_YES; + } + return MATCH_NO; + } } m = gfc_match_kind_spec (ts, false); if (m == MATCH_NO && ts->type != BT_CHARACTER) m = gfc_match_old_kind_spec (ts); + if (matched_type && gfc_match_char (')') != MATCH_YES) + return MATCH_ERROR; + /* Defer association of the KIND expression of function results until after USE and IMPORT statements. */ if ((gfc_current_state () == COMP_NONE && gfc_error_flag_test ()) @@ -4963,6 +5027,10 @@ gfc_match_entry (void) if (m != MATCH_YES) return m; + if (gfc_notify_std (GFC_STD_F2008_OBS, "Fortran 2008 obsolescent feature: " + "ENTRY statement at %C") == FAILURE) + return MATCH_ERROR; + state = gfc_current_state (); if (state != COMP_SUBROUTINE && state != COMP_FUNCTION) { @@ -5642,7 +5710,14 @@ gfc_match_end (gfc_statement *st) if (gfc_match_eos () == MATCH_YES) { - if (!eos_ok) + if (!eos_ok && (*st == ST_END_SUBROUTINE || *st == ST_END_FUNCTION)) + { + if (gfc_notify_std (GFC_STD_F2008, "Fortran 2008: END statement " + "instead of %s statement at %L", + gfc_ascii_statement (*st), &old_loc) == FAILURE) + goto cleanup; + } + else if (!eos_ok) { /* We would have required END [something]. */ gfc_error ("%s statement expected at %L", diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 940455dd054..1a649106f15 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -796,6 +796,15 @@ show_symbol (gfc_symbol *sym) fprintf (dumpfile, "symbol %s ", sym->name); show_typespec (&sym->ts); + + /* If this symbol is an associate-name, show its target expression. */ + if (sym->assoc) + { + fputs (" => ", dumpfile); + show_expr (sym->assoc->target); + fputs (" ", dumpfile); + } + show_attr (&sym->attr); if (sym->value) @@ -1177,6 +1186,7 @@ show_code_node (int level, gfc_code *c) gfc_filepos *fp; gfc_inquire *i; gfc_dt *dt; + gfc_namespace *ns; code_indent (level, c->here); @@ -1376,6 +1386,22 @@ show_code_node (int level, gfc_code *c) fputs ("ENDIF", dumpfile); break; + case EXEC_BLOCK: + { + const char* blocktype; + if (c->ext.block.assoc) + blocktype = "ASSOCIATE"; + else + blocktype = "BLOCK"; + show_indent (); + fprintf (dumpfile, "%s ", blocktype); + ns = c->ext.block.ns; + show_namespace (ns); + show_indent (); + fprintf (dumpfile, "END %s ", blocktype); + break; + } + case EXEC_SELECT: d = c->block; fputs ("SELECT CASE ", dumpfile); @@ -2146,7 +2172,7 @@ show_namespace (gfc_namespace *ns) fputc ('\n', dumpfile); fputc ('\n', dumpfile); - show_code (0, ns->code); + show_code (show_level, ns->code); for (ns = ns->contained; ns; ns = ns->sibling) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 4a9b5f0226b..0c96bf40e6e 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2077,9 +2077,9 @@ typedef struct gfc_code } ext; /* Points to additional structures required by statement */ - /* Backend_decl is used for cycle and break labels in do loops, and - probably for other constructs as well, once we translate them. */ - tree backend_decl; + /* Cycle and break labels in do loops. */ + tree cycle_label; + tree exit_label; } gfc_code; diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 939ae616e8a..8d43c8bf8a4 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -2335,9 +2335,10 @@ if e.g. an input-output edit descriptor is invalid in a given standard. Possible values are (bitwise or-ed) @code{GFC_STD_F77} (1), @code{GFC_STD_F95_OBS} (2), @code{GFC_STD_F95_DEL} (4), @code{GFC_STD_F95} (8), @code{GFC_STD_F2003} (16), @code{GFC_STD_GNU} (32), -@code{GFC_STD_LEGACY} (64), and @code{GFC_STD_F2008} (128). -Default: @code{GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F2003 -| GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 | GFC_STD_GNU | GFC_STD_LEGACY}. +@code{GFC_STD_LEGACY} (64), @code{GFC_STD_F2008} (128), and +@code{GFC_STD_F2008_OBS} (256). Default: @code{GFC_STD_F95_OBS +| GFC_STD_F95_DEL | GFC_STD_F95 | GFC_STD_F2003 | GFC_STD_F2008 +| GFC_STD_F2008_OBS | GFC_STD_F77 | GFC_STD_GNU | GFC_STD_LEGACY}. @item @var{option}[1] @tab Standard-warning flag; prints a warning to standard error. Default: @code{GFC_STD_F95_DEL | GFC_STD_LEGACY}. @item @var{option}[2] @tab If non zero, enable pedantic checking. diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index e5463a1a74f..833fd30beb1 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -2375,10 +2375,11 @@ add_functions (void) make_generic ("selected_int_kind", GFC_ISYM_SI_KIND, GFC_STD_F95); - add_sym_2 ("selected_real_kind", GFC_ISYM_SR_KIND, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, + add_sym_3 ("selected_real_kind", GFC_ISYM_SR_KIND, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, gfc_check_selected_real_kind, gfc_simplify_selected_real_kind, NULL, - p, BT_INTEGER, di, OPTIONAL, r, BT_INTEGER, di, OPTIONAL); + p, BT_INTEGER, di, OPTIONAL, r, BT_INTEGER, di, OPTIONAL, + "radix", BT_INTEGER, di, OPTIONAL); make_generic ("selected_real_kind", GFC_ISYM_SR_KIND, GFC_STD_F95); diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index a2cd55a87a9..919f09e90b4 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -126,7 +126,7 @@ gfc_try gfc_check_second_sub (gfc_expr *); gfc_try gfc_check_secnds (gfc_expr *); gfc_try gfc_check_selected_char_kind (gfc_expr *); gfc_try gfc_check_selected_int_kind (gfc_expr *); -gfc_try gfc_check_selected_real_kind (gfc_expr *, gfc_expr *); +gfc_try gfc_check_selected_real_kind (gfc_expr *, gfc_expr *, gfc_expr *); gfc_try gfc_check_set_exponent (gfc_expr *, gfc_expr *); gfc_try gfc_check_shape (gfc_expr *); gfc_try gfc_check_size (gfc_expr *, gfc_expr *, gfc_expr *); @@ -322,7 +322,7 @@ gfc_expr *gfc_simplify_scale (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_scan (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_selected_char_kind (gfc_expr *); gfc_expr *gfc_simplify_selected_int_kind (gfc_expr *); -gfc_expr *gfc_simplify_selected_real_kind (gfc_expr *, gfc_expr *); +gfc_expr *gfc_simplify_selected_real_kind (gfc_expr *, gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_set_exponent (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_sign (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_shape (gfc_expr *); diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index a24ad91cc2d..06c6793b2c4 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -8716,6 +8716,9 @@ Inquiry function The return value is of type @code{INTEGER} and of the default integer kind. +@item @emph{See also}: +@ref{SELECTED_REAL_KIND}, @ref{RANGE} + @item @emph{Example}: @smallexample program prec_and_range @@ -8861,6 +8864,9 @@ Inquiry function The return value is a scalar of type @code{INTEGER} and of the default integer kind. +@item @emph{See also}: +@ref{SELECTED_REAL_KIND} + @item @emph{Example}: @smallexample program test_radix @@ -9098,6 +9104,9 @@ or @code{COMPLEX}. The return value is of type @code{INTEGER} and of the default integer kind. +@item @emph{See also}: +@ref{SELECTED_REAL_KIND}, @ref{PRECISION} + @item @emph{Example}: See @code{PRECISION} for an example. @end table @@ -9676,45 +9685,58 @@ end program large_integers @fnindex SELECTED_REAL_KIND @cindex real kind @cindex kind, real +@cindex radix, real @table @asis @item @emph{Description}: @code{SELECTED_REAL_KIND(P,R)} returns the kind value of a real data type -with decimal precision of at least @code{P} digits and exponent -range greater at least @code{R}. +with decimal precision of at least @code{P} digits, exponent range of +at least @code{R}, and with a radix of @code{RADIX}. @item @emph{Standard}: -Fortran 95 and later +Fortran 95 and later, with @code{RADIX} Fortran 2008 or later @item @emph{Class}: Transformational function @item @emph{Syntax}: -@code{RESULT = SELECTED_REAL_KIND([P, R])} +@code{RESULT = SELECTED_REAL_KIND([P, R, RADIX])} @item @emph{Arguments}: @multitable @columnfractions .15 .70 @item @var{P} @tab (Optional) shall be a scalar and of type @code{INTEGER}. @item @var{R} @tab (Optional) shall be a scalar and of type @code{INTEGER}. +@item @var{RADIX} @tab (Optional) shall be a scalar and of type @code{INTEGER}. @end multitable -At least one argument shall be present. +Before Fortran 2008, at least one of the arguments @var{R} or @var{P} shall +be present; since Fortran 2008, they are assumed to be zero if absent. @item @emph{Return value}: @code{SELECTED_REAL_KIND} returns the value of the kind type parameter of -a real data type with decimal precision of at least @code{P} digits and a -decimal exponent range of at least @code{R}. If more than one real data -type meet the criteria, the kind of the data type with the smallest -decimal precision is returned. If no real data type matches the criteria, -the result is +a real data type with decimal precision of at least @code{P} digits, a +decimal exponent range of at least @code{R}, and with the requested +@code{RADIX}. If the @code{RADIX} parameter is absent, real kinds with +any radix can be returned. If more than one real data type meet the +criteria, the kind of the data type with the smallest decimal precision +is returned. If no real data type matches the criteria, the result is @table @asis @item -1 if the processor does not support a real data type with a -precision greater than or equal to @code{P} +precision greater than or equal to @code{P}, but the @code{R} and +@code{RADIX} requirements can be fulfilled @item -2 if the processor does not support a real type with an exponent -range greater than or equal to @code{R} -@item -3 if neither is supported. +range greater than or equal to @code{R}, but @code{P} and @code{RADIX} +are fulfillable +@item -3 if @code{RADIX} but not @code{P} and @code{R} requirements +are fulfillable +@item -4 if @code{RADIX} and either @code{P} or @code{R} requirements +are fulfillable +@item -5 if there is no real type with the given @code{RADIX} @end table +@item @emph{See also}: +@ref{PRECISION}, @ref{RANGE}, @ref{RADIX} + @item @emph{Example}: @smallexample program real_kinds diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index dc20bc2ffb6..f9a6d7b1240 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -730,7 +730,7 @@ data_desc: t = format_lex (); if (t == FMT_ERROR) goto fail; - if (gfc_option.allow_std < GFC_STD_F2003 && t != FMT_COMMA + if (!(gfc_option.allow_std & GFC_STD_F2003) && t != FMT_COMMA && t != FMT_F && t != FMT_E && t != FMT_EN && t != FMT_ES && t != FMT_D && t != FMT_G && t != FMT_RPAREN && t != FMT_SLASH) { diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h index 85bd43df98c..d9216d30149 100644 --- a/gcc/fortran/libgfortran.h +++ b/gcc/fortran/libgfortran.h @@ -23,15 +23,16 @@ along with GCC; see the file COPYING3. If not see Note that no features were obsoleted nor deleted in F2003. Please remember to keep those definitions in sync with gfortran.texi. */ -#define GFC_STD_F2008 (1<<7) /* New in F2008. */ -#define GFC_STD_LEGACY (1<<6) /* Backward compatibility. */ -#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */ -#define GFC_STD_F2003 (1<<4) /* New in F2003. */ -#define GFC_STD_F95 (1<<3) /* New in F95. */ -#define GFC_STD_F95_DEL (1<<2) /* Deleted in F95. */ -#define GFC_STD_F95_OBS (1<<1) /* Obsolescent in F95. */ -#define GFC_STD_F77 (1<<0) /* Included in F77, but not deleted or - obsolescent in later standards. */ +#define GFC_STD_F2008_OBS (1<<8) /* Obsolescent in F2008. */ +#define GFC_STD_F2008 (1<<7) /* New in F2008. */ +#define GFC_STD_LEGACY (1<<6) /* Backward compatibility. */ +#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */ +#define GFC_STD_F2003 (1<<4) /* New in F2003. */ +#define GFC_STD_F95 (1<<3) /* New in F95. */ +#define GFC_STD_F95_DEL (1<<2) /* Deleted in F95. */ +#define GFC_STD_F95_OBS (1<<1) /* Obsolescent in F95. */ +#define GFC_STD_F77 (1<<0) /* Included in F77, but not deleted or + obsolescent in later standards. */ /* Bitmasks for the various FPE that can be enabled. */ diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 3b8b8dc1667..af537a1e70e 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -48,7 +48,7 @@ set_default_std_flags (void) { gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 - | GFC_STD_GNU | GFC_STD_LEGACY; + | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY; gfc_option.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY; } @@ -857,7 +857,8 @@ gfc_handle_option (size_t scode, const char *arg, int value, break; case OPT_std_f95: - gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77; + gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77 + | GFC_STD_F2008_OBS; gfc_option.warn_std = GFC_STD_F95_OBS; gfc_option.max_continue_fixed = 19; gfc_option.max_continue_free = 39; @@ -868,7 +869,7 @@ gfc_handle_option (size_t scode, const char *arg, int value, case OPT_std_f2003: gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 - | GFC_STD_F2003 | GFC_STD_F95; + | GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008_OBS; gfc_option.warn_std = GFC_STD_F95_OBS; gfc_option.max_identifier_length = 63; gfc_option.warn_ampersand = 1; @@ -877,8 +878,8 @@ gfc_handle_option (size_t scode, const char *arg, int value, case OPT_std_f2008: gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 - | GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008; - gfc_option.warn_std = GFC_STD_F95_OBS; + | GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS; + gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS; gfc_option.max_identifier_length = 63; gfc_option.warn_ampersand = 1; gfc_option.warn_tabs = 0; diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 26ea73a627c..50f795723eb 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -717,7 +717,9 @@ next_free (void) if (at_bol && c == ';') { - gfc_error_now ("Semicolon at %C needs to be preceded by statement"); + if (!(gfc_option.allow_std & GFC_STD_F2008)) + gfc_error_now ("Fortran 2008: Semicolon at %C without preceding " + "statement"); gfc_next_ascii_char (); /* Eat up the semicolon. */ return ST_NONE; } @@ -853,7 +855,11 @@ next_fixed (void) if (c == ';') { - gfc_error_now ("Semicolon at %C needs to be preceded by statement"); + if (digit_flag) + gfc_error_now ("Semicolon at %C needs to be preceded by statement"); + else if (!(gfc_option.allow_std & GFC_STD_F2008)) + gfc_error_now ("Fortran 2008: Semicolon at %C without preceding " + "statement"); return ST_NONE; } diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 743c4632986..7356625cf41 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4589,9 +4589,11 @@ gfc_simplify_selected_int_kind (gfc_expr *e) gfc_expr * -gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q) +gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx) { - int range, precision, i, kind, found_precision, found_range; + int range, precision, radix, i, kind, found_precision, found_range, + found_radix; + locus *loc = &gfc_current_locus; if (p == NULL) precision = 0; @@ -4600,6 +4602,7 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q) if (p->expr_type != EXPR_CONSTANT || gfc_extract_int (p, &precision) != NULL) return NULL; + loc = &p->where; } if (q == NULL) @@ -4609,11 +4612,27 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q) if (q->expr_type != EXPR_CONSTANT || gfc_extract_int (q, &range) != NULL) return NULL; + + if (!loc) + loc = &q->where; + } + + if (rdx == NULL) + radix = 0; + else + { + if (rdx->expr_type != EXPR_CONSTANT + || gfc_extract_int (rdx, &radix) != NULL) + return NULL; + + if (!loc) + loc = &rdx->where; } kind = INT_MAX; found_precision = 0; found_range = 0; + found_radix = 0; for (i = 0; gfc_real_kinds[i].kind != 0; i++) { @@ -4623,23 +4642,30 @@ gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q) if (gfc_real_kinds[i].range >= range) found_range = 1; + if (gfc_real_kinds[i].radix >= radix) + found_radix = 1; + if (gfc_real_kinds[i].precision >= precision - && gfc_real_kinds[i].range >= range && gfc_real_kinds[i].kind < kind) + && gfc_real_kinds[i].range >= range + && gfc_real_kinds[i].radix >= radix && gfc_real_kinds[i].kind < kind) kind = gfc_real_kinds[i].kind; } if (kind == INT_MAX) { - kind = 0; - - if (!found_precision) + if (found_radix && found_range && !found_precision) kind = -1; - if (!found_range) - kind -= 2; + else if (found_radix && found_precision && !found_range) + kind = -2; + else if (found_radix && !found_precision && !found_range) + kind = -3; + else if (found_radix) + kind = -4; + else + kind = -5; } - return gfc_get_int_expr (gfc_default_integer_kind, - p ? &p->where : &q->where, kind); + return gfc_get_int_expr (gfc_default_integer_kind, loc, kind); } diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index d75a195924c..1c7226c41e6 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -2612,9 +2612,10 @@ gfc_build_intrinsic_function_decls (void) gfor_fndecl_sr_kind = gfc_build_library_function_decl (get_identifier - (PREFIX("selected_real_kind")), - gfc_int4_type_node, 2, - pvoid_type_node, pvoid_type_node); + (PREFIX("selected_real_kind2008")), + gfc_int4_type_node, 3, + pvoid_type_node, pvoid_type_node, + pvoid_type_node); /* Power functions. */ { diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 1be4b81c8e8..a5d5ba133e7 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -1357,12 +1357,10 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock, present for this loop. */ cycle_label = gfc_build_label_decl (NULL_TREE); - /* Put these labels where they can be found later. We put the - labels in a TREE_LIST node (because TREE_CHAIN is already - used). cycle_label goes in TREE_PURPOSE (backend_decl), exit - label in TREE_VALUE (backend_decl). */ + /* Put these labels where they can be found later. */ - code->block->backend_decl = tree_cons (cycle_label, NULL, NULL); + code->block->cycle_label = cycle_label; + code->block->exit_label = NULL_TREE; /* Main loop body. */ tmp = gfc_trans_omp_code (code->block->next, true); diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index ad054261dad..6fa84b91694 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -928,7 +928,8 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar, exit_label = gfc_build_label_decl (NULL_TREE); /* Put the labels where they can be found later. See gfc_trans_do(). */ - code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL); + code->block->cycle_label = cycle_label; + code->block->exit_label = exit_label; /* Loop body. */ gfc_start_block (&body); @@ -1196,12 +1197,10 @@ gfc_trans_do (gfc_code * code, tree exit_cond) /* Loop body. */ gfc_start_block (&body); - /* Put these labels where they can be found later. We put the - labels in a TREE_LIST node (because TREE_CHAIN is already - used). cycle_label goes in TREE_PURPOSE (backend_decl), exit - label in TREE_VALUE (backend_decl). */ + /* Put these labels where they can be found later. */ - code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL); + code->block->cycle_label = cycle_label; + code->block->exit_label = exit_label; /* Main loop body. */ tmp = gfc_trans_code_cond (code->block->next, exit_cond); @@ -1305,7 +1304,8 @@ gfc_trans_do_while (gfc_code * code) exit_label = gfc_build_label_decl (NULL_TREE); /* Put the labels where they can be found later. See gfc_trans_do(). */ - code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL); + code->block->cycle_label = cycle_label; + code->block->exit_label = exit_label; /* Create a GIMPLE version of the exit condition. */ gfc_init_se (&cond, NULL); @@ -4080,7 +4080,7 @@ gfc_trans_cycle (gfc_code * code) { tree cycle_label; - cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl); + cycle_label = code->ext.whichloop->cycle_label; TREE_USED (cycle_label) = 1; return build1_v (GOTO_EXPR, cycle_label); } @@ -4095,7 +4095,7 @@ gfc_trans_exit (gfc_code * code) { tree exit_label; - exit_label = TREE_VALUE (code->ext.whichloop->backend_decl); + exit_label = code->ext.whichloop->exit_label; TREE_USED (exit_label) = 1; return build1_v (GOTO_EXPR, exit_label); } diff --git a/gcc/gcc.c b/gcc/gcc.c index 6f846d7f896..6a0dae5c5a0 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -280,23 +280,6 @@ static const char *cross_compile = "1"; static const char *cross_compile = "0"; #endif -#ifdef MODIFY_TARGET_NAME - -/* Information on how to alter the target name based on a command-line - switch. The only case we support now is simply appending or deleting a - string to or from the end of the first part of the configuration name. */ - -enum add_del {ADD, DELETE}; - -static const struct modify_target -{ - const char *const sw; - const enum add_del add_del; - const char *const str; -} -modify_target[] = MODIFY_TARGET_NAME; -#endif - /* Greatest exit code of sub-processes that has been encountered up to now. */ static int greatest_status = 1; @@ -681,18 +664,6 @@ proper position among the other output files. */ "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}" #endif -/* config.h can define SWITCHES_NEED_SPACES to control which options - require spaces between the option and the argument. - - We define SWITCHES_NEED_SPACES to include "o" by default. This - causes "-ofoo.o" to be split into "-o foo.o" during the initial - processing of the command-line, before being seen by the specs - machinery. This makes sure we record "foo.o" as the temporary file - to be deleted in the case of error, rather than "-ofoo.o". */ -#ifndef SWITCHES_NEED_SPACES -#define SWITCHES_NEED_SPACES "o" -#endif - /* config.h can define ENDFILE_SPEC to override the default crtn files. */ #ifndef ENDFILE_SPEC #define ENDFILE_SPEC "" @@ -828,7 +799,6 @@ static const char *link_gomp_spec = ""; static const char *libgcc_spec = LIBGCC_SPEC; static const char *endfile_spec = ENDFILE_SPEC; static const char *startfile_spec = STARTFILE_SPEC; -static const char *switches_need_spaces = SWITCHES_NEED_SPACES; static const char *linker_name_spec = LINKER_NAME; static const char *linker_plugin_file_spec = ""; static const char *lto_wrapper_spec = ""; @@ -1668,7 +1638,6 @@ static struct spec_list static_specs[] = INIT_STATIC_SPEC ("link_gomp", &link_gomp_spec), INIT_STATIC_SPEC ("libgcc", &libgcc_spec), INIT_STATIC_SPEC ("startfile", &startfile_spec), - INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces), INIT_STATIC_SPEC ("cross_compile", &cross_compile), INIT_STATIC_SPEC ("version", &compiler_version), INIT_STATIC_SPEC ("multilib", &multilib_select), @@ -3268,6 +3237,8 @@ static struct switchstr *switches; static int n_switches; +static int n_switches_alloc; + /* Set to zero if -fcompare-debug is disabled, positive if it's enabled and we're running the first compilation, negative if it's enabled and we're running the second compilation. For most of the @@ -3313,6 +3284,8 @@ static struct infile *infiles; int n_infiles; +static int n_infiles_alloc; + /* True if multiple input files are being compiled to a single assembly file. */ @@ -3497,6 +3470,51 @@ add_linker_option (const char *option, int len) linker_options [n_linker_options - 1] = save_string (option, len); } +/* Allocate space for an input file in infiles. */ + +static void +alloc_infile (void) +{ + if (n_infiles_alloc == 0) + { + n_infiles_alloc = 16; + infiles = XNEWVEC (struct infile, n_infiles_alloc); + } + else if (n_infiles_alloc == n_infiles) + { + n_infiles_alloc *= 2; + infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc); + } +} + +/* Store an input file with the given NAME and LANGUAGE in + infiles. */ + +static void +add_infile (const char *name, const char *language) +{ + alloc_infile (); + infiles[n_infiles].name = name; + infiles[n_infiles++].language = language; +} + +/* Allocate space for a switch in switches. */ + +static void +alloc_switch (void) +{ + if (n_switches_alloc == 0) + { + n_switches_alloc = 16; + switches = XNEWVEC (struct switchstr, n_switches_alloc); + } + else if (n_switches_alloc == n_switches) + { + n_switches_alloc *= 2; + switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc); + } +} + /* Create the vector `switches' and its contents. Store its length in `n_switches'. */ @@ -3508,11 +3526,6 @@ process_command (int argc, const char **argv) char *temp1; const char *spec_lang = 0; int last_language_n_infiles; - int lang_n_infiles = 0; -#ifdef MODIFY_TARGET_NAME - int is_modify_target_name; - unsigned int j; -#endif const char *tooldir_prefix; char *(*get_relative_prefix) (const char *, const char *, const char *) = NULL; @@ -3726,12 +3739,22 @@ process_command (int argc, const char **argv) } } - /* Scan argv twice. Here, the first time, just count how many switches - there will be in their vector, and how many input files in theirs. - Here we also parse the switches that cc itself uses (e.g. -v). */ + /* Process the options and store input files and switches in their + vectors. */ + + last_language_n_infiles = -1; for (i = 1; i < argc; i++) { + const char *p = NULL; + int c = 0; + + if (argv[i][0] == '-' && argv[i][1] != 0) + { + p = &argv[i][1]; + c = *p; + } + if (! strcmp (argv[i], "-dumpspecs")) { struct spec_list *sl; @@ -3757,59 +3780,50 @@ process_command (int argc, const char **argv) /* translate_options () has turned --version into -fversion. */ print_version = 1; - /* We will be passing a dummy file on to the sub-processes. */ - n_infiles++; - n_switches++; - /* CPP driver cannot obtain switch from cc1_options. */ if (is_cpp_driver) add_preprocessor_option ("--version", strlen ("--version")); add_assembler_option ("--version", strlen ("--version")); add_linker_option ("--version", strlen ("--version")); + + goto normal_switch; } else if (strcmp (argv[i], "-fhelp") == 0) { /* translate_options () has turned --help into -fhelp. */ print_help_list = 1; - /* We will be passing a dummy file on to the sub-processes. */ - n_infiles++; - n_switches++; - /* CPP driver cannot obtain switch from cc1_options. */ if (is_cpp_driver) add_preprocessor_option ("--help", 6); add_assembler_option ("--help", 6); add_linker_option ("--help", 6); + + goto normal_switch; } else if (strncmp (argv[i], "-fhelp=", 7) == 0) { /* translate_options () has turned --help into -fhelp. */ print_subprocess_help = 2; - /* We will be passing a dummy file on to the sub-processes. */ - n_infiles++; - n_switches++; + goto normal_switch; } else if (strcmp (argv[i], "-ftarget-help") == 0) { /* translate_options() has turned --target-help into -ftarget-help. */ print_subprocess_help = 1; - /* We will be passing a dummy file on to the sub-processes. */ - n_infiles++; - n_switches++; - /* CPP driver cannot obtain switch from cc1_options. */ if (is_cpp_driver) add_preprocessor_option ("--target-help", 13); add_assembler_option ("--target-help", 13); add_linker_option ("--target-help", 13); + + goto normal_switch; } else if (! strcmp (argv[i], "-pass-exit-codes")) { pass_exit_codes = 1; - n_switches++; } else if (! strcmp (argv[i], "-print-search-dirs")) print_search_dirs = 1; @@ -3832,16 +3846,18 @@ process_command (int argc, const char **argv) else if (! strcmp (argv[i], "-fcompare-debug-second")) { compare_debug_second = 1; - n_switches++; + goto normal_switch; } else if (! strcmp (argv[i], "-fno-compare-debug")) { argv[i] = "-fcompare-debug="; + p = &argv[i][1]; goto compare_debug_with_arg; } else if (! strcmp (argv[i], "-fcompare-debug")) { argv[i] = "-fcompare-debug=-gtoggle"; + p = &argv[i][1]; goto compare_debug_with_arg; } #define OPT "-fcompare-debug=" @@ -3859,7 +3875,7 @@ process_command (int argc, const char **argv) compare_debug_opt = NULL; else compare_debug_opt = opt; - n_switches++; + goto normal_switch; } else if (! strncmp (argv[i], "-Wa,", 4)) { @@ -3897,17 +3913,24 @@ process_command (int argc, const char **argv) } else if (strncmp (argv[i], "-Wl,", 4) == 0) { - int j; + int prev, j; /* Split the argument at commas. */ - for (j = 3; argv[i][j]; j++) - n_infiles += (argv[i][j] == ','); + prev = 4; + for (j = 4; argv[i][j]; j++) + if (argv[i][j] == ',') + { + add_infile (save_string (argv[i] + prev, j - prev), "*"); + prev = j + 1; + } + /* Record the part after the last comma. */ + add_infile (argv[i] + prev, "*"); } else if (strcmp (argv[i], "-Xlinker") == 0) { if (i + 1 == argc) fatal_error ("argument to %<-Xlinker%> is missing"); - n_infiles++; + add_infile (argv[i+1], "*"); i++; } else if (strcmp (argv[i], "-Xpreprocessor") == 0) @@ -3916,6 +3939,7 @@ process_command (int argc, const char **argv) fatal_error ("argument to %<-Xpreprocessor%> is missing"); add_preprocessor_option (argv[i+1], strlen (argv[i+1])); + i++; } else if (strcmp (argv[i], "-Xassembler") == 0) { @@ -3923,25 +3947,29 @@ process_command (int argc, const char **argv) fatal_error ("argument to %<-Xassembler%> is missing"); add_assembler_option (argv[i+1], strlen (argv[i+1])); + i++; } else if (strcmp (argv[i], "-l") == 0) { if (i + 1 == argc) fatal_error ("argument to %<-l%> is missing"); - n_infiles++; + /* POSIX allows separation of -l and the lib arg; + canonicalize by concatenating -l with its arg */ + add_infile (concat ("-l", argv[i + 1], NULL), "*"); i++; } else if (strncmp (argv[i], "-l", 2) == 0) - n_infiles++; + { + add_infile (argv[i], "*"); + } else if (strcmp (argv[i], "-save-temps") == 0) { save_temps_flag = SAVE_TEMPS_CWD; - n_switches++; + goto normal_switch; } else if (strncmp (argv[i], "-save-temps=", 12) == 0) { - n_switches++; if (strcmp (argv[i]+12, "cwd") == 0) save_temps_flag = SAVE_TEMPS_CWD; else if (strcmp (argv[i]+12, "obj") == 0 @@ -3949,6 +3977,7 @@ process_command (int argc, const char **argv) save_temps_flag = SAVE_TEMPS_OBJ; else fatal_error ("%qs is an unknown -save-temps option", argv[i]); + goto normal_switch; } else if (strcmp (argv[i], "-no-canonical-prefixes") == 0) /* Already handled as a special case, so ignored here. */ @@ -3956,7 +3985,7 @@ process_command (int argc, const char **argv) else if (strcmp (argv[i], "-combine") == 0) { combine_flag = 1; - n_switches++; + goto normal_switch; } else if (strcmp (argv[i], "-specs") == 0) { @@ -3986,6 +4015,11 @@ process_command (int argc, const char **argv) user_specs_head = user; user_specs_tail = user; } + else if (! strncmp (argv[i], "--sysroot=", strlen ("--sysroot="))) + { + target_system_root = argv[i] + strlen ("--sysroot="); + target_system_root_changed = 1; + } else if (strcmp (argv[i], "-time") == 0) report_times = 1; else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0) @@ -3999,7 +4033,7 @@ process_command (int argc, const char **argv) /* -pipe has to go into the switches array as well as setting a flag. */ use_pipes = 1; - n_switches++; + goto normal_switch; } else if (strcmp (argv[i], "-wrapper") == 0) { @@ -4007,8 +4041,6 @@ process_command (int argc, const char **argv) fatal_error ("argument to %<-wrapper%> is missing"); wrapper_string = argv[i]; - n_switches++; - n_switches++; } else if (strcmp (argv[i], "-###") == 0) { @@ -4021,9 +4053,6 @@ process_command (int argc, const char **argv) } else if (argv[i][0] == '-' && argv[i][1] != 0) { - const char *p = &argv[i][1]; - int c = *p; - switch (c) { case 'B': @@ -4034,7 +4063,7 @@ process_command (int argc, const char **argv) if (p[1] == 0 && i + 1 == argc) fatal_error ("argument to %<-B%> is missing"); if (p[1] == 0) - value = argv[++i]; + value = argv[i + 1]; else value = p + 1; @@ -4063,28 +4092,38 @@ process_command (int argc, const char **argv) PREFIX_PRIORITY_B_OPT, 0, 0); add_prefix (&include_prefixes, value, NULL, PREFIX_PRIORITY_B_OPT, 0, 0); - n_switches++; } - break; + goto normal_switch; case 'v': /* Print our subcommands and print versions. */ - n_switches++; /* If they do anything other than exactly `-v', don't set verbose_flag; rather, continue on to give the error. */ if (p[1] != 0) break; verbose_flag++; + goto normal_switch; + + case 'x': + if (p[1] == 0 && i + 1 == argc) + fatal_error ("argument to %<-x%> is missing"); + if (p[1] == 0) + spec_lang = argv[++i]; + else + spec_lang = p + 1; + if (! strcmp (spec_lang, "none")) + /* Suppress the warning if -xnone comes after the last input + file, because alternate command interfaces like g++ might + find it useful to place -xnone after each input file. */ + spec_lang = 0; + else + last_language_n_infiles = n_infiles; break; case 'S': case 'c': case 'E': if (p[1] == 0) - { - have_c = 1; - n_switches++; - break; - } + have_c = 1; goto normal_switch; case 'o': @@ -4122,7 +4161,10 @@ process_command (int argc, const char **argv) if (p[1] == 0) argv[i + 1] = convert_filename (argv[i + 1], ! have_c, 0); else - argv[i] = convert_filename (argv[i], ! have_c, 0); + { + argv[i] = convert_filename (argv[i], ! have_c, 0); + p = &argv[i][1]; + } #endif /* Save the output name in case -save-temps=obj was used. */ if ((p[1] == 0) && argv[i + 1]) @@ -4134,55 +4176,105 @@ process_command (int argc, const char **argv) default: normal_switch: -#ifdef MODIFY_TARGET_NAME - is_modify_target_name = 0; - - for (j = 0; j < ARRAY_SIZE (modify_target); j++) - if (! strcmp (argv[i], modify_target[j].sw)) - { - char *new_name = XNEWVEC (char, strlen (modify_target[j].str) - + strlen (spec_machine)); - const char *p, *r; - char *q; - int made_addition = 0; - - is_modify_target_name = 1; - for (p = spec_machine, q = new_name; *p != 0; ) - { - if (modify_target[j].add_del == DELETE - && (! strncmp (q, modify_target[j].str, - strlen (modify_target[j].str)))) - p += strlen (modify_target[j].str); - else if (modify_target[j].add_del == ADD - && ! made_addition && *p == '-') - { - for (r = modify_target[j].str; *r != 0; ) - *q++ = *r++; - made_addition = 1; - } - - *q++ = *p++; - } - - spec_machine = new_name; - } - - if (is_modify_target_name) - break; -#endif + alloc_switch (); + switches[n_switches].part1 = p; + /* Deal with option arguments in separate argv elements. */ + if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) + || WORD_SWITCH_TAKES_ARG (p)) + { + int j = 0; + int n_args = WORD_SWITCH_TAKES_ARG (p); + if (n_args == 0) + { + /* Count only the option arguments in separate + argv elements. */ + n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); + } + if (i + n_args >= argc) + fatal_error ("argument to %<-%s%> is missing", p); + switches[n_switches].args + = XNEWVEC (const char *, n_args + 1); + while (j < n_args) + switches[n_switches].args[j++] = argv[++i]; + /* Null-terminate the vector. */ + switches[n_switches].args[j] = 0; + } + else if (c == 'o') + { + /* On some systems, ld cannot handle "-o" without + a space. So split the option from its argument. */ + char *part1 = XNEWVEC (char, 2); + part1[0] = c; + part1[1] = '\0'; + + switches[n_switches].part1 = part1; + switches[n_switches].args = XNEWVEC (const char *, 2); + switches[n_switches].args[0] = xstrdup (p+1); + switches[n_switches].args[1] = 0; + } + else + switches[n_switches].args = 0; + + switches[n_switches].live_cond = 0; + switches[n_switches].validated = 0; + switches[n_switches].ordering = 0; + /* These are always valid, since gcc.c itself understands the + first four, gfortranspec.c understands -static-libgfortran + and g++spec.c understands -static-libstdc++ */ + if (!strcmp (p, "save-temps") + || !strcmp (p, "static-libgcc") + || !strcmp (p, "shared-libgcc") + || !strcmp (p, "pipe") + || !strcmp (p, "static-libgfortran") + || !strcmp (p, "static-libstdc++")) + switches[n_switches].validated = 1; + else + { + char ch = switches[n_switches].part1[0]; + if (ch == 'B') + switches[n_switches].validated = 1; + } n_switches++; - - if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) - i += SWITCH_TAKES_ARG (c) - (p[1] != 0); - else if (WORD_SWITCH_TAKES_ARG (p)) - i += WORD_SWITCH_TAKES_ARG (p); } } else { - n_infiles++; - lang_n_infiles++; + const char *p = strrchr (argv[i], '@'); + char *fname; + long offset; + int consumed; +#ifdef HAVE_TARGET_OBJECT_SUFFIX + argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK)); +#endif + /* For LTO static archive support we handle input file + specifications that are composed of a filename and + an offset like FNAME@OFFSET. */ + if (p + && p != argv[i] + && sscanf (p, "@%li%n", &offset, &consumed) >= 1 + && strlen (p) == (unsigned int)consumed) + { + fname = (char *)xmalloc (p - argv[i] + 1); + memcpy (fname, argv[i], p - argv[i]); + fname[p - argv[i]] = '\0'; + /* Only accept non-stdin and existing FNAME parts, otherwise + try with the full name. */ + if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0) + { + free (fname); + fname = xstrdup (argv[i]); + } + } + else + fname = xstrdup (argv[i]); + + if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0) + perror_with_name (fname); + else + add_infile (argv[i], spec_lang); + + free (fname); } } @@ -4221,13 +4313,11 @@ process_command (int argc, const char **argv) { compare_debug = 2; compare_debug_opt = gcd; - n_switches++; } else if (gcd && *gcd && strcmp (gcd, "0")) { compare_debug = 3; compare_debug_opt = "-gtoggle"; - n_switches++; } } else if (compare_debug < 0) @@ -4280,7 +4370,7 @@ process_command (int argc, const char **argv) then consider it to relocate with the rest of the GCC installation if GCC_EXEC_PREFIX is set. ``make_relative_prefix'' is not compiled for VMS, so don't call it. */ - if (target_system_root && gcc_exec_prefix) + if (target_system_root && !target_system_root_changed && gcc_exec_prefix) { char *tmp_prefix = get_relative_prefix (argv[0], standard_bindir_prefix, @@ -4296,243 +4386,12 @@ process_command (int argc, const char **argv) /* More prefixes are enabled in main, after we read the specs file and determine whether this is cross-compilation or not. */ - /* Then create the space for the vectors and scan again. */ - - switches = XNEWVEC (struct switchstr, n_switches + 1); - infiles = XNEWVEC (struct infile, n_infiles + 1); - n_switches = 0; - n_infiles = 0; - last_language_n_infiles = -1; - - /* This, time, copy the text of each switch and store a pointer - to the copy in the vector of switches. - Store all the infiles in their vector. */ - - for (i = 1; i < argc; i++) - { - /* Just skip the switches that were handled by the preceding loop. */ -#ifdef MODIFY_TARGET_NAME - is_modify_target_name = 0; - - for (j = 0; j < ARRAY_SIZE (modify_target); j++) - if (! strcmp (argv[i], modify_target[j].sw)) - is_modify_target_name = 1; - - if (is_modify_target_name) - ; - else -#endif - if (! strncmp (argv[i], "-Wa,", 4)) - ; - else if (! strncmp (argv[i], "-Wp,", 4)) - ; - else if (! strcmp (argv[i], "-no-canonical-prefixes")) - ; - else if (! strcmp (argv[i], "-pass-exit-codes")) - ; - else if (! strcmp (argv[i], "-print-search-dirs")) - ; - else if (! strcmp (argv[i], "-print-libgcc-file-name")) - ; - else if (! strncmp (argv[i], "-print-file-name=", 17)) - ; - else if (! strncmp (argv[i], "-print-prog-name=", 17)) - ; - else if (! strcmp (argv[i], "-print-multi-lib")) - ; - else if (! strcmp (argv[i], "-print-multi-directory")) - ; - else if (! strcmp (argv[i], "-print-sysroot")) - ; - else if (! strcmp (argv[i], "-print-multi-os-directory")) - ; - else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) - ; - else if (! strncmp (argv[i], "--sysroot=", strlen ("--sysroot="))) - { - target_system_root = argv[i] + strlen ("--sysroot="); - target_system_root_changed = 1; - } - else if (strncmp (argv[i], "-Wl,", 4) == 0) - { - int prev, j; - /* Split the argument at commas. */ - prev = 4; - for (j = 4; argv[i][j]; j++) - if (argv[i][j] == ',') - { - infiles[n_infiles].language = "*"; - infiles[n_infiles++].name - = save_string (argv[i] + prev, j - prev); - prev = j + 1; - } - /* Record the part after the last comma. */ - infiles[n_infiles].language = "*"; - infiles[n_infiles++].name = argv[i] + prev; - } - else if (strcmp (argv[i], "-Xlinker") == 0) - { - infiles[n_infiles].language = "*"; - infiles[n_infiles++].name = argv[++i]; - } - /* Xassembler and Xpreprocessor were already handled in the first argv - scan, so all we need to do here is ignore them and their argument. */ - else if (strcmp (argv[i], "-Xassembler") == 0) - i++; - else if (strcmp (argv[i], "-Xpreprocessor") == 0) - i++; - else if (strcmp (argv[i], "-l") == 0) - { /* POSIX allows separation of -l and the lib arg; - canonicalize by concatenating -l with its arg */ - infiles[n_infiles].language = "*"; - infiles[n_infiles++].name = concat ("-l", argv[++i], NULL); - } - else if (strncmp (argv[i], "-l", 2) == 0) - { - infiles[n_infiles].language = "*"; - infiles[n_infiles++].name = argv[i]; - } - else if (strcmp (argv[i], "-wrapper") == 0) - i++; - else if (strcmp (argv[i], "-specs") == 0) - i++; - else if (strncmp (argv[i], "-specs=", 7) == 0) - ; - else if (strcmp (argv[i], "-time") == 0) - ; - else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0) - ; - else if (strcmp (argv[i], "-###") == 0) - ; - else if (argv[i][0] == '-' && argv[i][1] != 0) - { - const char *p = &argv[i][1]; - int c = *p; - - if (c == 'x') - { - if (p[1] == 0 && i + 1 == argc) - fatal_error ("argument to %<-x%> is missing"); - if (p[1] == 0) - spec_lang = argv[++i]; - else - spec_lang = p + 1; - if (! strcmp (spec_lang, "none")) - /* Suppress the warning if -xnone comes after the last input - file, because alternate command interfaces like g++ might - find it useful to place -xnone after each input file. */ - spec_lang = 0; - else - last_language_n_infiles = n_infiles; - continue; - } - switches[n_switches].part1 = p; - /* Deal with option arguments in separate argv elements. */ - if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) - || WORD_SWITCH_TAKES_ARG (p)) - { - int j = 0; - int n_args = WORD_SWITCH_TAKES_ARG (p); - - if (n_args == 0) - { - /* Count only the option arguments in separate argv elements. */ - n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); - } - if (i + n_args >= argc) - fatal_error ("argument to %<-%s%> is missing", p); - switches[n_switches].args - = XNEWVEC (const char *, n_args + 1); - while (j < n_args) - switches[n_switches].args[j++] = argv[++i]; - /* Null-terminate the vector. */ - switches[n_switches].args[j] = 0; - } - else if (strchr (switches_need_spaces, c)) - { - /* On some systems, ld cannot handle some options without - a space. So split the option from its argument. */ - char *part1 = XNEWVEC (char, 2); - part1[0] = c; - part1[1] = '\0'; - - switches[n_switches].part1 = part1; - switches[n_switches].args = XNEWVEC (const char *, 2); - switches[n_switches].args[0] = xstrdup (p+1); - switches[n_switches].args[1] = 0; - } - else - switches[n_switches].args = 0; - - switches[n_switches].live_cond = 0; - switches[n_switches].validated = 0; - switches[n_switches].ordering = 0; - /* These are always valid, since gcc.c itself understands the - first four, gfortranspec.c understands -static-libgfortran - and g++spec.c understands -static-libstdc++ */ - if (!strcmp (p, "save-temps") - || !strcmp (p, "static-libgcc") - || !strcmp (p, "shared-libgcc") - || !strcmp (p, "pipe") - || !strcmp (p, "static-libgfortran") - || !strcmp (p, "static-libstdc++")) - switches[n_switches].validated = 1; - else - { - char ch = switches[n_switches].part1[0]; - if (ch == 'B') - switches[n_switches].validated = 1; - } - n_switches++; - } - else - { - const char *p = strrchr (argv[i], '@'); - char *fname; - long offset; - int consumed; -#ifdef HAVE_TARGET_OBJECT_SUFFIX - argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK)); -#endif - /* For LTO static archive support we handle input file - specifications that are composed of a filename and - an offset like FNAME@OFFSET. */ - if (p - && p != argv[i] - && sscanf (p, "@%li%n", &offset, &consumed) >= 1 - && strlen (p) == (unsigned int)consumed) - { - fname = (char *)xmalloc (p - argv[i] + 1); - memcpy (fname, argv[i], p - argv[i]); - fname[p - argv[i]] = '\0'; - /* Only accept non-stdin and existing FNAME parts, otherwise - try with the full name. */ - if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0) - { - free (fname); - fname = xstrdup (argv[i]); - } - } - else - fname = xstrdup (argv[i]); - - if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0) - perror_with_name (fname); - else - { - infiles[n_infiles].language = spec_lang; - infiles[n_infiles++].name = argv[i]; - } - - free (fname); - } - } - if (n_infiles == last_language_n_infiles && spec_lang != 0) warning (0, "%<-x %s%> after last input file has no effect", spec_lang); if (compare_debug == 2 || compare_debug == 3) { + alloc_switch (); switches[n_switches].part1 = concat ("fcompare-debug=", compare_debug_opt, NULL); @@ -4547,15 +4406,16 @@ process_command (int argc, const char **argv) /* Ensure we only invoke each subprocess once. */ if (print_subprocess_help || print_help_list || print_version) { - n_infiles = 1; + n_infiles = 0; /* Create a dummy input file, so that we can pass the help option on to the various sub-processes. */ - infiles[0].language = "c"; - infiles[0].name = "help-dummy"; + add_infile ("help-dummy", "c"); } + alloc_switch (); switches[n_switches].part1 = 0; + alloc_infile (); infiles[n_infiles].name = 0; } @@ -4912,9 +4772,9 @@ do_self_spec (const char *spec) /* Null-terminate the vector. */ sw->args[j] = 0; } - else if (strchr (switches_need_spaces, c)) + else if (c == 'o') { - /* On some systems, ld cannot handle some options without + /* On some systems, ld cannot handle "-o" without a space. So split the option from its argument. */ char *part1 = XNEWVEC (char, 2); part1[0] = c; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 5df6ddf1dcc..a9c93ac972d 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -537,7 +537,7 @@ lookup_tmp_var (tree val, bool is_formal) /* Return true if T is a CALL_EXPR or an expression that can be - assignmed to a temporary. Note that this predicate should only be + assigned to a temporary. Note that this predicate should only be used during gimplification. See the rationale for this in gimplify_modify_expr. */ @@ -6516,7 +6516,7 @@ gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p) GIMPLE_TEST_F points to a function that takes a tree T and returns nonzero if T is in the GIMPLE form requested by the - caller. The GIMPLE predicates are in tree-gimple.c. + caller. The GIMPLE predicates are in gimple.c. FALLBACK tells the function what sort of a temporary we want if gimplification cannot produce an expression that complies with diff --git a/gcc/implicit-zee.c b/gcc/implicit-zee.c index 3344d7f8af2..46029cdac38 100644 --- a/gcc/implicit-zee.c +++ b/gcc/implicit-zee.c @@ -858,7 +858,7 @@ find_removable_zero_extends (void) { FOR_BB_INSNS (curr_block, curr_insn) { - if (!INSN_P (curr_insn)) + if (!NONDEBUG_INSN_P (curr_insn)) continue; type = for_each_rtx (&PATTERN (curr_insn), diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 1c1809b61d0..78dccf85b04 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -177,18 +177,6 @@ ipcp_init_cloned_node (struct cgraph_node *orig_node, IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node; } -/* Perform intraprocedrual analysis needed for ipcp. */ -static void -ipcp_analyze_node (struct cgraph_node *node) -{ - /* Unreachable nodes should have been eliminated before ipcp. */ - gcc_assert (node->needed || node->reachable); - - node->local.versionable = tree_versionable_function_p (node->decl); - ipa_initialize_node_params (node); - ipa_detect_param_modifications (node); -} - /* Return scale for NODE. */ static inline gcov_type ipcp_get_node_scale (struct cgraph_node *node) @@ -611,6 +599,7 @@ ipcp_compute_node_scale (struct cgraph_node *node) /* Initialization and computation of IPCP data structures. This is the initial intraprocedural analysis of functions, which gathers information to be propagated later on. */ + static void ipcp_init_stage (void) { @@ -618,16 +607,13 @@ ipcp_init_stage (void) for (node = cgraph_nodes; node; node = node->next) if (node->analyzed) - ipcp_analyze_node (node); - for (node = cgraph_nodes; node; node = node->next) - { - if (!node->analyzed) - continue; + { + /* Unreachable nodes should have been eliminated before ipcp. */ + gcc_assert (node->needed || node->reachable); - ipa_analyze_params_uses (node); - /* building jump functions */ - ipa_compute_jump_functions (node); - } + node->local.versionable = tree_versionable_function_p (node->decl); + ipa_analyze_node (node); + } } /* Return true if there are some formal parameters whose value is IPA_TOP (in diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index c7f85b218b5..4c524d10fb0 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2014,12 +2014,8 @@ struct gimple_opt_pass pass_inline_parameters = static void inline_indirect_intraprocedural_analysis (struct cgraph_node *node) { - ipa_initialize_node_params (node); - ipa_detect_param_modifications (node); - ipa_analyze_params_uses (node); - ipa_compute_jump_functions (node); - - if (dump_file) + ipa_analyze_node (node); + if (dump_file && (dump_flags & TDF_DETAILS)) { ipa_print_node_params (dump_file, node); ipa_print_node_jump_functions (dump_file, node); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 8dd301e9198..9bd07f039b9 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -39,6 +39,16 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "lto-streamer.h" + +/* Intermediate information about a parameter that is only useful during the + run of ipa_analyze_node and is not kept afterwards. */ + +struct param_analysis_info +{ + bool modified; + bitmap visited_statements; +}; + /* Vector where the parameter infos are actually stored. */ VEC (ipa_node_params_t, heap) *ipa_node_params_vector; /* Vector where the parameter infos are actually stored. */ @@ -196,101 +206,10 @@ ipa_initialize_node_params (struct cgraph_node *node) } } -/* Callback of walk_stmt_load_store_addr_ops for the visit_store and visit_addr - parameters. If OP is a parameter declaration, mark it as modified in the - info structure passed in DATA. */ - -static bool -visit_store_addr_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED, - tree op, void *data) -{ - struct ipa_node_params *info = (struct ipa_node_params *) data; - - op = get_base_address (op); - if (op - && TREE_CODE (op) == PARM_DECL) - { - int index = ipa_get_param_decl_index (info, op); - gcc_assert (index >= 0); - info->params[index].modified = true; - info->params[index].used = true; - } - - return false; -} - -/* Callback of walk_stmt_load_store_addr_ops for the visit_load. - If OP is a parameter declaration, mark it as used in the info structure - passed in DATA. */ - -static bool -visit_load_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED, - tree op, void *data) -{ - struct ipa_node_params *info = (struct ipa_node_params *) data; - - op = get_base_address (op); - if (op - && TREE_CODE (op) == PARM_DECL) - { - int index = ipa_get_param_decl_index (info, op); - gcc_assert (index >= 0); - info->params[index].used = true; - } - - return false; -} - -/* Compute which formal parameters of function associated with NODE are locally - modified or their address is taken. Note that this does not apply on - parameters with SSA names but those can and should be analyzed - differently. */ - -void -ipa_detect_param_modifications (struct cgraph_node *node) -{ - tree decl = node->decl; - basic_block bb; - struct function *func; - gimple_stmt_iterator gsi; - struct ipa_node_params *info = IPA_NODE_REF (node); - int i; - - if (ipa_get_param_count (info) == 0 || info->modification_analysis_done) - return; - - for (i = 0; i < ipa_get_param_count (info); i++) - { - tree parm = ipa_get_param (info, i); - /* For SSA regs see if parameter is used. For non-SSA we compute - the flag during modification analysis. */ - if (is_gimple_reg (parm) - && gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), parm)) - info->params[i].used = true; - } - - func = DECL_STRUCT_FUNCTION (decl); - FOR_EACH_BB_FN (bb, func) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, - visit_load_for_mod_analysis, - visit_store_addr_for_mod_analysis, - visit_store_addr_for_mod_analysis); - for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi)) - walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, - visit_load_for_mod_analysis, - visit_store_addr_for_mod_analysis, - visit_store_addr_for_mod_analysis); - } - - info->modification_analysis_done = 1; -} - /* Count number of arguments callsite CS has and store it in ipa_edge_args structure corresponding to this callsite. */ -void +static void ipa_count_arguments (struct cgraph_edge *cs) { gimple stmt; @@ -709,14 +628,53 @@ type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta) return true; } +/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the + boolean variable pointed to by DATA. */ + +static bool +mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED, + void *data) +{ + bool *b = (bool *) data; + *b = true; + return true; +} + +/* Return true if the formal parameter PARM might have been modified in this + function before reaching the statement CALL. PARM_INFO is a pointer to a + structure containing intermediate information about PARM. */ + +static bool +is_parm_modified_before_call (struct param_analysis_info *parm_info, + gimple call, tree parm) +{ + bool modified = false; + ao_ref refd; + + if (parm_info->modified) + return true; + + ao_ref_init (&refd, parm); + walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified, + &modified, &parm_info->visited_statements); + if (modified) + { + parm_info->modified = true; + return true; + } + return false; +} + /* Go through arguments of the CALL and for every one that looks like a member pointer, check whether it can be safely declared pass-through and if so, mark that to the corresponding item of jump FUNCTIONS. Return true iff there are non-pass-through member pointers within the arguments. INFO - describes formal parameters of the caller. */ + describes formal parameters of the caller. PARMS_INFO is a pointer to a + vector containing intermediate information about each formal parameter. */ static bool compute_pass_through_member_ptrs (struct ipa_node_params *info, + struct param_analysis_info *parms_info, struct ipa_jump_func *functions, gimple call) { @@ -735,7 +693,7 @@ compute_pass_through_member_ptrs (struct ipa_node_params *info, int index = ipa_get_param_decl_index (info, arg); gcc_assert (index >=0); - if (!ipa_is_param_modified (info, index)) + if (!is_parm_modified_before_call (&parms_info[index], call, arg)) { functions[num].type = IPA_JF_PASS_THROUGH; functions[num].value.pass_through.formal_id = index; @@ -808,6 +766,8 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, gimple stmt = gsi_stmt (gsi); tree lhs, rhs, fld; + if (!stmt_may_clobber_ref_p (stmt, arg)) + continue; if (!gimple_assign_single_p (stmt)) return; @@ -816,7 +776,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field, if (TREE_CODE (lhs) != COMPONENT_REF || TREE_OPERAND (lhs, 0) != arg) - continue; + return; fld = TREE_OPERAND (lhs, 1); if (!method && fld == method_field) @@ -886,7 +846,8 @@ compute_cst_member_ptr_arguments (struct ipa_jump_func *functions, to this callsite. */ static void -ipa_compute_jump_functions_for_edge (struct cgraph_edge *cs) +ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_info, + struct cgraph_edge *cs) { struct ipa_node_params *info = IPA_NODE_REF (cs->caller); struct ipa_edge_args *arguments = IPA_EDGE_REF (cs); @@ -905,7 +866,8 @@ ipa_compute_jump_functions_for_edge (struct cgraph_edge *cs) /* Let's check whether there are any potential member pointers and if so, whether we can determine their functions as pass_through. */ - if (!compute_pass_through_member_ptrs (info, arguments->jump_functions, call)) + if (!compute_pass_through_member_ptrs (info, parms_info, + arguments->jump_functions, call)) return; /* Finally, let's check whether we actually pass a new constant member @@ -916,8 +878,9 @@ ipa_compute_jump_functions_for_edge (struct cgraph_edge *cs) /* Compute jump functions for all edges - both direct and indirect - outgoing from NODE. Also count the actual arguments in the process. */ -void -ipa_compute_jump_functions (struct cgraph_node *node) +static void +ipa_compute_jump_functions (struct cgraph_node *node, + struct param_analysis_info *parms_info) { struct cgraph_edge *cs; @@ -928,16 +891,20 @@ ipa_compute_jump_functions (struct cgraph_node *node) if (!cs->callee->analyzed && !flag_lto && !flag_whopr) continue; ipa_count_arguments (cs); + /* If the descriptor of the callee is not initialized yet, we have to do + it now. */ + if (cs->callee->analyzed) + ipa_initialize_node_params (cs->callee); if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) != ipa_get_param_count (IPA_NODE_REF (cs->callee))) ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); - ipa_compute_jump_functions_for_edge (cs); + ipa_compute_jump_functions_for_edge (parms_info, cs); } for (cs = node->indirect_calls; cs; cs = cs->next_callee) { ipa_count_arguments (cs); - ipa_compute_jump_functions_for_edge (cs); + ipa_compute_jump_functions_for_edge (parms_info, cs); } } @@ -1021,17 +988,23 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, } /* Analyze the CALL and examine uses of formal parameters of the caller NODE - (described by INFO). Currently it checks whether the call calls a pointer - that is a formal parameter and if so, the parameter is marked with the - called flag and an indirect call graph edge describing the call is created. - This is very simple for ordinary pointers represented in SSA but not-so-nice - when it comes to member pointers. The ugly part of this function does - nothing more than trying to match the pattern of such a call. An example of - such a pattern is the gimple dump below, the call is on the last line: + (described by INFO). PARMS_INFO is a pointer to a vector containing + intermediate information about each formal parameter. Currently it checks + whether the call calls a pointer that is a formal parameter and if so, the + parameter is marked with the called flag and an indirect call graph edge + describing the call is created. This is very simple for ordinary pointers + represented in SSA but not-so-nice when it comes to member pointers. The + ugly part of this function does nothing more than trying to match the + pattern of such a call. An example of such a pattern is the gimple dump + below, the call is on the last line: <bb 2>: f$__delta_5 = f.__delta; f$__pfn_24 = f.__pfn; + + ... + + <bb 5> D.2496_3 = (int) f$__pfn_24; D.2497_4 = D.2496_3 & 1; if (D.2497_4 != 0) @@ -1039,7 +1012,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, else goto <bb 4>; - <bb 3>: + <bb 6>: D.2500_7 = (unsigned int) f$__delta_5; D.2501_8 = &S + D.2500_7; D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8; @@ -1050,7 +1023,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, D.2507_15 = *D.2506_14; iftmp.11_16 = (String:: *) D.2507_15; - <bb 4>: + <bb 7>: # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)> D.2500_19 = (unsigned int) f$__delta_5; D.2508_20 = &S + D.2500_19; @@ -1069,6 +1042,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, gimple stmt, static void ipa_analyze_indirect_call_uses (struct cgraph_node *node, struct ipa_node_params *info, + struct param_analysis_info *parms_info, gimple call, tree target) { gimple def; @@ -1111,17 +1085,18 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, d1 = SSA_NAME_DEF_STMT (n1); d2 = SSA_NAME_DEF_STMT (n2); + join = gimple_bb (def); if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false))) { if (ipa_get_stmt_member_ptr_load_param (d2, false)) return; - bb = gimple_bb (d1); + bb = EDGE_PRED (join, 0)->src; virt_bb = gimple_bb (d2); } else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false))) { - bb = gimple_bb (d2); + bb = EDGE_PRED (join, 1)->src; virt_bb = gimple_bb (d1); } else @@ -1130,7 +1105,6 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, /* Second, we need to check that the basic blocks are laid out in the way corresponding to the pattern. */ - join = gimple_bb (def); if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb) || single_pred (virt_bb) != bb || single_succ (virt_bb) != join) @@ -1140,7 +1114,7 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, significant bit of the pfn. */ branch = last_stmt (bb); - if (gimple_code (branch) != GIMPLE_COND) + if (!branch || gimple_code (branch) != GIMPLE_COND) return; if (gimple_cond_code (branch) != NE_EXPR @@ -1180,7 +1154,8 @@ ipa_analyze_indirect_call_uses (struct cgraph_node *node, return; index = ipa_get_param_decl_index (info, rec); - if (index >= 0 && !ipa_is_param_modified (info, index)) + if (index >= 0 && !is_parm_modified_before_call (&parms_info[index], + call, rec)) ipa_note_param_call (node, index, call, false); return; @@ -1223,16 +1198,18 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node, } /* Analyze a call statement CALL whether and how it utilizes formal parameters - of the caller (described by INFO). */ + of the caller (described by INFO). PARMS_INFO is a pointer to a vector + containing intermediate information about each formal parameter. */ static void ipa_analyze_call_uses (struct cgraph_node *node, - struct ipa_node_params *info, gimple call) + struct ipa_node_params *info, + struct param_analysis_info *parms_info, gimple call) { tree target = gimple_call_fn (call); if (TREE_CODE (target) == SSA_NAME) - ipa_analyze_indirect_call_uses (node, info, call, target); + ipa_analyze_indirect_call_uses (node, info, parms_info, call, target); else if (TREE_CODE (target) == OBJ_TYPE_REF) ipa_analyze_virtual_call_uses (node, info, call, target); } @@ -1240,45 +1217,120 @@ ipa_analyze_call_uses (struct cgraph_node *node, /* Analyze the call statement STMT with respect to formal parameters (described in INFO) of caller given by NODE. Currently it only checks whether formal - parameters are called. */ + parameters are called. PARMS_INFO is a pointer to a vector containing + intermediate information about each formal parameter. */ static void ipa_analyze_stmt_uses (struct cgraph_node *node, struct ipa_node_params *info, - gimple stmt) + struct param_analysis_info *parms_info, gimple stmt) { if (is_gimple_call (stmt)) - ipa_analyze_call_uses (node, info, stmt); + ipa_analyze_call_uses (node, info, parms_info, stmt); +} + +/* Callback of walk_stmt_load_store_addr_ops for the visit_load. + If OP is a parameter declaration, mark it as used in the info structure + passed in DATA. */ + +static bool +visit_ref_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED, + tree op, void *data) +{ + struct ipa_node_params *info = (struct ipa_node_params *) data; + + op = get_base_address (op); + if (op + && TREE_CODE (op) == PARM_DECL) + { + int index = ipa_get_param_decl_index (info, op); + gcc_assert (index >= 0); + info->params[index].used = true; + } + + return false; } /* Scan the function body of NODE and inspect the uses of formal parameters. Store the findings in various structures of the associated ipa_node_params - structure, such as parameter flags, notes etc. */ + structure, such as parameter flags, notes etc. PARMS_INFO is a pointer to a + vector containing intermediate information about each formal parameter. */ -void -ipa_analyze_params_uses (struct cgraph_node *node) +static void +ipa_analyze_params_uses (struct cgraph_node *node, + struct param_analysis_info *parms_info) { tree decl = node->decl; basic_block bb; struct function *func; gimple_stmt_iterator gsi; struct ipa_node_params *info = IPA_NODE_REF (node); + int i; if (ipa_get_param_count (info) == 0 || info->uses_analysis_done) return; + for (i = 0; i < ipa_get_param_count (info); i++) + { + tree parm = ipa_get_param (info, i); + /* For SSA regs see if parameter is used. For non-SSA we compute + the flag during modification analysis. */ + if (is_gimple_reg (parm) + && gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), parm)) + info->params[i].used = true; + } + func = DECL_STRUCT_FUNCTION (decl); FOR_EACH_BB_FN (bb, func) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - ipa_analyze_stmt_uses (node, info, stmt); + + if (is_gimple_debug (stmt)) + continue; + + ipa_analyze_stmt_uses (node, info, parms_info, stmt); + walk_stmt_load_store_addr_ops (stmt, info, + visit_ref_for_mod_analysis, + visit_ref_for_mod_analysis, + visit_ref_for_mod_analysis); } + for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi)) + walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, + visit_ref_for_mod_analysis, + visit_ref_for_mod_analysis, + visit_ref_for_mod_analysis); } info->uses_analysis_done = 1; } +/* Initialize the array describing properties of of formal parameters of NODE, + analyze their uses and and compute jump functions associated witu actual + arguments of calls from within NODE. */ + +void +ipa_analyze_node (struct cgraph_node *node) +{ + struct ipa_node_params *info = IPA_NODE_REF (node); + struct param_analysis_info *parms_info; + int i, param_count; + + ipa_initialize_node_params (node); + + param_count = ipa_get_param_count (info); + parms_info = XALLOCAVEC (struct param_analysis_info, param_count); + memset (parms_info, 0, sizeof (struct param_analysis_info) * param_count); + + ipa_analyze_params_uses (node, parms_info); + ipa_compute_jump_functions (node, parms_info); + + for (i = 0; i < param_count; i++) + if (parms_info[i].visited_statements) + BITMAP_FREE (parms_info[i].visited_statements); +} + + /* Update the jump function DST when the call graph edge correspondng to SRC is is being inlined, knowing that DST is of type ancestor and src of known type. */ @@ -1850,8 +1902,6 @@ ipa_print_node_params (FILE * f, struct cgraph_node *node) (DECL_NAME (temp) ? (*lang_hooks.decl_printable_name) (temp, 2) : "(unnamed)")); - if (ipa_is_param_modified (info, i)) - fprintf (f, " modified"); if (ipa_is_param_used (info, i)) fprintf (f, " used"); fprintf (f, "\n"); @@ -2039,6 +2089,13 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments, DECL_VINDEX (fndecl) = NULL_TREE; } + /* When signature changes, we need to clear builtin info. */ + if (DECL_BUILT_IN (fndecl)) + { + DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN; + DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0; + } + /* 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); @@ -2460,16 +2517,12 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) bp = bitpack_create (ob->main_stream); bp_pack_value (&bp, info->called_with_var_arguments, 1); - bp_pack_value (&bp, info->uses_analysis_done, 1); - gcc_assert (info->modification_analysis_done + gcc_assert (info->uses_analysis_done || ipa_get_param_count (info) == 0); gcc_assert (!info->node_enqueued); gcc_assert (!info->ipcp_orig_node); for (j = 0; j < ipa_get_param_count (info); j++) - { - bp_pack_value (&bp, info->params[j].modified, 1); - bp_pack_value (&bp, info->params[j].used, 1); - } + bp_pack_value (&bp, info->params[j].used, 1); lto_output_bitpack (&bp); for (e = node->callees; e; e = e->next_callee) { @@ -2499,18 +2552,11 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, bp = lto_input_bitpack (ib); info->called_with_var_arguments = bp_unpack_value (&bp, 1); - info->uses_analysis_done = bp_unpack_value (&bp, 1); if (ipa_get_param_count (info) != 0) - { - info->modification_analysis_done = true; - info->uses_analysis_done = true; - } + info->uses_analysis_done = true; info->node_enqueued = false; for (k = 0; k < ipa_get_param_count (info); k++) - { - info->params[k].modified = bp_unpack_value (&bp, 1); - info->params[k].used = bp_unpack_value (&bp, 1); - } + info->params[k].used = bp_unpack_value (&bp, 1); for (e = node->callees; e; e = e->next_callee) { struct ipa_edge_args *args = IPA_EDGE_REF (e); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 110044e4da4..c73367a4945 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -161,8 +161,6 @@ struct ipa_param_descriptor struct ipcp_lattice ipcp_lattice; /* PARAM_DECL of this parameter. */ tree decl; - /* Whether the value parameter has been modified within the function. */ - unsigned modified : 1; /* The parameter is used. */ unsigned used : 1; }; @@ -179,8 +177,6 @@ struct ipa_node_params /* Whether this function is called with variable number of actual arguments. */ unsigned called_with_var_arguments : 1; - /* Whether the modification analysis has already been performed. */ - unsigned modification_analysis_done : 1; /* Whether the param uses analysis has already been performed. */ unsigned uses_analysis_done : 1; /* Whether the function is enqueued in an ipa_func_list. */ @@ -228,17 +224,6 @@ ipa_get_param (struct ipa_node_params *info, int i) return info->params[i].decl; } -/* Return the modification flag corresponding to the Ith formal parameter of - the function associated with INFO. Note that there is no setter method as - the goal is to set all flags when building the array in - ipa_detect_param_modifications. */ - -static inline bool -ipa_is_param_modified (struct ipa_node_params *info, int i) -{ - return info->params[i].modified; -} - /* Return the used flag corresponding to the Ith formal parameter of the function associated with INFO. */ @@ -412,14 +397,10 @@ ipa_push_func_to_list (struct ipa_func_list **wl, struct cgraph_node *node) ipa_push_func_to_list_1 (wl, node, info); } -/* Callsite related calculations. */ -void ipa_compute_jump_functions (struct cgraph_node *); -void ipa_count_arguments (struct cgraph_edge *); +void ipa_analyze_node (struct cgraph_node *); /* Function formal parameters related computations. */ void ipa_initialize_node_params (struct cgraph_node *node); -void ipa_detect_param_modifications (struct cgraph_node *); -void ipa_analyze_params_uses (struct cgraph_node *); bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, VEC (cgraph_edge_p, heap) **new_edges); diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index e69de29bb2d..ccc89c431c3 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -0,0 +1,1105 @@ +/* Function splitting pass + Copyright (C) 2010 + Free Software Foundation, Inc. + Contributed by Jan Hubicka <jh@suse.cz> + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* The purpose of this pass is to split function bodies to improve + inlining. I.e. for function of the form: + + func (...) + { + if (cheap_test) + something_small + else + something_big + } + + Produce: + + func.part (...) + { + something_big + } + + func (...) + { + if (cheap_test) + something_small + else + func.part (...); + } + + When func becomes inlinable and when cheap_test is often true, inlining func, + but not fund.part leads to performance imrovement similar as inlining + original func while the code size growth is smaller. + + The pass is organized in three stages: + 1) Collect local info about basic block into BB_INFO structure and + compute function body estimated size and time. + 2) Via DFS walk find all possible basic blocks where we can split + and chose best one. + 3) If split point is found, split at the specified BB by creating a clone + and updating function to call it. + + The decisions what functions to split are in execute_split_functions + and consider_split. + + There are several possible future improvements for this pass including: + + 1) Splitting to break up large functions + 2) Splitting to reduce stack frame usage + 3) Allow split part of function to use values computed in the header part. + The values needs to be passed to split function, perhaps via same + interface as for nested functions or as argument. + 4) Support for simple rematerialization. I.e. when split part use + value computed in header from function parameter in very cheap way, we + can just recompute it. + 5) Support splitting of nested functions. + 6) Support non-SSA arguments. + 7) There is nothing preventing us from producing multiple parts of single function + when needed or splitting also the parts. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "target.h" +#include "cgraph.h" +#include "ipa-prop.h" +#include "tree-flow.h" +#include "tree-pass.h" +#include "flags.h" +#include "timevar.h" +#include "diagnostic.h" +#include "tree-dump.h" +#include "tree-inline.h" +#include "fibheap.h" +#include "params.h" +#include "gimple-pretty-print.h" + +/* Per basic block info. */ + +typedef struct +{ + unsigned int size; + unsigned int time; +} bb_info; +DEF_VEC_O(bb_info); +DEF_VEC_ALLOC_O(bb_info,heap); + +static VEC(bb_info, heap) *bb_info_vec; + +/* Description of split point. */ + +struct split_point +{ + /* Size of the partitions. */ + unsigned int header_time, header_size, split_time, split_size; + + /* SSA names that need to be passed into spit funciton. */ + bitmap ssa_names_to_pass; + + /* Basic block where we split (that will become entry point of new function. */ + basic_block entry_bb; + + /* Basic blocks we are splitting away. */ + bitmap split_bbs; +}; + +/* Best split point found. */ + +struct split_point best_split_point; + +/* Callback for walk_stmt_load_store_addr_ops. If T is non-ssa automatic + variable, check it if it is present in bitmap passed via DATA. */ + +static bool +test_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, + void *data ATTRIBUTE_UNUSED) +{ + t = get_base_address (t); + + if (t && !is_gimple_reg (t) + && ((TREE_CODE (t) == VAR_DECL + && auto_var_in_fn_p (t, current_function_decl)) + || (TREE_CODE (t) == PARM_DECL))) + return bitmap_bit_p ((bitmap)data, DECL_UID (t)); + return false; +} + +/* Dump split point CURRENT. */ + +static void +dump_split_point (FILE * file, struct split_point *current) +{ + fprintf (file, + "Split point at BB %i header time:%i header size: %i" + " split time: %i split size: %i\n bbs: ", + current->entry_bb->index, current->header_time, + current->header_size, current->split_time, current->split_size); + dump_bitmap (file, current->split_bbs); + fprintf (file, " SSA names to pass: "); + dump_bitmap (file, current->ssa_names_to_pass); +} + +/* We found an split_point CURRENT. NON_SSA_VARS is bitmap of all non ssa + variables used and RETURN_BB is return basic block. + See if we can split function here. */ + +static void +consider_split (struct split_point *current, bitmap non_ssa_vars, + basic_block return_bb) +{ + tree parm; + unsigned int num_args = 0; + unsigned int call_overhead; + edge e; + edge_iterator ei; + gimple_stmt_iterator bsi; + unsigned int i; + int incomming_freq = 0; + + if (dump_file && (dump_flags & TDF_DETAILS)) + dump_split_point (dump_file, current); + + FOR_EACH_EDGE (e, ei, current->entry_bb->preds) + if (!bitmap_bit_p (current->split_bbs, e->src->index)) + incomming_freq += EDGE_FREQUENCY (e); + + /* Do not split when we would end up calling function anyway. */ + if (incomming_freq + >= (ENTRY_BLOCK_PTR->frequency + * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: incomming frequency is too large.\n"); + return; + } + + if (!current->header_size) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Refused: header empty\n"); + gcc_unreachable (); + return; + } + + /* Verify that PHI args on entry are either virutal or all their operands + incomming from header are the same. */ + for (bsi = gsi_start_phis (current->entry_bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + tree val = NULL; + + if (!is_gimple_reg (gimple_phi_result (stmt))) + continue; + for (i = 0; i < gimple_phi_num_args (stmt); i++) + { + edge e = gimple_phi_arg_edge (stmt, i); + if (!bitmap_bit_p (current->split_bbs, e->src->index)) + { + tree edge_val = gimple_phi_arg_def (stmt, i); + if (val && edge_val != val) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: entry BB has PHI with multiple variants\n"); + return; + } + val = edge_val; + } + } + } + + + /* See what argument we will pass to the split function and compute + call overhead. */ + call_overhead = eni_size_weights.call_cost; + for (parm = DECL_ARGUMENTS (current_function_decl); parm; + parm = TREE_CHAIN (parm)) + { + if (!is_gimple_reg (parm)) + { + if (bitmap_bit_p (non_ssa_vars, DECL_UID (parm))) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: need to pass non-ssa param values\n"); + return; + } + } + else if (gimple_default_def (cfun, parm) + && bitmap_bit_p (current->ssa_names_to_pass, + SSA_NAME_VERSION (gimple_default_def + (cfun, parm)))) + { + if (!VOID_TYPE_P (TREE_TYPE (parm))) + call_overhead += estimate_move_cost (TREE_TYPE (parm)); + num_args++; + } + } + if (!VOID_TYPE_P (TREE_TYPE (current_function_decl))) + call_overhead += estimate_move_cost (TREE_TYPE (current_function_decl)); + + if (current->split_size <= call_overhead) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: split size is smaller than call overhead\n"); + return; + } + if (current->header_size + call_overhead + >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl) + ? MAX_INLINE_INSNS_SINGLE + : MAX_INLINE_INSNS_AUTO)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: header size is too large for inline candidate\n"); + return; + } + + /* FIXME: we currently can pass only SSA function parameters to the split + arguments. Once parm_adjustment infrastructure is supported by cloning, + we can pass more than that. */ + if (num_args != bitmap_count_bits (current->ssa_names_to_pass)) + { + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: need to pass non-param values\n"); + return; + } + + /* When there are non-ssa vars used in the split region, see if they + are used in the header region. If so, reject the split. + FIXME: we can use nested function support to access both. */ + if (!bitmap_empty_p (non_ssa_vars)) + { + basic_block bb; + FOR_EACH_BB (bb) + { + gimple_stmt_iterator bsi; + if (!bitmap_bit_p (current->split_bbs, bb->index)) + continue; + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + if (is_gimple_debug (gsi_stmt (bsi))) + continue; + if (walk_stmt_load_store_addr_ops + (gsi_stmt (bsi), non_ssa_vars, test_nonssa_use, + test_nonssa_use, test_nonssa_use)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: split part has non-ssa uses\n"); + return; + } + } + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + if (walk_stmt_load_store_addr_ops + (gsi_stmt (bsi), non_ssa_vars, test_nonssa_use, + test_nonssa_use, test_nonssa_use)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: split part has non-ssa uses\n"); + return; + } + } + FOR_EACH_EDGE (e, ei, bb->succs) + { + if (e->dest != return_bb) + continue; + for (bsi = gsi_start_phis (return_bb); !gsi_end_p (bsi); + gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + tree op = gimple_phi_arg_def (stmt, e->dest_idx); + + if (!is_gimple_reg (gimple_phi_result (stmt))) + continue; + if (TREE_CODE (op) != SSA_NAME + && test_nonssa_use (stmt, op, non_ssa_vars)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: split part has non-ssa uses\n"); + return; + } + } + } + } + return; + } + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Accepted!\n"); + + /* At the moment chose split point with lowest frequency and that leaves + out smallest size of header. + In future we might re-consider this heuristics. */ + if (!best_split_point.split_bbs + || best_split_point.entry_bb->frequency > current->entry_bb->frequency + || (best_split_point.entry_bb->frequency == current->entry_bb->frequency + && best_split_point.split_size < current->split_size)) + + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " New best split point!\n"); + if (best_split_point.ssa_names_to_pass) + { + BITMAP_FREE (best_split_point.ssa_names_to_pass); + BITMAP_FREE (best_split_point.split_bbs); + } + best_split_point = *current; + best_split_point.ssa_names_to_pass = BITMAP_ALLOC (NULL); + bitmap_copy (best_split_point.ssa_names_to_pass, + current->ssa_names_to_pass); + best_split_point.split_bbs = BITMAP_ALLOC (NULL); + bitmap_copy (best_split_point.split_bbs, current->split_bbs); + } +} + +/* Return basic block containing RETURN statement, or EXIT_BLOCK_PTR if none + found. + When there are multiple RETURN statement, chose one with return value, + since that one is more likely shared by multiple code paths. + TODO: We might support multiple return blocks. */ + +static basic_block +find_return_bb (void) +{ + edge e; + edge_iterator ei; + basic_block return_bb = EXIT_BLOCK_PTR; + + if (EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 1) + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) + { + gimple_stmt_iterator bsi; + bool found_return = false; + tree retval = NULL_TREE; + + for (bsi = gsi_start_bb (e->src); !gsi_end_p (bsi); gsi_next (&bsi)) + if (gimple_code (gsi_stmt (bsi)) != GIMPLE_RETURN + && gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL + && !is_gimple_debug (gsi_stmt (bsi))) + break; + else if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN) + { + found_return = true; + retval = gimple_return_retval (gsi_stmt (bsi)); + } + if (gsi_end_p (bsi) && found_return) + { + if (retval) + return e->src; + else + return_bb = e->src; + } + } + return return_bb; +} + +/* Callback for walk_stmt_load_store_addr_ops. If T is non-ssa automatic + variable, mark it as used in bitmap passed via DATA. + Return true when access to T prevents splitting the function. */ + +static bool +mark_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, + void *data ATTRIBUTE_UNUSED) +{ + t = get_base_address (t); + + if (!t || is_gimple_reg (t)) + return false; + + /* At present we can't pass non-SSA arguments to split function. + FIXME: this can be relaxed by passing references to arguments. */ + if (TREE_CODE (t) == PARM_DECL) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Can not split use of non-ssa function parameter.\n"); + return true; + } + + if (TREE_CODE (t) == VAR_DECL && auto_var_in_fn_p (t, current_function_decl)) + bitmap_set_bit ((bitmap)data, DECL_UID (t)); + return false; +} + +/* Compute local properties of basic block BB we collect when looking for + split points. We look for ssa defs and store them in SET_SSA_NAMES, + for ssa uses and store them in USED_SSA_NAMES and for any non-SSA automatic + vars stored in NON_SSA_VARS. + + When BB has edge to RETURN_BB, collect uses in RETURN_BB too. + + Return false when BB contains something that prevents it from being put into + split function. */ + +static bool +visit_bb (basic_block bb, basic_block return_bb, + bitmap set_ssa_names, bitmap used_ssa_names, + bitmap non_ssa_vars) +{ + gimple_stmt_iterator bsi; + edge e; + edge_iterator ei; + bool can_split = true; + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + tree op; + ssa_op_iter iter; + tree decl; + + if (is_gimple_debug (stmt)) + continue; + + /* FIXME: We can split regions containing EH. We can not however + split RESX, EH_DISPATCH and EH_POINTER referring to same region + into different partitions. This would require tracking of + EH regions and checking in consider_split_point if they + are not used elsewhere. */ + if (gimple_code (stmt) == GIMPLE_RESX + && stmt_can_throw_external (stmt)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Can not split external resx.\n"); + can_split = false; + } + if (gimple_code (stmt) == GIMPLE_EH_DISPATCH) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Can not split eh dispatch.\n"); + can_split = false; + } + + /* Check builtins that prevent splitting. */ + if (gimple_code (stmt) == GIMPLE_CALL + && (decl = gimple_call_fndecl (stmt)) != NULL_TREE + && DECL_BUILT_IN (decl) + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) + switch (DECL_FUNCTION_CODE (decl)) + { + /* FIXME: once we will allow passing non-parm values to split part, + we need to be sure to handle correct builtin_stack_save and + builtin_stack_restore. At the moment we are safe; there is no + way to store builtin_stack_save result in non-SSA variable + since all calls to those are compiler generated. */ + case BUILT_IN_APPLY: + case BUILT_IN_VA_START: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Can not split builtin_apply and va_start.\n"); + can_split = false; + break; + case BUILT_IN_EH_POINTER: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Can not split builtin_eh_pointer.\n"); + can_split = false; + break; + default: + break; + } + + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF) + bitmap_set_bit (set_ssa_names, SSA_NAME_VERSION (op)); + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op)); + can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars, + mark_nonssa_use, + mark_nonssa_use, + mark_nonssa_use); + } + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + unsigned int i; + + if (is_gimple_debug (stmt)) + continue; + if (!is_gimple_reg (gimple_phi_result (stmt))) + continue; + bitmap_set_bit (set_ssa_names, + SSA_NAME_VERSION (gimple_phi_result (stmt))); + for (i = 0; i < gimple_phi_num_args (stmt); i++) + { + tree op = gimple_phi_arg_def (stmt, i); + if (TREE_CODE (op) == SSA_NAME) + bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op)); + } + can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars, + mark_nonssa_use, + mark_nonssa_use, + mark_nonssa_use); + } + /* Record also uses comming from PHI operand in return BB. */ + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->dest == return_bb) + { + bool found_phi = false; + for (bsi = gsi_start_phis (return_bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + gimple stmt = gsi_stmt (bsi); + tree op = gimple_phi_arg_def (stmt, e->dest_idx); + + if (is_gimple_debug (stmt)) + continue; + if (!is_gimple_reg (gimple_phi_result (stmt))) + continue; + found_phi = true; + if (TREE_CODE (op) == SSA_NAME) + bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op)); + else + can_split &= !mark_nonssa_use (stmt, op, non_ssa_vars); + } + if (!gsi_end_p (gsi_last_bb (return_bb))) + { + ssa_op_iter iter; + gimple stmt = gsi_stmt (gsi_last_bb (return_bb)); + tree op; + if (!found_phi) + FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) + bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op)); + can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars, + mark_nonssa_use, + mark_nonssa_use, + mark_nonssa_use); + } + } + return can_split; +} + +/* Stack entry for recursive DFS walk in find_split_point. */ + +typedef struct +{ + /* Basic block we are examining. */ + basic_block bb; + + /* SSA names set and used by the BB and all BBs reachable + from it via DFS walk. */ + bitmap set_ssa_names, used_ssa_names; + bitmap non_ssa_vars; + + /* All BBS visited from this BB via DFS walk. */ + bitmap bbs_visited; + + /* Last examined edge in DFS walk. Since we walk unoriented graph, + the value is up to sum of incomming and outgoing edges of BB. */ + unsigned int edge_num; + + /* Stack entry index of earliest BB reachable from current BB + or any BB visited later in DFS valk. */ + int earliest; + + /* Overall time and size of all BBs reached from this BB in DFS walk. */ + int overall_time, overall_size; + + /* When false we can not split on this BB. */ + bool can_split; +} stack_entry; +DEF_VEC_O(stack_entry); +DEF_VEC_ALLOC_O(stack_entry,heap); + + +/* Find all articulations and call consider_split on them. + OVERALL_TIME and OVERALL_SIZE is time and size of the function. + + We perform basic algorithm for finding an articulation in a graph + created from CFG by considering it to be an unoriented graph. + + The articulation is discovered via DFS walk. We collect earliest + basic block on stack that is reachable via backward edge. Articulation + is any basic block such that there is no backward edge bypassing it. + To reduce stack usage we maintain heap allocated stack in STACK vector. + AUX pointer of BB is set to index it appears in the stack or -1 once + it is visited and popped off the stack. + + The algorithm finds articulation after visiting the whole component + reachable by it. This makes it convenient to collect information about + the component used by consider_split. */ + +static void +find_split_points (int overall_time, int overall_size) +{ + stack_entry first; + VEC(stack_entry, heap) *stack = NULL; + basic_block bb; + basic_block return_bb = find_return_bb (); + struct split_point current; + + current.header_time = overall_time; + current.header_size = overall_size; + current.split_time = 0; + current.split_size = 0; + current.ssa_names_to_pass = BITMAP_ALLOC (NULL); + + first.bb = ENTRY_BLOCK_PTR; + first.edge_num = 0; + first.overall_time = 0; + first.overall_size = 0; + first.earliest = INT_MAX; + first.set_ssa_names = 0; + first.used_ssa_names = 0; + first.bbs_visited = 0; + VEC_safe_push (stack_entry, heap, stack, &first); + ENTRY_BLOCK_PTR->aux = (void *)(intptr_t)-1; + + while (!VEC_empty (stack_entry, stack)) + { + stack_entry *entry = VEC_last (stack_entry, stack); + + /* We are walking an acyclic graph, so edge_num counts + succ and pred edges together. However when considering + articulation, we want to have processed everything reachable + from articulation but nothing that reaches into it. */ + if (entry->edge_num == EDGE_COUNT (entry->bb->succs) + && entry->bb != ENTRY_BLOCK_PTR) + { + int pos = VEC_length (stack_entry, stack); + entry->can_split &= visit_bb (entry->bb, return_bb, + entry->set_ssa_names, + entry->used_ssa_names, + entry->non_ssa_vars); + if (pos <= entry->earliest && !entry->can_split + && dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "found articulation at bb %i but can not split\n", + entry->bb->index); + if (pos <= entry->earliest && entry->can_split) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "found articulation at bb %i\n", + entry->bb->index); + current.entry_bb = entry->bb; + current.ssa_names_to_pass = BITMAP_ALLOC (NULL); + bitmap_and_compl (current.ssa_names_to_pass, + entry->used_ssa_names, entry->set_ssa_names); + current.header_time = overall_time - entry->overall_time; + current.header_size = overall_size - entry->overall_size; + current.split_time = entry->overall_time; + current.split_size = entry->overall_size; + current.split_bbs = entry->bbs_visited; + consider_split (¤t, entry->non_ssa_vars, return_bb); + BITMAP_FREE (current.ssa_names_to_pass); + } + } + /* Do actual DFS walk. */ + if (entry->edge_num + < (EDGE_COUNT (entry->bb->succs) + + EDGE_COUNT (entry->bb->preds))) + { + edge e; + basic_block dest; + if (entry->edge_num < EDGE_COUNT (entry->bb->succs)) + { + e = EDGE_SUCC (entry->bb, entry->edge_num); + dest = e->dest; + } + else + { + e = EDGE_PRED (entry->bb, entry->edge_num + - EDGE_COUNT (entry->bb->succs)); + dest = e->src; + } + + entry->edge_num++; + + /* New BB to visit, push it to the stack. */ + if (dest != return_bb && dest != EXIT_BLOCK_PTR + && !dest->aux) + { + stack_entry new_entry; + + new_entry.bb = dest; + new_entry.edge_num = 0; + new_entry.overall_time + = VEC_index (bb_info, bb_info_vec, dest->index)->time; + new_entry.overall_size + = VEC_index (bb_info, bb_info_vec, dest->index)->size; + new_entry.earliest = INT_MAX; + new_entry.set_ssa_names = BITMAP_ALLOC (NULL); + new_entry.used_ssa_names = BITMAP_ALLOC (NULL); + new_entry.bbs_visited = BITMAP_ALLOC (NULL); + new_entry.non_ssa_vars = BITMAP_ALLOC (NULL); + new_entry.can_split = true; + bitmap_set_bit (new_entry.bbs_visited, dest->index); + VEC_safe_push (stack_entry, heap, stack, &new_entry); + dest->aux = (void *)(intptr_t)VEC_length (stack_entry, stack); + } + /* Back edge found, record the earliest point. */ + else if ((intptr_t)dest->aux > 0 + && (intptr_t)dest->aux < entry->earliest) + entry->earliest = (intptr_t)dest->aux; + } + /* We are done with examing the edges. pop off the value from stack and + merge stuff we cummulate during the walk. */ + else if (entry->bb != ENTRY_BLOCK_PTR) + { + stack_entry *prev = VEC_index (stack_entry, stack, + VEC_length (stack_entry, stack) - 2); + + entry->bb->aux = (void *)(intptr_t)-1; + prev->can_split &= entry->can_split; + if (prev->set_ssa_names) + { + bitmap_ior_into (prev->set_ssa_names, entry->set_ssa_names); + bitmap_ior_into (prev->used_ssa_names, entry->used_ssa_names); + bitmap_ior_into (prev->bbs_visited, entry->bbs_visited); + bitmap_ior_into (prev->non_ssa_vars, entry->non_ssa_vars); + } + if (prev->earliest > entry->earliest) + prev->earliest = entry->earliest; + prev->overall_time += entry->overall_time; + prev->overall_size += entry->overall_size; + BITMAP_FREE (entry->set_ssa_names); + BITMAP_FREE (entry->used_ssa_names); + BITMAP_FREE (entry->bbs_visited); + BITMAP_FREE (entry->non_ssa_vars); + VEC_pop (stack_entry, stack); + } + else + VEC_pop (stack_entry, stack); + } + ENTRY_BLOCK_PTR->aux = NULL; + FOR_EACH_BB (bb) + bb->aux = NULL; + BITMAP_FREE (current.ssa_names_to_pass); +} + +/* Split function at SPLIT_POINT. */ + +static void +split_function (struct split_point *split_point) +{ + VEC (tree, heap) *args_to_pass = NULL; + bitmap args_to_skip = BITMAP_ALLOC (NULL); + tree parm; + int num = 0; + struct cgraph_node *node; + basic_block return_bb = find_return_bb (); + basic_block call_bb; + gimple_stmt_iterator gsi; + gimple call; + edge e; + edge_iterator ei; + tree retval = NULL, real_retval = NULL; + bool split_part_return_p = false; + gimple last_stmt = NULL; + + if (dump_file) + { + fprintf (dump_file, "\n\nSplitting function at:\n"); + dump_split_point (dump_file, split_point); + } + + /* Collect the parameters of new function and args_to_skip bitmap. */ + for (parm = DECL_ARGUMENTS (current_function_decl); + parm; parm = TREE_CHAIN (parm), num++) + if (!is_gimple_reg (parm) + || !gimple_default_def (cfun, parm) + || !bitmap_bit_p (split_point->ssa_names_to_pass, + SSA_NAME_VERSION (gimple_default_def (cfun, parm)))) + bitmap_set_bit (args_to_skip, num); + else + VEC_safe_push (tree, heap, args_to_pass, gimple_default_def (cfun, parm)); + + /* See if the split function will return. */ + FOR_EACH_EDGE (e, ei, return_bb->preds) + if (bitmap_bit_p (split_point->split_bbs, e->src->index)) + break; + if (e) + split_part_return_p = true; + + /* If we return, we will need the return block. */ + if (return_bb != EXIT_BLOCK_PTR && split_part_return_p) + bitmap_set_bit (split_point->split_bbs, return_bb->index); + + /* Now create the actual clone. */ + rebuild_cgraph_edges (); + node = cgraph_function_versioning (cgraph_node (current_function_decl), + NULL, NULL, + args_to_skip, + split_point->split_bbs, + split_point->entry_bb, "_part"); + /* For usual cloning it is enough to clear builtin only when signature + changes. For partial inlining we however can not expect the part + of builtin implementation to have same semantic as the whole. */ + if (DECL_BUILT_IN (node->decl)) + { + DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; + DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; + } + cgraph_node_remove_callees (cgraph_node (current_function_decl)); + if (!split_part_return_p) + TREE_THIS_VOLATILE (node->decl) = 1; + if (dump_file) + dump_function_to_file (node->decl, dump_file, dump_flags); + + /* Create the basic block we place call into. It is the entry basic block + split after last label. */ + call_bb = split_point->entry_bb; + for (gsi = gsi_start_bb (call_bb); !gsi_end_p (gsi);) + if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL) + { + last_stmt = gsi_stmt (gsi); + gsi_next (&gsi); + } + else + break; + e = split_block (split_point->entry_bb, last_stmt); + remove_edge (e); + + /* Produce the call statement. */ + gsi = gsi_last_bb (call_bb); + call = gimple_build_call_vec (node->decl, args_to_pass); + gimple_set_block (call, DECL_INITIAL (current_function_decl)); + + /* Update return value. This is bit tricky. When we do not return, + do nothing. When we return we might need to update return_bb + or produce a new return statement. */ + if (!split_part_return_p) + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + else + { + e = make_edge (call_bb, return_bb, + return_bb == EXIT_BLOCK_PTR ? 0 : EDGE_FALLTHRU); + e->count = call_bb->count; + e->probability = REG_BR_PROB_BASE; + if (return_bb != EXIT_BLOCK_PTR) + { + gimple return_stmt = gsi_stmt (gsi_last_bb (return_bb)); + gcc_assert (gimple_code (return_stmt) == GIMPLE_RETURN); + + if ((real_retval = retval = gimple_return_retval (return_stmt)) + && !is_gimple_min_invariant (retval) + && (TREE_CODE (retval) != SSA_NAME + || !SSA_NAME_IS_DEFAULT_DEF (retval))) + { + gimple_stmt_iterator psi; + + /* See if there is PHI definind return value. */ + for (psi = gsi_start_phis (return_bb); + !gsi_end_p (psi); gsi_next (&psi)) + if (is_gimple_reg (gimple_phi_result (gsi_stmt (psi)))) + break; + + /* When we have PHI, update PHI. When there is no PHI, + update the return statement itself. */ + if (TREE_CODE (retval) == SSA_NAME) + { + retval = make_ssa_name (SSA_NAME_VAR (retval), call); + if (TREE_CODE (retval) == SSA_NAME + && !gsi_end_p (psi)) + add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION); + else if (TREE_CODE (retval) == SSA_NAME) + { + gimple_return_set_retval (return_stmt, retval); + update_stmt (return_stmt); + } + } + gimple_call_set_lhs (call, retval); + } + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + } + else + { + gimple ret; + if (!VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))) + { + retval + = create_tmp_var (TREE_TYPE (TREE_TYPE (current_function_decl)), + "RET"); + if (is_gimple_reg (retval)) + retval = make_ssa_name (retval, call); + gimple_call_set_lhs (call, retval); + } + gsi_insert_after (&gsi, call, GSI_NEW_STMT); + ret = gimple_build_return (retval); + gsi_insert_after (&gsi, ret, GSI_NEW_STMT); + } + } + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + compute_inline_parameters (node); +} + +/* Execute function splitting pass. */ + +static unsigned int +execute_split_functions (void) +{ + gimple_stmt_iterator bsi; + basic_block bb; + int overall_time = 0, overall_size = 0; + int todo = 0; + struct cgraph_node *node = cgraph_node (current_function_decl); + + if (flags_from_decl_or_type (current_function_decl) & ECF_NORETURN) + { + if (dump_file) + fprintf (dump_file, "Not splitting: noreturn function.\n"); + return 0; + } + if (MAIN_NAME_P (DECL_NAME (current_function_decl))) + { + if (dump_file) + fprintf (dump_file, "Not splitting: main function.\n"); + return 0; + } + /* This can be relaxed; function might become inlinable after splitting + away the uninlinable part. */ + if (!node->local.inlinable) + { + if (dump_file) + fprintf (dump_file, "Not splitting: not inlinable.\n"); + return 0; + } + if (node->local.disregard_inline_limits) + { + if (dump_file) + fprintf (dump_file, "Not splitting: disregading inline limits.\n"); + return 0; + } + /* This can be relaxed; most of versioning tests actually prevents + a duplication. */ + if (!tree_versionable_function_p (current_function_decl)) + { + if (dump_file) + fprintf (dump_file, "Not splitting: not versionable.\n"); + return 0; + } + /* FIXME: we could support this. */ + if (DECL_STRUCT_FUNCTION (current_function_decl)->static_chain_decl) + { + if (dump_file) + fprintf (dump_file, "Not splitting: nested function.\n"); + return 0; + } + /* FIXME: Should be easy to support. */ + if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) + { + if (dump_file) + fprintf (dump_file, "Not splitting: returns value by reference.\n"); + return 0; + } + + /* See if it makes sense to try to split. + It makes sense to split if we inline, that is if we have direct calls to + handle or direct calls are possibly going to appear as result of indirect + inlining or LTO. + Note that we are not completely conservative about disqualifying functions + called once. It is possible that the caller is called more then once and + then inlining would still benefit. */ + if ((!node->callers || !node->callers->next_caller) + && !node->address_taken + && ((!flag_lto && !flag_whopr) || !node->local.externally_visible)) + { + if (dump_file) + fprintf (dump_file, "Not splitting: not called directly " + "or called once.\n"); + return 0; + } + + /* FIXME: We can actually split if splitting reduces call overhead. */ + if (!flag_inline_small_functions + && !DECL_DECLARED_INLINE_P (current_function_decl)) + { + if (dump_file) + fprintf (dump_file, "Not splitting: not autoinlining and function" + " is not inline.\n"); + return 0; + } + + /* Compute local info about basic blocks and determine function size/time. */ + VEC_safe_grow_cleared (bb_info, heap, bb_info_vec, last_basic_block + 1); + memset (&best_split_point, 0, sizeof (best_split_point)); + FOR_EACH_BB (bb) + { + int time = 0; + int size = 0; + int freq = compute_call_stmt_bb_frequency (current_function_decl, bb); + + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Basic block %i\n", bb->index); + + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + int this_time, this_size; + gimple stmt = gsi_stmt (bsi); + + this_size = estimate_num_insns (stmt, &eni_size_weights); + this_time = estimate_num_insns (stmt, &eni_time_weights) * freq; + size += this_size; + time += this_time; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " freq:%6i size:%3i time:%3i ", + freq, this_size, this_time); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + } + overall_time += time; + overall_size += size; + VEC_index (bb_info, bb_info_vec, bb->index)->time = time; + VEC_index (bb_info, bb_info_vec, bb->index)->size = size; + } + find_split_points (overall_time, overall_size); + if (best_split_point.split_bbs) + { + split_function (&best_split_point); + BITMAP_FREE (best_split_point.ssa_names_to_pass); + BITMAP_FREE (best_split_point.split_bbs); + todo = TODO_update_ssa | TODO_cleanup_cfg; + } + VEC_free (bb_info, heap, bb_info_vec); + bb_info_vec = NULL; + return todo; +} + +static bool +gate_split_functions (void) +{ + return flag_partial_inlining; +} + +struct gimple_opt_pass pass_split_functions = +{ + { + GIMPLE_PASS, + "fnsplit", /* name */ + gate_split_functions, /* gate */ + execute_split_functions, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IPA_FNSPLIT, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func /* todo_flags_finish */ + } +}; diff --git a/gcc/ipa.c b/gcc/ipa.c index 0cf2987427c..05e164271db 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -576,6 +576,8 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program) return false; if (!whole_program) return true; + if (node->local.used_from_object_file) + return true; if (DECL_PRESERVE_P (node->decl)) return true; /* COMDAT functions must be shared only if they have address taken, @@ -729,6 +731,7 @@ function_and_variable_visibility (bool whole_program) we start reordering datastructures. */ || DECL_COMDAT (vnode->decl) || DECL_WEAK (vnode->decl) + || vnode->used_from_object_file || lookup_attribute ("externally_visible", DECL_ATTRIBUTES (vnode->decl)))) vnode->externally_visible = true; diff --git a/gcc/ira-int.h b/gcc/ira-int.h index fd5ffb8cae4..1da087cecdb 100644 --- a/gcc/ira-int.h +++ b/gcc/ira-int.h @@ -724,7 +724,7 @@ minmax_set_iter_next (minmax_set_iterator *i) extern HARD_REG_SET ira_reg_mode_hard_regset [FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES]; -/* Array analogous to macro REGISTER_MOVE_COST. Don't use +/* Array based on TARGET_REGISTER_MOVE_COST. Don't use ira_register_move_cost directly. Use function of ira_get_may_move_cost instead. */ extern move_table *ira_register_move_cost[MAX_MACHINE_MODE]; diff --git a/gcc/ira.c b/gcc/ira.c index a2e8c384e2b..7f4c8d8c72d 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -358,7 +358,7 @@ HARD_REG_SET ira_reg_mode_hard_regset[FIRST_PSEUDO_REGISTER][NUM_MACHINE_MODES]; /* Array analogous to target hook TARGET_MEMORY_MOVE_COST. */ short int ira_memory_move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][2]; -/* Array analogous to macro REGISTER_MOVE_COST. */ +/* Array based on TARGET_REGISTER_MOVE_COST. */ move_table *ira_register_move_cost[MAX_MACHINE_MODE]; /* Similar to may_move_in_cost but it is calculated in IRA instead of diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index e1135318f1b..0d50a7f4439 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,12 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * lang.c: Do not include except.h + * except.c: Likewise. + (doing_eh): New, moved from except.c (in gcc/) but removed the + do_warning flag. + (maybe_start_try): Update doing_eh call. + * Make-lang.in: Update dependencies. + 2010-06-23 Anatoly Sokolov <aesok@post.ru> * decl.c (java_init_decl_processing): Use double_int_to_tree instead diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index 26a81bab79a..5e240ed0743 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -285,7 +285,7 @@ java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \ libfuncs.h java/java-except.h $(GGC_H) $(REAL_H) gt-java-decl.h \ $(TARGET_H) $(CGRAPH_H) langhooks.h java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h $(REAL_H) \ - java/javaop.h java/java-opcodes.h except.h java/java-except.h \ + java/javaop.h java/java-opcodes.h java/java-except.h \ toplev.h $(SYSTEM_H) coretypes.h java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h $(REAL_H) \ java/javaop.h java/java-opcodes.h \ @@ -302,7 +302,7 @@ java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H) \ coretypes.h $(TM_H) intl.h java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \ toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(DIAGNOSTIC_H) \ - langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h $(EXCEPT_H) + langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \ coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H) java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \ diff --git a/gcc/java/except.c b/gcc/java/except.c index f5a64071204..2c3aead1a4c 100644 --- a/gcc/java/except.c +++ b/gcc/java/except.c @@ -31,7 +31,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "javaop.h" #include "java-opcodes.h" #include "jcf.h" -#include "except.h" /* for doing_eh. */ #include "java-except.h" #include "toplev.h" #include "tree-iterator.h" @@ -565,6 +564,29 @@ check_start_handlers (struct eh_range *range, int pc) } +/* Routine to see if exception handling is turned on. + DO_WARN is nonzero if we want to inform the user that exception + handling is turned off. + + This is used to ensure that -fexceptions has been specified if the + compiler tries to use any exception-specific functions. */ + +static inline int +doing_eh (void) +{ + if (! flag_exceptions) + { + static int warned = 0; + if (! warned) + { + error ("exception handling disabled, use -fexceptions to enable"); + warned = 1; + } + return 0; + } + return 1; +} + static struct eh_range *current_range; /* Emit any start-of-try-range starting at start_pc and ending after @@ -574,7 +596,7 @@ void maybe_start_try (int start_pc, int end_pc) { struct eh_range *range; - if (! doing_eh (1)) + if (! doing_eh ()) return; range = find_handler (start_pc); diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 351952de1a6..6c31947c6a4 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -43,7 +43,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "tree-dump.h" #include "opts.h" #include "options.h" -#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */ static bool java_init (void); static void java_finish (void); diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 92755e24880..68085c72c9e 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -110,6 +110,7 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, #define LANG_HOOKS_INIT_TS lhd_do_nothing #define LANG_HOOKS_EH_PERSONALITY lhd_gcc_personality #define LANG_HOOKS_EH_RUNTIME_TYPE lhd_pass_through_t +#define LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS NULL #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false #define LANG_HOOKS_DEEP_UNSHARING false @@ -299,6 +300,7 @@ extern void lhd_end_section (void); LANG_HOOKS_EXPR_TO_DECL, \ LANG_HOOKS_EH_PERSONALITY, \ LANG_HOOKS_EH_RUNTIME_TYPE, \ + LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \ LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \ LANG_HOOKS_DEEP_UNSHARING \ } diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 535529a08f0..483a8dcdd77 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -446,6 +446,14 @@ struct lang_hooks /* Map a type to a runtime object to match type. */ tree (*eh_runtime_type) (tree); + /* If non-NULL, this is a function that returns a function decl to be + executed if an unhandled exception is propagated out of a cleanup + region. For example, in C++, an exception thrown by a destructor + during stack unwinding is required to result in a call to + `std::terminate', so the C++ version of this function returns a + FUNCTION_DECL for `std::terminate'. */ + tree (*eh_protect_cleanup_actions) (void); + /* True if this language uses __cxa_end_cleanup when the ARM EABI is enabled. */ bool eh_use_cxa_end_cleanup; diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index 6f46a733b42..e94bc204b22 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -530,11 +530,20 @@ lto_symtab_resolve_symbols (void **slot) return; found: - if (TREE_CODE (prevailing->decl) == VAR_DECL - && TREE_READONLY (prevailing->decl)) + /* If current lto files represent the whole program, + it is correct to use LDPR_PREVALING_DEF_IRONLY. + If current lto files are part of whole program, internal + resolver doesn't know if it is LDPR_PREVAILING_DEF + or LDPR_PREVAILING_DEF_IRONLY. Use IRONLY conforms to + using -fwhole-program. Otherwise, it doesn't + matter using either LDPR_PREVAILING_DEF or + LDPR_PREVAILING_DEF_IRONLY + + FIXME: above workaround due to gold plugin makes some + variables IRONLY, which are indeed PREVAILING_DEF in + resolution file. These variables still need manual + externally_visible attribute. */ prevailing->resolution = LDPR_PREVAILING_DEF_IRONLY; - else - prevailing->resolution = LDPR_PREVAILING_DEF; } /* Merge all decls in the symbol table chain to the prevailing decl and @@ -698,6 +707,24 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED) && TREE_CODE (prevailing->decl) != VAR_DECL) prevailing->next = NULL; + /* Set externally_visible flags for declaration of LDPR_PREVAILING_DEF */ + if (flag_whole_program) + { + if (prevailing->resolution == LDPR_PREVAILING_DEF) + { + if (TREE_CODE (prevailing->decl) == FUNCTION_DECL) + prevailing->node->local.used_from_object_file = true; + else + prevailing->vnode->used_from_object_file = true; + } + else if (prevailing->resolution == LDPR_PREVAILING_DEF_IRONLY) + { + if (TREE_CODE (prevailing->decl) == FUNCTION_DECL) + prevailing->node->local.used_from_object_file = false; + else + prevailing->vnode->used_from_object_file = false; + } + } return 1; } diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index a05a140c7cb..099bc6595ac 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,7 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * objc-act.c: Do not include except.h. + 2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com> * objc-act.h (ALLOC_OBJC_TYPE_LANG_SPECIFIC): Use typed GC diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 2ec9ca04009..45b10207629 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -59,7 +59,6 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "objc-act.h" #include "input.h" -#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */ #include "function.h" #include "output.h" #include "toplev.h" diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog index cfb27f413cd..109d2327ed6 100644 --- a/gcc/objcp/ChangeLog +++ b/gcc/objcp/ChangeLog @@ -1,3 +1,8 @@ +2010-06-28 Steven Bosscher <steven@gcc.gnu.org> + + * objcp-lang.c: Do not include except.h. + * Make-lang.in: Update dependencies. + 2010-06-25 Joseph Myers <joseph@codesourcery.com> * lang-specs.h: Remove +e handling. diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in index 873b9080ebf..22dc30f366e 100644 --- a/gcc/objcp/Make-lang.in +++ b/gcc/objcp/Make-lang.in @@ -73,7 +73,7 @@ cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS) objcp/objcp-lang.o : objcp/objcp-lang.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) \ $(C_COMMON_H) $(LANGHOOKS_DEF_H) objc/objc-act.h cp/cp-objcp-common.h \ - gtype-objcp.h $(EXCEPT_H) + gtype-objcp.h objcp/objcp-decl.o : objcp/objcp-decl.c \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) \ diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c index 91e5c7e693c..70a605bb87e 100644 --- a/gcc/objcp/objcp-lang.c +++ b/gcc/objcp/objcp-lang.c @@ -30,7 +30,6 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "langhooks-def.h" #include "cp-objcp-common.h" -#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */ enum c_language_kind c_language = clk_objcxx; static void objcxx_init_ts (void); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 79b969f8f8b..68bc84a881c 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3123,8 +3123,8 @@ maybe_catch_exception (gimple_seq body) if (!flag_exceptions) return body; - if (lang_protect_cleanup_actions) - decl = lang_protect_cleanup_actions (); + if (lang_hooks.eh_protect_cleanup_actions != NULL) + decl = lang_hooks.eh_protect_cleanup_actions (); else decl = built_in_decls[BUILT_IN_TRAP]; diff --git a/gcc/opts.c b/gcc/opts.c index 55f8c77d7f1..c30ff2ea4fc 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -825,6 +825,7 @@ decode_options (unsigned int argc, const char **argv, opt2 = (optimize >= 2); flag_inline_small_functions = opt2; flag_indirect_inlining = opt2; + flag_partial_inlining = opt2; flag_thread_jumps = opt2; flag_crossjumping = opt2; flag_optimize_sibling_calls = opt2; diff --git a/gcc/params.def b/gcc/params.def index 35650ff91b7..767ecd9e512 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -78,11 +78,11 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, that is applied to functions marked inlined (or defined in the class declaration in C++) given by the "max-inline-insns-single" parameter. - The default value is 90. */ + The default value is 40. */ DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, "max-inline-insns-auto", "The maximum number of instructions when automatically inlining", - 50, 0, 0) + 40, 0, 0) DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE, "max-inline-insns-recursive", @@ -117,6 +117,12 @@ DEFPARAM (PARAM_EARLY_INLINER_MAX_ITERATIONS, "The maximum number of nested indirect inlining performed by early inliner", 10, 0, 0) +/* Limit on probability of entry BB. */ +DEFPARAM (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY, + "partial-inlining-entry-probability", + "Maximum probability of the entry BB of split region (in percent relative to entry BB of the function) to make partial inlining happen", + 70, 0, 0) + /* Limit the number of expansions created by the variable expansion optimization to avoid register pressure. */ DEFPARAM (PARAM_MAX_VARIABLE_EXPANSIONS, diff --git a/gcc/passes.c b/gcc/passes.c index c58a300a49b..03de5810fb4 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -795,6 +795,10 @@ init_optimization_passes (void) NEXT_PASS (pass_cleanup_eh); NEXT_PASS (pass_profile); NEXT_PASS (pass_local_pure_const); + /* Split functions creates parts that are not run through + early optimizations again. It is thus good idea to do this + late. */ + NEXT_PASS (pass_split_functions); } NEXT_PASS (pass_release_ssa_names); NEXT_PASS (pass_rebuild_cgraph_edges); diff --git a/gcc/postreload.c b/gcc/postreload.c index c165b5245f1..3882719ccd3 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -264,7 +264,7 @@ reload_cse_simplify_set (rtx set, rtx insn) if (MEM_P (src)) old_cost = memory_move_cost (GET_MODE (src), dclass, true); else if (REG_P (src)) - old_cost = REGISTER_MOVE_COST (GET_MODE (src), + old_cost = register_move_cost (GET_MODE (src), REGNO_REG_CLASS (REGNO (src)), dclass); else old_cost = rtx_cost (src, SET, speed); @@ -314,7 +314,7 @@ reload_cse_simplify_set (rtx set, rtx insn) } else #endif - this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx), + this_cost = register_move_cost (GET_MODE (this_rtx), REGNO_REG_CLASS (REGNO (this_rtx)), dclass); } diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 66e774a30c2..b868c37fda8 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -183,7 +183,7 @@ bool have_regs_of_mode [MAX_MACHINE_MODE]; char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE]; /* Maximum cost of moving from a register in one class to a register in - another class. Based on REGISTER_MOVE_COST. */ + another class. Based on TARGET_REGISTER_MOVE_COST. */ move_table *move_cost[MAX_MACHINE_MODE]; /* Similar, but here we don't have to move if the first index is a subset @@ -274,7 +274,7 @@ init_move_cost (enum machine_mode m) cost = 65535; else { - cost = REGISTER_MOVE_COST (m, (enum reg_class) i, + cost = register_move_cost (m, (enum reg_class) i, (enum reg_class) j); gcc_assert (cost < 65535); } @@ -681,6 +681,17 @@ init_fake_stack_mems (void) top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx); } + +/* Compute cost of moving data from a register of class FROM to one of + TO, using MODE. */ + +int +register_move_cost (enum machine_mode mode, enum reg_class from, + enum reg_class to) +{ + return targetm.register_move_cost (mode, from, to); +} + /* Compute cost of moving registers to/from memory. */ int memory_move_cost (enum machine_mode mode, enum reg_class rclass, bool in) @@ -706,9 +717,9 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass, return 0; if (in) - partial_cost = REGISTER_MOVE_COST (mode, altclass, rclass); + partial_cost = register_move_cost (mode, altclass, rclass); else - partial_cost = REGISTER_MOVE_COST (mode, rclass, altclass); + partial_cost = register_move_cost (mode, rclass, altclass); if (rclass == altclass) /* This isn't simply a copy-to-temporary situation. Can't guess diff --git a/gcc/reload.c b/gcc/reload.c index d4b7982bc0a..30bee6db83d 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -688,7 +688,7 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED, if (bad || !good) continue; - cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, dest_class); + cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); if ((reg_class_size[rclass] > best_size && (best_cost < 0 || best_cost >= cost)) @@ -696,7 +696,7 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED, { best_class = (enum reg_class) rclass; best_size = reg_class_size[rclass]; - best_cost = REGISTER_MOVE_COST (outer, (enum reg_class) rclass, + best_cost = register_move_cost (outer, (enum reg_class) rclass, dest_class); } } @@ -2651,7 +2651,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER && REG_P (SET_SRC (body)) && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER - && REGISTER_MOVE_COST (GET_MODE (SET_SRC (body)), + && register_move_cost (GET_MODE (SET_SRC (body)), REGNO_REG_CLASS (REGNO (SET_SRC (body))), REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2) return 0; diff --git a/gcc/reload.h b/gcc/reload.h index 4625bf7fc19..a3c1f07bd9f 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see SECONDARY_RELOAD_CLASS (CLASS, MODE, X) #endif +extern int register_move_cost (enum machine_mode, enum reg_class, + enum reg_class); extern int memory_move_cost (enum machine_mode, enum reg_class, bool); extern int memory_move_secondary_cost (enum machine_mode, enum reg_class, bool); diff --git a/gcc/reload1.c b/gcc/reload1.c index 00d4c99b6c0..a0b61f5b926 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -6496,7 +6496,7 @@ choose_reload_regs (struct insn_chain *chain) register, we might use it for reload_override_in, if copying it to the desired class is cheap enough. */ - || ((REGISTER_MOVE_COST (mode, last_class, rclass) + || ((register_move_cost (mode, last_class, rclass) < memory_move_cost (mode, rclass, true)) && (secondary_reload_class (1, rclass, mode, last_reg) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index be63198e442..3a30e882907 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -208,10 +208,11 @@ avoid_constant_pool_reference (rtx x) rtx delegitimize_mem_from_attrs (rtx x) { + /* MEMs without MEM_OFFSETs may have been offset, so we can't just + use their base addresses as equivalent. */ if (MEM_P (x) && MEM_EXPR (x) - && (!MEM_OFFSET (x) - || GET_CODE (MEM_OFFSET (x)) == CONST_INT)) + && MEM_OFFSET (x)) { tree decl = MEM_EXPR (x); enum machine_mode mode = GET_MODE (x); @@ -264,8 +265,7 @@ delegitimize_mem_from_attrs (rtx x) { rtx newx; - if (MEM_OFFSET (x)) - offset += INTVAL (MEM_OFFSET (x)); + offset += INTVAL (MEM_OFFSET (x)); newx = DECL_RTL (decl); diff --git a/gcc/system.h b/gcc/system.h index 38a7c017af0..af3dd3a64e7 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -769,7 +769,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; ASM_OUTPUT_SHARED_LOCAL ASM_MAKE_LABEL_LINKONCE \ STACK_CHECK_PROBE_INTERVAL STACK_CHECK_PROBE_LOAD \ ORDER_REGS_FOR_LOCAL_ALLOC FUNCTION_OUTGOING_VALUE \ - ASM_DECLARE_CONSTANT_NAME + ASM_DECLARE_CONSTANT_NAME MODIFY_TARGET_NAME SWITCHES_NEED_SPACES /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ @@ -799,7 +799,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; /* Front ends should never have to include middle-end headers. Enforce this by poisoning the header double-include protection defines. */ #ifdef IN_GCC_FRONTEND -#pragma GCC poison GCC_RTL_H +#pragma GCC poison GCC_RTL_H GCC_EXCEPT_H #endif /* Note: not all uses of the `index' token (e.g. variable names and diff --git a/gcc/target-def.h b/gcc/target-def.h index 1aaf38c2e53..27b7fa8e041 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -474,6 +474,10 @@ #define TARGET_ADDRESS_COST default_address_cost #define TARGET_CONST_ANCHOR 0 +#ifndef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST default_register_move_cost +#endif + #ifndef TARGET_MEMORY_MOVE_COST #define TARGET_MEMORY_MOVE_COST default_memory_move_cost #endif @@ -1027,6 +1031,7 @@ TARGET_ADDR_SPACE_HOOKS, \ TARGET_SCALAR_MODE_SUPPORTED_P, \ TARGET_VECTOR_MODE_SUPPORTED_P, \ + TARGET_REGISTER_MOVE_COST, \ TARGET_MEMORY_MOVE_COST, \ TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P, \ TARGET_RTX_COSTS, \ diff --git a/gcc/target.h b/gcc/target.h index 2f181eb63c2..5a857d7edf7 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -812,6 +812,11 @@ struct gcc_target for further details. */ bool (* vector_mode_supported_p) (enum machine_mode mode); + /* Compute cost of moving data from a register of class FROM to one of + TO, using MODE. */ + int (* register_move_cost) (enum machine_mode, enum reg_class, + enum reg_class); + /* Compute cost of moving registers to/from memory. */ int (* memory_move_cost) (enum machine_mode, enum reg_class, bool); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 6c1d2588e44..62e357729bb 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1127,4 +1127,19 @@ default_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, #endif } +/* Compute cost of moving data from a register of class FROM to one of + TO, using MODE. */ + +int +default_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED, + enum reg_class from ATTRIBUTE_UNUSED, + enum reg_class to ATTRIBUTE_UNUSED) +{ +#ifndef REGISTER_MOVE_COST + return 2; +#else + return REGISTER_MOVE_COST (mode, from, to); +#endif +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 6e714451686..fdd0e4a3c75 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -140,3 +140,6 @@ extern rtx default_addr_space_convert (rtx, tree, tree); extern unsigned int default_case_values_threshold (void); extern bool default_have_conditional_execution (void); extern int default_memory_move_cost (enum machine_mode, enum reg_class, bool); +extern int default_register_move_cost (enum machine_mode, enum reg_class, + enum reg_class); + diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9a397e2d1ec..be888c89068 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,102 @@ +2010-06-27 Jan Hubicka <jh@suse.cz> + + * gcc.c-torture/compile/pr44686.c: New file. + +2010-06-27 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/44683 + * gcc.c-torture/execute/pr44683.c: New testcase. + +2010-06-27 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/noreturn3.ad[sb]: New test. + +2010-06-26 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp0x/explicit5.C: New. + +2010-06-26 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/44393 + * gcc.dg/pr44393.c: New testcase. + +2010-06-26 Jan Hubicka <jh@suse.cz> + + * gcc.dg/tree-ssa/ipa-split-2.c: New testcase. + +2010-06-26 Richard Guenther <rguenther@suse.de> + + PR middle-end/44674 + * gcc.dg/pr44674.c: New testcase. + +2010-06-26 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/opts-3.c: New test. + +2010-06-26 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/type_decl_1.f90: New. + * gfortran.dg/type_decl_2.f90: New. + +2010-06-26 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/semicolon_fixed.f: Fix dg syntax.. + * gfortran.dg/semicolon_fixed_2.f: Ditto. + +2010-06-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR testsuite/38946 + * gfortran.dg/array_constructor_23.f: Update test to allow for small + error in comparing reals. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * selected_real_kind_2.f90: New. + * selected_real_kind_3.f90: New. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/entry_19.f90: New. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/end_subroutine_1.f90: New. + * gfortran.dg/end_subroutine_2.f90: New. + * gfortran.dg/interface_proc_end.f90: Update. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * gfortran.dg/semicolon_fixed.f: Update. + * gfortran.dg/semicolon_fixed_2.f: New. + * gfortran.dg/semicolon_free_2.f90: New. + * gfortran.dg/semicolon_free.f90: Update. + +2010-06-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR fortran/44448 + * gfortran.dg/atan2_1.f90: Add -ffloat-store. + +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * g++.dg/ipa/iinline-3.C: New test. + * gcc.dg/ipa/modif-1.c: Removed. + +2010-06-25 Jan Hubicka <jh@suse.cz> + + * testsuite/gcc.dg/tree-ssa/ipa-split-1.c + +2010-06-25 Martin Jambor <mjambor@suse.cz> + + * g++.dg/ipa/iinline-2.C: New test. + +2010-06-25 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/43866 + * gfortran.dg/pr43866.f90: New test. + + PR tree-optimization/44539 + * gcc.dg/pr44539.c: New test. + 2010-06-25 Bernd Schmidt <bernds@codesourcery.com> From Jim Wilson: @@ -31,7 +130,7 @@ 2010-06-24 Andi Kleen <ak@linux.intel.com> - * c-c++-common/warn-omitted-condop.c: New. + * c-c++-common/warn-omitted-condop.c: New. 2010-06-24 Tobias Burnus <burnus@net-b.de> diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit5.C b/gcc/testsuite/g++.dg/cpp0x/explicit5.C new file mode 100644 index 00000000000..88a47071db1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit5.C @@ -0,0 +1,25 @@ +// test for extension of DR 899 to handle template ctors +// { dg-options "-std=c++0x" } +// { dg-do run } + +int r = 1; + +struct C { + C() { } + template <class T = int> C(C&, T = 0) { r = 0; } +}; + +C c; + +struct A +{ + explicit operator C&() const { return c; } +}; + +int main() +{ + A a; + C c2 (a); + + return r; +} diff --git a/gcc/testsuite/g++.dg/ipa/iinline-2.C b/gcc/testsuite/g++.dg/ipa/iinline-2.C new file mode 100644 index 00000000000..670a5dd9522 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-2.C @@ -0,0 +1,61 @@ +/* Verify that simple indirect calls are inlined even without early + inlining.. */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern void non_existent (const char *, int); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int delim) const; + int printStuffTwice (int delim) const; +}; + + +int String::funcOne (int delim) const +{ + int i; + for (i = 0; i < delim; i++) + non_existent(data, i); + + return 1; +} + +extern int global; + +int docalling (int c, int (String::* f)(int delim) const) +{ + String S ("muhehehe"); + + if (c > 2) + global = 3; + else + global = 5; + + return (S.*f)(4); +} + +int __attribute__ ((noinline,noclone)) get_input (void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 1000) + i += docalling (get_input (), &String::funcOne); + non_existent ("done", i); + return 0; +} + +/* { dg-final { scan-ipa-dump "String::funcOne\[^\\n\]*inline copy in int main" "inline" } } */ +/* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/iinline-3.C b/gcc/testsuite/g++.dg/ipa/iinline-3.C new file mode 100644 index 00000000000..3daee9a8681 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/iinline-3.C @@ -0,0 +1,64 @@ +/* Verify that we do not indirect-inline using member pointer + parameters which have been modified. */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining" } */ +/* { dg-add-options bind_pic_locally } */ + +extern "C" void abort (void); + +class String +{ +private: + const char *data; + +public: + String (const char *d) : data(d) + {} + + int funcOne (int stuff) const; + int funcTwo (int stuff) const; +}; + + +int String::funcOne (int stuff) const +{ + return stuff + 1; +} + +int String::funcTwo (int stuff) const +{ + return stuff + 100; +} + +int (String::* gmp)(int stuff) const = &String::funcTwo; + +int docalling_1 (int (String::* f)(int stuff) const) +{ + String S ("muhehehe"); + + return (S.*f)(4); +} + +int docalling (int a, int (String::* f)(int stuff) const) +{ + if (a < 200) + f = gmp; + + return docalling_1 (f); +} + +int __attribute__ ((noinline,noclone)) get_input (void) +{ + return 1; +} + +int main (int argc, char *argv[]) +{ + int i = 0; + while (i < 10) + i += docalling (get_input (), &String::funcOne); + + if (i != 104) + abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44686.c b/gcc/testsuite/gcc.c-torture/compile/pr44686.c new file mode 100644 index 00000000000..eacd83d3130 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr44686.c @@ -0,0 +1,7 @@ +/* { dg-options "-O2 -fipa-pta -fprofile-generate" } */ +void * +memcpy (void *a, const void *b, __SIZE_TYPE__ len) +{ + if (a == b) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr44683.c b/gcc/testsuite/gcc.c-torture/execute/pr44683.c new file mode 100644 index 00000000000..d0fd446f004 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr44683.c @@ -0,0 +1,18 @@ +int __attribute__((noinline,noclone)) +copysign_bug (double x) +{ + if (x != 0.0 && (x * 0.5 == x)) + return 1; + if (__builtin_copysign(1.0, x) < 0.0) + return 2; + else + return 3; +} +int main(void) +{ + double x = -0.0; + if (copysign_bug (x) != 2) + __builtin_abort (); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/ipa/modif-1.c b/gcc/testsuite/gcc.dg/ipa/modif-1.c deleted file mode 100644 index db6915a9d9e..00000000000 --- a/gcc/testsuite/gcc.dg/ipa/modif-1.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Verify that modification analysis detects modfications. */ -/* { dg-do compile } */ -/* { dg-options "-O3 -c -fdump-ipa-inline-details -fno-early-inlining" } */ - -struct whatever -{ - int first; - unsigned second; -}; - -void func1 (struct whatever w); -void func2 (struct whatever *pw); -void func3 (int i); -void func4 (int *pi); - -void the_test (struct whatever u, struct whatever v, - struct whatever w, struct whatever x, - int i, int k, int l) -{ - struct whatever *pw = &w; - int *pk = &k; - - v.first = 9; - - func1 (u); - func1 (v); - func2 (pw); - func2 (&x); - func3 (i); - func4 (pk); - func4 (&l); -} - -/* { dg-final { scan-ipa-dump-not "param 0\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump "param 1\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump "param 2\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump "param 3\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump-not "param 4\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump "param 5\[^\\n\]*modified" "inline" } } */ -/* { dg-final { scan-ipa-dump "param 6\[^\\n\]*modified" "inline" } } */ -/* { dg-final { cleanup-ipa-dump "inline" } } */ diff --git a/gcc/testsuite/gcc.dg/opts-3.c b/gcc/testsuite/gcc.dg/opts-3.c new file mode 100644 index 00000000000..50cd1db52d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/opts-3.c @@ -0,0 +1,7 @@ +/* Parameters of -Xassembler should not be interpreted as driver + options (and so cause the driver to exit prematurely, as in this + testcase, or have other unintended effects). */ +/* { dg-do compile } */ +/* { dg-options "-Xassembler -dumpmachine" } */ + +int int x; /* { dg-error "two or more data types" } */ diff --git a/gcc/testsuite/gcc.dg/pr44393.c b/gcc/testsuite/gcc.dg/pr44393.c new file mode 100644 index 00000000000..906d5932a0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr44393.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -ftree-loop-distribution" } */ + +int i; +void foo () +{ + int **pp = 0, *p = 0; + while (--i) + { + *p++ = 0; + *pp++ = p; + } + i = *p; +} + diff --git a/gcc/testsuite/gcc.dg/pr44539.c b/gcc/testsuite/gcc.dg/pr44539.c new file mode 100644 index 00000000000..9cfff7a3ae5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr44539.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/44539 */ +/* { dg-do compile } */ +/* { dg-options "-ftracer -freorder-blocks -O2" } */ + +void bar (int file); +extern int baz (void); + +void noret1 () +{ + bar (0); + __builtin_exit (0); +} + +void noret2 () +{ + __builtin_exit (0); +} + +void bar (int i) +{ + if (baz ()) + noret1 (i); +} + +void foo (int i) +{ + if (~i) bar (i); + i ? noret1 () : noret2 (); +} diff --git a/gcc/testsuite/gcc.dg/pr44674.c b/gcc/testsuite/gcc.dg/pr44674.c new file mode 100644 index 00000000000..c3f16ff20ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr44674.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fprofile-generate" } */ + +void +jumpfunc (void *p) +{ + void *l = &&jumplabel; +jumplabel: + __builtin_memcpy (p, l, 1); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-1.c new file mode 100644 index 00000000000..a31e8ea7a47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-1.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fnsplit" } */ +int test2(a) +{ + if (a<100) + return 1; + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + do_something_big (); + return 0; +} + +test() +{ + test2(10); + test2(20); +} +/* { dg-final { scan-tree-dump-times "Splitting function" 1 "fnsplit"} } */ +/* { dg-final { cleanup-tree-dump "fnsplit" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c new file mode 100644 index 00000000000..bbde73d6c7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fnsplit" } */ +int b; +int c; +int d; +split_me(int a) +{ + int t = 0; + if (d>4) + return; + do + { + long_function (t); + long_function (t); + long_function (t); + long_function (t); + long_function (t); + long_function (t); + make_me_irregular: + long_function (t); + long_function (t); + long_function (t); + long_function (t); + long_function (t); + t=b; + } + while (t); + if (c) + goto make_me_irregular; +} + +main() +{ + split_me (1); + split_me (2); + split_me (3); + split_me (4); + split_me (5); +} +/* { dg-final { scan-tree-dump-times "Splitting function" 1 "fnsplit"} } */ +/* { dg-final { cleanup-tree-dump "fnsplit" } } */ diff --git a/gcc/testsuite/gfortran.dg/array_constructor_23.f b/gcc/testsuite/gfortran.dg/array_constructor_23.f index ac57efc2440..fa0a28a1f17 100644 --- a/gcc/testsuite/gfortran.dg/array_constructor_23.f +++ b/gcc/testsuite/gfortran.dg/array_constructor_23.f @@ -20,7 +20,7 @@ DDA1 = ATAN2 ((/(REAL(J1,KV),J1=1,10)/), $ REAL((/(J1,J1=nf10,nf1,mf1)/), KV)) !fails DDA2 = ATAN2 (DDA, DDA(10:1:-1)) - if (any (DDA1 .ne. DDA2)) call abort () + if (any (DDA1 - DDA2 .gt. epsilon(dval))) call abort () END subroutine FA6077 (nf10,nf1,mf1, ida) @@ -42,7 +42,7 @@ QDA1 = MOD ( 1.1_k*( QDA(1) -5.0_k), P=( QDA -2.5_k)) DO J1 = 1,10 QVAL = MOD(1.1_k*(QDA(1)-5.0_k),P=(QDA(J1)-2.5_k)) - if (qval .ne. qda1(j1)) call abort () + if (qval - qda1(j1) .gt. epsilon(qval)) call abort () ENDDO END diff --git a/gcc/testsuite/gfortran.dg/atan2_1.f90 b/gcc/testsuite/gfortran.dg/atan2_1.f90 index 1f998a1ccde..65da63cd2d3 100644 --- a/gcc/testsuite/gfortran.dg/atan2_1.f90 +++ b/gcc/testsuite/gfortran.dg/atan2_1.f90 @@ -1,4 +1,5 @@ ! { dg-do run } +! { dg-options "-ffloat-store" } ! ! PR fortran/33197 ! diff --git a/gcc/testsuite/gfortran.dg/end_subroutine_1.f90 b/gcc/testsuite/gfortran.dg/end_subroutine_1.f90 new file mode 100644 index 00000000000..b42f950546b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/end_subroutine_1.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } +! +interface + subroutine foo() + end + integer function bar() + end +end interface +contains + subroutine test() + end + integer function f() + f = 42 + end +end diff --git a/gcc/testsuite/gfortran.dg/end_subroutine_2.f90 b/gcc/testsuite/gfortran.dg/end_subroutine_2.f90 new file mode 100644 index 00000000000..8f2e3d10a13 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/end_subroutine_2.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-options "-std=f2003" } +! +program main +interface + subroutine foo() + end + integer function bar() + end +end interface +contains + subroutine test() + end ! { dg-error "Fortran 2008: END statement instead of END SUBROUTINE" } + end subroutine ! To silence successive errors +end program + +subroutine test2() +contains + integer function f() + f = 42 + end ! { dg-error "Fortran 2008: END statement instead of END FUNCTION" } + end function ! To silence successive errors +end subroutine test2 + diff --git a/gcc/testsuite/gfortran.dg/entry_19.f90 b/gcc/testsuite/gfortran.dg/entry_19.f90 new file mode 100644 index 00000000000..b7b8bfa2f2e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/entry_19.f90 @@ -0,0 +1,9 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } +! +! +! Entry is obsolete in Fortran 2008 +! +subroutine foo() +entry bar() ! { dg-error "Fortran 2008 obsolescent feature: ENTRY" } +end diff --git a/gcc/testsuite/gfortran.dg/interface_proc_end.f90 b/gcc/testsuite/gfortran.dg/interface_proc_end.f90 index ab95b794268..2fc9921df41 100644 --- a/gcc/testsuite/gfortran.dg/interface_proc_end.f90 +++ b/gcc/testsuite/gfortran.dg/interface_proc_end.f90 @@ -14,6 +14,5 @@ REAL :: TLS1,TLS2 END ! OK END INTERFACE - end ! { dg-error "END SUBROUTINE statement" } - end module ! { dg-error "END SUBROUTINE statement" } -! { dg-error "Unexpected end of file" "" { target "*-*-*" } 0 } + end subroutine + end module diff --git a/gcc/testsuite/gfortran.dg/pr43866.f90 b/gcc/testsuite/gfortran.dg/pr43866.f90 new file mode 100644 index 00000000000..abfdaa1557f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr43866.f90 @@ -0,0 +1,44 @@ +! PR middle-end/43866 +! { dg-do run } +! { dg-options "-funswitch-loops -fbounds-check" } + +MODULE PR43866 + IMPLICIT NONE + TYPE TT + REAL(KIND=4), DIMENSION(:,:), POINTER :: A + REAL(KIND=8), DIMENSION(:,:), POINTER :: B + END TYPE +CONTAINS + SUBROUTINE FOO(M,X,Y,T) + TYPE(TT), POINTER :: M + INTEGER, INTENT(IN) :: Y, X + INTEGER :: C, D + LOGICAL :: T + REAL(KIND = 4), DIMENSION(:,:), POINTER :: P + REAL(KIND = 8), DIMENSION(:,:), POINTER :: Q + + Q => M%B + P => M%A + DO C=1,X + DO D=C+1,Y + IF (T) THEN + P(D,C)=P(C,D) + ELSE + Q(D,C)=Q(C,D) + ENDIF + ENDDO + ENDDO + END SUBROUTINE FOO +END MODULE PR43866 + + USE PR43866 + TYPE(TT), POINTER :: Q + INTEGER, PARAMETER :: N=17 + ALLOCATE (Q) + NULLIFY (Q%A) + ALLOCATE (Q%B(N,N)) + Q%B=0 + CALL FOO (Q,N,N,.FALSE.) +END + +! { dg-final { cleanup-modules "pr43866" } } diff --git a/gcc/testsuite/gfortran.dg/selected_real_kind_2.f90 b/gcc/testsuite/gfortran.dg/selected_real_kind_2.f90 new file mode 100644 index 00000000000..cf73520f930 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/selected_real_kind_2.f90 @@ -0,0 +1,32 @@ +! { dg-do run } +! { dg-options "-std=f2008 -fall-intrinsics" } +! + +integer :: p, r, rdx + +! Compile-time version + +if (selected_real_kind(radix=2) /= 4) call should_not_fail() +if (selected_real_kind(radix=4) /= -5) call should_not_fail() +if (selected_real_kind(precision(0.0),range(0.0),radix(0.0)) /= kind(0.0)) & + call should_not_fail() +if (selected_real_kind(precision(0.0d0),range(0.0d0),radix(0.0d0)) /= kind(0.0d0)) & + call should_not_fail() + +! Run-time version + +rdx = 2 +if (selected_real_kind(radix=rdx) /= 4) call abort() +rdx = 4 +if (selected_real_kind(radix=rdx) /= -5) call abort() + +rdx = radix(0.0) +p = precision(0.0) +r = range(0.0) +if (selected_real_kind(p,r,rdx) /= kind(0.0)) call abort() + +rdx = radix(0.0d0) +p = precision(0.0d0) +r = range(0.0d0) +if (selected_real_kind(p,r,rdx) /= kind(0.0d0)) call abort() +end diff --git a/gcc/testsuite/gfortran.dg/selected_real_kind_3.f90 b/gcc/testsuite/gfortran.dg/selected_real_kind_3.f90 new file mode 100644 index 00000000000..d24d877acfe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/selected_real_kind_3.f90 @@ -0,0 +1,6 @@ +! { dg-do compile } +! { dg-options "-std=f2003" } +! +print *, selected_real_kind(p=precision(0.0),radix=2) ! { dg-error "Fortran 2008" } +print *, selected_real_kind() ! { dg-error "neither 'P' nor 'R' argument" } +end diff --git a/gcc/testsuite/gfortran.dg/semicolon_fixed.f b/gcc/testsuite/gfortran.dg/semicolon_fixed.f index 2c667ae0cb9..7bd0ada825c 100644 --- a/gcc/testsuite/gfortran.dg/semicolon_fixed.f +++ b/gcc/testsuite/gfortran.dg/semicolon_fixed.f @@ -1,9 +1,11 @@ ! { dg-do compile } -! PR 19259 Semicolon cannot start a line +! { dg-options "-std=f2003" } +! +! PR 19259 Semicolon cannot start a line (in F2003) x=1; y=1; x=2;; x=3; - ; ! { dg-error "Semicolon at" } - ;; ! { dg-error "Semicolon at" } + ; ! { dg-error "Fortran 2008: Semicolon at" } + ;; ! { dg-error "Fortran 2008: Semicolon at" } 900 ; ! { dg-error "Semicolon at" } end diff --git a/gcc/testsuite/gfortran.dg/semicolon_fixed_2.f b/gcc/testsuite/gfortran.dg/semicolon_fixed_2.f new file mode 100644 index 00000000000..8ee444c3ff5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/semicolon_fixed_2.f @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } + +! PR 19259 Semicolon cannot start a line +! but it F2008 it can! + x=1; y=1; + x=2;; + x=3; + ; ! OK + ;; ! OK + 900 ; ! { dg-error "Semicolon at" } + end diff --git a/gcc/testsuite/gfortran.dg/semicolon_free.f90 b/gcc/testsuite/gfortran.dg/semicolon_free.f90 index 28e8da2b285..4d05d83f86b 100644 --- a/gcc/testsuite/gfortran.dg/semicolon_free.f90 +++ b/gcc/testsuite/gfortran.dg/semicolon_free.f90 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-std=f2003" } ! PR 19259 Semicolon cannot start a line x=1; y=1; x=2;; diff --git a/gcc/testsuite/gfortran.dg/semicolon_free_2.f90 b/gcc/testsuite/gfortran.dg/semicolon_free_2.f90 new file mode 100644 index 00000000000..2fae26e1607 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/semicolon_free_2.f90 @@ -0,0 +1,10 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } +! PR 19259 Semicolon cannot start a line +x=1; y=1; +x=2;; +x=3; + ; ! OK +;; ! OK +111 ; ! { dg-error "Semicolon at" } +end diff --git a/gcc/testsuite/gfortran.dg/type_decl_1.f90 b/gcc/testsuite/gfortran.dg/type_decl_1.f90 new file mode 100644 index 00000000000..93928652a05 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/type_decl_1.f90 @@ -0,0 +1,30 @@ +! { dg-do compile } +! { dg-options "-std=f2008" } +! +! Fortran 2008: TYPE ( intrinsic-type-spec ) +! +implicit none +type(integer) :: a +type(real) :: b +type(logical ) :: c +type(character) :: d +type(double precision) :: e + +type(integer(8)) :: f +type(real(kind=4)) :: g +type(logical ( kind = 1 ) ) :: h +type(character (len=10,kind=1) ) :: i + +type(double complex) :: j ! { dg-error "Extension: DOUBLE COMPLEX" } +end + +module m + integer, parameter :: k4 = 4 +end module m + +type(integer (kind=k4)) function f() + use m + f = 42 +end + +! { dg-final { cleanup-modules "m" } } diff --git a/gcc/testsuite/gfortran.dg/type_decl_2.f90 b/gcc/testsuite/gfortran.dg/type_decl_2.f90 new file mode 100644 index 00000000000..6525880e06e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/type_decl_2.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-std=f2003" } +! +! Fortran 2008: TYPE ( intrinsic-type-spec ) +! +implicit none +type(integer) :: a ! { dg-error "Fortran 2008" } +type(real) :: b ! { dg-error "Fortran 2008" } +type(logical) :: c ! { dg-error "Fortran 2008" } +type(character) :: d ! { dg-error "Fortran 2008" } +type(double precision) :: e ! { dg-error "Fortran 2008" } +end diff --git a/gcc/testsuite/gnat.dg/noreturn3.adb b/gcc/testsuite/gnat.dg/noreturn3.adb new file mode 100644 index 00000000000..4457373c308 --- /dev/null +++ b/gcc/testsuite/gnat.dg/noreturn3.adb @@ -0,0 +1,27 @@ +-- { dg-do compile } + +with Ada.Exceptions; + +package body Noreturn3 is + + procedure Raise_Error (E : Enum; ErrorMessage : String) is + + function Msg return String is + begin + return "Error :" & ErrorMessage; + end; + + begin + case E is + when One => + Ada.Exceptions.Raise_Exception (Exc1'Identity, Msg); + + when Two => + Ada.Exceptions.Raise_Exception (Exc2'Identity, Msg); + + when others => + Ada.Exceptions.Raise_Exception (Exc3'Identity, Msg); + end case; + end; + +end Noreturn3; diff --git a/gcc/testsuite/gnat.dg/noreturn3.ads b/gcc/testsuite/gnat.dg/noreturn3.ads new file mode 100644 index 00000000000..d830a14910e --- /dev/null +++ b/gcc/testsuite/gnat.dg/noreturn3.ads @@ -0,0 +1,12 @@ +package Noreturn3 is + + Exc1 : Exception; + Exc2 : Exception; + Exc3 : Exception; + + type Enum is (One, Two, Three); + + procedure Raise_Error (E : Enum; ErrorMessage : String); + pragma No_Return (Raise_Error); + +end Noreturn3; diff --git a/gcc/timevar.def b/gcc/timevar.def index 2a124e6a949..e4e61fb2f1a 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -52,6 +52,7 @@ DEFTIMEVAR (TV_CGRAPH , "callgraph construction") DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization") DEFTIMEVAR (TV_VARPOOL , "varpool construction") DEFTIMEVAR (TV_IPA_CONSTANT_PROP , "ipa cp") +DEFTIMEVAR (TV_IPA_FNSPLIT , "ipa function splitting") DEFTIMEVAR (TV_IPA_LTO_GIMPLE_IO , "ipa lto gimple I/O") DEFTIMEVAR (TV_IPA_LTO_DECL_IO , "ipa lto decl I/O") DEFTIMEVAR (TV_IPA_LTO_DECL_INIT_IO , "ipa lto decl init I/O") diff --git a/gcc/toplev.c b/gcc/toplev.c index 220c1f777f0..c22cb98fd62 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2013,13 +2013,13 @@ process_options (void) } #ifndef HAVE_prefetch - if (flag_prefetch_loop_arrays) + if (flag_prefetch_loop_arrays > 0) { warning (0, "-fprefetch-loop-arrays not supported for this target"); flag_prefetch_loop_arrays = 0; } #else - if (flag_prefetch_loop_arrays && !HAVE_prefetch) + if (flag_prefetch_loop_arrays > 0 && !HAVE_prefetch) { warning (0, "-fprefetch-loop-arrays not supported for this target (try -march switches)"); flag_prefetch_loop_arrays = 0; @@ -2028,7 +2028,7 @@ process_options (void) /* This combination of options isn't handled for i386 targets and doesn't make much sense anyway, so don't allow it. */ - if (flag_prefetch_loop_arrays && optimize_size) + if (flag_prefetch_loop_arrays > 0 && optimize_size) { warning (0, "-fprefetch-loop-arrays is not supported with -Os"); flag_prefetch_loop_arrays = 0; diff --git a/gcc/toplev.h b/gcc/toplev.h index a7ded4c47ad..2424fd17695 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -49,6 +49,11 @@ extern void init_optimization_passes (void); extern void finish_optimization_passes (void); extern bool enable_rtl_dump_file (void); +/* In except.c. Initialize exception handling. This is used by the Ada + and LTO front ends to initialize EH "on demand". See lto-streamer-in.c + and ada/gcc-interface/misc.c. */ +extern void init_eh (void); + extern void announce_function (tree); extern void error_for_asm (const_rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 0cf446668f4..3b8ab9d9e7d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -5850,21 +5850,6 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, return NULL_TREE; } -/* Marks virtual operands of all statements in basic blocks BBS for - renaming. */ - -void -mark_virtual_ops_in_bb (basic_block bb) -{ - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - mark_virtual_ops_for_renaming (gsi_stmt (gsi)); - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - mark_virtual_ops_for_renaming (gsi_stmt (gsi)); -} - /* Move basic block BB from function CFUN to function DEST_FN. The block is moved out of the original linked list and placed after block AFTER in the new list. Also, the block is removed from the diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 7e7817403d5..7f8498a4483 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -591,6 +591,9 @@ 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-eh.c b/gcc/tree-eh.c index 49e1aaf74ed..c117013810d 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -951,12 +951,12 @@ lower_try_finally_fallthru_label (struct leh_tf_state *tf) return label; } -/* A subroutine of lower_try_finally. If lang_protect_cleanup_actions - returns non-null, then the language requires that the exception path out - of a try_finally be treated specially. To wit: the code within the - finally block may not itself throw an exception. We have two choices here. - First we can duplicate the finally block and wrap it in a must_not_throw - region. Second, we can generate code like +/* A subroutine of lower_try_finally. If the eh_protect_cleanup_actions + langhook returns non-null, then the language requires that the exception + path out of a try_finally be treated specially. To wit: the code within + the finally block may not itself throw an exception. We have two choices + here. First we can duplicate the finally block and wrap it in a + must_not_throw region. Second, we can generate code like try { finally_block; @@ -983,9 +983,9 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, gimple x; /* First check for nothing to do. */ - if (lang_protect_cleanup_actions == NULL) + if (lang_hooks.eh_protect_cleanup_actions == NULL) return; - protect_cleanup_actions = lang_protect_cleanup_actions (); + protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions (); if (protect_cleanup_actions == NULL) return; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 56f9546f773..c0b776026bb 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -486,7 +486,6 @@ extern void end_recording_case_labels (void); extern basic_block move_sese_region_to_fn (struct function *, basic_block, basic_block, tree); void remove_edge_and_dominated_blocks (edge); -void mark_virtual_ops_in_bb (basic_block); bool tree_node_can_be_shared (tree); /* In tree-cfgcleanup.c */ diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 16864734a24..8d5d2268ec5 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -98,6 +98,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-data-ref.h" #include "tree-scalar-evolution.h" #include "tree-pass.h" +#include "dbgcnt.h" /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; @@ -174,7 +175,7 @@ init_bb_predicate (basic_block bb) { bb->aux = XNEW (struct bb_predicate_s); set_bb_predicate_gimplified_stmts (bb, NULL); - set_bb_predicate (bb, NULL_TREE); + set_bb_predicate (bb, boolean_true_node); } /* Free the predicate of basic block BB. */ @@ -202,6 +203,16 @@ free_bb_predicate (basic_block bb) bb->aux = NULL; } +/* Free the predicate of BB and reinitialize it with the true + predicate. */ + +static inline void +reset_bb_predicate (basic_block bb) +{ + free_bb_predicate (bb); + init_bb_predicate (bb); +} + /* Create a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP to the new variable. */ @@ -604,8 +615,7 @@ predicate_bbs (loop_p loop) to be processed: skip it. */ if (bb == loop->latch) { - set_bb_predicate (loop->latch, boolean_true_node); - set_bb_predicate_gimplified_stmts (loop->latch, NULL); + reset_bb_predicate (loop->latch); continue; } @@ -679,7 +689,7 @@ predicate_bbs (loop_p loop) } /* The loop header is always executed. */ - set_bb_predicate (loop->header, boolean_true_node); + reset_bb_predicate (loop->header); gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL && bb_predicate_gimplified_stmts (loop->latch) == NULL); @@ -1011,6 +1021,15 @@ insert_gimplified_predicates (loop_p loop) basic_block bb = ifc_bbs[i]; gimple_seq stmts = bb_predicate_gimplified_stmts (bb); + if (!is_predicated (bb)) + { + /* Do not insert statements for a basic block that is not + predicated. Also make sure that the predicate of the + basic block is set to true. */ + reset_bb_predicate (bb); + continue; + } + if (stmts) { gimple_stmt_iterator gsi = gsi_last_bb (bb); @@ -1161,9 +1180,7 @@ combine_blocks (struct loop *loop) /* If possible, merge loop header to the block with the exit edge. This reduces the number of basic blocks to two, to please the - vectorizer that handles only loops with two nodes. - - FIXME: Call cleanup_tree_cfg. */ + vectorizer that handles only loops with two nodes. */ if (exit_bb && exit_bb != loop->header && can_merge_blocks_p (loop->header, exit_bb)) @@ -1171,20 +1188,23 @@ combine_blocks (struct loop *loop) } /* If-convert LOOP when it is legal. For the moment this pass has no - profitability analysis. */ + profitability analysis. Returns true when something changed. */ -static void +static bool tree_if_conversion (struct loop *loop) { + bool changed = false; ifc_bbs = NULL; - if (!if_convertible_loop_p (loop)) + if (!if_convertible_loop_p (loop) + || !dbg_cnt (if_conversion_tree)) goto cleanup; /* Now all statements are if-convertible. Combine all the basic blocks into one huge basic block doing the if-conversion on-the-fly. */ combine_blocks (loop); + changed = true; cleanup: if (ifc_bbs) @@ -1197,6 +1217,8 @@ tree_if_conversion (struct loop *loop) free (ifc_bbs); ifc_bbs = NULL; } + + return changed; } /* Tree if-conversion pass management. */ @@ -1206,14 +1228,15 @@ main_tree_if_conversion (void) { loop_iterator li; struct loop *loop; + bool changed = false; if (number_of_loops () <= 1) return 0; FOR_EACH_LOOP (li, loop, 0) - tree_if_conversion (loop); + changed |= tree_if_conversion (loop); - return 0; + return changed ? TODO_cleanup_cfg : 0; } static bool diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index f2e3baf0f0e..e63a230c0d6 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1983,11 +1983,22 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) = new_phi = create_phi_node (new_res, new_bb); FOR_EACH_EDGE (new_edge, ei, new_bb->preds) { - edge const old_edge - = find_edge ((basic_block) new_edge->src->aux, bb); - tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge); - tree new_arg = arg; + edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb); + tree arg; + tree new_arg; tree block = id->block; + edge_iterator ei2; + + /* When doing partial clonning, we allow PHIs on the entry block + as long as all the arguments are the same. Find any input + edge to see argument to copy. */ + if (!old_edge) + FOR_EACH_EDGE (old_edge, ei2, bb->preds) + if (!old_edge->src->aux) + break; + + arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge); + new_arg = arg; id->block = NULL_TREE; walk_tree (&new_arg, copy_tree_body_r, id, NULL); id->block = block; @@ -2205,12 +2216,6 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map); - if (gimple_in_ssa_p (cfun)) - FOR_ALL_BB_FN (bb, cfun_to_copy) - if (!blocks_to_copy - || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) - copy_phis_for_bb (bb, id); - if (new_entry) { edge e; @@ -2219,6 +2224,12 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, e->count = entry_block_map->count; } + if (gimple_in_ssa_p (cfun)) + FOR_ALL_BB_FN (bb, cfun_to_copy) + if (!blocks_to_copy + || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) + copy_phis_for_bb (bb, id); + FOR_ALL_BB_FN (bb, cfun_to_copy) if (bb->aux) { @@ -4036,7 +4047,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* Expand call statements reachable from STMT_P. We can only have CALL_EXPRs as the "toplevel" tree code or nested - in a MODIFY_EXPR. See tree-gimple.c:get_call_expr_in(). We can + in a MODIFY_EXPR. See gimple.c:get_call_expr_in(). We can unfortunately not use that function here because we need a pointer to the CALL_EXPR, not the tree itself. */ diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 3f20c32ae7b..099a7fe479f 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -195,18 +195,28 @@ generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p) for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);) if (!bitmap_bit_p (partition, x++)) - remove_phi_node (&bsi, true); + { + gimple phi = gsi_stmt (bsi); + if (!is_gimple_reg (gimple_phi_result (phi))) + mark_virtual_phi_result_for_renaming (phi); + remove_phi_node (&bsi, true); + } else gsi_next (&bsi); for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);) - if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL - && !bitmap_bit_p (partition, x++)) - gsi_remove (&bsi, false); - else - gsi_next (&bsi); - - mark_virtual_ops_in_bb (bb); + { + gimple stmt = gsi_stmt (bsi); + if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL + && !bitmap_bit_p (partition, x++)) + { + unlink_stmt_vdef (stmt); + gsi_remove (&bsi, true); + release_defs (stmt); + } + else + gsi_next (&bsi); + } } free (bbs); @@ -240,7 +250,6 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter, gimple_seq stmt_list = NULL, stmts; gimple fn_call; tree mem, fn; - gimple_stmt_iterator i; struct data_reference *dr = XCNEW (struct data_reference); location_t loc = gimple_location (stmt); @@ -291,13 +300,6 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter, fn = build_fold_addr_expr (implicit_built_in_decls [BUILT_IN_MEMSET]); fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes); gimple_seq_add_stmt (&stmt_list, fn_call); - - for (i = gsi_start (stmt_list); !gsi_end_p (i); gsi_next (&i)) - { - gimple s = gsi_stmt (i); - update_stmt_if_modified (s); - } - gsi_insert_seq_after (&bsi, stmt_list, GSI_CONTINUE_LINKING); res = true; diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index b5971d5433a..a4c97b39155 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -442,6 +442,7 @@ extern struct gimple_opt_pass pass_build_cgraph_edges; extern struct gimple_opt_pass pass_local_pure_const; extern struct gimple_opt_pass pass_tracer; extern struct gimple_opt_pass pass_warn_unused_result; +extern struct gimple_opt_pass pass_split_functions; /* IPA Passes */ extern struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 5433ab5b865..78eb362ca5c 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -879,20 +879,20 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) HOST_WIDE_INT max_size1 = -1, max_size2 = -1; bool var1_p, var2_p, ind1_p, ind2_p; - gcc_assert ((!ref1->ref - || SSA_VAR_P (ref1->ref) - || handled_component_p (ref1->ref) - || INDIRECT_REF_P (ref1->ref) - || TREE_CODE (ref1->ref) == MEM_REF - || TREE_CODE (ref1->ref) == TARGET_MEM_REF - || TREE_CODE (ref1->ref) == CONST_DECL) - && (!ref2->ref - || SSA_VAR_P (ref2->ref) - || handled_component_p (ref2->ref) - || INDIRECT_REF_P (ref2->ref) - || TREE_CODE (ref2->ref) == MEM_REF - || TREE_CODE (ref2->ref) == TARGET_MEM_REF - || TREE_CODE (ref2->ref) == CONST_DECL)); + gcc_checking_assert ((!ref1->ref + || TREE_CODE (ref1->ref) == SSA_NAME + || DECL_P (ref1->ref) + || handled_component_p (ref1->ref) + || INDIRECT_REF_P (ref1->ref) + || TREE_CODE (ref1->ref) == MEM_REF + || TREE_CODE (ref1->ref) == TARGET_MEM_REF) + && (!ref2->ref + || TREE_CODE (ref2->ref) == SSA_NAME + || DECL_P (ref2->ref) + || handled_component_p (ref2->ref) + || INDIRECT_REF_P (ref2->ref) + || TREE_CODE (ref2->ref) == MEM_REF + || TREE_CODE (ref2->ref) == TARGET_MEM_REF)); /* Decompose the references into their base objects and the access. */ base1 = ao_ref_base (ref1); @@ -913,10 +913,13 @@ refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) || is_gimple_min_invariant (base2)) return false; - /* We can end up refering to code via function decls. As we likely - do not properly track code aliases conservatively bail out. */ + /* We can end up refering to code via function and label decls. + As we likely do not properly track code aliases conservatively + bail out. */ if (TREE_CODE (base1) == FUNCTION_DECL - || TREE_CODE (base2) == FUNCTION_DECL) + || TREE_CODE (base2) == FUNCTION_DECL + || TREE_CODE (base1) == LABEL_DECL + || TREE_CODE (base2) == LABEL_DECL) return true; /* Defer to simple offset based disambiguation if we have @@ -1442,11 +1445,15 @@ stmt_may_clobber_ref_p_1 (gimple stmt, ao_ref *ref) return call_may_clobber_ref_p_1 (stmt, ref); } - else if (is_gimple_assign (stmt)) + else if (gimple_assign_single_p (stmt)) { - ao_ref r; - ao_ref_init (&r, gimple_assign_lhs (stmt)); - return refs_may_alias_p_1 (ref, &r, true); + tree lhs = gimple_assign_lhs (stmt); + if (!is_gimple_reg (lhs)) + { + ao_ref r; + ao_ref_init (&r, gimple_assign_lhs (stmt)); + return refs_may_alias_p_1 (ref, &r, true); + } } else if (gimple_code (stmt) == GIMPLE_ASM) return true; diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index d15df31238d..68338206a8a 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1635,7 +1635,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); record_conditions (edge_info, inverted, cond); - if (code == NE_EXPR) + if (TREE_CODE (inverted) == EQ_EXPR) { edge_info->lhs = op1; edge_info->rhs = op0; @@ -1662,7 +1662,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); record_conditions (edge_info, inverted, cond); - if (TREE_CODE (cond) == NE_EXPR) + if (TREE_CODE (inverted) == EQ_EXPR) { edge_info->lhs = op0; edge_info->rhs = op1; diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index 6bc40af263c..b6b32dcd99a 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -1,5 +1,5 @@ /* Loop unswitching. - Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -129,6 +129,12 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop) if (!stmt || gimple_code (stmt) != GIMPLE_COND) return NULL_TREE; + /* To keep the things simple, we do not directly remove the conditions, + but just replace tests with 0 != 0 resp. 1 != 0. Prevent the infinite + loop where we would unswitch again on such a condition. */ + if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt)) + return NULL_TREE; + /* Condition must be invariant. */ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { @@ -142,12 +148,6 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop) cond = build2 (gimple_cond_code (stmt), boolean_type_node, gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); - /* To keep the things simple, we do not directly remove the conditions, - but just replace tests with 0/1. Prevent the infinite loop where we - would unswitch again on such a condition. */ - if (integer_zerop (cond) || integer_nonzerop (cond)) - return NULL_TREE; - return cond; } @@ -193,21 +193,14 @@ tree_unswitch_single_loop (struct loop *loop, int num) { basic_block *bbs; struct loop *nloop; - unsigned i; + unsigned i, found; tree cond = NULL_TREE; gimple stmt; bool changed = false; - /* Do not unswitch too much. */ - if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, ";; Not unswitching anymore, hit max level\n"); - return false; - } - i = 0; bbs = get_loop_body (loop); + found = loop->num_nodes; while (1) { @@ -218,8 +211,17 @@ tree_unswitch_single_loop (struct loop *loop, int num) if (i == loop->num_nodes) { - free (bbs); - return changed; + if (dump_file + && num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL) + && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, ";; Not unswitching anymore, hit max level\n"); + + if (found == loop->num_nodes) + { + free (bbs); + return changed; + } + break; } cond = simplify_using_entry_checks (loop, cond); @@ -236,19 +238,107 @@ tree_unswitch_single_loop (struct loop *loop, int num) gimple_cond_set_condition_from_tree (stmt, boolean_false_node); changed = true; } + /* Do not unswitch too much. */ + else if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)) + { + i++; + continue; + } + /* In nested tree_unswitch_single_loop first optimize all conditions + using entry checks, then discover still reachable blocks in the + loop and find the condition only among those still reachable bbs. */ + else if (num != 0) + { + if (found == loop->num_nodes) + found = i; + i++; + continue; + } else - break; + { + found = i; + break; + } update_stmt (stmt); i++; } + if (num != 0) + { + basic_block *tos, *worklist; + + /* When called recursively, first do a quick discovery + of reachable bbs after the above changes and only + consider conditions in still reachable bbs. */ + tos = worklist = XNEWVEC (basic_block, loop->num_nodes); + + for (i = 0; i < loop->num_nodes; i++) + bbs[i]->flags &= ~BB_REACHABLE; + + /* Start with marking header. */ + *tos++ = bbs[0]; + bbs[0]->flags |= BB_REACHABLE; + + /* Iterate: find everything reachable from what we've already seen + within the same innermost loop. Don't look through false edges + if condition is always true or true edges if condition is + always false. */ + while (tos != worklist) + { + basic_block b = *--tos; + edge e; + edge_iterator ei; + int flags = 0; + + if (EDGE_COUNT (b->succs) == 2) + { + gimple stmt = last_stmt (b); + if (stmt + && gimple_code (stmt) == GIMPLE_COND) + { + if (gimple_cond_true_p (stmt)) + flags = EDGE_FALSE_VALUE; + else if (gimple_cond_false_p (stmt)) + flags = EDGE_TRUE_VALUE; + } + } + + FOR_EACH_EDGE (e, ei, b->succs) + { + basic_block dest = e->dest; + + if (dest->loop_father == loop + && !(dest->flags & BB_REACHABLE) + && !(e->flags & flags)) + { + *tos++ = dest; + dest->flags |= BB_REACHABLE; + } + } + } + + free (worklist); + + /* Find a bb to unswitch on. */ + for (; found < loop->num_nodes; found++) + if ((bbs[found]->flags & BB_REACHABLE) + && (cond = tree_may_unswitch_on (bbs[found], loop))) + break; + + if (found == loop->num_nodes) + { + free (bbs); + return changed; + } + } + if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, ";; Unswitching loop\n"); initialize_original_copy_tables (); /* Unswitch the loop on this condition. */ - nloop = tree_unswitch_loop (loop, bbs[i], cond); + nloop = tree_unswitch_loop (loop, bbs[found], cond); if (!nloop) { free_original_copy_tables (); diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 344cfa8acbe..c9c5bbd0f0c 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -600,7 +600,7 @@ tree_ssa_loop_prefetch (void) static bool gate_tree_ssa_loop_prefetch (void) { - return flag_prefetch_loop_arrays != 0; + return flag_prefetch_loop_arrays > 0; } struct gimple_opt_pass pass_loop_prefetch = diff --git a/gcc/tree.c b/gcc/tree.c index f2331bea5d6..38b3da93011 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7340,6 +7340,13 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip) we expect first argument to be THIS pointer. */ if (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) && !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; + } return new_decl; } diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 83ff864a5ff..3c2c75cd1b1 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,21 @@ +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * intrinsics/selected_real_kind.f90 + (_gfortran_selected_real_kind2008): Add function. + (_gfortran_selected_real_kind): Stub which calls + _gfortran_selected_real_kind2008. + * gfortran.map (GFORTRAN_1.4): Add + _gfortran_selected_real_kind2008. + * mk-srk-inc.sh: Save also RADIX. + +2010-06-25 Tobias Burnus <burnus@net-b.de> + + * runtime/compile_options.c (init_compile_options): Update + compile_options.allow_std for GFC_STD_F2008_OBS. + * io/transfer.c (formatted_transfer_scalar_read, + formatted_transfer_scalar_write): Fix allow_std check. + * io/list_read.c (nml_parse_qualifier): Ditto. + 2010-06-18 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/44477 diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map index 3e854eb0eae..ce5aa77b02d 100644 --- a/libgfortran/gfortran.map +++ b/libgfortran/gfortran.map @@ -1106,6 +1106,7 @@ GFORTRAN_1.3 { GFORTRAN_1.4 { global: _gfortran_error_stop_numeric; + _gfortran_selected_real_kind2008; } GFORTRAN_1.3; F2C_1.0 { diff --git a/libgfortran/intrinsics/selected_real_kind.f90 b/libgfortran/intrinsics/selected_real_kind.f90 index ea3b46aabdd..92708d7205f 100644 --- a/libgfortran/intrinsics/selected_real_kind.f90 +++ b/libgfortran/intrinsics/selected_real_kind.f90 @@ -1,7 +1,7 @@ -! Copyright 2003, 2004, 2009 Free Software Foundation, Inc. +! Copyright 2003, 2004, 2009, 2010 Free Software Foundation, Inc. ! Contributed by Kejia Zhao <kejia_zh@yahoo.com.cn> ! -!This file is part of the GNU Fortran 95 runtime library (libgfortran). +!This file is part of the GNU Fortran runtime library (libgfortran). ! !Libgfortran is free software; you can redistribute it and/or !modify it under the terms of the GNU General Public @@ -22,43 +22,74 @@ !see the files COPYING3 and COPYING.RUNTIME respectively. If not, see !<http://www.gnu.org/licenses/>. -function _gfortran_selected_real_kind (p, r) +function _gfortran_selected_real_kind2008 (p, r, rdx) implicit none - integer, optional, intent (in) :: p, r - integer :: _gfortran_selected_real_kind - integer :: i, p2, r2 - logical :: found_p, found_r + integer, optional, intent (in) :: p, r, rdx + integer :: _gfortran_selected_real_kind2008 + integer :: i, p2, r2, radix2 + logical :: found_p, found_r, found_radix ! Real kind_precision_range table type :: real_info integer :: kind integer :: precision integer :: range + integer :: radix end type real_info include "selected_real_kind.inc" - _gfortran_selected_real_kind = 0 + _gfortran_selected_real_kind2008 = 0 p2 = 0 r2 = 0 + radix2 = 0 found_p = .false. found_r = .false. + found_radix = .false. if (present (p)) p2 = p if (present (r)) r2 = r + if (present (rdx)) radix2 = rdx ! Assumes each type has a greater precision and range than previous one. do i = 1, c if (p2 <= real_infos (i) % precision) found_p = .true. if (r2 <= real_infos (i) % range) found_r = .true. - if (found_p .and. found_r) then - _gfortran_selected_real_kind = real_infos (i) % kind + if (radix2 <= real_infos (i) % radix) found_radix = .true. + + if (p2 <= real_infos (i) % precision & + .and. r2 <= real_infos (i) % range & + .and. radix2 <= real_infos (i) % radix) then + _gfortran_selected_real_kind2008 = real_infos (i) % kind return end if end do - if (.not. (found_p)) _gfortran_selected_real_kind = _gfortran_selected_real_kind - 1 - if (.not. (found_r)) _gfortran_selected_real_kind = _gfortran_selected_real_kind - 2 + if (found_radix .and. found_r .and. .not. found_p) then + _gfortran_selected_real_kind2008 = -1 + elseif (found_radix .and. found_p .and. .not. found_r) then + _gfortran_selected_real_kind2008 = -2 + elseif (found_radix .and. .not. found_p .and. .not. found_r) then + _gfortran_selected_real_kind2008 = -3 + elseif (found_radix) then + _gfortran_selected_real_kind2008 = -4 + else + _gfortran_selected_real_kind2008 = -5 + end if +end function _gfortran_selected_real_kind2008 + +function _gfortran_selected_real_kind (p, r) + implicit none + integer, optional, intent (in) :: p, r + integer :: _gfortran_selected_real_kind + + interface + function _gfortran_selected_real_kind2008 (p, r, rdx) + implicit none + integer, optional, intent (in) :: p, r, rdx + integer :: _gfortran_selected_real_kind2008 + end function _gfortran_selected_real_kind2008 + end interface - return + _gfortran_selected_real_kind = _gfortran_selected_real_kind2008 (p, r) end function diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 2f0f931ab5a..798521d62ad 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -2077,7 +2077,7 @@ nml_parse_qualifier (st_parameter_dt *dtp, descriptor_dimension *ad, /* If -std=f95/2003 or an array section is specified, do not allow excess data to be processed. */ if (is_array_section == 1 - || compile_options.allow_std < GFC_STD_GNU) + || !(compile_options.allow_std & GFC_STD_GNU)) ls[dim].end = ls[dim].start; else dtp->u.p.expanded_read = 1; diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 9f2aafaf1a4..f44c02538a9 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -4,7 +4,7 @@ Namelist transfer functions contributed by Paul Thomas F2003 I/O support contributed by Jerry DeLisle -This file is part of the GNU Fortran 95 runtime library (libgfortran). +This file is part of the GNU Fortran runtime library (libgfortran). Libgfortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1042,7 +1042,7 @@ formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind case FMT_B: if (n == 0) goto need_read_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; read_radix (dtp, f, p, kind, 2); @@ -1051,7 +1051,7 @@ formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind case FMT_O: if (n == 0) goto need_read_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; read_radix (dtp, f, p, kind, 8); @@ -1060,7 +1060,7 @@ formatted_transfer_scalar_read (st_parameter_dt *dtp, bt type, void *p, int kind case FMT_Z: if (n == 0) goto need_read_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; read_radix (dtp, f, p, kind, 16); @@ -1443,7 +1443,7 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin case FMT_B: if (n == 0) goto need_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; write_b (dtp, f, p, kind); @@ -1452,7 +1452,7 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin case FMT_O: if (n == 0) goto need_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; write_o (dtp, f, p, kind); @@ -1461,7 +1461,7 @@ formatted_transfer_scalar_write (st_parameter_dt *dtp, bt type, void *p, int kin case FMT_Z: if (n == 0) goto need_data; - if (compile_options.allow_std < GFC_STD_GNU + if (!(compile_options.allow_std & GFC_STD_GNU) && require_type (dtp, BT_INTEGER, type, f)) return; write_z (dtp, f, p, kind); diff --git a/libgfortran/mk-srk-inc.sh b/libgfortran/mk-srk-inc.sh index 10c428f02d6..402441ce6f2 100755 --- a/libgfortran/mk-srk-inc.sh +++ b/libgfortran/mk-srk-inc.sh @@ -22,7 +22,7 @@ echo " type (real_info), parameter :: real_infos(c) = (/ &" i=0 for k in $kinds; do # echo -n is not portable - str=" real_info ($k, precision(0.0_$k), range(0.0_$k))" + str=" real_info ($k, precision(0.0_$k), range(0.0_$k), radix(0.0_$k))" i=`expr $i + 1` if [ $i -lt $c ]; then echo "$str, &" diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index c3d26f4148d..62c401be6b3 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -1,7 +1,7 @@ /* Handling of compile-time options that influence the library. - Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc. -This file is part of the GNU Fortran 95 runtime library (libgfortran). +This file is part of the GNU Fortran runtime library (libgfortran). Libgfortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -138,7 +138,7 @@ init_compile_options (void) compile_options.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY; compile_options.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 - | GFC_STD_GNU | GFC_STD_LEGACY; + | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY; compile_options.pedantic = 0; compile_options.dump_core = 0; compile_options.backtrace = 0; diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 08ceefc1e24..394d5602634 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,221 @@ +2010-06-27 Paolo Carlini <paolo.carlini@oracle.com> + + * include/bits/regex_compiler.h: Trivial formatting / stylistic fixes. + * include/bits/regex_grep_matcher.tcc: Likewise. + * include/bits/regex_cursor.h: Likewise. + * include/bits/regex.h: Likewise. + +2010-06-26 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/util/testsuite_hooks.h: Cast fn to bool. + +2010-06-26 Kees Cook <kees.cook@canonical.com> + + * testsuite/27_io/ios_base/sync_with_stdio/1.cc: Verify freopen. + * testsuite/27_io/objects/wchar_t/9520.cc: Likewise. + * testsuite/27_io/objects/wchar_t/9661-1.cc: Likewise. + * testsuite/27_io/objects/wchar_t/12048-2.cc: Likewise. + * testsuite/27_io/objects/wchar_t/12048-4.cc: Likewise. + * testsuite/27_io/objects/wchar_t/11.cc: Likewise. + * testsuite/27_io/objects/wchar_t/12048-1.cc: Likewise. + * testsuite/27_io/objects/wchar_t/12048-3.cc: Likewise. + * testsuite/27_io/objects/wchar_t/10.cc: Likewise. + * testsuite/27_io/objects/wchar_t/12048-5.cc: Likewise. + * testsuite/27_io/objects/char/9661-1.cc: Likewise. + * testsuite/27_io/objects/char/12048-2.cc: Likewise. + * testsuite/27_io/objects/char/12048-4.cc: Likewise. + * testsuite/27_io/objects/char/9.cc: Likewise. + * testsuite/27_io/objects/char/12048-1.cc: Likewise. + * testsuite/27_io/objects/char/12048-3.cc: Likewise. + * testsuite/27_io/objects/char/12048-5.cc: Likewise. + * testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc: Likewise. + * testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc: Verify fgets. + * testsuite/27_io/basic_filebuf/underflow/wchar_t/11544-2.cc: Verify + fwrite. + * testsuite/ext/stdio_sync_filebuf/wchar_t/1.cc: Likewise. + * testsuite/ext/stdio_sync_filebuf/char/1.cc: Likewise. + +2010-06-26 Jonathan Wakely <jwakely.gcc@gmail.com> + + * doc/xml/faq.xml: Fix typo. + * doc/html/faq.xml: Likewise. + +2010-06-25 Stephen M. Webb <stephen.webb@bregmasoft.ca> + + Initial regex implementation. + * include/std/regex: Modified to use bits/regex_* headers. + * include/bits/regex_compiler.h: New. + * include/bits/regex_constants.h: Likewise. + * include/bits/regex_cursor.h: Likewise. + * include/bits/regex_error.h: Likewise. + * include/bits/regex_grep_matcher.h: Likewise. + * include/bits/regex_grep_matcher.tcc: Likewise. + * include/bits/regex.h: Likewise. + * include/bits/regex_nfa.h: Likewise. + * include/bits/regex_nfa.tcc: Likewise. + * include/Makefile.am: Add. + * include/Makefile.in: Regenerated. + * testsuite/28_regex/02_definitions: New. + * testsuite/28_regex/03_requirements: Likewise. + * testsuite/28_regex/03_requirements/typedefs.cc: Likewise. + * testsuite/28_regex/04_header: Likewise. + * testsuite/28_regex/04_header/regex: Likewise. + * testsuite/28_regex/04_header/regex/std_c++0x_neg.cc: Likewise. + * testsuite/28_regex/05_constants: Likewise. + * testsuite/28_regex/05_constants/error_type.cc: Likewise. + * testsuite/28_regex/05_constants/match_flag_type.cc: Likewise. + * testsuite/28_regex/05_constants/syntax_option_type.cc: Likewise. + * testsuite/28_regex/06_exception_type: Likewise. + * testsuite/28_regex/06_exception_type/regex_error.cc: Likewise. + * testsuite/28_regex/07_traits: Likewise. + * testsuite/28_regex/07_traits/char: Likewise. + * testsuite/28_regex/07_traits/char/ctor.cc: Likewise. + * testsuite/28_regex/07_traits/char/isctype.cc: Likewise. + * testsuite/28_regex/07_traits/char/length.cc: Likewise. + * testsuite/28_regex/07_traits/char/lookup_classname.cc: Likewise. + * testsuite/28_regex/07_traits/char/lookup_collatename.cc: Likewise. + * testsuite/28_regex/07_traits/char/transform.cc: Likewise. + * testsuite/28_regex/07_traits/char/transform_primary.cc: Likewise. + * testsuite/28_regex/07_traits/char/translate.cc: Likewise. + * testsuite/28_regex/07_traits/char/translate_nocase.cc: Likewise. + * testsuite/28_regex/07_traits/char/value.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t: Likewise. + * testsuite/28_regex/07_traits/wchar_t/ctor.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t/length.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t/transform.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t/translate.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t/translate_nocase.cc: Likewise. + * testsuite/28_regex/07_traits/wchar_t/value.cc: Likewise. + * testsuite/28_regex/08_basic_regex: Likewise. + * testsuite/28_regex/08_basic_regex/assign: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/cstring_op.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/moveable.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/pstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/range.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/string.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/char/string_op.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring_op.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/pstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/range.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/string.cc: Likewise. + * testsuite/28_regex/08_basic_regex/assign/wchar_t/string_op.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/basic: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/basic/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/basic/pstring_char.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors/basic/pstring_wchar_t.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors/basic/ + string_range_01_02_03.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/cstring_awk.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/cstring_ecma.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/cstring_egrep.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/cstring_grep.cc: + Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/default.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/char/range.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/copy_char.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/extended: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/extended/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/extended/ + string_range_01_02_03.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/move_char.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/string_char.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/string_wchar_t.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/wchar_t: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/wchar_t/cstring.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/wchar_t/default.cc: Likewise. + * testsuite/28_regex/08_basic_regex/ctors/wchar_t/range.cc: Likewise. + * testsuite/28_regex/08_basic_regex/regex.cc: Likewise. + * testsuite/28_regex/09_sub_match: Likewise. + * testsuite/28_regex/09_sub_match/cast_char.cc: Likewise. + * testsuite/28_regex/09_sub_match/cast_wchar_t.cc: Likewise. + * testsuite/28_regex/09_sub_match/length.cc: Likewise. + * testsuite/28_regex/09_sub_match/typedefs.cc: Likewise. + * testsuite/28_regex/10_match_results: Likewise. + * testsuite/28_regex/10_match_results/ctors: Likewise. + * testsuite/28_regex/10_match_results/ctors/char: Likewise. + * testsuite/28_regex/10_match_results/ctors/char/default.cc: Likewise. + * testsuite/28_regex/10_match_results/ctors/wchar_t: Likewise. + * testsuite/28_regex/10_match_results/ctors/wchar_t/default.cc: + Likewise. + * testsuite/28_regex/10_match_results/typedefs.cc: Likewise. + * testsuite/28_regex/11_algorithms: Likewise. + * testsuite/28_regex/11_algorithms/02_match: Likewise. + * testsuite/28_regex/11_algorithms/02_match/basic: Likewise. + * testsuite/28_regex/11_algorithms/02_match/basic/string_01.cc: + Likewise. + * testsuite/28_regex/11_algorithms/02_match/basic/ + string_range_00_03.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/basic/ + string_range_01_03.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/basic/ + string_range_02_03.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended: Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/cstring_plus.cc: + Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/ + cstring_questionmark.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/string_any.cc: + Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/ + string_range_00_03.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/ + string_range_01_03.cc: Likewise. + * testsuite/28_regex/11_algorithms/02_match/extended/ + string_range_02_03.cc: Likewise. + * testsuite/28_regex/12_iterators: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/ctors: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/ctors/char: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/ctors/char/ + default.cc: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/ctors/wchar_t: + Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/ctors/wchar_t/ + default.cc: Likewise. + * testsuite/28_regex/12_iterators/regex_iterator/typedefs.cc: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ctors: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ctors/char: + Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ctors/char/ + default.cc: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ctors/ + wchar_t: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ctors/ + wchar_t/default.cc: Likewise. + * testsuite/28_regex/12_iterators/regex_token_iterator/ + typedefs.cc: Likewise. + * testsuite/28_regex/13_ecmascript: Likewise. + +2010-06-25 Paolo Carlini <paolo.carlini@oracle.com> + + * include/profile/impl/profiler_list_to_slist.h: Remove spurious + semicolon; prefer pre-increment. + * include/profile/impl/profiler_container_size.h: Use everywhere + qualified std::size_t. + * include/profile/impl/profiler_trace.h (__trace_base<>:: + __collect_warnings): Tidy loop. + * include/profile/impl/profiler_vector_to_list.h: Minor formatting + changes. + +2010-06-25 Paolo Carlini <paolo.carlini@oracle.com> + + * include/profile/impl/profiler_trace.h: Uglify it to __it, use + everywhere std::size_t instead of size_t. + 2010-06-24 Paolo Carlini <paolo.carlini@oracle.com> * include/profile/impl/profiler_trace.h (__trace_base<>:: diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html index f245bebfd53..76f318c969d 100644 --- a/libstdc++-v3/doc/html/faq.html +++ b/libstdc++-v3/doc/html/faq.html @@ -396,7 +396,7 @@ non-standard features of g++ that are not present in older versions of proprietary compilers. It may take as much as a year or two after an official release of GCC that contains these features for - proprietary tools support these constructs. + proprietary tools to support these constructs. </p><p> In the near past, specific released versions of libstdc++ have been known to work with versions of the EDG C++ compiler, and diff --git a/libstdc++-v3/doc/xml/faq.xml b/libstdc++-v3/doc/xml/faq.xml index 57f08041789..5ed2777337c 100644 --- a/libstdc++-v3/doc/xml/faq.xml +++ b/libstdc++-v3/doc/xml/faq.xml @@ -491,7 +491,7 @@ non-standard features of g++ that are not present in older versions of proprietary compilers. It may take as much as a year or two after an official release of GCC that contains these features for - proprietary tools support these constructs. + proprietary tools to support these constructs. </para> <para> In the near past, specific released versions of libstdc++ have diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 1ced7813c1c..6c0230ad292 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -121,6 +121,15 @@ bits_headers = \ ${bits_srcdir}/postypes.h \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ + ${bits_srcdir}/regex.h \ + ${bits_srcdir}/regex_compiler.h \ + ${bits_srcdir}/regex_constants.h \ + ${bits_srcdir}/regex_cursor.h \ + ${bits_srcdir}/regex_error.h \ + ${bits_srcdir}/regex_grep_matcher.h \ + ${bits_srcdir}/regex_grep_matcher.tcc \ + ${bits_srcdir}/regex_nfa.h \ + ${bits_srcdir}/regex_nfa.tcc \ ${bits_srcdir}/stream_iterator.h \ ${bits_srcdir}/streambuf_iterator.h \ ${bits_srcdir}/shared_ptr.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index fd45a43e9da..631561c585e 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -361,6 +361,15 @@ bits_headers = \ ${bits_srcdir}/postypes.h \ ${bits_srcdir}/random.h \ ${bits_srcdir}/random.tcc \ + ${bits_srcdir}/regex.h \ + ${bits_srcdir}/regex_compiler.h \ + ${bits_srcdir}/regex_constants.h \ + ${bits_srcdir}/regex_cursor.h \ + ${bits_srcdir}/regex_error.h \ + ${bits_srcdir}/regex_grep_matcher.h \ + ${bits_srcdir}/regex_grep_matcher.tcc \ + ${bits_srcdir}/regex_nfa.h \ + ${bits_srcdir}/regex_nfa.tcc \ ${bits_srcdir}/stream_iterator.h \ ${bits_srcdir}/streambuf_iterator.h \ ${bits_srcdir}/shared_ptr.h \ diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h new file mode 100644 index 00000000000..f035fd4ade4 --- /dev/null +++ b/libstdc++-v3/include/bits/regex.h @@ -0,0 +1,2428 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ + +/** + * @defgroup regex Regular Expressions + * A facility for performing regular expression pattern matching. + */ + //@{ + + // [7.7] Class regex_traits + /** + * @brief Describes aspects of a regular expression. + * + * A regular expression traits class that satisfies the requirements of + * section [28.7]. + * + * The class %regex is parameterized around a set of related types and + * functions used to complete the definition of its semantics. This class + * satisfies the requirements of such a traits class. + */ + template<typename _Ch_type> + struct regex_traits + { + public: + typedef _Ch_type char_type; + typedef std::basic_string<char_type> string_type; + typedef std::locale locale_type; + typedef std::ctype_base::mask char_class_type; + + public: + /** + * @brief Constructs a default traits object. + */ + regex_traits() + { } + + /** + * @brief Gives the length of a C-style string starting at @p __p. + * + * @param __p a pointer to the start of a character sequence. + * + * @returns the number of characters between @p *__p and the first + * default-initialized value of type @p char_type. In other words, uses + * the C-string algorithm for determining the length of a sequence of + * characters. + */ + static std::size_t + length(const char_type* __p) + { return string_type::traits_type::length(__p); } + + /** + * @brief Performs the identity translation. + * + * @param c A character to the locale-specific character set. + * + * @returns c. + */ + char_type + translate(char_type __c) const + { return __c; } + + /** + * @brief Translates a character into a case-insensitive equivalent. + * + * @param c A character to the locale-specific character set. + * + * @returns the locale-specific lower-case equivalent of c. + * @throws std::bad_cast if the imbued locale does not support the ctype + * facet. + */ + char_type + translate_nocase(char_type __c) const + { + using std::ctype; + using std::use_facet; + return use_facet<ctype<char_type> >(_M_locale).tolower(__c); + } + + /** + * @brief Gets a sort key for a character sequence. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * + * Returns a sort key for the character sequence designated by the + * iterator range [F1, F2) such that if the character sequence [G1, G2) + * sorts before the character sequence [H1, H2) then + * v.transform(G1, G2) < v.transform(H1, H2). + * + * What this really does is provide a more efficient way to compare a + * string to multiple other strings in locales with fancy collation + * rules and equivalence classes. + * + * @returns a locale-specific sort key equivalent to the input range. + * + * @throws std::bad_cast if the current locale does not have a collate + * facet. + */ + template<typename _Fwd_iter> + string_type + transform(_Fwd_iter __first, _Fwd_iter __last) const + { + using std::collate; + using std::use_facet; + const collate<_Ch_type>& __c(use_facet< + collate<_Ch_type> >(_M_locale)); + string_type __s(__first, __last); + return __c.transform(__s.data(), __s.data() + __s.size()); + } + + /** + * @brief Gets a sort key for a character sequence, independant of case. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * + * Effects: if typeid(use_facet<collate<_Ch_type> >) == + * typeid(collate_byname<_Ch_type>) and the form of the sort key + * returned by collate_byname<_Ch_type>::transform(first, last) is known + * and can be converted into a primary sort key then returns that key, + * otherwise returns an empty string. + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + string_type + transform_primary(_Fwd_iter __first, _Fwd_iter __last) const + { return string_type(); } + + /** + * @brief Gets a collation element by name. + * + * @param first beginning of the collation element name. + * @param last one-past-the-end of the collation element name. + * + * @returns a sequence of one or more characters that represents the + * collating element consisting of the character sequence designated by + * the iterator range [first, last). Returns an empty string if the + * character sequence is not a valid collating element. + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + string_type + lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const + { return string_type(); } + + /** + * @brief Maps one or more characters to a named character + * classification. + * + * @param first beginning of the character sequence. + * @param last one-past-the-end of the character sequence. + * @param icase ignores the case of the classification name. + * + * @returns an unspecified value that represents the character + * classification named by the character sequence designated by the + * iterator range [first, last). If @p icase is true, the returned mask + * identifies the classification regardless of the case of the characters + * to be matched (for example, [[:lower:]] is the same as [[:alpha:]]), + * otherwise a case-dependant classification is returned. The value + * returned shall be independent of the case of the characters in the + * character sequence. If the name is not recognized then returns a value + * that compares equal to 0. + * + * At least the following names (or their wide-character equivalent) are + * supported. + * - d + * - w + * - s + * - alnum + * - alpha + * - blank + * - cntrl + * - digit + * - graph + * - lower + * - print + * - punct + * - space + * - upper + * - xdigit + * + * @todo Implement this function. + */ + template<typename _Fwd_iter> + char_class_type + lookup_classname(_Fwd_iter __first, _Fwd_iter __last, + bool __icase = false) const + { return 0; } + + /** + * @brief Determines if @p c is a member of an identified class. + * + * @param c a character. + * @param f a class type (as returned from lookup_classname). + * + * @returns true if the character @p c is a member of the classification + * represented by @p f, false otherwise. + * + * @throws std::bad_cast if the current locale does not have a ctype + * facet. + */ + bool + isctype(_Ch_type __c, char_class_type __f) const; + + /** + * @brief Converts a digit to an int. + * + * @param ch a character representing a digit. + * @param radix the radix if the numeric conversion (limited to 8, 10, + * or 16). + * + * @returns the value represented by the digit ch in base radix if the + * character ch is a valid digit in base radix; otherwise returns -1. + */ + int + value(_Ch_type __ch, int __radix) const; + + /** + * @brief Imbues the regex_traits object with a copy of a new locale. + * + * @param loc A locale. + * + * @returns a copy of the previous locale in use by the regex_traits + * object. + * + * @note Calling imbue with a different locale than the one currently in + * use invalidates all cached data held by *this. + */ + locale_type + imbue(locale_type __loc) + { + std::swap(_M_locale, __loc); + return __loc; + } + + /** + * @brief Gets a copy of the current locale in use by the regex_traits + * object. + */ + locale_type + getloc() const + { return _M_locale; } + + protected: + locale_type _M_locale; + }; + + template<typename _Ch_type> + bool + regex_traits<_Ch_type>:: + isctype(_Ch_type __c, char_class_type __f) const + { + using std::ctype; + using std::use_facet; + const ctype<_Ch_type>& __ctype(use_facet< + ctype<_Ch_type> >(_M_locale)); + + if (__ctype.is(__c, __f)) + return true; + + // special case of underscore in [[:w:]] + if (__c == __ctype.widen('_')) + { + const char __wb[] = "w"; + char_class_type __wt = this->lookup_classname(__wb, + __wb + sizeof(__wb)); + if (__f | __wt) + return true; + } + + // special case of [[:space:]] in [[:blank:]] + if (__ctype.is(std::ctype_base::space, __c)) + { + const char __bb[] = "blank"; + char_class_type __bt = this->lookup_classname(__bb, + __bb + sizeof(__bb)); + if (__f | __bt) + return true; + } + + return false; + } + + template<typename _Ch_type> + int + regex_traits<_Ch_type>:: + value(_Ch_type __ch, int __radix) const + { + std::basic_istringstream<_Ch_type> __is(string_type(1, __ch)); + int __v; + if (__radix == 8) + __is >> std::oct; + else if (__radix == 16) + __is >> std::hex; + __is >> __v; + return __is.fail() ? -1 : __v; + } + + // [7.8] Class basic_regex + /** + * Objects of specializations of this class represent regular expressions + * constructed from sequences of character type @p _Ch_type. + * + * Storage for the regular expression is allocated and deallocated as + * necessary by the member functions of this class. + */ + template<typename _Ch_type, typename _Rx_traits = regex_traits<_Ch_type> > + class basic_regex + { + public: + // types: + typedef _Ch_type value_type; + typedef regex_constants::syntax_option_type flag_type; + typedef typename _Rx_traits::locale_type locale_type; + typedef typename _Rx_traits::string_type string_type; + + /** + * @name Constants + * std [28.8.1](1) + * @todo These should be constexpr. + */ + //@{ + static const regex_constants::syntax_option_type icase + = regex_constants::icase; + static const regex_constants::syntax_option_type nosubs + = regex_constants::nosubs; + static const regex_constants::syntax_option_type optimize + = regex_constants::optimize; + static const regex_constants::syntax_option_type collate + = regex_constants::collate; + static const regex_constants::syntax_option_type ECMAScript + = regex_constants::ECMAScript; + static const regex_constants::syntax_option_type basic + = regex_constants::basic; + static const regex_constants::syntax_option_type extended + = regex_constants::extended; + static const regex_constants::syntax_option_type awk + = regex_constants::awk; + static const regex_constants::syntax_option_type grep + = regex_constants::grep; + static const regex_constants::syntax_option_type egrep + = regex_constants::egrep; + //@} + + // [7.8.2] construct/copy/destroy + /** + * Constructs a basic regular expression that does not match any + * character sequence. + */ + basic_regex() + : _M_flags(regex_constants::ECMAScript), + _M_automaton(__regex::__compile<const _Ch_type*, _Rx_traits>(0, 0, + _M_traits, _M_flags)) + { } + + /** + * @brief Constructs a basic regular expression from the sequence + * [p, p + char_traits<_Ch_type>::length(p)) interpreted according to the + * flags in @p f. + * + * @param p A pointer to the start of a C-style null-terminated string + * containing a regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p p is not a valid regular expression. + */ + explicit + basic_regex(const _Ch_type* __p, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), + _M_automaton(__regex::__compile(__p, __p + _Rx_traits::length(__p), + _M_traits, _M_flags)) + { } + + /** + * @brief Constructs a basic regular expression from the sequence + * [p, p + len) interpreted according to the flags in @p f. + * + * @param p A pointer to the start of a string containing a regular + * expression. + * @param len The length of the string containing the regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p p is not a valid regular expression. + */ + basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f) + : _M_flags(__f), + _M_automaton(__regex::__compile(__p, __p + __len, _M_traits, _M_flags)) + { } + + /** + * @brief Copy-constructs a basic regular expression. + * + * @param rhs A @p regex object. + */ + basic_regex(const basic_regex& __rhs) + : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits), + _M_automaton(__rhs._M_automaton) + { } + + /** + * @brief Move-constructs a basic regular expression. + * + * @param rhs A @p regex object. + */ + basic_regex(const basic_regex&& __rhs) + : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits), + _M_automaton(std::move(__rhs._M_automaton)) + { } + + /** + * @brief Constructs a basic regular expression from the string + * @p s interpreted according to the flags in @p f. + * + * @param s A string containing a regular expression. + * @param f Flags indicating the syntax rules and options. + * + * @throws regex_error if @p s is not a valid regular expression. + */ + template<typename _Ch_traits, typename _Ch_alloc> + explicit + basic_regex(const std::basic_string<_Ch_type, _Ch_traits, + _Ch_alloc>& __s, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), + _M_automaton(__regex::__compile(__s.begin(), __s.end(), + _M_traits, _M_flags)) + { } + + /** + * @brief Constructs a basic regular expression from the range + * [first, last) interpreted according to the flags in @p f. + * + * @param first The start of a range containing a valid regular + * expression. + * @param last The end of a range containing a valid regular + * expression. + * @param f The format flags of the regular expression. + * + * @throws regex_error if @p [first, last) is not a valid regular + * expression. + */ + template<typename _InputIterator> + basic_regex(_InputIterator __first, _InputIterator __last, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), + _M_automaton(__regex::__compile(__first, __last, _M_traits, _M_flags)) + { } + + /** + * @brief Constructs a basic regular expression from an initializer list. + * + * @param l The initializer list. + * @param f The format flags of the regular expression. + * + * @throws regex_error if @p l is not a valid regular expression. + */ + basic_regex(initializer_list<_Ch_type> __l, + flag_type __f = regex_constants::ECMAScript) + : _M_flags(__f), + _M_automaton(__regex::__compile(__l.begin(), __l.end(), + _M_traits, _M_flags)) + { } + + /** + * @brief Destroys a basic regular expression. + */ + ~basic_regex() + { } + + /** + * @brief Assigns one regular expression to another. + */ + basic_regex& + operator=(const basic_regex& __rhs) + { return this->assign(__rhs); } + + /** + * @brief Move-assigns one regular expression to another. + */ + basic_regex& + operator=(basic_regex&& __rhs) + { return this->assign(std::move(__rhs)); } + + /** + * @brief Replaces a regular expression with a new one constructed from + * a C-style null-terminated string. + * + * @param A pointer to the start of a null-terminated C-style string + * containing a regular expression. + */ + basic_regex& + operator=(const _Ch_type* __p) + { return this->assign(__p, flags()); } + + /** + * @brief Replaces a regular expression with a new one constructed from + * a string. + * + * @param A pointer to a string containing a regular expression. + */ + template<typename _Ch_typeraits, typename _Allocator> + basic_regex& + operator=(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s) + { return this->assign(__s, flags()); } + + // [7.8.3] assign + /** + * @brief the real assignment operator. + * + * @param rhs Another regular expression object. + */ + basic_regex& + assign(const basic_regex& __rhs) + { + basic_regex __tmp(__rhs); + this->swap(__tmp); + return *this; + } + + /** + * @brief The move-assignment operator. + * + * @param rhs Another regular expression object. + */ + basic_regex& + assign(basic_regex&& __rhs) + { + basic_regex __tmp(std::move(__rhs)); + this->swap(__tmp); + return *this; + } + + /** + * @brief Assigns a new regular expression to a regex object from a + * C-style null-terminated string containing a regular expression + * pattern. + * + * @param p A pointer to a C-style null-terminated string containing + * a regular expression pattern. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + basic_regex& + assign(const _Ch_type* __p, + flag_type __flags = regex_constants::ECMAScript) + { return this->assign(string_type(__p), __flags); } + + /** + * @brief Assigns a new regular expression to a regex object from a + * C-style string containing a regular expression pattern. + * + * @param p A pointer to a C-style string containing a + * regular expression pattern. + * @param len The length of the regular expression pattern string. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + basic_regex& + assign(const _Ch_type* __p, std::size_t __len, flag_type __flags) + { return this->assign(string_type(__p, __len), __flags); } + + /** + * @brief Assigns a new regular expression to a regex object from a + * string containing a regular expression pattern. + * + * @param s A string containing a regular expression pattern. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * *this remains unchanged. + */ + template<typename _Ch_typeraits, typename _Allocator> + basic_regex& + assign(const basic_string<_Ch_type, _Ch_typeraits, _Allocator>& __s, + flag_type __f = regex_constants::ECMAScript) + { + basic_regex __tmp(__s, __f); + this->swap(__tmp); + return *this; + } + + /** + * @brief Assigns a new regular expression to a regex object. + * + * @param first The start of a range containing a valid regular + * expression. + * @param last The end of a range containing a valid regular + * expression. + * @param flags Syntax option flags. + * + * @throws regex_error if p does not contain a valid regular expression + * pattern interpreted according to @p flags. If regex_error is thrown, + * the object remains unchanged. + */ + template<typename _InputIterator> + basic_regex& + assign(_InputIterator __first, _InputIterator __last, + flag_type __flags = regex_constants::ECMAScript) + { return this->assign(string_type(__first, __last), __flags); } + + /** + * @brief Assigns a new regular expression to a regex object. + * + * @param l An initializer list representing a regular expression. + * @param flags Syntax option flags. + * + * @throws regex_error if @p l does not contain a valid regular + * expression pattern interpreted according to @p flags. If regex_error + * is thrown, the object remains unchanged. + */ + basic_regex& + assign(initializer_list<_Ch_type> __l, + flag_type __f = regex_constants::ECMAScript) + { return this->assign(__l.begin(), __l.end(), __f); } + + // [7.8.4] const operations + /** + * @brief Gets the number of marked subexpressions within the regular + * expression. + */ + unsigned int + mark_count() const + { return _M_automaton->_M_sub_count() - 1; } + + /** + * @brief Gets the flags used to construct the regular expression + * or in the last call to assign(). + */ + flag_type + flags() const + { return _M_flags; } + + // [7.8.5] locale + /** + * @brief Imbues the regular expression object with the given locale. + * + * @param loc A locale. + */ + locale_type + imbue(locale_type __loc) + { return _M_traits.imbue(__loc); } + + /** + * @brief Gets the locale currently imbued in the regular expression + * object. + */ + locale_type + getloc() const + { return _M_traits.getloc(); } + + // [7.8.6] swap + /** + * @brief Swaps the contents of two regular expression objects. + * + * @param rhs Another regular expression object. + */ + void + swap(basic_regex& __rhs) + { + std::swap(_M_flags, __rhs._M_flags); + std::swap(_M_traits, __rhs._M_traits); + std::swap(_M_automaton, __rhs._M_automaton); + } + +#ifdef _GLIBCXX_DEBUG + void + _M_dot(std::ostream& __ostr) + { _M_automaton->_M_dot(__ostr); } +#endif + + const __regex::_AutomatonPtr& + _M_get_automaton() const + { return _M_automaton; } + + protected: + flag_type _M_flags; + _Rx_traits _M_traits; + __regex::_AutomatonPtr _M_automaton; + }; + + /** @brief Standard regular expressions. */ + typedef basic_regex<char> regex; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Standard wide-character regular expressions. */ + typedef basic_regex<wchar_t> wregex; +#endif + + + // [7.8.6] basic_regex swap + /** + * @brief Swaps the contents of two regular expression objects. + * @param lhs First regular expression. + * @param rhs Second regular expression. + */ + template<typename _Ch_type, typename _Rx_traits> + inline void + swap(basic_regex<_Ch_type, _Rx_traits>& __lhs, + basic_regex<_Ch_type, _Rx_traits>& __rhs) + { __lhs.swap(__rhs); } + + + // [7.9] Class template sub_match + /** + * A sequence of characters matched by a particular marked sub-expression. + * + * An object of this class is essentially a pair of iterators marking a + * matched subexpression within a regular expression pattern match. Such + * objects can be converted to and compared with std::basic_string objects + * of a similar base character type as the pattern matched by the regular + * expression. + * + * The iterators that make up the pair are the usual half-open interval + * referencing the actual original pattern matched. + */ + template<typename _BiIter> + class sub_match : public std::pair<_BiIter, _BiIter> + { + public: + typedef typename iterator_traits<_BiIter>::value_type value_type; + typedef typename iterator_traits<_BiIter>::difference_type + difference_type; + typedef _BiIter iterator; + typedef std::basic_string<value_type> string_type; + + public: + bool matched; + + /** + * Gets the length of the matching sequence. + */ + difference_type + length() const + { return this->matched ? std::distance(this->first, this->second) : 0; } + + /** + * @brief Gets the matching sequence as a string. + * + * @returns the matching sequence as a string. + * + * This is the implicit conversion operator. It is identical to the + * str() member function except that it will want to pop up in + * unexpected places and cause a great deal of confusion and cursing + * from the unwary. + */ + operator string_type() const + { + return this->matched + ? string_type(this->first, this->second) + : string_type(); + } + + /** + * @brief Gets the matching sequence as a string. + * + * @returns the matching sequence as a string. + */ + string_type + str() const + { + return this->matched + ? string_type(this->first, this->second) + : string_type(); + } + + /** + * @brief Compares this and another matched sequence. + * + * @param s Another matched sequence to compare to this one. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const sub_match& __s) const + { return this->str().compare(__s.str()); } + + /** + * @brief Compares this sub_match to a string. + * + * @param s A string to compare to this sub_match. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const string_type& __s) const + { return this->str().compare(__s); } + + /** + * @brief Compares this sub_match to a C-style string. + * + * @param s A C-style string to compare to this sub_match. + * + * @retval <0 this matched sequence will collate before @p s. + * @retval =0 this matched sequence is equivalent to @p s. + * @retval <0 this matched sequence will collate after @p s. + */ + int + compare(const value_type* __s) const + { return this->str().compare(__s); } + }; + + + /** @brief Standard regex submatch over a C-style null-terminated string. */ + typedef sub_match<const char*> csub_match; + /** @brief Standard regex submatch over a standard string. */ + typedef sub_match<string::const_iterator> ssub_match; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Regex submatch over a C-style null-terminated wide string. */ + typedef sub_match<const wchar_t*> wcsub_match; + /** @brief Regex submatch over a standard wide string. */ + typedef sub_match<wstring::const_iterator> wssub_match; +#endif + + // [7.9.2] sub_match non-member operators + + /** + * @brief Tests the equivalence of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator==(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) == 0; } + + /** + * @brief Tests the inequivalence of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator!=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) != 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator<(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) < 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator<=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) <= 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator>=(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) >= 0; } + + /** + * @brief Tests the ordering of two regular expression submatches. + * @param lhs First regular expression submatch. + * @param rhs Second regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _BiIter> + inline bool + operator>(const sub_match<_BiIter>& __lhs, + const sub_match<_BiIter>& __rhs) + { return __lhs.compare(__rhs) > 0; } + + /** + * @brief Tests the equivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator==(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator!=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator<(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator>(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator>=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator<=(const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __lhs, const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter, class _Ch_traits, class _Ch_alloc> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + const basic_string< + typename iterator_traits<_Bi_iter>::value_type, + _Ch_traits, _Ch_alloc>& __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Tests the equivalence of a C string and a regular expression + * submatch. + * @param lhs A C string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of an iterator value and a regular + * expression submatch. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(typename iterator_traits<_Bi_iter>::value_type const* __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A pointer to a string? + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A pointer to a string. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A string. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const* __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Tests the equivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs == __rhs.str(); } + + /** + * @brief Tests the inequivalence of a string and a regular expression + * submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs != __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs < __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs > __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs >= __rhs.str(); } + + /** + * @brief Tests the ordering of a string and a regular expression submatch. + * @param lhs A string. + * @param rhs A regular expression submatch. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(typename iterator_traits<_Bi_iter>::value_type const& __lhs, + const sub_match<_Bi_iter>& __rhs) + { return __lhs <= __rhs.str(); } + + /** + * @brief Tests the equivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs is equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator==(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() == __rhs; } + + /** + * @brief Tests the inequivalence of a regular expression submatch and a + * string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs is not equivalent to @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator!=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() != __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs precedes @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() < __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs succeeds @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() > __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs does not precede @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator>=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() >= __rhs; } + + /** + * @brief Tests the ordering of a regular expression submatch and a string. + * @param lhs A regular expression submatch. + * @param rhs A const string reference. + * @returns true if @a lhs does not succeed @a rhs, false otherwise. + */ + template<typename _Bi_iter> + inline bool + operator<=(const sub_match<_Bi_iter>& __lhs, + typename iterator_traits<_Bi_iter>::value_type const& __rhs) + { return __lhs.str() <= __rhs; } + + /** + * @brief Inserts a matched string into an output stream. + * + * @param os The output stream. + * @param m A submatch string. + * + * @returns the output stream with the submatch string inserted. + */ + template<typename _Ch_type, typename _Ch_traits, typename _Bi_iter> + inline + basic_ostream<_Ch_type, _Ch_traits>& + operator<<(basic_ostream<_Ch_type, _Ch_traits>& __os, + const sub_match<_Bi_iter>& __m) + { return __os << __m.str(); } + + // [7.10] Class template match_results + + /* + * Special sub_match object representing an unmatched sub-expression. + */ + template<typename _Bi_iter> + inline const sub_match<_Bi_iter>& + __unmatched_sub() + { + static const sub_match<_Bi_iter> __unmatched = sub_match<_Bi_iter>(); + return __unmatched; + } + + /** + * @brief The results of a match or search operation. + * + * A collection of character sequences representing the result of a regular + * expression match. Storage for the collection is allocated and freed as + * necessary by the member functions of class template match_results. + * + * This class satisfies the Sequence requirements, with the exception that + * only the operations defined for a const-qualified Sequence are supported. + * + * The sub_match object stored at index 0 represents sub-expression 0, i.e. + * the whole match. In this case the %sub_match member matched is always true. + * The sub_match object stored at index n denotes what matched the marked + * sub-expression n within the matched expression. If the sub-expression n + * participated in a regular expression match then the %sub_match member + * matched evaluates to true, and members first and second denote the range + * of characters [first, second) which formed that match. Otherwise matched + * is false, and members first and second point to the end of the sequence + * that was searched. + * + * @nosubgrouping + */ + template<typename _Bi_iter, + typename _Allocator = allocator<sub_match<_Bi_iter> > > + class match_results + : private std::vector<std::sub_match<_Bi_iter>, _Allocator> + { + private: + /* + * The vector base is empty if this does not represent a successful match. + * Otherwise it contains n+3 elements where n is the number of marked + * sub-expressions: + * [0] entire match + * [1] 1st marked subexpression + * ... + * [n] nth marked subexpression + * [n+1] prefix + * [n+2] suffix + */ + typedef std::vector<std::sub_match<_Bi_iter>, _Allocator> + _Base_type; + + public: + /** + * @name 10.? Public Types + */ + //@{ + typedef sub_match<_Bi_iter> value_type; + typedef const value_type& const_reference; + typedef const_reference reference; + typedef typename _Base_type::const_iterator const_iterator; + typedef const_iterator iterator; + typedef typename std::iterator_traits<_Bi_iter>::difference_type + difference_type; + /* TODO: needs allocator_traits */ + typedef typename _Allocator::size_type size_type; + typedef _Allocator allocator_type; + typedef typename std::iterator_traits<_Bi_iter>::value_type + char_type; + typedef std::basic_string<char_type> string_type; + //@} + + public: + /** + * @name 10.1 Construction, Copying, and Destruction + */ + //@{ + + /** + * @brief Constructs a default %match_results container. + * @post size() returns 0 and str() returns an empty string. + */ + explicit + match_results(const _Allocator& __a = _Allocator()) + : _Base_type(__a) + { } + + /** + * @brief Copy constructs a %match_results. + */ + match_results(const match_results& __rhs) + : _Base_type(__rhs) + { } + + /** + * @brief Assigns rhs to *this. + */ + match_results& + operator=(const match_results __rhs) + { + match_results(__rhs).swap(*this); + return *this; + } + + /** + * @brief Destroys a %match_results object. + */ + ~match_results() + { } + + //@} + + /** + * @name 10.2 Size + */ + //@{ + + /** + * @brief Gets the number of matches and submatches. + * + * The number of matches for a given regular expression will be either 0 + * if there was no match or mark_count() + 1 if a match was successful. + * Some matches may be empty. + * + * @returns the number of matches found. + */ + size_type + size() const + { + size_type __size = _Base_type::size(); + return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0; + } + + size_type + max_size() const + { return _Base_type::max_size(); } + + /** + * @brief Indicates if the %match_results contains no results. + * @retval true The %match_results object is empty. + * @retval false The %match_results object is not empty. + */ + bool + empty() const + { return _Base_type::empty(); } + + //@} + + /** + * @name 10.3 Element Access + */ + //@{ + + /** + * @brief Gets the length of the indicated submatch. + * @param sub indicates the submatch. + * + * This function returns the length of the indicated submatch, or the + * length of the entire match if @p sub is zero (the default). + */ + difference_type + length(size_type __sub = 0) const + { return this[__sub].length(); } + + /** + * @brief Gets the offset of the beginning of the indicated submatch. + * @param sub indicates the submatch. + * + * This function returns the offset from the beginning of the target + * sequence to the beginning of the submatch, unless the value of @p sub + * is zero (the default), in which case this function returns the offset + * from the beginning of the target sequence to the beginning of the + * match. + * + * Returns -1 if @p sub is out of range. + */ + difference_type + position(size_type __sub = 0) const + { + return __sub < size() ? std::distance(this->prefix().first, + (*this)[__sub].first) : -1; + } + + /** + * @brief Gets the match or submatch converted to a string type. + * @param sub indicates the submatch. + * + * This function gets the submatch (or match, if @p sub is zero) extracted + * from the target range and converted to the associated string type. + */ + string_type + str(size_type __sub = 0) const + { return (*this)[__sub].str(); } + + /** + * @brief Gets a %sub_match reference for the match or submatch. + * @param sub indicates the submatch. + * + * This function gets a reference to the indicated submatch, or the entire + * match if @p sub is zero. + * + * If @p sub >= size() then this function returns a %sub_match with a + * special value indicating no submatch. + */ + const_reference + operator[](size_type __sub) const + { + return __sub < size() + ? _Base_type::operator[](__sub) + : __unmatched_sub<_Bi_iter>(); + } + + /** + * @brief Gets a %sub_match representing the match prefix. + * + * This function gets a reference to a %sub_match object representing the + * part of the target range between the start of the target range and the + * start of the match. + */ + const_reference + prefix() const + { + return !empty() + ? _Base_type::operator[](_Base_type::size() - 2) + : __unmatched_sub<_Bi_iter>(); + } + + /** + * @brief Gets a %sub_match representing the match suffix. + * + * This function gets a reference to a %sub_match object representing the + * part of the target range between the end of the match and the end of + * the target range. + */ + const_reference + suffix() const + { + return !empty() + ? _Base_type::operator[](_Base_type::size() - 1) + : __unmatched_sub<_Bi_iter>(); + } + + /** + * @brief Gets an iterator to the start of the %sub_match collection. + */ + const_iterator + begin() const + { return _Base_type::begin(); } + + /** + * @brief Gets an iterator to the start of the %sub_match collection. + */ + const_iterator + cbegin() const + { return _Base_type::cbegin(); } + + /** + * @brief Gets an iterator to one-past-the-end of the collection. + */ + const_iterator + end() const + { + return !empty() + ? _Base_type::end() - 2 + : _Base_type::end(); + } + + /** + * @brief Gets an iterator to one-past-the-end of the collection. + */ + const_iterator + cend() const + { + return !empty() + ? _Base_type::cend() - 2 + : _Base_type::cend(); + } + + //@} + + /** + * @name 10.4 Formatting + * + * These functions perform formatted substitution of the matched character + * sequences into their target. The format specifiers and escape sequences + * accepted by these functions are determined by their @p flags parameter + * as documented above. + */ + //@{ + + /** + * @todo Implement this function. + */ + template<typename _Out_iter> + _Out_iter + format(_Out_iter __out, const string_type& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::format_default) const + { return __out; } + + /** + * @todo Implement this function. + */ + string_type + format(const string_type& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::format_default) const; + + //@} + + /** + * @name 10.5 Allocator + */ + //@{ + + /** + * @brief Gets a copy of the allocator. + */ + allocator_type + get_allocator() const + { return _Base_type::get_allocator(); } + + //@} + + /** + * @name 10.6 Swap + */ + //@{ + + /** + * @brief Swaps the contents of two match_results. + */ + void + swap(match_results& __that) + { _Base_type::swap(__that); } + //@} + + private: + friend class __regex::_SpecializedResults<_Bi_iter, _Allocator>; + }; + + typedef match_results<const char*> cmatch; + typedef match_results<string::const_iterator> smatch; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef match_results<const wchar_t*> wcmatch; + typedef match_results<wstring::const_iterator> wsmatch; +#endif + + // match_results comparisons + /** + * @brief Compares two match_results for equality. + * @returns true if the two objects refer to the same match, + * false otherwise. + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator> + inline bool + operator==(const match_results<_Bi_iter, _Allocator>& __m1, + const match_results<_Bi_iter, _Allocator>& __m2); + + /** + * @brief Compares two match_results for inequality. + * @returns true if the two objects do not refer to the same match, + * false otherwise. + */ + template<typename _Bi_iter, class _Allocator> + inline bool + operator!=(const match_results<_Bi_iter, _Allocator>& __m1, + const match_results<_Bi_iter, _Allocator>& __m2) + { return !(__m1 == __m2); } + + // [7.10.6] match_results swap + /** + * @brief Swaps two match results. + * @param lhs A match result. + * @param rhs A match result. + * + * The contents of the two match_results objects are swapped. + */ + template<typename _Bi_iter, typename _Allocator> + inline void + swap(match_results<_Bi_iter, _Allocator>& __lhs, + match_results<_Bi_iter, _Allocator>& __rhs) + { __lhs.swap(__rhs); } + + // [7.11.2] Function template regex_match + /** + * @name Matching, Searching, and Replacing + */ + //@{ + + /** + * @brief Determines if there is a match between the regular expression @p e + * and all of the character sequence [first, last). + * + * @param s Start of the character sequence to match. + * @param e One-past-the-end of the character sequence to match. + * @param m The match results. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator, + typename _Ch_type, typename _Rx_traits> + bool + regex_match(_Bi_iter __s, + _Bi_iter __e, + match_results<_Bi_iter, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + __regex::_AutomatonPtr __a = __re._M_get_automaton(); + __regex::_Automaton::_SizeT __sz = __a->_M_sub_count(); + __regex::_SpecializedCursor<_Bi_iter> __cs(__s, __e); + __regex::_SpecializedResults<_Bi_iter, _Allocator> __r(__sz, __cs, __m); + __regex::_Grep_matcher __matcher(__cs, __r, __a, __flags); + return __m[0].matched; + } + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and all of the character sequence [first, last). + * + * @param first Beginning of the character sequence to match. + * @param last One-past-the-end of the character sequence to match. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + bool + regex_match(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_match(__first, __last, __what, __re, __flags); + } + + /** + * @brief Determines if there is a match between the regular expression @p e + * and a C-style null-terminated string. + * + * @param s The C-style null-terminated string to match. + * @param m The match results. + * @param re The regular expression. + * @param f Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, typename _Allocator, typename _Rx_traits> + inline bool + regex_match(const _Ch_type* __s, + match_results<const _Ch_type*, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_match(__s, __s + _Rx_traits::length(__s), __m, __re, __f); } + + /** + * @brief Determines if there is a match between the regular expression @p e + * and a string. + * + * @param s The string to match. + * @param m The match results. + * @param re The regular expression. + * @param flags Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Ch_alloc, + typename _Allocator, typename _Ch_type, typename _Rx_traits> + inline bool + regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, + match_results<typename basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_match(__s.begin(), __s.end(), __m, __re, __flags); } + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and a C-style null-terminated string. + * + * @param s The C-style null-terminated string to match. + * @param re The regular expression. + * @param f Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, class _Rx_traits> + inline bool + regex_match(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_match(__s, __s + _Rx_traits::length(__s), __re, __f); } + + /** + * @brief Indicates if there is a match between the regular expression @p e + * and a string. + * + * @param s [IN] The string to match. + * @param re [IN] The regular expression. + * @param flags [IN] Controls how the regular expression is matched. + * + * @retval true A match exists. + * @retval false Otherwise. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Str_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_match(const basic_string<_Ch_type, _Ch_traits, _Str_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_match(__s.begin(), __s.end(), __re, __flags); } + + // [7.11.3] Function template regex_search + /** + * Searches for a regular expression within a range. + * @param first [IN] The start of the string to search. + * @param last [IN] One-past-the-end of the string to search. + * @param m [OUT] The match results. + * @param re [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Bi_iter, typename _Allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(_Bi_iter __first, _Bi_iter __last, + match_results<_Bi_iter, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return false; } + + /** + * Searches for a regular expression within a range. + * @param first [IN] The start of the string to search. + * @param last [IN] One-past-the-end of the string to search. + * @param re [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return regex_search(__first, __last, __what, __re, __flags); + } + + /** + * @brief Searches for a regular expression within a C-string. + * @param s [IN] A C-string to search for the regex. + * @param m [OUT] The set of regex matches. + * @param e [IN] The regex to search for in @p s. + * @param f [IN] The search flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, class _Allocator, class _Rx_traits> + inline bool + regex_search(const _Ch_type* __s, + match_results<const _Ch_type*, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s, __s + _Rx_traits::length(__s), __m, __e, __f); } + + /** + * @brief Searches for a regular expression within a C-string. + * @param s [IN] The C-string to search. + * @param e [IN] The regular expression to search for. + * @param f [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s, __s + _Rx_traits::length(__s), __e, __f); } + + /** + * @brief Searches for a regular expression within a string. + * @param s [IN] The string to search. + * @param e [IN] The regular expression to search for. + * @param flags [IN] Search policy flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string. + * @doctodo + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _String_allocator, + typename _Ch_type, typename _Rx_traits> + inline bool + regex_search(const basic_string<_Ch_type, _Ch_traits, + _String_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return regex_search(__s.begin(), __s.end(), __e, __flags); } + + /** + * @brief Searches for a regular expression within a string. + * @param s [IN] A C++ string to search for the regex. + * @param m [OUT] The set of regex matches. + * @param e [IN] The regex to search for in @p s. + * @param f [IN] The search flags. + * @retval true A match was found within the string. + * @retval false No match was found within the string, the content of %m is + * undefined. + * + * @throws an exception of type regex_error. + */ + template<typename _Ch_traits, typename _Ch_alloc, + typename _Allocator, typename _Ch_type, + typename _Rx_traits> + inline bool + regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s, + match_results<typename basic_string<_Ch_type, + _Ch_traits, _Ch_alloc>::const_iterator, _Allocator>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return regex_search(__s.begin(), __s.end(), __m, __e, __f); } + + // std [28.11.4] Function template regex_replace + /** + * @doctodo + * @param out + * @param first + * @param last + * @param e + * @param fmt + * @param flags + * + * @returns out + * @throws an exception of type regex_error. + * + * @todo Implement this function. + */ + template<typename _Out_iter, typename _Bi_iter, + typename _Rx_traits, typename _Ch_type> + inline _Out_iter + regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return __out; } + + /** + * @doctodo + * @param s + * @param e + * @param fmt + * @param flags + * + * @returns a copy of string @p s with replacements. + * + * @throws an exception of type regex_error. + */ + template<typename _Rx_traits, typename _Ch_type> + inline basic_string<_Ch_type> + regex_replace(const basic_string<_Ch_type>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + const basic_string<_Ch_type>& __fmt, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + std::string __result; + regex_replace(std::back_inserter(__result), + __s.begin(), __s.end(), __e, __fmt, __flags); + return __result; + } + + //@} + + // std [28.12] Class template regex_iterator + /** + * An iterator adaptor that will provide repeated calls of regex_search over + * a range until no more matches remain. + */ + template<typename _Bi_iter, + typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, + typename _Rx_traits = regex_traits<_Ch_type> > + class regex_iterator + { + public: + typedef basic_regex<_Ch_type, _Rx_traits> regex_type; + typedef match_results<_Bi_iter> value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + public: + /** + * @brief Provides a singular iterator, useful for indicating + * one-past-the-end of a range. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(); + + /** + * Constructs a %regex_iterator... + * @param a [IN] The start of a text range to search. + * @param b [IN] One-past-the-end of the text range to search. + * @param re [IN] The regular expression to match. + * @param m [IN] Policy flags for match rules. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Copy constructs a %regex_iterator. + * @todo Implement this function. + * @doctodo + */ + regex_iterator(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator& + operator=(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + bool + operator==(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + bool + operator!=(const regex_iterator& __rhs); + + /** + * @todo Implement this function. + * @doctodo + */ + const value_type& + operator*(); + + /** + * @todo Implement this function. + * @doctodo + */ + const value_type* + operator->(); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator& + operator++(); + + /** + * @todo Implement this function. + * @doctodo + */ + regex_iterator + operator++(int); + + private: + // these members are shown for exposition only: + _Bi_iter begin; + _Bi_iter end; + const regex_type* pregex; + regex_constants::match_flag_type flags; + match_results<_Bi_iter> match; + }; + + typedef regex_iterator<const char*> cregex_iterator; + typedef regex_iterator<string::const_iterator> sregex_iterator; +#ifdef _GLIBCXX_USE_WCHAR_T + typedef regex_iterator<const wchar_t*> wcregex_iterator; + typedef regex_iterator<wstring::const_iterator> wsregex_iterator; +#endif + + // [7.12.2] Class template regex_token_iterator + /** + * Iterates over submatches in a range (or @a splits a text string). + * + * The purpose of this iterator is to enumerate all, or all specified, + * matches of a regular expression within a text range. The dereferenced + * value of an iterator of this class is a std::sub_match object. + */ + template<typename _Bi_iter, + typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type, + typename _Rx_traits = regex_traits<_Ch_type> > + class regex_token_iterator + { + public: + typedef basic_regex<_Ch_type, _Rx_traits> regex_type; + typedef sub_match<_Bi_iter> value_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + public: + /** + * @brief Default constructs a %regex_token_iterator. + * @todo Implement this function. + * + * A default-constructed %regex_token_iterator is a singular iterator + * that will compare equal to the one-past-the-end value for any + * iterator of the same type. + */ + regex_token_iterator(); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatch [IN] Which submatch to return. There are some + * special values for this parameter: + * - -1 each enumerated subexpression does NOT + * match the regular expression (aka field + * splitting) + * - 0 the entire string matching the + * subexpression is returned for each match + * within the text. + * - >0 enumerates only the indicated + * subexpression from a match within the text. + * @param m [IN] Policy flags for match rules. + * + * @todo Implement this function. + * @doctodo + */ + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, const regex_type& __re, + int __submatch = 0, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatches [IN] A list of subexpressions to return for each + * regular expression match within the text. + * @param m [IN] Policy flags for match rules. + * + * @todo Implement this function. + * @doctodo + */ + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, + const regex_type& __re, + const std::vector<int>& __submatches, + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * Constructs a %regex_token_iterator... + * @param a [IN] The start of the text to search. + * @param b [IN] One-past-the-end of the text to search. + * @param re [IN] The regular expression to search for. + * @param submatches [IN] A list of subexpressions to return for each + * regular expression match within the text. + * @param m [IN] Policy flags for match rules. + + * @todo Implement this function. + * @doctodo + */ + template<std::size_t _Nm> + regex_token_iterator(_Bi_iter __a, _Bi_iter __b, + const regex_type& __re, + const int (&__submatches)[_Nm], + regex_constants::match_flag_type __m + = regex_constants::match_default); + + /** + * @brief Copy constructs a %regex_token_iterator. + * @param rhs [IN] A %regex_token_iterator to copy. + * @todo Implement this function. + */ + regex_token_iterator(const regex_token_iterator& __rhs); + + /** + * @brief Assigns a %regex_token_iterator to another. + * @param rhs [IN] A %regex_token_iterator to copy. + * @todo Implement this function. + */ + regex_token_iterator& + operator=(const regex_token_iterator& __rhs); + + /** + * @brief Compares a %regex_token_iterator to another for equality. + * @todo Implement this function. + */ + bool + operator==(const regex_token_iterator& __rhs); + + /** + * @brief Compares a %regex_token_iterator to another for inequality. + * @todo Implement this function. + */ + bool + operator!=(const regex_token_iterator& __rhs); + + /** + * @brief Dereferences a %regex_token_iterator. + * @todo Implement this function. + */ + const value_type& + operator*(); + + /** + * @brief Selects a %regex_token_iterator member. + * @todo Implement this function. + */ + const value_type* + operator->(); + + /** + * @brief Increments a %regex_token_iterator. + * @todo Implement this function. + */ + regex_token_iterator& + operator++(); + + /** + * @brief Postincrements a %regex_token_iterator. + * @todo Implement this function. + */ + regex_token_iterator + operator++(int); + + private: // data members for exposition only: + typedef regex_iterator<_Bi_iter, _Ch_type, _Rx_traits> position_iterator; + + position_iterator __position; + const value_type* __result; + value_type __suffix; + std::size_t __n; + std::vector<int> __subs; + }; + + /** @brief Token iterator for C-style NULL-terminated strings. */ + typedef regex_token_iterator<const char*> cregex_token_iterator; + /** @brief Token iterator for standard strings. */ + typedef regex_token_iterator<string::const_iterator> sregex_token_iterator; +#ifdef _GLIBCXX_USE_WCHAR_T + /** @brief Token iterator for C-style NULL-terminated wide strings. */ + typedef regex_token_iterator<const wchar_t*> wcregex_token_iterator; + /** @brief Token iterator for standard wide-character strings. */ + typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; +#endif + + //@} // group regex + +} + diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h new file mode 100644 index 00000000000..0bc362dc77e --- /dev/null +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -0,0 +1,1115 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_parser.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ +namespace __regex +{ + struct _Scanner_base + { + // FIXME: replace these constanst with constexpr + typedef unsigned int _StateT; + + static const _StateT _S_state_at_start = 1 << 0; + static const _StateT _S_state_in_brace = 1 << 2; + static const _StateT _S_state_in_bracket = 1 << 3; + }; + + // + // @brief Scans an input range for regex tokens. + // + // The %_Scanner class interprets the regular expression pattern in the input + // range passed to its constructor as a sequence of parse tokens passed to + // the regular expression compiler. The sequence of tokens provided depends + // on the flag settings passed to the constructor: different regular + // expression gramars will interpret the same input pattern in syntactically + // different ways. + // + template<typename _InputIterator> + class _Scanner: public _Scanner_base + { + public: + typedef _InputIterator _IteratorT; + typedef typename std::iterator_traits<_IteratorT>::value_type _CharT; + typedef std::basic_string<_CharT> _StringT; + typedef regex_constants::syntax_option_type _FlagT; + typedef const std::ctype<_CharT> _CtypeT; + + // Token types returned from the scanner. + enum _TokenT + { + _S_token_anychar, + _S_token_backref, + _S_token_bracket_begin, + _S_token_bracket_end, + _S_token_inverse_class, + _S_token_char_class_name, + _S_token_closure0, + _S_token_closure1, + _S_token_collelem_multi, + _S_token_collelem_single, + _S_token_collsymbol, + _S_token_comma, + _S_token_dash, + _S_token_dup_count, + _S_token_eof, + _S_token_equiv_class_name, + _S_token_interval_begin, + _S_token_interval_end, + _S_token_line_begin, + _S_token_line_end, + _S_token_opt, + _S_token_or, + _S_token_ord_char, + _S_token_quoted_char, + _S_token_subexpr_begin, + _S_token_subexpr_end, + _S_token_word_begin, + _S_token_word_end, + _S_token_unknown + }; + + public: + _Scanner(_IteratorT __begin, _IteratorT __end, _FlagT __flags, + std::locale __loc) + : _M_current(__begin) , _M_end(__end) , _M_flags(__flags), + _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(_S_state_at_start) + { _M_advance(); } + + void + _M_advance(); + + _TokenT + _M_token() const + { return _M_curToken; } + + const _StringT& + _M_value() const + { return _M_curValue; } + +#ifdef _GLIBCXX_DEBUG + std::ostream& + _M_print(std::ostream&); +#endif + + private: + void + _M_eat_escape(); + + void + _M_scan_in_brace(); + + void + _M_scan_in_bracket(); + + void + _M_eat_charclass(); + + void + _M_eat_equivclass(); + + void + _M_eat_collsymbol(); + + private: + _IteratorT _M_current; + _IteratorT _M_end; + _FlagT _M_flags; + _CtypeT& _M_ctype; + _TokenT _M_curToken; + _StringT _M_curValue; + _StateT _M_state; + }; + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_advance() + { + if (_M_current == _M_end) + { + _M_curToken = _S_token_eof; + return; + } + + _CharT __c = *_M_current; + if (_M_state & _S_state_in_bracket) + { + _M_scan_in_bracket(); + return; + } + if (_M_state & _S_state_in_brace) + { + _M_scan_in_brace(); + return; + } + else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^')) + { + _M_curToken = _S_token_line_begin; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('$')) + { + _M_curToken = _S_token_line_end; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('.')) + { + _M_curToken = _S_token_anychar; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('*')) + { + _M_curToken = _S_token_closure0; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('+')) + { + _M_curToken = _S_token_closure1; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('|')) + { + _M_curToken = _S_token_or; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('[')) + { + _M_curToken = _S_token_bracket_begin; + _M_state |= (_S_state_in_bracket | _S_state_at_start); + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('\\')) + { + _M_eat_escape(); + return; + } + else if (!(_M_flags & (regex_constants::basic | regex_constants::grep))) + { + if (__c == _M_ctype.widen('(')) + { + _M_curToken = _S_token_subexpr_begin; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen(')')) + { + _M_curToken = _S_token_subexpr_end; + ++_M_current; + return; + } + else if (__c == _M_ctype.widen('{')) + { + _M_curToken = _S_token_interval_begin; + _M_state |= _S_state_in_brace; + ++_M_current; + return; + } + } + + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + ++_M_current; + } + + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_scan_in_brace() + { + if (_M_ctype.is(_CtypeT::digit, *_M_current)) + { + _M_curToken = _S_token_dup_count; + _M_curValue.assign(1, *_M_current); + ++_M_current; + while (_M_current != _M_end + && _M_ctype.is(_CtypeT::digit, *_M_current)) + { + _M_curValue += *_M_current; + ++_M_current; + } + return; + } + else if (*_M_current == _M_ctype.widen(',')) + { + _M_curToken = _S_token_comma; + ++_M_current; + return; + } + if (_M_flags & (regex_constants::basic | regex_constants::grep)) + { + if (*_M_current == _M_ctype.widen('\\')) + _M_eat_escape(); + } + else + { + if (*_M_current == _M_ctype.widen('}')) + { + _M_curToken = _S_token_interval_end; + _M_state &= ~_S_state_in_brace; + ++_M_current; + return; + } + } + } + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_scan_in_bracket() + { + if (_M_state & _S_state_at_start && *_M_current == _M_ctype.widen('^')) + { + _M_curToken = _S_token_inverse_class; + _M_state &= ~_S_state_at_start; + ++_M_current; + return; + } + else if (*_M_current == _M_ctype.widen('[')) + { + ++_M_current; + if (_M_current == _M_end) + { + _M_curToken = _S_token_eof; + return; + } + + if (*_M_current == _M_ctype.widen('.')) + { + _M_curToken = _S_token_collsymbol; + _M_eat_collsymbol(); + return; + } + else if (*_M_current == _M_ctype.widen(':')) + { + _M_curToken = _S_token_char_class_name; + _M_eat_charclass(); + return; + } + else if (*_M_current == _M_ctype.widen('=')) + { + _M_curToken = _S_token_equiv_class_name; + _M_eat_equivclass(); + return; + } + } + else if (*_M_current == _M_ctype.widen('-')) + { + _M_curToken = _S_token_dash; + ++_M_current; + return; + } + else if (*_M_current == _M_ctype.widen(']')) + { + if (!(_M_flags & regex_constants::ECMAScript) + || !(_M_state & _S_state_at_start)) + { + // special case: only if _not_ chr first after + // '[' or '[^' and if not ECMAscript + _M_curToken = _S_token_bracket_end; + ++_M_current; + return; + } + } + _M_curToken = _S_token_collelem_single; + _M_curValue.assign(1, *_M_current); + ++_M_current; + } + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_eat_escape() + { + ++_M_current; + if (_M_current == _M_end) + { + _M_curToken = _S_token_eof; + return; + } + _CharT __c = *_M_current; + ++_M_current; + + if (__c == _M_ctype.widen('(')) + { + if (!(_M_flags & (regex_constants::basic | regex_constants::grep))) + { + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + } + else + _M_curToken = _S_token_subexpr_begin; + } + else if (__c == _M_ctype.widen(')')) + { + if (!(_M_flags & (regex_constants::basic | regex_constants::grep))) + { + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + } + else + _M_curToken = _S_token_subexpr_end; + } + else if (__c == _M_ctype.widen('{')) + { + if (!(_M_flags & (regex_constants::basic | regex_constants::grep))) + { + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + } + else + { + _M_curToken = _S_token_interval_begin; + _M_state |= _S_state_in_brace; + } + } + else if (__c == _M_ctype.widen('}')) + { + if (!(_M_flags & (regex_constants::basic | regex_constants::grep))) + { + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + } + else + { + if (!(_M_state && _S_state_in_brace)) + __throw_regex_error(regex_constants::error_badbrace); + _M_state &= ~_S_state_in_brace; + _M_curToken = _S_token_interval_end; + } + } + else if (__c == _M_ctype.widen('x')) + { + ++_M_current; + if (_M_current == _M_end) + { + _M_curToken = _S_token_eof; + return; + } + if (_M_ctype.is(_CtypeT::digit, *_M_current)) + { + _M_curValue.assign(1, *_M_current); + ++_M_current; + if (_M_current == _M_end) + { + _M_curToken = _S_token_eof; + return; + } + if (_M_ctype.is(_CtypeT::digit, *_M_current)) + { + _M_curValue += *_M_current; + ++_M_current; + return; + } + } + } + else if (__c == _M_ctype.widen('^') + || __c == _M_ctype.widen('.') + || __c == _M_ctype.widen('*') + || __c == _M_ctype.widen('$') + || __c == _M_ctype.widen('\\')) + { + _M_curToken = _S_token_ord_char; + _M_curValue.assign(1, __c); + } + else if (_M_ctype.is(_CtypeT::digit, __c)) + { + _M_curToken = _S_token_backref; + _M_curValue.assign(1, __c); + } + else + __throw_regex_error(regex_constants::error_escape); + } + + + // Eats a character class or throwns an exception. + // current point to ':' delimiter on entry, char after ']' on return + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_eat_charclass() + { + ++_M_current; // skip ':' + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_ctype); + for (_M_curValue.clear(); + _M_current != _M_end && *_M_current != _M_ctype.widen(':'); + ++_M_current) + _M_curValue += *_M_current; + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_ctype); + ++_M_current; // skip ':' + if (*_M_current != _M_ctype.widen(']')) + __throw_regex_error(regex_constants::error_ctype); + ++_M_current; // skip ']' + } + + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_eat_equivclass() + { + ++_M_current; // skip '=' + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_collate); + for (_M_curValue.clear(); + _M_current != _M_end && *_M_current != _M_ctype.widen('='); + ++_M_current) + _M_curValue += *_M_current; + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_collate); + ++_M_current; // skip '=' + if (*_M_current != _M_ctype.widen(']')) + __throw_regex_error(regex_constants::error_collate); + ++_M_current; // skip ']' + } + + + template<typename _InputIterator> + void + _Scanner<_InputIterator>:: + _M_eat_collsymbol() + { + ++_M_current; // skip '.' + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_collate); + for (_M_curValue.clear(); + _M_current != _M_end && *_M_current != _M_ctype.widen('.'); + ++_M_current) + _M_curValue += *_M_current; + if (_M_current == _M_end) + __throw_regex_error(regex_constants::error_collate); + ++_M_current; // skip '.' + if (*_M_current != _M_ctype.widen(']')) + __throw_regex_error(regex_constants::error_collate); + ++_M_current; // skip ']' + } + +#ifdef _GLIBCXX_DEBUG + template<typename _InputIterator> + std::ostream& + _Scanner<_InputIterator>:: + _M_print(std::ostream& ostr) + { + switch (_M_curToken) + { + case _S_token_anychar: + ostr << "any-character\n"; + break; + case _S_token_backref: + ostr << "backref\n"; + break; + case _S_token_bracket_begin: + ostr << "bracket-begin\n"; + break; + case _S_token_bracket_end: + ostr << "bracket-end\n"; + break; + case _S_token_char_class_name: + ostr << "char-class-name \"" << _M_curValue << "\"\n"; + break; + case _S_token_closure0: + ostr << "closure0\n"; + break; + case _S_token_closure1: + ostr << "closure1\n"; + break; + case _S_token_collelem_multi: + ostr << "coll-elem-multi \"" << _M_curValue << "\"\n"; + break; + case _S_token_collelem_single: + ostr << "coll-elem-single \"" << _M_curValue << "\"\n"; + break; + case _S_token_collsymbol: + ostr << "collsymbol \"" << _M_curValue << "\"\n"; + break; + case _S_token_comma: + ostr << "comma\n"; + break; + case _S_token_dash: + ostr << "dash\n"; + break; + case _S_token_dup_count: + ostr << "dup count: " << _M_curValue << "\n"; + break; + case _S_token_eof: + ostr << "EOF\n"; + break; + case _S_token_equiv_class_name: + ostr << "equiv-class-name \"" << _M_curValue << "\"\n"; + break; + case _S_token_interval_begin: + ostr << "interval begin\n"; + break; + case _S_token_interval_end: + ostr << "interval end\n"; + break; + case _S_token_line_begin: + ostr << "line begin\n"; + break; + case _S_token_line_end: + ostr << "line end\n"; + break; + case _S_token_opt: + ostr << "opt\n"; + break; + case _S_token_or: + ostr << "or\n"; + break; + case _S_token_ord_char: + ostr << "ordinary character: \"" << _M_value() << "\"\n"; + break; + case _S_token_quoted_char: + ostr << "quoted char\n"; + break; + case _S_token_subexpr_begin: + ostr << "subexpr begin\n"; + break; + case _S_token_subexpr_end: + ostr << "subexpr end\n"; + break; + case _S_token_word_begin: + ostr << "word begin\n"; + break; + case _S_token_word_end: + ostr << "word end\n"; + break; + case _S_token_unknown: + ostr << "-- unknown token --\n"; + break; + } + return ostr; + } +#endif + + // Builds an NFA from an input iterator interval. + template<typename _InIter, typename _TraitsT> + class _Compiler + { + public: + typedef _InIter _IterT; + typedef typename std::iterator_traits<_InIter>::value_type _CharT; + typedef std::basic_string<_CharT> _StringT; + typedef regex_constants::syntax_option_type _FlagT; + + public: + _Compiler(const _InIter& __b, const _InIter& __e, + _TraitsT& __traits, _FlagT __flags); + + const _Nfa& + _M_nfa() const + { return _M_state_store; } + + private: + typedef _Scanner<_InIter> _ScannerT; + typedef typename _ScannerT::_TokenT _TokenT; + typedef std::stack<_StateSeq, std::vector<_StateSeq> > _StackT; + typedef _RangeMatcher<_InIter, _TraitsT> _RMatcherT; + + // accepts a specific token or returns false. + bool + _M_match_token(_TokenT __token); + + void + _M_disjunction(); + + bool + _M_alternative(); + + bool + _M_term(); + + bool + _M_assertion(); + + bool + _M_quantifier(); + + bool + _M_atom(); + + bool + _M_bracket_expression(); + + bool + _M_bracket_list(_RMatcherT& __matcher); + + bool + _M_follow_list(_RMatcherT& __matcher); + + bool + _M_follow_list2(_RMatcherT& __matcher); + + bool + _M_expression_term(_RMatcherT& __matcher); + + bool + _M_range_expression(_RMatcherT& __matcher); + + bool + _M_start_range(_RMatcherT& __matcher); + + bool + _M_collating_symbol(_RMatcherT& __matcher); + + bool + _M_equivalence_class(_RMatcherT& __matcher); + + bool + _M_character_class(_RMatcherT& __matcher); + + int + _M_cur_int_value(int __radix); + + private: + _TraitsT& _M_traits; + _ScannerT _M_scanner; + _StringT _M_cur_value; + _Nfa _M_state_store; + _StackT _M_stack; + }; + + template<typename _InIter, typename _TraitsT> + _Compiler<_InIter, _TraitsT>:: + _Compiler(const _InIter& __b, const _InIter& __e, _TraitsT& __traits, + _Compiler<_InIter, _TraitsT>::_FlagT __flags) + : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()), + _M_state_store(__flags) + { + using std::bind; + using std::placeholders::_1; + using std::placeholders::_2; + typedef _StartTagger<_InIter, _TraitsT> _Start; + typedef _EndTagger<_InIter, _TraitsT> _End; + + _StateSeq __r(_M_state_store, + _M_state_store._M_insert_subexpr_begin( + bind(_Start(0), _1, _2))); + _M_disjunction(); + if (!_M_stack.empty()) + { + __r._M_append(_M_stack.top()); + _M_stack.pop(); + } + __r._M_append(_M_state_store. + _M_insert_subexpr_end(0, bind(_End(0), _1, _2))); + __r._M_append(_M_state_store._M_insert_accept()); + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_match_token(_Compiler<_InIter, _TraitsT>::_TokenT token) + { + if (token == _M_scanner._M_token()) + { + _M_cur_value = _M_scanner._M_value(); + _M_scanner._M_advance(); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + void + _Compiler<_InIter, _TraitsT>:: + _M_disjunction() + { + this->_M_alternative(); + if (_M_match_token(_ScannerT::_S_token_or)) + { + _StateSeq __alt1 = _M_stack.top(); _M_stack.pop(); + this->_M_disjunction(); + _StateSeq __alt2 = _M_stack.top(); _M_stack.pop(); + _M_stack.push(_StateSeq(__alt1, __alt2)); + } + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_alternative() + { + if (this->_M_term()) + { + _StateSeq __re = _M_stack.top(); _M_stack.pop(); + this->_M_alternative(); + if (!_M_stack.empty()) + { + __re._M_append(_M_stack.top()); + _M_stack.pop(); + } + _M_stack.push(__re); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_term() + { + if (this->_M_assertion()) + return true; + if (this->_M_atom()) + { + this->_M_quantifier(); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_assertion() + { + if (_M_match_token(_ScannerT::_S_token_line_begin)) + { + // __m.push(_Matcher::_S_opcode_line_begin); + return true; + } + if (_M_match_token(_ScannerT::_S_token_line_end)) + { + // __m.push(_Matcher::_S_opcode_line_end); + return true; + } + if (_M_match_token(_ScannerT::_S_token_word_begin)) + { + // __m.push(_Matcher::_S_opcode_word_begin); + return true; + } + if (_M_match_token(_ScannerT::_S_token_word_end)) + { + // __m.push(_Matcher::_S_opcode_word_end); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_quantifier() + { + if (_M_match_token(_ScannerT::_S_token_closure0)) + { + if (_M_stack.empty()) + __throw_regex_error(regex_constants::error_badrepeat); + _StateSeq __r(_M_stack.top(), -1); + __r._M_append(__r._M_front()); + _M_stack.pop(); + _M_stack.push(__r); + return true; + } + if (_M_match_token(_ScannerT::_S_token_closure1)) + { + if (_M_stack.empty()) + __throw_regex_error(regex_constants::error_badrepeat); + _StateSeq __r(_M_state_store, + _M_state_store. + _M_insert_alt(_S_invalid_state_id, + _M_stack.top()._M_front())); + _M_stack.top()._M_append(__r); + return true; + } + if (_M_match_token(_ScannerT::_S_token_opt)) + { + if (_M_stack.empty()) + __throw_regex_error(regex_constants::error_badrepeat); + _StateSeq __r(_M_stack.top(), -1); + _M_stack.pop(); + _M_stack.push(__r); + return true; + } + if (_M_match_token(_ScannerT::_S_token_interval_begin)) + { + if (_M_stack.empty()) + __throw_regex_error(regex_constants::error_badrepeat); + if (!_M_match_token(_ScannerT::_S_token_dup_count)) + __throw_regex_error(regex_constants::error_badbrace); + _StateSeq __r(_M_stack.top()); + int __min_rep = _M_cur_int_value(10); + for (int __i = 1; __i < __min_rep; ++__i) + _M_stack.top()._M_append(__r._M_clone()); + if (_M_match_token(_ScannerT::_S_token_comma)) + if (_M_match_token(_ScannerT::_S_token_dup_count)) + { + int __n = _M_cur_int_value(10) - __min_rep; + if (__n < 0) + __throw_regex_error(regex_constants::error_badbrace); + for (int __i = 0; __i < __n; ++__i) + { + _StateSeq __r(_M_state_store, + _M_state_store. + _M_insert_alt(_S_invalid_state_id, + _M_stack.top()._M_front())); + _M_stack.top()._M_append(__r); + } + } + else + { + _StateSeq __r(_M_stack.top(), -1); + __r._M_push_back(__r._M_front()); + _M_stack.pop(); + _M_stack.push(__r); + } + if (!_M_match_token(_ScannerT::_S_token_interval_end)) + __throw_regex_error(regex_constants::error_brace); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_atom() + { + using std::bind; + using std::placeholders::_1; + using std::placeholders::_2; + typedef _CharMatcher<_InIter, _TraitsT> _CMatcher; + typedef _StartTagger<_InIter, _TraitsT> _Start; + typedef _EndTagger<_InIter, _TraitsT> _End; + + if (_M_match_token(_ScannerT::_S_token_anychar)) + { + _M_stack.push(_StateSeq(_M_state_store, + _M_state_store. + _M_insert_matcher(bind(_AnyMatcher, _1)))); + return true; + } + if (_M_match_token(_ScannerT::_S_token_ord_char)) + { + _M_stack.push(_StateSeq + (_M_state_store, _M_state_store. + _M_insert_matcher + (bind(_CMatcher(_M_cur_value[0], _M_traits), _1)))); + return true; + } + if (_M_match_token(_ScannerT::_S_token_quoted_char)) + { + // note that in the ECMA grammar, this case covers backrefs. + _M_stack.push(_StateSeq(_M_state_store, + _M_state_store. + _M_insert_matcher + (bind(_CMatcher(_M_cur_value[0], _M_traits), + _1)))); + return true; + } + if (_M_match_token(_ScannerT::_S_token_backref)) + { + // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value); + return true; + } + if (_M_match_token(_ScannerT::_S_token_subexpr_begin)) + { + int __mark = _M_state_store._M_sub_count(); + _StateSeq __r(_M_state_store, + _M_state_store. + _M_insert_subexpr_begin(bind(_Start(__mark), _1, _2))); + this->_M_disjunction(); + if (!_M_match_token(_ScannerT::_S_token_subexpr_end)) + __throw_regex_error(regex_constants::error_paren); + if (!_M_stack.empty()) + { + __r._M_append(_M_stack.top()); + _M_stack.pop(); + } + __r._M_append(_M_state_store._M_insert_subexpr_end + (__mark, bind(_End(__mark), _1, _2))); + _M_stack.push(__r); + return true; + } + return _M_bracket_expression(); + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_bracket_expression() + { + using std::bind; + using std::placeholders::_1; + if (_M_match_token(_ScannerT::_S_token_bracket_begin)) + { + _RMatcherT __matcher(_M_match_token(_ScannerT::_S_token_line_begin), + _M_traits); + if (!_M_bracket_list(__matcher) + || !_M_match_token(_ScannerT::_S_token_bracket_end)) + __throw_regex_error(regex_constants::error_brack); + _M_stack.push(_StateSeq(_M_state_store, + _M_state_store._M_insert_matcher + (bind(__matcher, _1)))); + return true; + } + return false; + } + + // If the dash is the last character in the bracket expression, it is not + // special. + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_bracket_list(_RMatcherT& __matcher) + { + if (_M_follow_list(__matcher)) + { + if (_M_match_token(_ScannerT::_S_token_dash)) + __matcher._M_add_char(_M_cur_value[0]); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_follow_list(_RMatcherT& __matcher) + { return _M_expression_term(__matcher) && _M_follow_list2(__matcher); } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_follow_list2(_RMatcherT& __matcher) + { + if (_M_expression_term(__matcher)) + return _M_follow_list2(__matcher); + return true; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_expression_term(_RMatcherT& __matcher) + { + return (_M_collating_symbol(__matcher) + || _M_character_class(__matcher) + || _M_equivalence_class(__matcher) + || (_M_start_range(__matcher) + && _M_range_expression(__matcher))); + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_range_expression(_RMatcherT& __matcher) + { + if (!_M_collating_symbol(__matcher)) + if (!_M_match_token(_ScannerT::_S_token_dash)) + __throw_regex_error(regex_constants::error_range); + __matcher._M_make_range(); + return true; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_start_range(_RMatcherT& __matcher) + { return _M_match_token(_ScannerT::_S_token_dash); } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_collating_symbol(_RMatcherT& __matcher) + { + if (_M_match_token(_ScannerT::_S_token_collelem_single)) + { + __matcher._M_add_char(_M_cur_value[0]); + return true; + } + if (_M_match_token(_ScannerT::_S_token_collsymbol)) + { + __matcher._M_add_collating_element(_M_cur_value); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_equivalence_class(_RMatcherT& __matcher) + { + if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) + { + __matcher._M_add_equivalence_class(_M_cur_value); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + bool + _Compiler<_InIter, _TraitsT>:: + _M_character_class(_RMatcherT& __matcher) + { + if (_M_match_token(_ScannerT::_S_token_char_class_name)) + { + __matcher._M_add_character_class(_M_cur_value); + return true; + } + return false; + } + + template<typename _InIter, typename _TraitsT> + int + _Compiler<_InIter, _TraitsT>:: + _M_cur_int_value(int __radix) + { + int __v = 0; + for (typename _StringT::size_type __i = 0; + __i < _M_cur_value.length(); ++__i) + __v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix); + return __v; + } + + template<typename _InIter, typename _TraitsT> + _AutomatonPtr + __compile(const _InIter& __b, const _InIter& __e, _TraitsT& __t, + regex_constants::syntax_option_type __f) + { return _AutomatonPtr(new _Nfa(_Compiler<_InIter, _TraitsT>(__b, __e, __t, + __f)._M_nfa())); } + +} // namespace __regex +} // namespace std + +/* vim: set ts=8 sw=2 sts=2: */ diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h new file mode 100644 index 00000000000..787b88b8cd4 --- /dev/null +++ b/libstdc++-v3/include/bits/regex_constants.h @@ -0,0 +1,299 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_constants + * @brief Constant definitions for the std regex library. + * + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ + +/** + * @namespace std::regex_constants + * @brief ISO C++-0x entities sub namespace for regex. + */ +namespace regex_constants +{ + /** + * @name 5.1 Regular Expression Syntax Options + */ + //@{ + enum __syntax_option + { + _S_icase, + _S_nosubs, + _S_optimize, + _S_collate, + _S_ECMAScript, + _S_basic, + _S_extended, + _S_awk, + _S_grep, + _S_egrep, + _S_syntax_last + }; + + /** + * @brief This is a bitmask type indicating how to interpret the regex. + * + * The @c syntax_option_type is implementation defined but it is valid to + * perform bitwise operations on these values and expect the right thing to + * happen. + * + * A valid value of type syntax_option_type shall have exactly one of the + * elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep + * %set. + */ + typedef unsigned int syntax_option_type; + + /** + * Specifies that the matching of regular expressions against a character + * sequence shall be performed without regard to case. + */ + static const syntax_option_type icase = 1 << _S_icase; + + /** + * Specifies that when a regular expression is matched against a character + * container sequence, no sub-expression matches are to be stored in the + * supplied match_results structure. + */ + static const syntax_option_type nosubs = 1 << _S_nosubs; + + /** + * Specifies that the regular expression engine should pay more attention to + * the speed with which regular expressions are matched, and less to the + * speed with which regular expression objects are constructed. Otherwise + * it has no detectable effect on the program output. + */ + static const syntax_option_type optimize = 1 << _S_optimize; + + /** + * Specifies that character ranges of the form [a-b] should be locale + * sensitive. + */ + static const syntax_option_type collate = 1 << _S_collate; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript + * Language Specification, Standard Ecma-262, third edition, 1999], as + * modified in section [28.13]. This grammar is similar to that defined + * in the PERL scripting language but extended with elements found in the + * POSIX regular expression grammar. + */ + static const syntax_option_type ECMAScript = 1 << _S_ECMAScript; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and + * Headers, Section 9, Regular Expressions [IEEE, Information Technology -- + * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + static const syntax_option_type basic = 1 << _S_basic; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001, + * Portable Operating System Interface (POSIX), Base Definitions and Headers, + * Section 9, Regular Expressions. + */ + static const syntax_option_type extended = 1 << _S_extended; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type extended, except that C-style escape + * sequences are supported. These sequences are: + * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\', ', + * and \\ddd (where ddd is one, two, or three octal digits). + */ + static const syntax_option_type awk = 1 << _S_awk; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is + * identical to syntax_option_type basic, except that newlines are treated + * as whitespace. + */ + static const syntax_option_type grep = 1 << _S_grep; + + /** + * Specifies that the grammar recognized by the regular expression engine is + * that used by POSIX utility grep when given the -E option in + * IEEE Std 1003.1-2001. This option is identical to syntax_option_type + * extended, except that newlines are treated as whitespace. + */ + static const syntax_option_type egrep = 1 << _S_egrep; + + //@} + + /** + * @name 5.2 Matching Rules + * + * Matching a regular expression against a sequence of characters [first, + * last) proceeds according to the rules of the grammar specified for the + * regular expression object, modified according to the effects listed + * below for any bitmask elements set. + * + */ + //@{ + + enum __match_flag + { + _S_not_bol, + _S_not_eol, + _S_not_bow, + _S_not_eow, + _S_any, + _S_not_null, + _S_continuous, + _S_prev_avail, + _S_sed, + _S_no_copy, + _S_first_only, + _S_match_flag_last + }; + + /** + * @brief This is a bitmask type indicating regex matching rules. + * + * The @c match_flag_type is implementation defined but it is valid to + * perform bitwise operations on these values and expect the right thing to + * happen. + */ + typedef std::bitset<_S_match_flag_last> match_flag_type; + + /** + * The default matching rules. + */ + static const match_flag_type match_default = 0; + + /** + * The first character in the sequence [first, last) is treated as though it + * is not at the beginning of a line, so the character (^) in the regular + * expression shall not match [first, first). + */ + static const match_flag_type match_not_bol = 1 << _S_not_bol; + + /** + * The last character in the sequence [first, last) is treated as though it + * is not at the end of a line, so the character ($) in the regular + * expression shall not match [last, last). + */ + static const match_flag_type match_not_eol = 1 << _S_not_eol; + + /** + * The expression \\b is not matched against the sub-sequence + * [first,first). + */ + static const match_flag_type match_not_bow = 1 << _S_not_bow; + + /** + * The expression \\b should not be matched against the sub-sequence + * [last,last). + */ + static const match_flag_type match_not_eow = 1 << _S_not_eow; + + /** + * If more than one match is possible then any match is an acceptable + * result. + */ + static const match_flag_type match_any = 1 << _S_any; + + /** + * The expression does not match an empty sequence. + */ + static const match_flag_type match_not_null = 1 << _S_not_null; + + /** + * The expression only matches a sub-sequence that begins at first . + */ + static const match_flag_type match_continuous = 1 << _S_continuous; + + /** + * --first is a valid iterator position. When this flag is set then the + * flags match_not_bol and match_not_bow are ignored by the regular + * expression algorithms 7.11 and iterators 7.12. + */ + static const match_flag_type match_prev_avail = 1 << _S_prev_avail; + + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the ECMAScript replace + * function in ECMA- 262 [Ecma International, ECMAScript Language + * Specification, Standard Ecma-262, third edition, 1999], part 15.5.4.11 + * String.prototype.replace. In addition, during search and replace + * operations all non-overlapping occurrences of the regular expression + * are located and replaced, and sections of the input that did not match + * the expression are copied unchanged to the output string. + * + * Format strings (from ECMA-262 [15.5.4.11]): + * @li $$ The dollar-sign itself ($) + * @li $& The matched substring. + * @li $` The portion of @a string that precedes the matched substring. + * This would be match_results::prefix(). + * @li $' The portion of @a string that follows the matched substring. + * This would be match_results::suffix(). + * @li $n The nth capture, where n is in [1,9] and $n is not followed by a + * decimal digit. If n <= match_results::size() and the nth capture + * is undefined, use the empty string instead. If n > + * match_results::size(), the result is implementation-defined. + * @li $nn The nnth capture, where nn is a two-digit decimal number on + * [01, 99]. If nn <= match_results::size() and the nth capture is + * undefined, use the empty string instead. If + * nn > match_results::size(), the result is implementation-defined. + */ + static const match_flag_type format_default = 0; + + /** + * When a regular expression match is to be replaced by a new string, the + * new string is constructed using the rules used by the POSIX sed utility + * in IEEE Std 1003.1- 2001 [IEEE, Information Technology -- Portable + * Operating System Interface (POSIX), IEEE Standard 1003.1-2001]. + */ + static const match_flag_type format_sed = 1 << _S_sed; + + /** + * During a search and replace operation, sections of the character + * container sequence being searched that do not match the regular + * expression shall not be copied to the output string. + */ + static const match_flag_type format_no_copy = 1 << _S_no_copy; + + /** + * When specified during a search and replace operation, only the first + * occurrence of the regular expression shall be replaced. + */ + static const match_flag_type format_first_only = 1 << _S_first_only; + + //@} + +} // namespace regex_constants +} // namespace std + diff --git a/libstdc++-v3/include/bits/regex_cursor.h b/libstdc++-v3/include/bits/regex_cursor.h new file mode 100644 index 00000000000..e8330fb7885 --- /dev/null +++ b/libstdc++-v3/include/bits/regex_cursor.h @@ -0,0 +1,92 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_cursor.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ +namespace __regex +{ + // ABC for pattern matching + struct _PatternCursor + { + virtual ~_PatternCursor() { }; + virtual void _M_next() = 0; + virtual bool _M_at_end() const = 0; + }; + + // Provides a cursor into the specific target string. + template<typename _FwdIterT> + class _SpecializedCursor + : public _PatternCursor + { + public: + _SpecializedCursor(const _FwdIterT& __b, const _FwdIterT __e) + : _M_b(__b), _M_c(__b), _M_e(__e) + { } + + typename std::iterator_traits<_FwdIterT>::value_type + _M_current() const + { return *_M_c; } + + void + _M_next() + { ++_M_c; } + + _FwdIterT + _M_pos() const + { return _M_c; } + + const _FwdIterT& + _M_begin() const + { return _M_b; } + + const _FwdIterT& + _M_end() const + { return _M_e; } + + bool + _M_at_end() const + { return _M_c == _M_e; } + + private: + _FwdIterT _M_b; + _FwdIterT _M_c; + _FwdIterT _M_e; + }; + + // Helper funxtion to create a cursor specialized for an iterator class. + template<typename _FwdIterT> + inline _SpecializedCursor<_FwdIterT> + __cursor(const _FwdIterT& __b, const _FwdIterT __e) + { return _SpecializedCursor<_FwdIterT>(__b, __e); } + +} // namespace __regex +} // namespace std + +/* vim: set ts=8 sw=2 sts=2: */ diff --git a/libstdc++-v3/include/bits/regex_error.h b/libstdc++-v3/include/bits/regex_error.h new file mode 100644 index 00000000000..56bfae4cc66 --- /dev/null +++ b/libstdc++-v3/include/bits/regex_error.h @@ -0,0 +1,160 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_error + * @brief Error and exception objects for the std regex library. + * + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ + +namespace regex_constants +{ + /** + * @name 5.3 Error Types + */ + //@{ + + enum error_type + { + _S_error_collate, + _S_error_ctype, + _S_error_escape, + _S_error_backref, + _S_error_brack, + _S_error_paren, + _S_error_brace, + _S_error_badbrace, + _S_error_range, + _S_error_space, + _S_error_badrepeat, + _S_error_complexity, + _S_error_stack, + _S_error_last + }; + + /** The expression contained an invalid collating element name. */ + static const error_type error_collate(_S_error_collate); + + /** The expression contained an invalid character class name. */ + static const error_type error_ctype(_S_error_ctype); + + /** + * The expression contained an invalid escaped character, or a trailing + * escape. + */ + static const error_type error_escape(_S_error_escape); + + /** The expression contained an invalid back reference. */ + static const error_type error_backref(_S_error_backref); + + /** The expression contained mismatched [ and ]. */ + static const error_type error_brack(_S_error_brack); + + /** The expression contained mismatched ( and ). */ + static const error_type error_paren(_S_error_paren); + + /** The expression contained mismatched { and } */ + static const error_type error_brace(_S_error_brace); + + /** The expression contained an invalid range in a {} expression. */ + static const error_type error_badbrace(_S_error_badbrace); + + /** + * The expression contained an invalid character range, + * such as [b-a] in most encodings. + */ + static const error_type error_range(_S_error_range); + + /** + * There was insufficient memory to convert the expression into a + * finite state machine. + */ + static const error_type error_space(_S_error_space); + + /** + * One of <em>*?+{<em> was not preceded by a valid regular expression. + */ + static const error_type error_badrepeat(_S_error_badrepeat); + + /** + * The complexity of an attempted match against a regular expression + * exceeded a pre-set level. + */ + static const error_type error_complexity(_S_error_complexity); + + /** + * There was insufficient memory to determine whether the + * regular expression could match the specified character sequence. + */ + static const error_type error_stack(_S_error_stack); + + //@} +} + + // [7.8] Class regex_error + /** + * @brief A regular expression exception class. + * @ingroup exceptions + * + * The regular expression library throws objects of this class on error. + */ + class regex_error + : public std::runtime_error + { + public: + /** + * @brief Constructs a regex_error object. + * + * @param ecode the regex error code. + */ + explicit + regex_error(regex_constants::error_type __ecode) + : std::runtime_error("regex_error"), _M_code(__ecode) + { } + + /** + * @brief Gets the regex error code. + * + * @returns the regex error code. + */ + regex_constants::error_type + code() const + { return _M_code; } + + protected: + regex_constants::error_type _M_code; + }; + + + inline void + __throw_regex_error(regex_constants::error_type __ecode) + { throw regex_error(__ecode); } + +} // namespace std + diff --git a/libstdc++-v3/include/bits/regex_grep_matcher.h b/libstdc++-v3/include/bits/regex_grep_matcher.h new file mode 100644 index 00000000000..f243c92406b --- /dev/null +++ b/libstdc++-v3/include/bits/regex_grep_matcher.h @@ -0,0 +1,131 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_executor.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + + +namespace std +{ + template<typename _BiIter> + class sub_match; + + template<typename _Bi_iter, typename _Allocator> + class match_results; + +namespace __regex +{ + // A _Results facade specialized for wrapping a templated sub_match. + template<typename _FwdIterT, typename _Alloc> + class _SpecializedResults + : public _Results + { + public: + _SpecializedResults(const _Automaton::_SizeT __size, + const _SpecializedCursor<_FwdIterT>& __cursor, + match_results<_FwdIterT, _Alloc>& __m); + + void + _M_set_pos(int __i, int __j, const _PatternCursor& __pc); + + void + _M_set_matched(int __i, bool __is_matched) + { _M_results.at(__i).matched = __is_matched; } + + private: + match_results<_FwdIterT, _Alloc>& _M_results; + }; + + template<typename _FwdIterT, typename _Alloc> + _SpecializedResults<_FwdIterT, _Alloc>:: + _SpecializedResults(const _Automaton::_SizeT __size, + const _SpecializedCursor<_FwdIterT>& __cursor, + match_results<_FwdIterT, _Alloc>& __m) + : _M_results(__m) + { + typedef typename match_results<_FwdIterT, _Alloc>::size_type size_type; + _M_results.clear(); + std::sub_match<_FwdIterT> __sm; + __sm.matched = false; + size_type __result_count = __size + 2; + for (size_type __i = 0; __i < __result_count; ++__i) + _M_results.push_back(__sm); + _M_results.at(__size+0).first = __cursor._M_begin(); + _M_results.at(__size+0).second = __cursor._M_begin(); + _M_results.at(__size+1).first = __cursor._M_end(); + _M_results.at(__size+1).second = __cursor._M_end(); + } + + template<typename _FwdIterT, typename _Alloc> + void + _SpecializedResults<_FwdIterT, _Alloc>:: + _M_set_pos(int __i, int __j, const _PatternCursor& __pc) + { + typedef const _SpecializedCursor<_FwdIterT>& _CursorT; + _CursorT __c = static_cast<_CursorT>(__pc); + if (__j == 0) + _M_results.at(__i).first = __c._M_pos(); + else + _M_results.at(__i).second = __c._M_pos()+1; + } + + // A stack of states used in evaluating the NFA. + typedef std::stack<_StateIdT, std::vector<_StateIdT> > _StateStack; + + // Executes a regular expression NFA/DFA over a range using a variant of + // the parallel execution algorithm featured in the grep utility, modified + // to use Laurikari tags. + class _Grep_matcher + { + public: + _Grep_matcher(_PatternCursor& __p, + _Results& __r, + const _AutomatonPtr& __automaton, + regex_constants::match_flag_type __flags); + + private: + _StateSet + _M_e_closure(_StateIdT __i); + + _StateSet + _M_e_closure(const _StateSet& __s); + + _StateSet + _M_e_closure(_StateStack& __stack, const _StateSet& __s); + + private: + const std::shared_ptr<_Nfa> _M_nfa; + _PatternCursor& _M_pattern; + _Results& _M_results; + }; + +} // namespace __regex +} // namespace std + +#include <bits/regex_grep_matcher.tcc> + +/* vim: set ts=8 sw=2 sts=2: */ diff --git a/libstdc++-v3/include/bits/regex_grep_matcher.tcc b/libstdc++-v3/include/bits/regex_grep_matcher.tcc new file mode 100644 index 00000000000..17d1e6449dc --- /dev/null +++ b/libstdc++-v3/include/bits/regex_grep_matcher.tcc @@ -0,0 +1,177 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file regex_grep_matcher.cc + */ +#include <regex> + +namespace std +{ + +namespace +{ + + // A stack of states used in evaluating the NFA. + typedef std::stack<std::__regex::_StateIdT, + std::vector<std::__regex::_StateIdT> + > _StateStack; + + // Obtains the next state set given the current state set __s and the current + // input character. + inline std::__regex::_StateSet + __move(const std::__regex::_PatternCursor& __p, + const std::__regex::_Nfa& __nfa, + const std::__regex::_StateSet& __s) + { + std::__regex::_StateSet __m; + for (std::__regex::_StateSet::const_iterator __i = __s.begin(); + __i != __s.end(); ++__i) + { + if (*__i == std::__regex::_S_invalid_state_id) + continue; + + const std::__regex::_State& __state = __nfa[*__i]; + if (__state._M_opcode == std::__regex::_S_opcode_match + && __state._M_matches(__p)) + __m.insert(__state._M_next); + } + return __m; + } + + // returns true if (__s intersect __t) is not empty + inline bool + __includes_some(const std::__regex::_StateSet& __s, + const std::__regex::_StateSet& __t) + { + if (__s.size() > 0 && __t.size() > 0) + { + std::__regex::_StateSet::const_iterator __first = __s.begin(); + std::__regex::_StateSet::const_iterator __second = __t.begin(); + while (__first != __s.end() && __second != __t.end()) + { + if (*__first < *__second) + ++__first; + else if (*__second < *__first) + ++__second; + else + return true; + } + } + return false; + } + + // If an identified state __u is not already in the current state set __e, + // insert it and push it on the current state stack __s. + inline void + __add_visited_state(const std::__regex::_StateIdT __u, + _StateStack& __s, + std::__regex::_StateSet& __e) + { + if (__e.count(__u) == 0) + { + __e.insert(__u); + __s.push(__u); + } + } + +} // anonymous namespace + +namespace __regex +{ + inline _Grep_matcher:: + _Grep_matcher(_PatternCursor& __p, _Results& __r, + const _AutomatonPtr& __nfa, + regex_constants::match_flag_type __flags) + : _M_nfa(static_pointer_cast<_Nfa>(__nfa)), _M_pattern(__p), _M_results(__r) + { + __regex::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start()); + for (; !_M_pattern._M_at_end(); _M_pattern._M_next()) + __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t)); + + _M_results._M_set_matched(0, + __includes_some(_M_nfa->_M_final_states(), __t)); + } + + // Creates the e-closure set for the initial state __i. + inline _StateSet _Grep_matcher:: + _M_e_closure(_StateIdT __i) + { + _StateSet __s; + __s.insert(__i); + _StateStack __stack; + __stack.push(__i); + return this->_M_e_closure(__stack, __s); + } + + // Creates the e-closure set for an arbitrary state set __s. + inline _StateSet _Grep_matcher:: + _M_e_closure(const _StateSet& __s) + { + _StateStack __stack; + for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i) + __stack.push(*__i); + return this->_M_e_closure(__stack, __s); + } + + inline _StateSet _Grep_matcher:: + _M_e_closure(_StateStack& __stack, const _StateSet& __s) + { + _StateSet __e = __s; + while (!__stack.empty()) + { + _StateIdT __t = __stack.top(); __stack.pop(); + if (__t == _S_invalid_state_id) + continue; + // for each __u with edge from __t to __u labeled e do ... + const _State& __state = _M_nfa->operator[](__t); + switch (__state._M_opcode) + { + case _S_opcode_alternative: + __add_visited_state(__state._M_next, __stack, __e); + __add_visited_state(__state._M_alt, __stack, __e); + break; + case _S_opcode_subexpr_begin: + __add_visited_state(__state._M_next, __stack, __e); + __state._M_tagger(_M_pattern, _M_results); + break; + case _S_opcode_subexpr_end: + __add_visited_state(__state._M_next, __stack, __e); + __state._M_tagger(_M_pattern, _M_results); + _M_results._M_set_matched(__state._M_subexpr, true); + break; + case _S_opcode_accept: + __add_visited_state(__state._M_next, __stack, __e); + break; + default: + break; + } + } + return __e; + } + +} // namespace __regex +} // namespace std + +/* vim: set ts=8 sw=2 sts=2: */ diff --git a/libstdc++-v3/include/bits/regex_nfa.h b/libstdc++-v3/include/bits/regex_nfa.h new file mode 100644 index 00000000000..2a938915b97 --- /dev/null +++ b/libstdc++-v3/include/bits/regex_nfa.h @@ -0,0 +1,403 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file bits/regex_nfa.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +namespace std +{ +namespace __regex +{ + + // Base class for, um, automata. Could be an NFA or a DFA. Your choice. + class _Automaton + { + public: + typedef unsigned int _SizeT; + + public: + virtual + ~_Automaton() + { } + + virtual _SizeT + _M_sub_count() const = 0; + +#ifdef _GLIBCXX_DEBUG + virtual std::ostream& + _M_dot(std::ostream& __ostr) const = 0; +#endif + }; + + // Generic shred pointer to an automaton. + typedef std::shared_ptr<_Automaton> _AutomatonPtr; + + // Operation codes that define the type of transitions within the base NFA + // that represents the regular expression. + enum _Opcode + { + _S_opcode_unknown = 0, + _S_opcode_alternative = 1, + _S_opcode_subexpr_begin = 4, + _S_opcode_subexpr_end = 5, + _S_opcode_match = 100, + _S_opcode_accept = 255 + }; + + // Provides a generic facade for a templated match_results. + struct _Results + { + virtual void _M_set_pos(int __i, int __j, const _PatternCursor& __p) = 0; + virtual void _M_set_matched(int __i, bool __is_matched) = 0; + }; + + // Tags current state (for subexpr begin/end). + typedef std::function<void (const _PatternCursor&, _Results&)> _Tagger; + + template<typename _FwdIterT, typename _TraitsT> + struct _StartTagger + : public _Tagger + { + explicit + _StartTagger(int __i) + : _M_index(__i) + { } + + void + operator()(const _PatternCursor& __pc, _Results& __r) + { __r._M_set_pos(_M_index, 0, __pc); } + + int _M_index; + }; + + template<typename _FwdIterT, typename _TraitsT> + struct _EndTagger + : public _Tagger + { + explicit + _EndTagger(int __i) + : _M_index(__i) + { } + + void + operator()(const _PatternCursor& __pc, _Results& __r) + { __r._M_set_pos(_M_index, 1, __pc); } + + int _M_index; + _FwdIterT _M_pos; + }; + // Indicates if current state matches cursor current. + typedef std::function<bool (const _PatternCursor&)> _Matcher; + + // Matches any character + inline bool + _AnyMatcher(const _PatternCursor&) + { return true; } + + // Matches a single character + template<typename _InIterT, typename _TraitsT> + struct _CharMatcher + : public _Matcher + { + typedef typename _TraitsT::char_type char_type; + + explicit + _CharMatcher(char_type __c, const _TraitsT& __t = _TraitsT()) + : _M_traits(__t), _M_c(_M_traits.translate(__c)) + { } + + bool + operator()(const _PatternCursor& __pc) const + { + typedef const _SpecializedCursor<_InIterT>& _CursorT; + _CursorT __c = static_cast<_CursorT>(__pc); + return _M_traits.translate(__c._M_current()) == _M_c; + } + + const _TraitsT& _M_traits; + char_type _M_c; + }; + + // Matches a character range (bracket expression) + template<typename _InIterT, typename _TraitsT> + struct _RangeMatcher + : public _Matcher + { + typedef typename _TraitsT::char_type _CharT; + typedef std::basic_string<_CharT> _StringT; + + explicit + _RangeMatcher(bool __is_non_matching, const _TraitsT& __t = _TraitsT()) + : _M_traits(__t), _M_is_non_matching(__is_non_matching) + { } + + bool + operator()(const _PatternCursor& __pc) const + { + typedef const _SpecializedCursor<_InIterT>& _CursorT; + _CursorT __c = static_cast<_CursorT>(__pc); + return true; + } + + void + _M_add_char(_CharT __c) + { } + + void + _M_add_collating_element(const _StringT& __s) + { } + + void + _M_add_equivalence_class(const _StringT& __s) + { } + + void + _M_add_character_class(const _StringT& __s) + { } + + void + _M_make_range() + { } + + const _TraitsT& _M_traits; + bool _M_is_non_matching; + }; + + // Identifies a state in the NFA. + typedef int _StateIdT; + + // The special case in which a state identifier is not an index. + static const _StateIdT _S_invalid_state_id = -1; + + + // An individual state in an NFA + // + // In this case a "state" is an entry in the NFA definition coupled with its + // outgoing transition(s). All states have a single outgoing transition, + // except for accepting states (which have no outgoing transitions) and alt + // states, which have two outgoing transitions. + // + struct _State + { + typedef int _OpcodeT; + + _OpcodeT _M_opcode; // type of outgoing transition + _StateIdT _M_next; // outgoing tranition + _StateIdT _M_alt; // for _S_opcode_alternative + unsigned int _M_subexpr; // for _S_opcode_subexpr_* + _Tagger _M_tagger; // for _S_opcode_subexpr_* + _Matcher _M_matches; // for _S_opcode_match + + explicit _State(_OpcodeT __opcode) + : _M_opcode(__opcode), _M_next(_S_invalid_state_id) + { } + + _State(const _Matcher& __m) + : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), _M_matches(__m) + { } + + _State(_OpcodeT __opcode, unsigned int __s, const _Tagger& __t) + : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__s), + _M_tagger(__t) + { } + + _State(_StateIdT __next, _StateIdT __alt) + : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt) + { } + +#ifdef _GLIBCXX_DEBUG + std::ostream& + _M_print(std::ostream& ostr) const; + + // Prints graphviz dot commands for state. + std::ostream& + _M_dot(std::ostream& __ostr, _StateIdT __id) const; +#endif + }; + + + // The Grep Matcher works on sets of states. Here are sets of states. + typedef std::set<_StateIdT> _StateSet; + + // A collection of all states making up an NFA + // + // An NFA is a 4-tuple M = (K, S, s, F), where + // K is a finite set of states, + // S is the alphabet of the NFA, + // s is the initial state, + // F is a set of final (accepting) states. + // + // This NFA class is templated on S, a type that will hold values of the + // underlying alphabet (without regard to semantics of that alphabet). The + // other elements of the tuple are generated during construction of the NFA + // and are available through accessor member functions. + // + class _Nfa + : public _Automaton, public std::vector<_State> + { + public: + typedef _State _StateT; + typedef unsigned int _SizeT; + typedef regex_constants::syntax_option_type _FlagT; + + public: + _Nfa(_FlagT __f) + : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0) + { } + + ~_Nfa() + { } + + _FlagT + _M_options() const + { return _M_flags; } + + _StateIdT + _M_start() const + { return _M_start_state; } + + const _StateSet& + _M_final_states() const + { return _M_accepting_states; } + + _SizeT + _M_sub_count() const + { return _M_subexpr_count; } + + _StateIdT + _M_insert_accept() + { + this->push_back(_StateT(_S_opcode_accept)); + _M_accepting_states.insert(this->size()-1); + return this->size()-1; + } + + _StateIdT + _M_insert_alt(_StateIdT __next, _StateIdT __alt) + { + this->push_back(_StateT(__next, __alt)); + return this->size()-1; + } + + _StateIdT + _M_insert_matcher(_Matcher __m) + { + this->push_back(_StateT(__m)); + return this->size()-1; + } + + _StateIdT + _M_insert_subexpr_begin(const _Tagger& __t) + { + this->push_back(_StateT(_S_opcode_subexpr_begin, _M_subexpr_count++, __t)); + return this->size()-1; + } + + _StateIdT + _M_insert_subexpr_end(unsigned int __i, const _Tagger& __t) + { + this->push_back(_StateT(_S_opcode_subexpr_end, __i, __t)); + return this->size()-1; + } + +#ifdef _GLIBCXX_DEBUG + std::ostream& + _M_dot(std::ostream& __ostr) const; +#endif + + private: + _FlagT _M_flags; + _StateIdT _M_start_state; + _StateSet _M_accepting_states; + _SizeT _M_subexpr_count; + }; + + // Describes a sequence of one or more %_State, its current start and end(s). + // + // This structure contains fragments of an NFA during construction. + class _StateSeq + { + public: + // Constructs a single-node sequence + _StateSeq(_Nfa& __ss, _StateIdT __s, _StateIdT __e = _S_invalid_state_id) + : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e) + { } + // Constructs a split sequence from two other sequencces + _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2) + : _M_nfa(__e1._M_nfa), + _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)), + _M_end1(__e1._M_end1), _M_end2(__e2._M_end1) + { } + + // Constructs a split sequence from a single sequence + _StateSeq(const _StateSeq& __e, _StateIdT __id) + : _M_nfa(__e._M_nfa), + _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)), + _M_end1(__id), _M_end2(__e._M_end1) + { } + + // Constructs a copy of a %_StateSeq + _StateSeq(const _StateSeq& __rhs) + : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start), + _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2) + { } + + + _StateSeq& operator=(const _StateSeq& __rhs); + + _StateIdT + _M_front() const + { return _M_start; } + + // Extends a sequence by one. + void + _M_push_back(_StateIdT __id); + + // Extends and maybe joins a sequence. + void + _M_append(_StateIdT __id); + + void + _M_append(_StateSeq& __rhs); + + // Clones an entire sequence. + _StateIdT + _M_clone(); + + private: + _Nfa& _M_nfa; + _StateIdT _M_start; + _StateIdT _M_end1; + _StateIdT _M_end2; + + }; + +} // namespace __regex +} // namespace std + +#include <bits/regex_nfa.tcc> + diff --git a/libstdc++-v3/include/bits/regex_nfa.tcc b/libstdc++-v3/include/bits/regex_nfa.tcc new file mode 100644 index 00000000000..38ab7e0b2ae --- /dev/null +++ b/libstdc++-v3/include/bits/regex_nfa.tcc @@ -0,0 +1,170 @@ +// class template regex -*- C++ -*- + +// Copyright (C) 2010 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. + +// 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/>. + +/** + * @file regex_nfa.cc + */ +#include <regex> + +namespace std +{ +namespace __regex +{ +#ifdef _GLIBCXX_DEBUG +inline std::ostream& _State:: +_M_print(std::ostream& ostr) const +{ + switch (_M_opcode) + { + case _S_opcode_alternative: + ostr << "alt next=" << _M_next << " alt=" << _M_alt; + break; + case _S_opcode_subexpr_begin: + ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr; + break; + case _S_opcode_subexpr_end: + ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr; + break; + case _S_opcode_match: + ostr << "match next=" << _M_next; + break; + case _S_opcode_accept: + ostr << "accept next=" << _M_next; + break; + default: + ostr << "unknown next=" << _M_next; + break; + } + return ostr; +} + +// Prints graphviz dot commands for state. +inline std::ostream& _State:: +_M_dot(std::ostream& __ostr, _StateIdT __id) const +{ + switch (_M_opcode) + { + case _S_opcode_alternative: + __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n" + << __id << " -> " << _M_next + << " [label=\"epsilon\", tailport=\"s\"];\n" + << __id << " -> " << _M_alt + << " [label=\"epsilon\", tailport=\"n\"];\n"; + break; + case _S_opcode_subexpr_begin: + __ostr << __id << " [label=\"" << __id << "\\nSBEGIN " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_subexpr_end: + __ostr << __id << " [label=\"" << __id << "\\nSEND " + << _M_subexpr << "\"];\n" + << __id << " -> " << _M_next << " [label=\"epsilon\"];\n"; + break; + case _S_opcode_match: + __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n" + << __id << " -> " << _M_next << " [label=\"<match>\"];\n"; + break; + case _S_opcode_accept: + __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ; + break; + default: + __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n" + << __id << " -> " << _M_next << " [label=\"?\"];\n"; + break; + } + return __ostr; +} + +inline std::ostream& _Nfa:: +_M_dot(std::ostream& __ostr) const +{ + __ostr << "digraph _Nfa {\n" + << " rankdir=LR;\n"; + for (unsigned int __i = 0; __i < this->size(); ++__i) + { this->at(__i)._M_dot(__ostr, __i); } + __ostr << "}\n"; + return __ostr; +} +#endif + +inline _StateSeq& _StateSeq:: +operator=(const _StateSeq& __rhs) +{ + _M_start = __rhs._M_start; + _M_end1 = __rhs._M_end1; + _M_end2 = __rhs._M_end2; + return *this; +} + +inline void _StateSeq:: +_M_push_back(_StateIdT __id) +{ + if (_M_end1 != _S_invalid_state_id) + _M_nfa[_M_end1]._M_next = __id; + _M_end1 = __id; +} + +inline void _StateSeq:: +_M_append(_StateIdT __id) +{ + if (_M_end2 != _S_invalid_state_id) + { + if (_M_end2 == _M_end1) + _M_nfa[_M_end2]._M_alt = __id; + else + _M_nfa[_M_end2]._M_next = __id; + _M_end2 = _S_invalid_state_id; + } + if (_M_end1 != _S_invalid_state_id) + _M_nfa[_M_end1]._M_next = __id; + _M_end1 = __id; +} + +inline void _StateSeq:: +_M_append(_StateSeq& __rhs) +{ + if (_M_end2 != _S_invalid_state_id) + { + if (_M_end2 == _M_end1) + _M_nfa[_M_end2]._M_alt = __rhs._M_start; + else + _M_nfa[_M_end2]._M_next = __rhs._M_start; + _M_end2 = _S_invalid_state_id; + } + if (__rhs._M_end2 != _S_invalid_state_id) + _M_end2 = __rhs._M_end2; + if (_M_end1 != _S_invalid_state_id) + _M_nfa[_M_end1]._M_next = __rhs._M_start; + _M_end1 = __rhs._M_end1; +} + +// @todo implement this function. +inline _StateIdT _StateSeq:: +_M_clone() +{ return 0; } + +} // namespace __regex +} // namespace std + diff --git a/libstdc++-v3/include/profile/impl/profiler_container_size.h b/libstdc++-v3/include/profile/impl/profiler_container_size.h index aceef914c54..5c7d08b92b9 100644 --- a/libstdc++-v3/include/profile/impl/profiler_container_size.h +++ b/libstdc++-v3/include/profile/impl/profiler_container_size.h @@ -179,16 +179,16 @@ namespace __gnu_profile // Insert a new node at construct with object, callstack and initial size. void - __insert(const __object_t __obj, __stack_t __stack, size_t __num) + __insert(const __object_t __obj, __stack_t __stack, std::size_t __num) { __add_object(__obj, __container_size_info(__stack, __num)); } // XXX Undefined? void - __construct(const void* __obj, size_t __inum); + __construct(const void* __obj, std::size_t __inum); // Call at destruction/clean to set container final size. void - __destruct(const void* __obj, size_t __num, size_t __inum) + __destruct(const void* __obj, std::size_t __num, std::size_t __inum) { if (!__is_on()) return; diff --git a/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h index 9b5a5b28047..299a17d5af6 100644 --- a/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h +++ b/libstdc++-v3/include/profile/impl/profiler_list_to_slist.h @@ -77,7 +77,7 @@ namespace __gnu_profile } void - __merge(const __list2slist_info&) { }; + __merge(const __list2slist_info&) { } void __write(FILE* __f) const @@ -96,7 +96,7 @@ namespace __gnu_profile void __record_operation() - { _M_operations++; } + { ++_M_operations; } bool __has_rewind() diff --git a/libstdc++-v3/include/profile/impl/profiler_trace.h b/libstdc++-v3/include/profile/impl/profiler_trace.h index 0c0aec8f598..1dfdd013b08 100644 --- a/libstdc++-v3/include/profile/impl/profiler_trace.h +++ b/libstdc++-v3/include/profile/impl/profiler_trace.h @@ -225,12 +225,11 @@ namespace __gnu_profile __trace_base<__object_info, __stack_info>:: __collect_warnings(__warning_vector_t& __warnings) { - typename __stack_table_t::iterator __i = __stack_table.begin(); - for (; __i != __stack_table.end(); ++__i) - __warnings.push_back(__warning_data((*__i).second.__magnitude(), - (*__i).first, - __id, - (*__i).second.__advice())); + for (typename __stack_table_t::iterator __it + = __stack_table.begin(); __it != __stack_table.end(); ++__it) + __warnings.push_back(__warning_data((*__it).second.__magnitude(), + (*__it).first, __id, + (*__it).second.__advice())); } template<typename __object_info, typename __stack_info> @@ -462,8 +461,8 @@ namespace __gnu_profile std::fclose(__raw_file); // Sort data by magnitude, keeping just top N. - size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count), - __warnings.size()); + std::size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count), + __warnings.size()); __top_n(__warnings, __top_warnings, __cutoff); FILE* __warn_file = __open_output_file("txt"); @@ -564,10 +563,10 @@ namespace __gnu_profile if (!__env_value) { // Look it up in the config file. - __env_t::iterator it + __env_t::iterator __it = _GLIBCXX_PROFILE_DATA(__env).find(__factor->__env_var); - if (it != _GLIBCXX_PROFILE_DATA(__env).end()) - __env_value = (*it).second.c_str(); + if (__it != _GLIBCXX_PROFILE_DATA(__env).end()) + __env_value = (*__it).second.c_str(); } if (__env_value) diff --git a/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h index 01c7a19f147..91963139bd8 100644 --- a/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h +++ b/libstdc++-v3/include/profile/impl/profiler_vector_to_list.h @@ -98,7 +98,8 @@ namespace __gnu_profile __iterate() { return _M_iterate; } - float __list_cost() + float + __list_cost() { return _M_list_cost; } std::size_t diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex index e8238299b22..95ad4239459 100644 --- a/libstdc++-v3/include/std/regex +++ b/libstdc++-v3/include/std/regex @@ -35,33 +35,30 @@ # include <bits/c++0x_warning.h> #else -#if defined(_GLIBCXX_INCLUDE_AS_TR1) -# error C++0x header cannot be included from TR1 header -#endif - #include <algorithm> #include <bitset> +#include <functional> +#ifdef _GLIBCXX_DEBUG +# include <iosfwd> +#endif #include <iterator> #include <locale> +#include <memory> +#include <set> +#include <sstream> +#include <stack> #include <stdexcept> #include <string> -#include <vector> #include <utility> -#include <sstream> +#include <vector> -#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) -# include <tr1_impl/regex> -#else -# define _GLIBCXX_INCLUDE_AS_CXX0X -# define _GLIBCXX_BEGIN_NAMESPACE_TR1 -# define _GLIBCXX_END_NAMESPACE_TR1 -# define _GLIBCXX_TR1 -# include <tr1_impl/regex> -# undef _GLIBCXX_TR1 -# undef _GLIBCXX_END_NAMESPACE_TR1 -# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 -# undef _GLIBCXX_INCLUDE_AS_CXX0X -#endif +#include <bits/regex_constants.h> +#include <bits/regex_error.h> +#include <bits/regex_cursor.h> +#include <bits/regex_nfa.h> +#include <bits/regex_compiler.h> +#include <bits/regex_grep_matcher.h> +#include <bits/regex.h> #endif // __GXX_EXPERIMENTAL_CXX0X__ diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc index ff22967600e..b736b146070 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc @@ -44,7 +44,7 @@ void test02() FILE* in = fopen(name, "r"); char str[256]; - fgets(str, 256, in); + VERIFY( fgets(str, 256, in) ); VERIFY( !strcmp(str, "Hello, world") ); fclose(in); } diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11544-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11544-2.cc index ff1cc405bd3..f6a2eaca94b 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11544-2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/wchar_t/11544-2.cc @@ -161,7 +161,7 @@ void test02() const char* name = "tmp_11544-2"; FILE* f = fopen(name, "w"); - fwrite("aaaab", 1, 5, f); + VERIFY( fwrite("aaaab", 1, 5, f) == 5 ); fclose(f); wifstream in; diff --git a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc index 7ed97c2b81b..29ec9754870 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/1.cc @@ -41,7 +41,7 @@ void test01() { std::ios_base::sync_with_stdio(); - std::freopen("ios_base_members_static-1.txt", "w", stderr); + VERIFY( std::freopen("ios_base_members_static-1.txt", "w", stderr) ); for (int i = 0; i < 2; i++) { diff --git a/libstdc++-v3/testsuite/27_io/objects/char/12048-1.cc b/libstdc++-v3/testsuite/27_io/objects/char/12048-1.cc index 2c6bbd60403..e4982c5e768 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/12048-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/12048-1.cc @@ -28,7 +28,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); char c1; char c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/char/12048-2.cc b/libstdc++-v3/testsuite/27_io/objects/char/12048-2.cc index 23ab8eea888..f18e5d393c7 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/12048-2.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/12048-2.cc @@ -24,7 +24,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); char c1; int c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/char/12048-3.cc b/libstdc++-v3/testsuite/27_io/objects/char/12048-3.cc index 5158003410e..3b83ef176cd 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/12048-3.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/12048-3.cc @@ -25,7 +25,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); char buf[2]; VERIFY( std::cin.rdbuf()->sgetn(buf, 2) == 2 ); diff --git a/libstdc++-v3/testsuite/27_io/objects/char/12048-4.cc b/libstdc++-v3/testsuite/27_io/objects/char/12048-4.cc index 02f73b6211c..0f8600dbb40 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/12048-4.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/12048-4.cc @@ -24,7 +24,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); char buf[2]; VERIFY( std::cin.rdbuf()->sgetn(buf, 2) == 2 ); diff --git a/libstdc++-v3/testsuite/27_io/objects/char/12048-5.cc b/libstdc++-v3/testsuite/27_io/objects/char/12048-5.cc index 0a0159f82c2..dd544b7370e 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/12048-5.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/12048-5.cc @@ -33,7 +33,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); char c1; int c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/char/9.cc b/libstdc++-v3/testsuite/27_io/objects/char/9.cc index 1ba5bd12d53..e4905bb46f2 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/9.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/9.cc @@ -34,7 +34,7 @@ void test09() fputs("abc\n", fout); fclose(fout); - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); // basic_streambuf::showmanyc returns 0. VERIFY( 0 == std::cin.rdbuf()->in_avail() ); diff --git a/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc b/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc index 1ad194cd81f..8ca77c76e75 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc @@ -68,7 +68,7 @@ bool test01() exit(0); } - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); s1.wait(); int c1 = fgetc(stdin); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/10.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/10.cc index 672f0c15439..c5a198a34ee 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/10.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/10.cc @@ -95,7 +95,7 @@ void test10() VERIFY( n == e_size ); fclose(file); - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); wchar_t* wbuf = new wchar_t[i_size + 10]; wcin.read(wbuf, i_size + 10); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/11.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/11.cc index c9c386f4707..566fdb6be17 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/11.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/11.cc @@ -90,7 +90,7 @@ void test11() }; size_t i_size = wcslen(i_lit); - freopen(name, "w", stdout); + VERIFY( freopen(name, "w", stdout) ); wcout.write(i_lit, i_size); wcout.flush(); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc index 8489dbb47df..58a40ce91c0 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-1.cc @@ -26,7 +26,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); wchar_t c1; wchar_t c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc index 82c1ba2b3a3..7eaef212f07 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-2.cc @@ -23,7 +23,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); wchar_t c1; std::wint_t c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc index 67f3a5b8b5b..8e236ab30cf 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-3.cc @@ -27,7 +27,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); wchar_t buf[2]; VERIFY( std::wcin.rdbuf()->sgetn(buf, 2) == 2 ); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc index fc1191f9f2e..3649e7e2259 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-4.cc @@ -23,7 +23,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); wchar_t buf[2]; VERIFY( std::wcin.rdbuf()->sgetn(buf, 2) == 2 ); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-5.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-5.cc index 1672a0ee925..49486e3c450 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-5.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/12048-5.cc @@ -29,7 +29,7 @@ void test01() { - std::freopen("cin_unget-1.txt", "r", stdin); + VERIFY( std::freopen("cin_unget-1.txt", "r", stdin) ); wchar_t c1; std::wint_t c2; diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9520.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9520.cc index dcaf9bc2540..641d621ded5 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9520.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9520.cc @@ -38,7 +38,7 @@ void test01() locale loc (locale("de_DE.ISO-8859-15@euro")); locale::global(loc); // Set locale for stdin - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); wcin.imbue(loc); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc index 08d544ef6b3..ca470dac9eb 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc @@ -67,7 +67,7 @@ bool test01() exit(0); } - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); s1.wait(); wint_t c1 = fgetwc(stdin); diff --git a/libstdc++-v3/testsuite/28_regex/03_requirements/typedefs.cc b/libstdc++-v3/testsuite/28_regex/03_requirements/typedefs.cc new file mode 100644 index 00000000000..072d5d07f40 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/03_requirements/typedefs.cc @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements + +#include <regex> + +void +test01() +{ + typedef std::regex_traits<char> traits; + + typedef traits::char_type char_type; + typedef traits::string_type string_type; + typedef traits::locale_type locale_type; + typedef traits::char_class_type char_class_type; +} diff --git a/libstdc++-v3/testsuite/28_regex/04_header/regex/std_c++0x_neg.cc b/libstdc++-v3/testsuite/28_regex/04_header/regex/std_c++0x_neg.cc new file mode 100644 index 00000000000..e8ddb77bbb3 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/04_header/regex/std_c++0x_neg.cc @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-std=gnu++98" } + +// Copyright (C) 2007, 2009, 2010 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 <regex> // { dg-excess-errors "In file included from" } + + diff --git a/libstdc++-v3/testsuite/28_regex/05_constants/error_type.cc b/libstdc++-v3/testsuite/28_regex/05_constants/error_type.cc new file mode 100644 index 00000000000..1841a462688 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/05_constants/error_type.cc @@ -0,0 +1,54 @@ +// { dg-options "-std=c++0x" } +// { dg-do compile } +// +// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com> +// +// Copyright (C) 2009 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/>. + +// 28.5.3 + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex_constants::error_type err __attribute__((unused)); + + err = std::regex_constants::error_collate; + err = std::regex_constants::error_ctype; + err = std::regex_constants::error_escape; + err = std::regex_constants::error_backref; + err = std::regex_constants::error_brack; + err = std::regex_constants::error_paren; + err = std::regex_constants::error_brace; + err = std::regex_constants::error_badbrace; + err = std::regex_constants::error_range; + err = std::regex_constants::error_space; + err = std::regex_constants::error_badrepeat; + err = std::regex_constants::error_complexity; + err = std::regex_constants::error_stack; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/05_constants/match_flag_type.cc b/libstdc++-v3/testsuite/28_regex/05_constants/match_flag_type.cc new file mode 100644 index 00000000000..10635ff5f7f --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/05_constants/match_flag_type.cc @@ -0,0 +1,53 @@ +// { dg-options "-std=c++0x" } +// { dg-do compile } +// +// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com> +// +// Copyright (C) 2009 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/>. + +// 28.5.1 + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex_constants::match_flag_type flag = std::regex_constants::match_default; + + flag |= std::regex_constants::match_not_bol; + flag |= std::regex_constants::match_not_eol; + flag |= std::regex_constants::match_not_bow; + flag |= std::regex_constants::match_not_eow; + flag |= std::regex_constants::match_any; + flag |= std::regex_constants::match_not_null; + flag |= std::regex_constants::match_continuous; + flag |= std::regex_constants::match_prev_avail; + flag |= std::regex_constants::format_default; + flag |= std::regex_constants::format_sed; + flag |= std::regex_constants::format_no_copy; + flag |= std::regex_constants::format_first_only; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/05_constants/syntax_option_type.cc b/libstdc++-v3/testsuite/28_regex/05_constants/syntax_option_type.cc new file mode 100644 index 00000000000..2aebf46d19e --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/05_constants/syntax_option_type.cc @@ -0,0 +1,51 @@ +// { dg-options "-std=c++0x" } +// { dg-do compile } +// +// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com> +// +// Copyright (C) 2009 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/>. + +// 28.5.1 + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex_constants::syntax_option_type option = 0; + + option |= std::regex_constants::icase; + option |= std::regex_constants::nosubs; + option |= std::regex_constants::optimize; + option |= std::regex_constants::collate; + option |= std::regex_constants::ECMAScript; + option |= std::regex_constants::basic; + option |= std::regex_constants::extended; + option |= std::regex_constants::awk; + option |= std::regex_constants::grep; + option |= std::regex_constants::egrep; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/06_exception_type/regex_error.cc b/libstdc++-v3/testsuite/28_regex/06_exception_type/regex_error.cc new file mode 100644 index 00000000000..04fd7124277 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/06_exception_type/regex_error.cc @@ -0,0 +1,49 @@ +// { dg-options "-std=c++0x" } +// { dg-do compile } +// +// 2009-06-17 Stephen M. Webb <stephen.webb@xandros.com> +// +// Copyright (C) 2009 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/>. + +// 28.6 [re.badexp] + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex_error error(std::regex_constants::error_collate); + VERIFY(error.code() == std::regex_constants::error_collate); + + try + { + throw error; + } + catch (std::runtime_error& ex) + { + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/ctor.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/ctor.cc new file mode 100644 index 00000000000..6f5a2f3ab8d --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/ctor.cc @@ -0,0 +1,50 @@ +// { dg-do link } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the regex_traits class. There is only the +// default constructor. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::regex_traits<char> test_type; + + // required default constructor + test_type t; + + // Check for required typedefs + typedef test_type::char_type char_type; + typedef test_type::string_type string_type; + typedef test_type::locale_type locale_type; + typedef test_type::char_class_type char_class_type; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/isctype.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/isctype.cc new file mode 100644 index 00000000000..cb8664ca8bf --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/isctype.cc @@ -0,0 +1,48 @@ +// { dg-do run { xfail *-*-* } } +// { dg-options "-std=c++0x" } + +// +// 2010-06-23 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2(4) Table 127 - Regular expression traits class requirements +// 28.7(11) Class template regex_traits [re.traits] + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + typedef std::regex_traits<CharT> traits; + + char name[] = "lower"; + traits t; + + VERIFY( t.isctype('e', t.lookup_classname(name, name+sizeof(name)-1)) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/length.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/length.cc new file mode 100644 index 00000000000..55406dd0ded --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/length.cc @@ -0,0 +1,49 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] +// 28.7 (3) static std::size_t length(const char_type* p); + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + typedef char CharT; + typedef std::regex_traits<CharT> traits; + bool test __attribute__((unused)) = true; + const CharT* p = ""; + + std::size_t i = traits::length(p); + + VERIFY( i == 0 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_classname.cc new file mode 100644 index 00000000000..49ffb511add --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_classname.cc @@ -0,0 +1,54 @@ +// { dg-do run { xfail *-*-* } } +// { dg-options "-std=c++0x" } + +// +// 2010-06-23 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2(4) Table 127 - Regular expression traits class requirements +// 28.7(9) Class template regex_traits [re.traits] + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + typedef std::regex_traits<CharT> traits; + + char n1[] = "lower"; + char n2[] = "alpha"; + traits t; + + traits::char_class_type c1 = t.lookup_classname(n1, n1+sizeof(n1)-1); + VERIFY( c1 != 0 ); + + traits::char_class_type c2 = t.lookup_classname(n1, n1+sizeof(n1)-1, true); + traits::char_class_type c3 = t.lookup_classname(n2, n2+sizeof(n2)-1, true); + VERIFY( c2 == c3 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_collatename.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_collatename.cc new file mode 100644 index 00000000000..58eb5878de5 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/lookup_collatename.cc @@ -0,0 +1,50 @@ +// { dg-do run { xfail *-*-* } } +// { dg-options "-std=c++0x" } + +// +// 2010-06-23 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 (8) Class template regex_traits [re.traits] + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + typedef std::regex_traits<CharT> traits; + + char name[] = "ll"; + traits t; + + traits::string_type sname = t.lookup_collatename(name, name+sizeof(name)-1); + + VERIFY( !sname.empty() ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/transform.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/transform.cc new file mode 100644 index 00000000000..1481dcfbb8c --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/transform.cc @@ -0,0 +1,51 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] + +#include <regex> +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + typedef std::regex_traits<CharT> traits; + + traits t; + traits::string_type G = "abc"; + traits::string_type H = "def"; + + VERIFY( G < H ); + VERIFY( t.transform(G.begin(), G.end()) < t.transform(H.begin(), H.end()) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/transform_primary.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/transform_primary.cc new file mode 100644 index 00000000000..7de8904b49a --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/transform_primary.cc @@ -0,0 +1,55 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] + +#include <regex> +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + typedef std::regex_traits<CharT> traits; + + traits t; + traits::string_type G = "abc"; + traits::string_type H = "def"; + traits::string_type J = "ABC"; + + VERIFY( G < H ); + VERIFY( t.transform_primary(G.begin(), G.end()) < t.transform_primary(H.begin(), H.end()) ); + + VERIFY( G == H ); + VERIFY( t.transform_primary(G.begin(), G.end()) == t.transform_primary(J.begin(), J.end()) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/translate.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/translate.cc new file mode 100644 index 00000000000..2dbbba39637 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/translate.cc @@ -0,0 +1,49 @@ +// { dg_do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] +// 28.7 (3) static std::size_t length(const char_type* p); + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + + std::regex_traits<CharT> t; + CharT c = 'a'; + CharT d = 'a'; + + VERIFY( t.translate(c) == t.translate(d) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/translate_nocase.cc new file mode 100644 index 00000000000..4c963ddd3a5 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/translate_nocase.cc @@ -0,0 +1,46 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits (5) translate_nocase + +#include <regex> +#include <testsuite_hooks.h> + +// Verifies the workings of the regex_traits translate_nocase function. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef char CharT; + + std::regex_traits<CharT> t; + CharT c = 'a'; + CharT C = 'A'; + + VERIFY( t.translate_nocase(c) == t.translate_nocase(C) ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/char/value.cc b/libstdc++-v3/testsuite/28_regex/07_traits/char/value.cc new file mode 100644 index 00000000000..f0535acb2cc --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/char/value.cc @@ -0,0 +1,49 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// 2008-08-11 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits value() function + +#include <regex> +#include <testsuite_hooks.h> + +// Tests the value() function of the regex_traits<char> class. +void test01() +{ + bool test __attribute__((unused)) = true; + std::regex_traits<char> t; + VERIFY( t.value('7', 8) == 7 ); + VERIFY( t.value('7', 10) == 7 ); + VERIFY( t.value('7', 16) == 7 ); + VERIFY( t.value('9', 8) == -1 ); + VERIFY( t.value('9', 10) == 9 ); + VERIFY( t.value('9', 16) == 9 ); + VERIFY( t.value('d', 8) == -1 ); + VERIFY( t.value('d', 10) == -1 ); + VERIFY( t.value('d', 16) == 13 ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/ctor.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/ctor.cc new file mode 100644 index 00000000000..39caf432d32 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/ctor.cc @@ -0,0 +1,49 @@ +// { dg-do link } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the regex_traits class. There is only the +// default constructor. +void test01() +{ + typedef std::regex_traits<wchar_t> test_type; + + // required default constructor + test_type t; + + // Check for required typedefs + typedef test_type::char_type char_type; + typedef test_type::string_type string_type; + typedef test_type::locale_type locale_type; + typedef test_type::char_class_type char_class_type; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/length.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/length.cc new file mode 100644 index 00000000000..c3cd7b60d0c --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/length.cc @@ -0,0 +1,49 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] +// 28.7 (3) static std::size_t length(const char_type* p); + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + typedef wchar_t CharT; + typedef std::regex_traits<CharT> traits; + bool test __attribute__((unused)) = true; + const CharT* p = L""; + + std::size_t i = traits::length(p); + + VERIFY( i == 0 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/transform.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/transform.cc new file mode 100644 index 00000000000..c1f7af44d71 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/transform.cc @@ -0,0 +1,51 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] + +#include <regex> +#include <string> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef wchar_t CharT; + typedef std::regex_traits<CharT> traits; + + traits t; + traits::string_type G = L"abc"; + traits::string_type H = L"def"; + + VERIFY( G < H ); + VERIFY( t.transform(G.begin(), G.end()) < t.transform(H.begin(), H.end()) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate.cc new file mode 100644 index 00000000000..962c381520c --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate.cc @@ -0,0 +1,49 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// +// 2010-02-17 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.3 Requirements [re.req] +// 28.2 (4) Table 127 - Regular expression traits class requirements +// 28.7 Class template regex_traits [re.traits] +// 28.7 (3) static std::size_t length(const char_type* p); + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef wchar_t CharT; + + std::regex_traits<CharT> t; + CharT c = L'a'; + CharT d = L'a'; + + VERIFY( t.translate(c) == t.translate(d) ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate_nocase.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate_nocase.cc new file mode 100644 index 00000000000..5602cf00117 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/translate_nocase.cc @@ -0,0 +1,46 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits (5) translate_nocase + +#include <regex> +#include <testsuite_hooks.h> + +// Verifies the workings of the regex_traits translate_nocase function. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef wchar_t CharT; + + std::regex_traits<CharT> t; + CharT c = L'a'; + CharT C = L'A'; + + VERIFY( t.translate_nocase(c) == t.translate_nocase(C) ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/value.cc b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/value.cc new file mode 100644 index 00000000000..f0535acb2cc --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/07_traits/wchar_t/value.cc @@ -0,0 +1,49 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// 2008-08-11 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.7] class template regex_traits value() function + +#include <regex> +#include <testsuite_hooks.h> + +// Tests the value() function of the regex_traits<char> class. +void test01() +{ + bool test __attribute__((unused)) = true; + std::regex_traits<char> t; + VERIFY( t.value('7', 8) == 7 ); + VERIFY( t.value('7', 10) == 7 ); + VERIFY( t.value('7', 16) == 7 ); + VERIFY( t.value('9', 8) == -1 ); + VERIFY( t.value('9', 10) == 9 ); + VERIFY( t.value('9', 16) == 9 ); + VERIFY( t.value('d', 8) == -1 ); + VERIFY( t.value('d', 10) == -1 ); + VERIFY( t.value('d', 16) == 13 ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring.cc new file mode 100644 index 00000000000..1552818e987 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2009-06-05 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2009 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/>. + +// C++0X [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests assign operation from a C-style null-terminated-string. +void test01() +{ + bool test __attribute__((unused)) = true; + + std::basic_regex<char> re; + + const char* cs = "aab"; + re.assign(cs); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring_op.cc new file mode 100644 index 00000000000..12353023b38 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/cstring_op.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests basic_regex assign operator from a C-style null-terminated-string. +void test01() +{ + typedef std::basic_regex<char> test_type; + + const char* cs = "aab"; + test_type re; + re = cs; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/moveable.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/moveable.cc new file mode 100644 index 00000000000..64f5bcac570 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/moveable.cc @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3](9-11) class template basic_regex assign + +#include <regex> +#include <testsuite_hooks.h> +#include <utility> + +// Tests assign operator of the basic_regex class for moveable rvalues. +void test01() +{ + bool test __attribute__((unused)) = true; + + std::regex src_re("aaba"); + const unsigned mark_count = src_re.mark_count(); + const std::regex::flag_type flags = src_re.flags(); + + std::regex target_re; + + target_re.assign(std::move(src_re)); + + VERIFY( target_re.flags() == flags ); + VERIFY( target_re.mark_count() == mark_count ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/pstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/pstring.cc new file mode 100644 index 00000000000..398b66c6063 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/pstring.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests assign operation from a Pascal-style counted-string. +void test01() +{ + typedef std::basic_regex<char> test_type; + + const char cs[] = "aab"; + test_type re; + re.assign(cs, sizeof(cs)-1, std::regex_constants::basic); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/range.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/range.cc new file mode 100644 index 00000000000..cd741d5fff2 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/range.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests range assign of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + char s[] = "a+b|c"; + test_type re; + re.assign(s, s + 5); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string.cc new file mode 100644 index 00000000000..afa071eb312 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <string> +#include <regex> +#include <testsuite_hooks.h> + +// Tests C++ string assignment of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + std::string s("a*b"); + test_type re; + re.assign(s); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string_op.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string_op.cc new file mode 100644 index 00000000000..724872decd5 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/char/string_op.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <string> +#include <regex> +#include <testsuite_hooks.h> + +// Tests basic_regex assignment operator from a C++ string; +void test01() +{ + typedef std::basic_regex<char> test_type; + + std::string s("a*b"); + test_type re; + re = s; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring.cc new file mode 100644 index 00000000000..20ccab01244 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests assign operation from a C-style null-terminated-string. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + const wchar_t* cs = L"aab"; + test_type re; + re.assign(cs); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring_op.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring_op.cc new file mode 100644 index 00000000000..8d8e9656d9e --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/cstring_op.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests basic_regex assign operator from a C-style null-terminated-string. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + const wchar_t* cs = L"aab"; + test_type re; + re = cs; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/pstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/pstring.cc new file mode 100644 index 00000000000..9034a542c01 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/pstring.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests assign operation from a Pascal-style counted-string. +void test01() +{ + typedef std::basic_regex<wchar_t> test_type; + + const wchar_t cs[] = L"aab"; + test_type re; + re.assign(cs, sizeof(cs)-1, std::regex_constants::basic); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/range.cc new file mode 100644 index 00000000000..2e31a708417 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/range.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <regex> +#include <testsuite_hooks.h> + +// Tests range assign of the basic_regex class. +void test01() +{ + typedef std::basic_regex<wchar_t> test_type; + bool test __attribute__((unused)) = true; + + wchar_t s[] = L"a+b|c"; + test_type re; + re.assign(s, s + 5); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string.cc new file mode 100644 index 00000000000..156374ac1a7 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string.cc @@ -0,0 +1,45 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <string> +#include <regex> +#include <testsuite_hooks.h> + +// Tests C++ string assignment of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + std::wstring s(L"a*b"); + test_type re; + re.assign(s); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string_op.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string_op.cc new file mode 100644 index 00000000000..43704af2bd1 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/assign/wchar_t/string_op.cc @@ -0,0 +1,45 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.3] class template basic_regex assign() + +#include <string> +#include <regex> +#include <testsuite_hooks.h> + +// Tests basic_regex assignment operator from a C++ string; +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + std::wstring s(L"a*b"); + test_type re; + re = s; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/cstring.cc new file mode 100644 index 00000000000..b91453c0e77 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/cstring.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> + +void +test01() +{ + std::regex re("(a|b)*abb", std::regex::basic); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_char.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_char.cc new file mode 100644 index 00000000000..2f011fe52c4 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_char.cc @@ -0,0 +1,42 @@ +// { dg-do run } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests Pascal-style counted-string constructor of the basic_regex class. +void test01() +{ + const char* cs = "aab"; + std::regex re(cs, 3, std::regex::basic); + + VERIFY( re.flags() & std::regex_constants::basic ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_wchar_t.cc new file mode 100644 index 00000000000..89deef6f19f --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/pstring_wchar_t.cc @@ -0,0 +1,44 @@ +// { dg-do run } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests Pascal-style counted-string constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + + const wchar_t* cs = L"aab"; + std::wregex re(cs, 3, std::wregex::basic); + + VERIFY( re.flags() & std::regex_constants::basic ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/string_range_01_02_03.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/string_range_01_02_03.cc new file mode 100644 index 00000000000..471c89c9024 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/basic/string_range_01_02_03.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.8.2 basic_regex ctor +// Tests for invalid range expression + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + try + { + std::regex re("a\\{1,2,3\\}", std::regex::basic); + } + catch (std::regex_error& ex) + { + VERIFY( ex.code() == std::regex_constants::error_badbrace ); + } +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring.cc new file mode 100644 index 00000000000..ac87e4d69a0 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring.cc @@ -0,0 +1,42 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests C-style null-terminated-string constructor of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + const char* cs = "aab"; + test_type re(cs); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_awk.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_awk.cc new file mode 100644 index 00000000000..8b93fe7a721 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_awk.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> + +void +test01() +{ + std::regex re("(a|b)*abb", std::regex::awk); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_ecma.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_ecma.cc new file mode 100644 index 00000000000..6c72736c5cd --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_ecma.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> + +void +test01() +{ + std::regex re("(a|b)*abb"); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_egrep.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_egrep.cc new file mode 100644 index 00000000000..f38a9b8704e --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_egrep.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> + +void +test01() +{ + std::regex re("(a|b)*abb", std::regex::egrep); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_grep.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_grep.cc new file mode 100644 index 00000000000..458f6d21cc5 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/cstring_grep.cc @@ -0,0 +1,39 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> + +void +test01() +{ + using std::regex; + + regex re("(a|b)*abb", regex::grep); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/default.cc new file mode 100644 index 00000000000..b7c6f410cde --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/default.cc @@ -0,0 +1,47 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + // default constructor + test_type re; + + // Check for required typedefs + typedef test_type::value_type value_type; + typedef test_type::flag_type flag_type; + typedef test_type::locale_type locale_type; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/range.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/range.cc new file mode 100644 index 00000000000..027a927849e --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/char/range.cc @@ -0,0 +1,42 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests range constructor of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + char s[] = "a+b|c"; + test_type re(s, s + 5); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/copy_char.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/copy_char.cc new file mode 100644 index 00000000000..4ed5f92c8b0 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/copy_char.cc @@ -0,0 +1,45 @@ +// { dg-options "-std=c++0x" } + +// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2](11) class template basic_regex constructors + +#include <regex> +#include <testsuite_hooks.h> + +// Tests copy constructor of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + test_type src_re("aaba"); + + test_type target_re(src_re); + + VERIFY( target_re.flags() == src_re.flags() ); + VERIFY( target_re.mark_count() == src_re.mark_count() ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/cstring.cc new file mode 100644 index 00000000000..691b8c7f5f1 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/cstring.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009 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/>. + +// 7.8.2 basic_regex constructors + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("(wee|week)(knights|night)", std::regex::extended); + + VERIFY( re.flags() == std::regex::extended ); + VERIFY( re.mark_count() == 0 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/string_range_01_02_03.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/string_range_01_02_03.cc new file mode 100644 index 00000000000..036321face5 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/extended/string_range_01_02_03.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.8.2 basic_regex ctor +// Tests for invalid range expression + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + try + { + std::regex re("a{1,2,3}", std::regex::extended); + } + catch (std::regex_error& ex) + { + VERIFY( ex.code() == std::regex_constants::error_badbrace ); + } +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/move_char.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/move_char.cc new file mode 100644 index 00000000000..ba056969c5c --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/move_char.cc @@ -0,0 +1,49 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-07-07 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2](12-14) class template basic_regex constructors + +#include <regex> +#include <testsuite_hooks.h> +#include <utility> + +// Tests move constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<char> test_type; + + test_type src_re("aaba"); + const unsigned mark_count = src_re.mark_count(); + const test_type::flag_type flags = src_re.flags(); + + test_type target_re = std::move(src_re); + + VERIFY( target_re.flags() == flags ); + VERIFY( target_re.mark_count() == mark_count ); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_char.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_char.cc new file mode 100644 index 00000000000..f65d783a735 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_char.cc @@ -0,0 +1,54 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <string> +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_allocator.h> + +// Tests C++ string constructor of the basic_regex class. +void test01() +{ + typedef std::basic_regex<char> test_type; + + std::string s("a*b"); + test_type re(s); +} + +void test02() +{ + typedef std::basic_regex<char> test_type; + typedef __gnu_test::tracker_allocator<char> alloc_type; + + std::basic_string<char, std::char_traits<char>, alloc_type> s("a*b"); + test_type re(s); +} + +int +main() +{ + test01(); + test02(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_wchar_t.cc new file mode 100644 index 00000000000..b715195c383 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/string_wchar_t.cc @@ -0,0 +1,56 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <string> +#include <regex> +#include <testsuite_hooks.h> +#include <testsuite_allocator.h> + +// Tests C++ string constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + std::wstring s(L"a*b"); + test_type re(s); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + typedef __gnu_test::tracker_allocator<wchar_t> alloc_type; + + std::basic_string<wchar_t, std::char_traits<wchar_t>, alloc_type> s(L"a*b"); + test_type re(s); +} + +int +main() +{ + test01(); + test02(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/cstring.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/cstring.cc new file mode 100644 index 00000000000..4dabf399677 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/cstring.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests C-style null-terminated-string constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + const wchar_t* cs = L"aab"; + test_type re(cs); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/default.cc new file mode 100644 index 00000000000..a0f41740229 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/default.cc @@ -0,0 +1,48 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + // default constructor + test_type re; + + // Check for required typedefs + typedef test_type::value_type value_type; + typedef test_type::flag_type flag_type; + typedef test_type::locale_type locale_type; +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/range.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/range.cc new file mode 100644 index 00000000000..efc0597cc1d --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/ctors/wchar_t/range.cc @@ -0,0 +1,43 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2010 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/>. + +// [28.8.2] class template basic_regex constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests range constructor of the basic_regex class. +void test01() +{ + bool test __attribute__((unused)) = true; + typedef std::basic_regex<wchar_t> test_type; + + wchar_t s[] = L"a+b|c"; + test_type re(s, s + 5); +} + +int +main() +{ + test01(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/08_basic_regex/regex.cc b/libstdc++-v3/testsuite/28_regex/08_basic_regex/regex.cc new file mode 100644 index 00000000000..8a803ede81f --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/08_basic_regex/regex.cc @@ -0,0 +1,37 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// 2007-03-12 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2007, 2009, 2010 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/>. + +// 7.4 typedef std::regex + +#include <regex> + +void +test01() +{ + std::regex re; +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_char.cc b/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_char.cc new file mode 100644 index 00000000000..6beb9c5cdb2 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_char.cc @@ -0,0 +1,49 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.9.1 [re.submatch.members] sub_match members + +#include <regex> +#include <string> +#include <testsuite_hooks.h> + + +void +test01() +{ + bool test __attribute__((unused)) = true; + + typedef char value_type; + typedef std::basic_string<value_type> string_type; + typedef std::sub_match<value_type*> sub_match_type; + value_type test_data[] = "cabbage"; + + sub_match_type sm; + sm.first = test_data + 0; + sm.second = test_data + sizeof(test_data)/sizeof(value_type); + sm.matched = true; + + string_type sm_string = sm; + + VERIFY( sm_string == string_type(test_data) ); +} diff --git a/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_wchar_t.cc b/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_wchar_t.cc new file mode 100644 index 00000000000..6e29ac88c09 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/09_sub_match/cast_wchar_t.cc @@ -0,0 +1,49 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.9.1 [re.submatch.members] sub_match members + +#include <regex> +#include <string> +#include <testsuite_hooks.h> + + +void +test01() +{ + bool test __attribute__((unused)) = true; + + typedef wchar_t value_type; + typedef std::basic_string<value_type> string_type; + typedef std::sub_match<value_type*> sub_match_type; + value_type test_data[] = L"cabbage"; + + sub_match_type sm; + sm.first = test_data + 0; + sm.second = test_data + sizeof(test_data)/sizeof(value_type); + sm.matched = true; + + string_type sm_string = sm; + + VERIFY( sm_string == string_type(test_data) ); +} diff --git a/libstdc++-v3/testsuite/28_regex/09_sub_match/length.cc b/libstdc++-v3/testsuite/28_regex/09_sub_match/length.cc new file mode 100644 index 00000000000..fc12b920ad9 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/09_sub_match/length.cc @@ -0,0 +1,49 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-09 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.9.1 [re.submatch.members] sub_match members + +#include <regex> +#include <testsuite_hooks.h> + + +void +test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::sub_match<const char*> sm_t; + const char* test_data = "cabbage"; + sm_t::difference_type test_len = 3; + + sm_t sm1; + sm1.first = test_data + 0; + sm1.second = test_data + test_len; + sm1.matched = true; + + sm_t sm2; + sm2.matched = false; + + VERIFY( sm1.length() == test_len ); + VERIFY( sm2.length() == 0 ); +} diff --git a/libstdc++-v3/testsuite/28_regex/09_sub_match/typedefs.cc b/libstdc++-v3/testsuite/28_regex/09_sub_match/typedefs.cc new file mode 100644 index 00000000000..c150da02dac --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/09_sub_match/typedefs.cc @@ -0,0 +1,38 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-07 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.9 Class template sub_match + +#include <regex> + + +void +test01() +{ + typedef std::sub_match<char*> sm; + + typedef sm::value_type value_type; + typedef sm::difference_type difference_type; + typedef sm::iterator iterator; + typedef sm::string_type string_type; +} diff --git a/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/char/default.cc new file mode 100644 index 00000000000..4c897d7a4a0 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/char/default.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=c++0x" } + +// 2009-06-10 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2009 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/>. + +// C++0X [28.10.1] class template match_results constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the match_result class. +void test01() +{ + bool test __attribute__((unused)) = true; + + std::cmatch cm; + VERIFY( cm.size() == 0 ); + VERIFY( cm.str() == std::cmatch::string_type() ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + std::smatch sm; + VERIFY( sm.size() == 0 ); + VERIFY( sm.str() == std::smatch::string_type() ); +} + +int +main() +{ + test01(); + test02(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/wchar_t/default.cc new file mode 100644 index 00000000000..f8b3d45e867 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/10_match_results/ctors/wchar_t/default.cc @@ -0,0 +1,52 @@ +// { dg-options "-std=c++0x" } + +// 2009-06-05 Stephen M. Webb <stephen.webb@bregmasoft.com> +// +// Copyright (C) 2009 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/>. + +// C++0X [28.10.1] class template match_results constructor + +#include <regex> +#include <testsuite_hooks.h> + +// Tests default constructor of the match_result class. +void test01() +{ + bool test __attribute__((unused)) = true; + + std::wcmatch cm; + VERIFY( cm.size() == 0 ); + VERIFY( cm.str() == std::wcmatch::string_type() ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + + std::wsmatch sm; + VERIFY( sm.size() == 0 ); + VERIFY( sm.str() == std::wsmatch::string_type() ); +} + +int +main() +{ + test01(); + test02(); + return 0; +}; diff --git a/libstdc++-v3/testsuite/28_regex/10_match_results/typedefs.cc b/libstdc++-v3/testsuite/28_regex/10_match_results/typedefs.cc new file mode 100644 index 00000000000..02bdcdadb71 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/10_match_results/typedefs.cc @@ -0,0 +1,44 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.10 Class template sub_match + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef std::match_results<char*> mr; + + typedef mr::value_type value_type; + typedef mr::const_reference const_reference; + typedef mr::reference reference; + typedef mr::const_iterator const_iterator; + typedef mr::iterator iterator; + typedef mr::difference_type difference_type; + typedef mr::size_type size_type; + typedef mr::allocator_type allocator_type; + typedef mr::char_type char_type; + typedef mr::string_type string_type; +} diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_01.cc new file mode 100644 index 00000000000..4a7161a7967 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_01.cc @@ -0,0 +1,63 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-11 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests BRE against a std::string target. + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("\\(a\\).*", std::regex::basic); + std::string target("aaba"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); + VERIFY( m[1].first == target.begin() ); + VERIFY( m[1].second == target.begin()+1 ); + VERIFY( m[1].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_00_03.cc new file mode 100644 index 00000000000..6c0fdd76f2c --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_00_03.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests BRE against a std::string target, exercising range {0,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a\\{0,3\\}", std::regex::basic); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_01_03.cc new file mode 100644 index 00000000000..3439b544b63 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_01_03.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests BRE against a std::string target, exercising range {1,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a\\{1,3\\}", std::regex::basic); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_02_03.cc new file mode 100644 index 00000000000..dfd00a0f3d7 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/basic/string_range_02_03.cc @@ -0,0 +1,61 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests BRE against a std::string target, exercising range {2,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a\\{2,3\\}", std::regex::basic); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_plus.cc new file mode 100644 index 00000000000..ad0f57e221d --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_plus.cc @@ -0,0 +1,65 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a C-string target, plus-sign match. + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("(a+)", std::regex::extended); + const char target[] = "aa"; + std::cmatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( re.mark_count() == 1 ); + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target ); + VERIFY( m.prefix().second == target ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target+sizeof(target) ); + VERIFY( m.suffix().second == target+sizeof(target) ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target ); + VERIFY( m[0].second == target+sizeof(target) ); + VERIFY( m[0].matched == true ); + VERIFY( m[1].first == target ); + VERIFY( m[1].second == target+sizeof(target) ); + VERIFY( m[1].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_questionmark.cc new file mode 100644 index 00000000000..21abea456a9 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/cstring_questionmark.cc @@ -0,0 +1,65 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a C-string target, question-mark match. + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("(aa?)", std::regex::extended); + char target[] = "a"; + std::cmatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( re.mark_count() == 1 ); + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target ); + VERIFY( m.prefix().second == target ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target+sizeof(target) ); + VERIFY( m.suffix().second == target+sizeof(target) ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target ); + VERIFY( m[0].second == target+sizeof(target) ); + VERIFY( m[0].matched == true ); + VERIFY( m[1].first == target ); + VERIFY( m[1].second == target+sizeof(target) ); + VERIFY( m[1].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_any.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_any.cc new file mode 100644 index 00000000000..8d3716b1edf --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_any.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-11 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a std::string target. + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re(".*", std::regex::extended); + std::string target("aaba"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_00_03.cc new file mode 100644 index 00000000000..a0a2e1fa9d8 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_00_03.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a std::string target, exercising range {0,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a{0,3}", std::regex::extended); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_01_03.cc new file mode 100644 index 00000000000..b50e07645ab --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_01_03.cc @@ -0,0 +1,60 @@ +// { dg-options "-std=c++0x" } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a std::string target, exercising range {1,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a{1,3}", std::regex::extended); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_02_03.cc new file mode 100644 index 00000000000..ca322a8d4cd --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/11_algorithms/02_match/extended/string_range_02_03.cc @@ -0,0 +1,61 @@ +// { dg-options "-std=c++0x" } +// { dg-do run { xfail *-*-* } } + +// +// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.11.2 regex_match +// Tests ERE against a std::string target, exercising range {2,3} + +#include <regex> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::regex re("a{2,3}", std::regex::extended); + std::string target("aa"); + std::smatch m; + + VERIFY( std::regex_match(target, m, re) ); + + VERIFY( m.size() == re.mark_count()+1 ); + VERIFY( m.empty() == false ); + VERIFY( m.prefix().first == target.begin() ); + VERIFY( m.prefix().second == target.begin() ); + VERIFY( m.prefix().matched == false ); + VERIFY( m.suffix().first == target.end() ); + VERIFY( m.suffix().second == target.end() ); + VERIFY( m.suffix().matched == false ); + VERIFY( m[0].first == target.begin() ); + VERIFY( m[0].second == target.end() ); + VERIFY( m[0].matched == true ); +} + + +int +main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/char/default.cc new file mode 100644 index 00000000000..2de4a0d09b8 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/char/default.cc @@ -0,0 +1,35 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.1 Class template regex_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + std::regex_iterator<char*> it; + std::cregex_iterator cit; + std::sregex_iterator sit; +} diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/wchar_t/default.cc new file mode 100644 index 00000000000..33fb5baa808 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/ctors/wchar_t/default.cc @@ -0,0 +1,35 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.1 Class template regex_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + std::regex_iterator<wchar_t*> it; + std::wcregex_iterator cit; + std::wsregex_iterator sit; +} diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/typedefs.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/typedefs.cc new file mode 100644 index 00000000000..8ad88995078 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_iterator/typedefs.cc @@ -0,0 +1,40 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.1 Class template regex_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef std::regex_iterator<char*> it; + + typedef it::regex_type regex_type; + typedef it::value_type value_type; + typedef it::difference_type difference_type; + typedef it::pointer pointer; + typedef it::reference reference; + typedef it::iterator_category iterator_category; +} diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/char/default.cc new file mode 100644 index 00000000000..5105c7d8732 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/char/default.cc @@ -0,0 +1,35 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.2 Class template regex_token_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + std::regex_token_iterator<char*> it; + std::cregex_token_iterator cit; + std::sregex_token_iterator sit; +} diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/wchar_t/default.cc new file mode 100644 index 00000000000..fe918c80d71 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/ctors/wchar_t/default.cc @@ -0,0 +1,35 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.2 Class template regex_token_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + std::regex_token_iterator<wchar_t*> it; + std::wcregex_token_iterator cit; + std::wsregex_token_iterator sit; +} diff --git a/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/typedefs.cc b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/typedefs.cc new file mode 100644 index 00000000000..d765ab2f403 --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/12_iterators/regex_token_iterator/typedefs.cc @@ -0,0 +1,40 @@ +// { dg-do compile } +// { dg-options "-std=c++0x" } + +// +// 2010-06-10 Stephen M. Webb <stephen.webb@bregmasoft.ca> +// +// Copyright (C) 2010 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/>. + +// 28.12.2 Class template regex_token_iterator + +#include <regex> + +void +test01() +{ + bool test __attribute__((unused)) = true; + typedef std::regex_token_iterator<char*> it; + + typedef it::regex_type regex_type; + typedef it::value_type value_type; + typedef it::difference_type difference_type; + typedef it::pointer pointer; + typedef it::reference reference; + typedef it::iterator_category iterator_category; +} diff --git a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/char/1.cc b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/char/1.cc index 7eb4719a7c7..dab6c50b64d 100644 --- a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/char/1.cc +++ b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/char/1.cc @@ -33,7 +33,7 @@ void test01() const char* name = "stdiobuf-1.txt"; FILE* fout = fopen(name, "w"); - fwrite(c_lit, 1, size, fout); + VERIFY( fwrite(c_lit, 1, size, fout) == size ); fclose(fout); FILE* fin = fopen(name, "r"); diff --git a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/1.cc b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/1.cc index 6b0cee4db92..61e7a553482 100644 --- a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/1.cc @@ -33,7 +33,7 @@ void test01() const char* name = "stdiobuf-1.txt"; FILE* fout = fopen(name, "w"); - fwrite(c_lit, 1, size, fout); + VERIFY( fwrite(c_lit, 1, size, fout) == size ); fclose(fout); FILE* fin = fopen(name, "r"); diff --git a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc index aeb957618ae..fa754c459d0 100644 --- a/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc +++ b/libstdc++-v3/testsuite/ext/stdio_sync_filebuf/wchar_t/12077.cc @@ -64,7 +64,7 @@ void test01() fputs(str, file); fclose(file); - freopen(name, "r", stdin); + VERIFY( freopen(name, "r", stdin) ); streamsize n = wcin.rdbuf()->in_avail(); while (n--) diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h index da51d37ae62..fe41b1cb3e6 100644 --- a/libstdc++-v3/testsuite/util/testsuite_hooks.h +++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h @@ -1,7 +1,8 @@ // -*- C++ -*- // Utility subroutines for the C++ library testsuite. // -// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +// 2009, 2010 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -59,7 +60,7 @@ # include <cassert> # define VERIFY(fn) assert(fn) #else -# define VERIFY(fn) test &= (fn) +# define VERIFY(fn) test &= bool(fn) #endif #ifdef _GLIBCXX_HAVE_UNISTD_H |