summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-10-08 05:57:48 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-10-08 05:57:48 +0000
commitc95b9ae3504a8da1a31c1ed2224f97b3d4b829a2 (patch)
tree775928cf6a1e9f1553ce9d66715128ff7443febe
parent6b478e0035aa8103bd1985b85280892386cd32ef (diff)
downloadgcc-c95b9ae3504a8da1a31c1ed2224f97b3d4b829a2.tar.gz
2008-10-08 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r140962 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@140963 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog.melt3
-rw-r--r--gcc/ChangeLog274
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/gcc-interface/decl.c68
-rw-r--r--gcc/ada/gcc-interface/trans.c4
-rw-r--r--gcc/ada/gcc-interface/utils.c125
-rw-r--r--gcc/alloc-pool.c76
-rw-r--r--gcc/basic-block.h3
-rw-r--r--gcc/c-common.c19
-rw-r--r--gcc/c-common.h8
-rw-r--r--gcc/c-decl.c2
-rw-r--r--gcc/c-omp.c21
-rw-r--r--gcc/c-parser.c42
-rw-r--r--gcc/c-typeck.c190
-rw-r--r--gcc/cfgcleanup.c26
-rw-r--r--gcc/cfgexpand.c48
-rw-r--r--gcc/cfglayout.c40
-rw-r--r--gcc/cfgrtl.c35
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/darwin-protos.h3
-rw-r--r--gcc/config/darwin.c93
-rw-r--r--gcc/config/darwin.h5
-rw-r--r--gcc/config/i386/darwin.h2
-rw-r--r--gcc/config/i386/i386-protos.h4
-rw-r--r--gcc/config/i386/i386.c213
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/i386/i386.md29
-rw-r--r--gcc/config/i386/i386.opt4
-rw-r--r--gcc/config/i386/mingw32.h2
-rw-r--r--gcc/config/i386/ppro.md170
-rw-r--r--gcc/config/i386/predicates.md3
-rw-r--r--gcc/config/mips/10000.md253
-rw-r--r--gcc/config/mips/mips.c22
-rw-r--r--gcc/config/mips/mips.h1
-rw-r--r--gcc/config/mips/mips.md37
-rw-r--r--gcc/config/rs6000/rs6000-c.c8
-rw-r--r--gcc/config/rs6000/rs6000-protos.h2
-rw-r--r--gcc/config/rs6000/rs6000.c166
-rw-r--r--gcc/config/rs6000/rs6000.h8
-rw-r--r--gcc/config/rs6000/rs6000.md6
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-gimplify.c35
-rw-r--r--gcc/cp/decl.c1
-rw-r--r--gcc/cp/mangle.c116
-rw-r--r--gcc/cp/name-lookup.c11
-rw-r--r--gcc/cp/operators.def5
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/cp/typeck.c16
-rw-r--r--gcc/doc/invoke.texi1
-rw-r--r--gcc/doc/rtl.texi8
-rw-r--r--gcc/dwarf2out.c185
-rw-r--r--gcc/expmed.c3
-rw-r--r--gcc/expr.c3
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/f95-lang.c10
-rw-r--r--gcc/fortran/trans-decl.c19
-rw-r--r--gcc/gimplify.c18
-rw-r--r--gcc/ira-lives.c142
-rw-r--r--gcc/objc/ChangeLog26
-rw-r--r--gcc/objc/objc-act.c111
-rw-r--r--gcc/opts.c3
-rw-r--r--gcc/opts.h16
-rw-r--r--gcc/print-tree.c6
-rw-r--r--gcc/profile.c6
-rw-r--r--gcc/testsuite/ChangeLog74
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle30.C22
-rw-r--r--gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto6.C71
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic4.C8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic42.C4
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C35
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-mangle.C8
-rw-r--r--gcc/testsuite/g++.dg/parse/struct-4.C13
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c35
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c53
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c39
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c53
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c41
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr29609-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr29609-2.c53
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr36690-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr36690-2.c40
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr36690-3.c47
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr37616.c40
-rw-r--r--gcc/testsuite/gcc.dg/gomp/for-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/misc-column.c11
-rw-r--r--gcc/testsuite/gcc.dg/struct-parse-2.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr37731-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr37731-2.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp1
-rw-r--r--gcc/testsuite/gcc.target/mips/r3900-mult.c9
-rw-r--r--gcc/testsuite/gfortran.dg/debug/pr37738.f30
-rw-r--r--gcc/testsuite/gnat.dg/addr4.adb12
-rw-r--r--gcc/testsuite/gnat.dg/addr5.adb10
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization4.adb9
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization4_pkg.adb17
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization4_pkg.ads9
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert2.adb34
-rw-r--r--gcc/tree-cfg.c24
-rw-r--r--gcc/tree-ssa-loop-ivopts.c2
-rw-r--r--gcc/tree.c2
-rw-r--r--gcc/tree.def11
-rw-r--r--gcc/tree.h7
-rw-r--r--include/ChangeLog5
-rw-r--r--include/demangle.h4
-rw-r--r--libiberty/ChangeLog25
-rw-r--r--libiberty/config.in6
-rwxr-xr-xlibiberty/configure367
-rw-r--r--libiberty/configure.ac1
-rw-r--r--libiberty/cp-demangle.c298
-rw-r--r--libiberty/cp-demangle.h2
-rw-r--r--libiberty/testsuite/demangle-expected32
-rw-r--r--libstdc++-v3/ChangeLog19
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver12
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h20
-rw-r--r--libstdc++-v3/testsuite/abi/demangle/abi_examples/20.cc2
-rw-r--r--libstdc++-v3/testsuite/abi/demangle/abi_text/02.cc2
-rw-r--r--libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc8
122 files changed, 3654 insertions, 962 deletions
diff --git a/ChangeLog.melt b/ChangeLog.melt
index a0df0bf9333..be537e1ac1e 100644
--- a/ChangeLog.melt
+++ b/ChangeLog.melt
@@ -1,3 +1,6 @@
+2008-10-08 Basile Starynkevitch <basile@starynkevitch.net>
+ MELT branch merged with trunk r140962
+
2008-10-05 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r140892
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71eaead3463..abe7fdc4959 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,277 @@
+2008-10-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.md: Remove trailing white spaces.
+
+2008-10-07 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ PR rtl-optimization/37448
+ alloc_pool_desc (elt_size): New field.
+ alloc_pool_desc (created, allocated, current, peak): Make unsigned
+ long.
+ output_info (count): Renamed total_created and made unsigned long.
+ output_info (size): Renamed total_allocated and made unsigned long.
+ alloc-pool.c (create_alloc_pool, empty_alloc_pool, pool_alloc,
+ pool_free): Properly keep track of desc->size.
+ (print_statistics, dump_alloc_pool_statistics): Enhance the
+ printing of statistics to print the number of elements and to use
+ unsigned longs.
+
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/37576
+ * opts.h (CL_SAVE): Move up to flags range.
+ (CL_PARAMS, CL_WARNING, CL_OPTIMIZATION, CL_TARGET,
+ CL_COMMON): Renumber.
+ (CL_MIN_OPTION_CLASS): Set to CL_PARAMS.
+ * opts.c (common_handle_option): Revert last change.
+
+2008-10-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386-protos.h (ix86_schedule): New.
+
+ * config/i386/i386.c (ix86_schedule): New.
+ (override_options): Add schedule to processor_alias_table. Set
+ ix86_schedule from the schedule field in processor_alias_table.
+ (ix86_function_specific_save): Save ix86_schedule.
+ (ix86_function_specific_restore): Restore ix86_schedule.
+
+ * config/i386/i386.md (cpu): Map to ix86_schedule instead of
+ ix86_tune. Add none and remove i386, i486, pentium4, nocona
+ and generic32.
+
+ * config/i386/i386.opt: Add schedule.
+
+ * config/i386/ppro.md: Remove generic32.
+
+2008-10-07 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c/35437
+ * expr.c (count_type_elements): Handle ERROR_MARK.
+
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/29609
+ PR debug/36690
+ PR debug/37616
+ * basic-block.h (struct edge_def): Add goto_block field.
+ * cfglayout.c (fixup_reorder_chain): Ensure that there is at least
+ one insn with locus corresponding to edge's goto_locus if !optimize.
+ * profile.c (branch_prob): Copy edge's goto_block.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Use goto_locus for
+ emitted jumps.
+ (cfg_layout_merge_blocks): Emit a nop with edge's goto_locus
+ locator in between the merged basic blocks if !optimize and needed.
+ * cfgexpand.c (expand_gimple_cond): Convert goto_block and
+ goto_locus into RTL locator. For unconditional jump use that
+ locator for the jump insn.
+ (expand_gimple_cond): Convert goto_block and goto_locus into
+ RTL locator for all remaining edges. For unconditional jump
+ use that locator for the jump insn.
+ * cfgcleanup.c (try_forward_edges): Avoid the optimization if
+ there is more than one edge or insn locator along the forwarding
+ edges and !optimize. If there is just one, set e->goto_locus.
+ * tree-cfg.c (make_cond_expr_edges, make_goto_expr_edges): Set also
+ edge's goto_block.
+ (move_block_to_fn): Adjust edge's goto_block.
+
+2008-10-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/37731
+ * expmed.c (expand_mult): Properly check DImode constant in
+ CONST_DOUBLE.
+
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/37738
+ * dwarf2out.c (common_block_die_table): New variable.
+ (common_block_die_table_hash, common_block_die_table_eq): New
+ functions.
+ (gen_variable_die): Look up a DW_TAG_common_block die for a particular
+ COMMON block in the current scope rather than globally. Optimize
+ DW_OP_addr SYMBOL_REF DW_OP_plus_uconst off into
+ DW_OP_addr SYMBOL_REF+off.
+
+2008-10-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-loop-ivopts.c (may_be_nonaddressable_p) <VIEW_CONVERT_EXPR>:
+ Return true for non-addressable GIMPLE operands.
+
+2008-10-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/24765
+ * config/i386/i386.c (initial_ix86_tune_features): Remove
+ X86_TUNE_USE_BIT_TEST.
+ * config/i386/i386.h (ix86_tune_indices): Likewise.
+ (TARGET_USE_BIT_TEST): Removed.
+
+2008-10-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * config.gcc (arm*-*-*): Add aapcs-linux to supported ABIs.
+
+2008-10-06 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (mulsi3_mul3, muldi3_mul3): Merge these ...
+ (mul<mode>3_mul3): ... into this new template.
+
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_arg): Add location argument. Use it.
+ (gimplify_call_expr): Pass location to gimplify_arg.
+ (gimplify_modify_expr_to_memcpy): Same.
+ (gimplify_modify_expr_to_memset): Same.
+
+2008-10-06 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
+ Update calls to build_unary_op and build_indirect_ref for location
+ changes.
+
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ build_modify_expr.
+ * c-decl.c (finish_decl): Pass input_location to build_unary_op.
+ * c-typeck.c (array_to_pointer_conversion): Pass location to
+ build_unary_op.
+ (function_to_pointer_conversion): Use error_at and warning_at.
+ (build_indirect_ref): Same.
+ (build_array_ref): Pass location to build_binary_op.
+ (parser_build_unary_op): Do not set location after calling
+ build_unary_op.
+ (build_unary_op): Add location argument. Use it throughout. Set
+ EXPR_LOCATION before returning new tree.
+ (build_modify_expr): Same.
+ (build_binary_op): Use location throughout. Set EXPR_LOCATION before
+ returning node.
+ * c-omp.c (c_finish_omp_atomic): Pass location to build_unary_op,
+ build_indirect_ref, build_modify_expr.
+ (c_finish_omp_for): Same. Use error_at instead of error.
+ * c-common.c (c_common_truthvalue_conversion): Pass location to
+ build_unary_op.
+ (warn_for_div_by_zero): Add location argument.
+ * c-common.h: Add argument to build_modify_expr, build_indirect_ref,
+ build_unary_op, warn_for_div_by_zero.
+ * c-parser.c (c_parser_typeof_specifier): Use
+ protected_set_expr_location.
+ (c_parser_statement_after_labels): Same.
+ (c_parser_condition): Same.
+ (c_parser_expr_no_commas): Pass correct location to build_modify_expr.
+ (c_parser_conditional_expression): Use protected_set_expr_location.
+ (c_parser_unary_expression): Pass location to build_indirect_ref.
+ (c_parser_postfix_expression_after_primary): Pass location to
+ build_indirect_ref, build_unary_op.
+ (c_parser_omp_for_loop): Set the increment expression's EXPR_LOCATION.
+
+2008-10-06 Joshua Kinard <kumba@gentoo.org>
+
+ * doc/invoke.texi: List r1x000 family under the -march MIPS option.
+ * config/mips/mips.h (PROCESSOR_R10000): New processor_type.
+ * config/mips/mips.c (mips_cpu_info_table): Add r10000, r12000,
+ r14000 and r16000.
+ (mips_rtx_cost_data): Add a PROCESSOR_R10000 entry.
+ (mips_issue_rate): Handle PROCESSOR_R10000.
+ * config/mips/mips.md (cpu): Add r10000.
+ Include r10000.md.
+ * config/mips/10000.md: New file.
+
+2008-10-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_find_base_term): Declare.
+ * config/rs6000/rs6000.h (FIND_BASE_TERM): New macro.
+ * config/rs6000/rs6000.c (rs6000_find_base_term): New function.
+
+2008-10-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/darwin-protos.h (machopic_function_base_name): Delete.
+ (machopic_function_base_sym): Likewise.
+ (machopic_gen_offset): Declare.
+ * config/darwin.h (MACHOPIC_FUNCTION_BASE_NAME): New macro.
+ (ASM_OUTPUT_LABELREF): Use it instead of a hard-coded string constant.
+ * config/darwin.c (machopic_function_base_name): Delete.
+ (machopic_function_base_sym): Likewise.
+ (gen_pic_offset): Rename to...
+ (machopic_gen_offset): ...this and remove the pic_base argument.
+ Instead use MACHO_DYNAMIC_NO_PIC_P to decide whether a PIC offset
+ is needed. Create an UNSPEC_MACHOPIC_OFFSET if so, and set
+ crtl->uses_pic_offset_table.
+ (machopic_indirect_data_reference): Use new machopic_gen_offset
+ interface.
+ (machopic_legitimize_pic_address): Likewise.
+ (machopic_operand_p): Check for UNSPEC_MACHOPIC_OFFSET.
+
+ * config/i386/darwin.h (GOT_SYMBOL_NAME): Use
+ MACHOPIC_FUNCTION_BASE_NAME instead of machopic_function_base_name.
+ * config/i386/i386.c (output_set_got): Likewise.
+ (darwin_local_data_pic): Check for an UNSPEC_MACHOPIC_OFFSET
+ instead of a MINUS.
+ (legitimate_pic_operand_p): Handle UNSPEC_MACHOPIC_OFFSET.
+ (legitimate_address_p): Likewise.
+ (output_pic_addr_const): Likewise.
+ (output_addr_const_extra): Likewise.
+ (ix86_delegitimize_address): Expect darwin_local_data_pic to
+ match an UNSPEC rather than a MINUS.
+ * config/i386/i386.md (UNSPEC_MACHOPIC_OFFSET): Define.
+ (builtin_setjmp_receiver): Use machopic_gen_offset.
+ * config/i386/predicates.md (pic_symbolic_operand): Handle
+ UNSPEC_MACHOPIC_OFFSET.
+
+ * config/rs6000/rs6000.c (rs6000_legitimize_reload_address):
+ Use machopic_gen_offset and machopic_operand_p.
+ (rs6000_output_addr_const_extra): Handle UNSPEC_MACHOPIC_OFFSET.
+ (rs6000_emit_prologue): Use MACHOPIC_FUNCTION_BASE_NAME.
+ * config/rs6000/rs6000.md (UNSPEC_MACHOPIC_OFFSET): Define.
+ (builtin_setjmp_receiver): Use MACHOPIC_FUNCTION_BASE_NAME.
+ Set crtl->uses_pic_offset_table.
+
+2008-10-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_output_addr_const_extra):
+ Declare.
+ * config/rs6000/rs6000.h (OUTPUT_ADDR_CONST_EXTRA): New macro.
+ * config/rs6000/rs6000.md (UNSPEC_TOCREL): New constant.
+ * config/rs6000/rs6000.c (constant_pool_expr_1): Delete.
+ (constant_pool_expr_p): Use split_const and check the base.
+ (toc_relative_expr_p): Likewise, checking for an UNSPEC_TOCREL
+ instead of a MINUS.
+ (legitimate_constant_pool_address_p): Check toc_relative_p
+ instead of constant_pool_expr_p.
+ (print_operand_address): Always use output_addr_const for
+ constant pool addresses.
+ (rs6000_output_addr_const_extra): New function.
+ (create_TOC_reference): Create an UNSPEC_TOCREL instead of
+ a MINUS.
+
+2008-10-06 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR middle-end/37535
+
+ * ira-lives.c (mark_reg_live, mark_reg_dead): New functions.
+ (mark_ref_live, mark_ref_dead): Use them.
+ (def_conflicts_with_inputs_p): Remove.
+ (mark_early_clobbers): New function.
+ (process_bb_node_lives): Call preprocess_constraints and
+ mark_early_clobbers.
+
+ * doc/rtx.texi (clobber): Change how RA deals with clobbers.
+
+2008-10-06 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/mingw32.h (REAL_LIBGCC_SPEC): Add thread cleanup
+ lib with -mthread switch.
+
+2008-10-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37410
+ * dwarf2out.c (dwarf2out_imported_module_or_decl): Split this
+ function in two, making it call a new and reusable
+ dwarf2out_imported_module_or_decl() that takes the containing
+ BLOCK of the declaration in argument.
+ (dwarf2out_imported_module_or_decl_real): New function.
+ (decls_for_scope, gen_decl_die, dwarf2out_decl): Take
+ IMPORTED_DECL in account.
+ * tree.def: Added IMPORTED_DECL node type.
+ * tree.h: Added accessors for IMPORTED_DECL nodes.
+ * tree.c (init_ttree): Initialise IMPORTED_DECL node type.
+
2008-10-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/gimple.texi: Fix some typos, wrap some long lines,
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index ff0adc38af2..12db959fdbc 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20081005
+20081008
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 7d06122ccaa..d384ff538b2 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,21 @@
+2008-10-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Move code
+ dealing with volatileness to after code dealing with renaming.
+
+2008-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Minor tweaks.
+ * gcc-interface/trans.c (Pragma_to_gnu): Likewise.
+
+2008-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils.c (can_fold_for_view_convert_p): New predicate.
+ (unchecked_convert): Use it to disable problematic folding with
+ VIEW_CONVERT_EXPR in the general case. Always disable it for the
+ special VIEW_CONVERT_EXPR built for integral types and cope with
+ its addressability issues by preserving the first conversion.
+
2008-10-01 Andreas Schwab <schwab@suse.de>
* system-linux-ppc64.ads: New file.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index b0dfc7d33e4..cdee2277608 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -828,22 +828,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
"PAD", false, definition,
gnu_size ? true : false);
- /* Make a volatile version of this object's type if we are to make
- the object volatile. We also interpret 13.3(19) conservatively
- and disallow any optimizations for an object covered by it. */
- if ((Treat_As_Volatile (gnat_entity)
- || (Is_Exported (gnat_entity)
- /* Exclude exported constants created by the compiler,
- which should boil down to static dispatch tables and
- make it possible to put them in read-only memory. */
- && (Comes_From_Source (gnat_entity) || !const_flag))
- || Is_Imported (gnat_entity)
- || Present (Address_Clause (gnat_entity)))
- && !TYPE_VOLATILE (gnu_type))
- gnu_type = build_qualified_type (gnu_type,
- (TYPE_QUALS (gnu_type)
- | TYPE_QUAL_VOLATILE));
-
/* If this is a renaming, avoid as much as possible to create a new
object. However, in several cases, creating it is required.
This processing needs to be applied to the raw expression so
@@ -991,22 +975,38 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
}
- /* If this is an aliased object whose nominal subtype is unconstrained,
- the object is a record that contains both the template and
- the object. If there is an initializer, it will have already
- been converted to the right type, but we need to create the
- template if there is no initializer. */
- else if (definition
- && TREE_CODE (gnu_type) == RECORD_TYPE
- && (TYPE_CONTAINS_TEMPLATE_P (gnu_type)
- /* Beware that padding might have been introduced
- via maybe_pad_type above. */
- || (TYPE_IS_PADDING_P (gnu_type)
- && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type)))
- == RECORD_TYPE
- && TYPE_CONTAINS_TEMPLATE_P
- (TREE_TYPE (TYPE_FIELDS (gnu_type)))))
- && !gnu_expr)
+ /* Make a volatile version of this object's type if we are to make
+ the object volatile. We also interpret 13.3(19) conservatively
+ and disallow any optimizations for an object covered by it. */
+ if ((Treat_As_Volatile (gnat_entity)
+ || (Is_Exported (gnat_entity)
+ /* Exclude exported constants created by the compiler,
+ which should boil down to static dispatch tables and
+ make it possible to put them in read-only memory. */
+ && (Comes_From_Source (gnat_entity) || !const_flag))
+ || Is_Imported (gnat_entity)
+ || Present (Address_Clause (gnat_entity)))
+ && !TYPE_VOLATILE (gnu_type))
+ gnu_type = build_qualified_type (gnu_type,
+ (TYPE_QUALS (gnu_type)
+ | TYPE_QUAL_VOLATILE));
+
+ /* If we are defining an aliased object whose nominal subtype is
+ unconstrained, the object is a record that contains both the
+ template and the object. If there is an initializer, it will
+ have already been converted to the right type, but we need to
+ create the template if there is no initializer. */
+ if (definition
+ && !gnu_expr
+ && TREE_CODE (gnu_type) == RECORD_TYPE
+ && (TYPE_CONTAINS_TEMPLATE_P (gnu_type)
+ /* Beware that padding might have been introduced
+ via maybe_pad_type above. */
+ || (TYPE_IS_PADDING_P (gnu_type)
+ && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type)))
+ == RECORD_TYPE
+ && TYPE_CONTAINS_TEMPLATE_P
+ (TREE_TYPE (TYPE_FIELDS (gnu_type))))))
{
tree template_field
= TYPE_IS_PADDING_P (gnu_type)
@@ -1328,7 +1328,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& (definition || Sloc (gnat_entity) > Standard_Location)
&& ((Is_Public (gnat_entity)
&& !Present (Address_Clause (gnat_entity)))
- || optimize == 0
+ || !optimize
|| Address_Taken (gnat_entity)
|| Is_Aliased (gnat_entity)
|| Is_Aliased (Etype (gnat_entity))))
@@ -1343,7 +1343,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* As debugging information will be generated for the variable,
do not generate information for the constant. */
- DECL_IGNORED_P (gnu_decl) = true;
+ DECL_IGNORED_P (gnu_decl) = 1;
}
/* If this is declared in a block that contains a block with an
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 9a6f4cf36ef..e4c86225fac 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -801,12 +801,12 @@ Pragma_to_gnu (Node_Id gnat_node)
(First (Pragma_Argument_Associations (gnat_node)))))
{
case Name_Time: case Name_Space:
- if (optimize == 0)
+ if (!optimize)
post_error ("insufficient -O value?", gnat_node);
break;
case Name_Off:
- if (optimize != 0)
+ if (optimize)
post_error ("must specify -O0?", gnat_node);
break;
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 7f1bc7bebbb..d883d533e46 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4489,8 +4489,72 @@ maybe_unconstrained_array (tree exp)
return exp;
}
+/* Return true if EXPR is an expression that can be folded as an operand
+ of a VIEW_CONVERT_EXPR. See the head comment of unchecked_convert for
+ the rationale. */
+
+static bool
+can_fold_for_view_convert_p (tree expr)
+{
+ tree t1, t2;
+
+ /* The folder will fold NOP_EXPRs between integral types with the same
+ precision (in the middle-end's sense). We cannot allow it if the
+ types don't have the same precision in the Ada sense as well. */
+ if (TREE_CODE (expr) != NOP_EXPR)
+ return true;
+
+ t1 = TREE_TYPE (expr);
+ t2 = TREE_TYPE (TREE_OPERAND (expr, 0));
+
+ /* Defer to the folder for non-integral conversions. */
+ if (!(INTEGRAL_TYPE_P (t1) && INTEGRAL_TYPE_P (t2)))
+ return true;
+
+ /* Only fold conversions that preserve both precisions. */
+ if (TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
+ && operand_equal_p (rm_size (t1), rm_size (t2), 0))
+ return true;
+
+ return false;
+}
+
/* Return an expression that does an unchecked conversion of EXPR to TYPE.
- If NOTRUNC_P is true, truncation operations should be suppressed. */
+ If NOTRUNC_P is true, truncation operations should be suppressed.
+
+ Special care is required with (source or target) integral types whose
+ precision is not equal to their size, to make sure we fetch or assign
+ the value bits whose location might depend on the endianness, e.g.
+
+ Rmsize : constant := 8;
+ subtype Int is Integer range 0 .. 2 ** Rmsize - 1;
+
+ type Bit_Array is array (1 .. Rmsize) of Boolean;
+ pragma Pack (Bit_Array);
+
+ function To_Bit_Array is new Unchecked_Conversion (Int, Bit_Array);
+
+ Value : Int := 2#1000_0001#;
+ Vbits : Bit_Array := To_Bit_Array (Value);
+
+ we expect the 8 bits at Vbits'Address to always contain Value, while
+ their original location depends on the endianness, at Value'Address
+ on a little-endian architecture but not on a big-endian one.
+
+ ??? There is a problematic discrepancy between what is called precision
+ here (and more generally throughout gigi) for integral types and what is
+ called precision in the middle-end. In the former case it's the RM size
+ as given by TYPE_RM_SIZE (or rm_size) whereas it's TYPE_PRECISION in the
+ latter case, the hitch being that they are not equal when they matter,
+ that is when the number of value bits is not equal to the type's size:
+ TYPE_RM_SIZE does give the number of value bits but TYPE_PRECISION is set
+ to the size. The sole exception are BOOLEAN_TYPEs for which both are 1.
+
+ The consequence is that gigi must duplicate code bridging the gap between
+ the type's size and its precision that exists for TYPE_PRECISION in the
+ middle-end, because the latter knows nothing about TYPE_RM_SIZE, and be
+ wary of transformations applied in the middle-end based on TYPE_PRECISION
+ because this value doesn't reflect the actual precision for Ada. */
tree
unchecked_convert (tree type, tree expr, bool notrunc_p)
@@ -4517,14 +4581,10 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
&& TYPE_JUSTIFIED_MODULAR_P (etype))))
|| TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
{
- tree rtype = type;
- bool final_unchecked = false;
-
if (TREE_CODE (etype) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (etype))
{
tree ntype = copy_type (etype);
-
TYPE_BIASED_REPRESENTATION_P (ntype) = 0;
TYPE_MAIN_VARIANT (ntype) = ntype;
expr = build1 (NOP_EXPR, ntype, expr);
@@ -4533,15 +4593,18 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
if (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (type))
{
- rtype = copy_type (type);
+ tree rtype = copy_type (type);
TYPE_BIASED_REPRESENTATION_P (rtype) = 0;
TYPE_MAIN_VARIANT (rtype) = rtype;
+ expr = convert (rtype, expr);
+ expr = build1 (NOP_EXPR, type, expr);
}
- /* We have another special case: if we are unchecked converting subtype
- into a base type, we need to ensure that VRP doesn't propagate range
- information since this conversion may be done precisely to validate
- that the object is within the range it is supposed to have. */
+ /* We have another special case: if we are unchecked converting either
+ a subtype or a type with limited range into a base type, we need to
+ ensure that VRP doesn't propagate range information because this
+ conversion may be done precisely to validate that the object is
+ within the range it is supposed to have. */
else if (TREE_CODE (expr) != INTEGER_CST
&& TREE_CODE (type) == INTEGER_TYPE && !TREE_TYPE (type)
&& ((TREE_CODE (etype) == INTEGER_TYPE && TREE_TYPE (etype))
@@ -4552,26 +4615,34 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
in order not to be deemed an useless type conversion, it must
be from subtype to base type.
+ Therefore we first do the bulk of the conversion to a subtype of
+ the final type. And this conversion must itself not be deemed
+ useless if the source type is not a subtype because, otherwise,
+ the final VIEW_CONVERT_EXPR will be deemed so as well. That's
+ why we toggle the unsigned flag in this conversion, which is
+ harmless since the final conversion is only a reinterpretation
+ of the bit pattern.
+
??? This may raise addressability and/or aliasing issues because
VIEW_CONVERT_EXPR gets gimplified as an lvalue, thus causing the
address of its operand to be taken if it is deemed addressable
and not already in GIMPLE form. */
- rtype = gnat_type_for_mode (TYPE_MODE (type), TYPE_UNSIGNED (type));
+ tree rtype
+ = gnat_type_for_mode (TYPE_MODE (type), !TYPE_UNSIGNED (etype));
rtype = copy_type (rtype);
TYPE_MAIN_VARIANT (rtype) = rtype;
TREE_TYPE (rtype) = type;
- final_unchecked = true;
+ expr = convert (rtype, expr);
+ expr = build1 (VIEW_CONVERT_EXPR, type, expr);
}
- expr = convert (rtype, expr);
- if (type != rtype)
- expr = fold_build1 (final_unchecked ? VIEW_CONVERT_EXPR : NOP_EXPR,
- type, expr);
+ else
+ expr = convert (type, expr);
}
- /* If we are converting TO an integral type whose precision is not the
- same as its size, first unchecked convert to a record that contains
- an object of the output type. Then extract the field. */
+ /* If we are converting to an integral type whose precision is not equal
+ to its size, first unchecked convert to a record that contains an
+ object of the output type. Then extract the field. */
else if (INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type)
&& 0 != compare_tree_int (TYPE_RM_SIZE (type),
GET_MODE_BITSIZE (TYPE_MODE (type))))
@@ -4587,8 +4658,8 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
expr = build_component_ref (expr, NULL_TREE, field, 0);
}
- /* Similarly for integral input type whose precision is not equal to its
- size. */
+ /* Similarly if we are converting from an integral type whose precision
+ is not equal to its size. */
else if (INTEGRAL_TYPE_P (etype) && TYPE_RM_SIZE (etype)
&& 0 != compare_tree_int (TYPE_RM_SIZE (etype),
GET_MODE_BITSIZE (TYPE_MODE (etype))))
@@ -4618,13 +4689,15 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
{
expr = maybe_unconstrained_array (expr);
etype = TREE_TYPE (expr);
- expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr);
+ if (can_fold_for_view_convert_p (expr))
+ expr = fold_build1 (VIEW_CONVERT_EXPR, type, expr);
+ else
+ expr = build1 (VIEW_CONVERT_EXPR, type, expr);
}
- /* If the result is an integral type whose size is not equal to
- the size of the underlying machine type, sign- or zero-extend
- the result. We need not do this in the case where the input is
- an integral type of the same precision and signedness or if the output
+ /* If the result is an integral type whose precision is not equal to its
+ size, sign- or zero-extend the result. We need not do this if the input
+ is an integral type of the same precision and signedness or if the output
is a biased type or if both the input and output are unsigned. */
if (!notrunc_p
&& INTEGRAL_TYPE_P (type) && TYPE_RM_SIZE (type)
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index 7f0dc8ce7d2..f098a84b19c 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -64,14 +64,25 @@ static ALLOC_POOL_ID_TYPE last_id;
#ifdef GATHER_STATISTICS
-/* Store information about each particular alloc_pool. */
+/* Store information about each particular alloc_pool. Note that this
+ will underestimate the amount the amount of storage used by a small amount:
+ 1) The overhead in a pool is not accounted for.
+ 2) The unallocated elements in a block are not accounted for. Note
+ that this can at worst case be one element smaller that the block
+ size for that pool. */
struct alloc_pool_descriptor
{
const char *name;
- int allocated;
- int created;
- int peak;
- int current;
+ /* Number of pools allocated. */
+ unsigned long created;
+ /* Gross allocated storage. */
+ unsigned long allocated;
+ /* Amount of currently active storage. */
+ unsigned long current;
+ /* Peak amount of storage used. */
+ unsigned long peak;
+ /* Size of element in the pool. */
+ int elt_size;
};
/* Hashtable mapping alloc_pool names to descriptors. */
@@ -150,6 +161,7 @@ create_alloc_pool (const char *name, size_t size, size_t num)
pool->name = /*xstrdup (name)*/name;
#ifdef GATHER_STATISTICS
desc = alloc_pool_descriptor (name);
+ desc->elt_size = size;
desc->created++;
#endif
pool->elt_size = size;
@@ -196,11 +208,11 @@ empty_alloc_pool (alloc_pool pool)
{
next_block = block->next;
free (block);
-#ifdef GATHER_STATISTICS
- desc->current -= pool->block_size;
-#endif
}
+#ifdef GATHER_STATISTICS
+ desc->current -= (pool->elts_allocated - pool->elts_free) * pool->elt_size;
+#endif
pool->returned_free_list = NULL;
pool->virgin_free_list = NULL;
pool->virgin_elts_remaining = 0;
@@ -242,7 +254,10 @@ pool_alloc (alloc_pool pool)
#ifdef GATHER_STATISTICS
struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
- desc->allocated+=pool->elt_size;
+ desc->allocated += pool->elt_size;
+ desc->current += pool->elt_size;
+ if (desc->peak < desc->current)
+ desc->peak = desc->current;
#endif
gcc_assert (pool);
@@ -259,11 +274,6 @@ pool_alloc (alloc_pool pool)
block = XNEWVEC (char, pool->block_size);
block_header = (alloc_pool_list) block;
block += align_eight (sizeof (struct alloc_pool_list_def));
-#ifdef GATHER_STATISTICS
- desc->current += pool->block_size;
- if (desc->peak < desc->current)
- desc->peak = desc->current;
-#endif
/* Throw it on the block list. */
block_header->next = pool->block_list;
@@ -314,6 +324,9 @@ void
pool_free (alloc_pool pool, void *ptr)
{
alloc_pool_list header;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+#endif
gcc_assert (ptr);
@@ -334,6 +347,11 @@ pool_free (alloc_pool pool, void *ptr)
header->next = pool->returned_free_list;
pool->returned_free_list = header;
pool->elts_free++;
+
+#ifdef GATHER_STATISTICS
+ desc->current -= pool->elt_size;
+#endif
+
}
/* Output per-alloc_pool statistics. */
#ifdef GATHER_STATISTICS
@@ -341,8 +359,8 @@ pool_free (alloc_pool pool, void *ptr)
/* Used to accumulate statistics about alloc_pool sizes. */
struct output_info
{
- int count;
- int size;
+ unsigned long total_created;
+ unsigned long total_allocated;
};
/* Called via htab_traverse. Output alloc_pool descriptor pointed out by SLOT
@@ -355,10 +373,12 @@ print_statistics (void **slot, void *b)
if (d->allocated)
{
- fprintf (stderr, "%-21s %6d %10d %10d %10d\n", d->name,
- d->created, d->allocated, d->peak, d->current);
- i->size += d->allocated;
- i->count += d->created;
+ fprintf (stderr, "%-22s %6d %10lu %10lu(%10lu) %10lu(%10lu) %10lu(%10lu)\n", d->name,
+ d->elt_size, d->created, d->allocated, d->allocated / d->elt_size,
+ d->peak, d->peak / d->elt_size,
+ d->current, d->current / d->elt_size);
+ i->total_allocated += d->allocated;
+ i->total_created += d->created;
}
return 1;
}
@@ -374,14 +394,14 @@ dump_alloc_pool_statistics (void)
if (!alloc_pool_hash)
return;
- fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
- fprintf (stderr, "-------------------------------------------------------------\n");
- info.count = 0;
- info.size = 0;
+ fprintf (stderr, "\nAlloc-pool Kind Elt size Pools Allocated (elts) Peak (elts) Leak (elts)\n");
+ fprintf (stderr, "--------------------------------------------------------------------------------------------------------------\n");
+ info.total_created = 0;
+ info.total_allocated = 0;
htab_traverse (alloc_pool_hash, print_statistics, &info);
- fprintf (stderr, "-------------------------------------------------------------\n");
- fprintf (stderr, "%-20s %7d %10d\n",
- "Total", info.count, info.size);
- fprintf (stderr, "-------------------------------------------------------------\n");
+ fprintf (stderr, "--------------------------------------------------------------------------------------------------------------\n");
+ fprintf (stderr, "%-22s %7lu %10lu\n",
+ "Total", info.total_created, info.total_allocated);
+ fprintf (stderr, "--------------------------------------------------------------------------------------------------------------\n");
#endif
}
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index d848357b1d1..e84ed88a8e1 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -129,7 +129,8 @@ struct edge_def GTY(())
/* Auxiliary info specific to a pass. */
PTR GTY ((skip (""))) aux;
- /* Location of any goto implicit in the edge, during tree-ssa. */
+ /* Location of any goto implicit in the edge and associated BLOCK. */
+ tree goto_block;
location_t goto_locus;
/* The index number corresponding to this edge in the edge vector
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 57bd0bb5ca9..61d80fd82bc 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -3423,7 +3423,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
: truthvalue_false_node;
case FUNCTION_DECL:
- expr = build_unary_op (ADDR_EXPR, expr, 0);
+ expr = build_unary_op (location, ADDR_EXPR, expr, 0);
/* Fall through. */
case ADDR_EXPR:
@@ -3526,10 +3526,12 @@ c_common_truthvalue_conversion (location_t location, tree expr)
(EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
- c_common_truthvalue_conversion (location,
- build_unary_op (REALPART_EXPR, t, 0)),
- c_common_truthvalue_conversion (location,
- build_unary_op (IMAGPART_EXPR, t, 0)),
+ c_common_truthvalue_conversion
+ (location,
+ build_unary_op (location, REALPART_EXPR, t, 0)),
+ c_common_truthvalue_conversion
+ (location,
+ build_unary_op (location, IMAGPART_EXPR, t, 0)),
0));
}
@@ -8219,10 +8221,11 @@ warn_for_unused_label (tree label)
struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
#endif
-/* Warn for division by zero according to the value of DIVISOR. */
+/* Warn for division by zero according to the value of DIVISOR. LOC
+ is the location of the division operator. */
void
-warn_for_div_by_zero (tree divisor)
+warn_for_div_by_zero (location_t loc, tree divisor)
{
/* If DIVISOR is zero, and has integral or fixed-point type, issue a warning
about division by zero. Do not issue a warning if DIVISOR has a
@@ -8230,7 +8233,7 @@ warn_for_div_by_zero (tree divisor)
generating a NaN. */
if (skip_evaluation == 0
&& (integer_zerop (divisor) || fixed_zerop (divisor)))
- warning (OPT_Wdiv_by_zero, "division by zero");
+ warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
}
/* Subroutine of build_binary_op. Give warnings for comparisons
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 622100a40cf..cd4eb3138b7 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -356,8 +356,8 @@ extern tree add_stmt (tree);
extern void push_cleanup (tree, tree, bool);
extern tree pushdecl_top_level (tree);
extern tree pushdecl (tree);
-extern tree build_modify_expr (tree, enum tree_code, tree);
-extern tree build_indirect_ref (tree, const char *, location_t);
+extern tree build_modify_expr (location_t, tree, enum tree_code, tree);
+extern tree build_indirect_ref (location_t, tree, const char *);
extern int c_expand_decl (tree);
@@ -815,7 +815,7 @@ extern tree build_case_label (tree, tree, tree);
/* These functions must be defined by each front-end which implements
a variant of the C language. They are used in c-common.c. */
-extern tree build_unary_op (enum tree_code, tree, int);
+extern tree build_unary_op (location_t, enum tree_code, tree, int);
extern tree build_binary_op (location_t, enum tree_code, tree, tree, int);
extern tree perform_integral_promotions (tree);
@@ -915,7 +915,7 @@ extern void warn_array_subscript_with_type_char (tree);
extern void warn_about_parentheses (enum tree_code, enum tree_code,
enum tree_code);
extern void warn_for_unused_label (tree label);
-extern void warn_for_div_by_zero (tree divisor);
+extern void warn_for_div_by_zero (location_t, tree divisor);
extern void warn_for_sign_compare (location_t,
tree orig_op0, tree orig_op1,
tree op0, tree op1,
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 70265557269..2a6dcf2361c 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3650,7 +3650,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
tree cleanup;
/* Build "cleanup(&decl)" for the destructor. */
- cleanup = build_unary_op (ADDR_EXPR, decl, 0);
+ cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
cleanup = build_tree_list (NULL_TREE, cleanup);
cleanup = build_function_call (cleanup_decl, cleanup);
diff --git a/gcc/c-omp.c b/gcc/c-omp.c
index 6d9d5fa3810..b06c83039b9 100644
--- a/gcc/c-omp.c
+++ b/gcc/c-omp.c
@@ -124,7 +124,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
/* Take and save the address of the lhs. From then on we'll reference it
via indirection. */
- addr = build_unary_op (ADDR_EXPR, lhs, 0);
+ addr = build_unary_op (input_location, ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
return error_mark_node;
addr = save_expr (addr);
@@ -137,12 +137,12 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
}
- lhs = build_indirect_ref (addr, NULL, EXPR_LOCATION (addr));
+ lhs = build_indirect_ref (input_location, addr, NULL);
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
to do this, and then take it apart again. */
- x = build_modify_expr (lhs, code, rhs);
+ x = build_modify_expr (input_location, lhs, code, rhs);
if (x == error_mark_node)
return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
@@ -242,7 +242,7 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
&& TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
{
- error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
+ error_at (elocus, "invalid type for iteration variable %qE", decl);
fail = true;
}
@@ -255,20 +255,19 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
init = DECL_INITIAL (decl);
if (init == NULL)
{
- error ("%H%qE is not initialized", &elocus, decl);
+ error_at (elocus, "%qE is not initialized", decl);
init = integer_zero_node;
fail = true;
}
- init = build_modify_expr (decl, NOP_EXPR, init);
- SET_EXPR_LOCATION (init, elocus);
+ init = build_modify_expr (elocus, decl, NOP_EXPR, init);
}
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
gcc_assert (TREE_OPERAND (init, 0) == decl);
if (cond == NULL_TREE)
{
- error ("%Hmissing controlling predicate", &elocus);
+ error_at (elocus, "missing controlling predicate");
fail = true;
}
else
@@ -329,14 +328,14 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
if (!cond_ok)
{
- error ("%Hinvalid controlling predicate", &elocus);
+ error_at (elocus, "invalid controlling predicate");
fail = true;
}
}
if (incr == NULL_TREE)
{
- error ("%Hmissing increment expression", &elocus);
+ error_at (elocus, "missing increment expression");
fail = true;
}
else
@@ -402,7 +401,7 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
}
if (!incr_ok)
{
- error ("%Hinvalid increment expression", &elocus);
+ error_at (elocus, "invalid increment expression");
fail = true;
}
}
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 9597660915d..f08b2813010 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -2098,8 +2098,7 @@ c_parser_typeof_specifier (c_parser *parser)
if (DECL_P (e) || CONSTANT_CLASS_P (e))
e = build1 (NOP_EXPR, void_type_node, e);
- if (CAN_HAVE_LOCATION_P (e))
- SET_EXPR_LOCATION (e, here);
+ protected_set_expr_location (e, here);
add_stmt (e);
}
@@ -3789,8 +3788,7 @@ c_parser_statement_after_labels (c_parser *parser)
(recursively) all of the component statements should already have
line numbers assigned. ??? Can we discard no-op statements
earlier? */
- if (stmt && CAN_HAVE_LOCATION_P (stmt))
- SET_EXPR_LOCATION (stmt, loc);
+ protected_set_expr_location (stmt, loc);
parser->in_if_block = in_if_block;
}
@@ -3805,8 +3803,7 @@ c_parser_condition (c_parser *parser)
loc = c_parser_peek_token (parser)->location;
cond = c_objc_common_truthvalue_conversion
(loc, c_parser_expression_conv (parser).value);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, loc);
+ protected_set_expr_location (cond, loc);
if (warn_sequence_point)
verify_sequence_points (cond);
return cond;
@@ -4361,8 +4358,10 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
{
struct c_expr lhs, rhs, ret;
enum tree_code code;
+ location_t op_location;
gcc_assert (!after || c_dialect_objc ());
lhs = c_parser_conditional_expression (parser, after);
+ op_location = c_parser_peek_token (parser)->location;
switch (c_parser_peek_token (parser)->type)
{
case CPP_EQ:
@@ -4404,7 +4403,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
c_parser_consume_token (parser);
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_conversion (rhs);
- ret.value = build_modify_expr (lhs.value, code, rhs.value);
+ ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -4439,6 +4438,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
+ protected_set_expr_location (cond.value, cond_loc);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
@@ -4836,7 +4836,7 @@ c_parser_unary_expression (c_parser *parser)
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- ret.value = build_indirect_ref (op.value, "unary *", loc);
+ ret.value = build_indirect_ref (loc, op.value, "unary *");
ret.original_code = ERROR_MARK;
return ret;
case CPP_PLUS:
@@ -5594,8 +5594,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (build_indirect_ref (expr.value,
- "->", loc),
+ expr.value = build_component_ref (build_indirect_ref (loc,
+ expr.value,
+ "->"),
ident);
expr.original_code = ERROR_MARK;
break;
@@ -5603,14 +5604,16 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
/* Postincrement. */
c_parser_consume_token (parser);
expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (loc,
+ POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (loc,
+ POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
break;
default:
@@ -7594,14 +7597,17 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
&& c_parser_peek_2nd_token (parser)->type == CPP_EQ)
{
struct c_expr init_exp;
+ location_t init_loc;
decl = c_parser_postfix_expression (parser).value;
c_parser_require (parser, CPP_EQ, "expected %<=%>");
+ init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_conversion (init_exp);
- init = build_modify_expr (decl, NOP_EXPR, init_exp.value);
+ init = build_modify_expr (init_loc,
+ decl, NOP_EXPR, init_exp.value);
init = c_process_expr_stmt (init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -7625,15 +7631,19 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, cond_loc);
+ protected_set_expr_location (cond, cond_loc);
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
/* Parse the increment expression. */
incr = NULL_TREE;
if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ {
+ location_t incr_loc = c_parser_peek_token (parser)->location;
+
+ incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ protected_set_expr_location (incr, incr_loc);
+ }
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
if (decl == NULL || decl == error_mark_node || init == error_mark_node)
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index c6474ed5da1..ab8df375448 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1618,7 +1618,7 @@ array_to_pointer_conversion (tree exp)
/* This way is better for a COMPONENT_REF since it can
simplify the offset for a component. */
- adr = build_unary_op (ADDR_EXPR, exp, 1);
+ adr = build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 1);
return convert (ptrtype, adr);
}
@@ -1635,7 +1635,7 @@ function_to_pointer_conversion (tree exp)
if (TREE_NO_WARNING (orig_exp))
TREE_NO_WARNING (exp) = 1;
- return build_unary_op (ADDR_EXPR, exp, 0);
+ return build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 0);
}
/* Perform the default conversion of arrays and functions to pointers.
@@ -1972,7 +1972,7 @@ build_component_ref (tree datum, tree component)
LOC is the location to use for the generated tree. */
tree
-build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
+build_indirect_ref (location_t loc, tree ptr, const char *errorstring)
{
tree pointer = default_conversion (ptr);
tree type = TREE_TYPE (pointer);
@@ -2008,11 +2008,11 @@ build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
{
- error ("dereferencing pointer to incomplete type");
+ error_at (loc, "dereferencing pointer to incomplete type");
return error_mark_node;
}
if (VOID_TYPE_P (t) && skip_evaluation == 0)
- warning (0, "dereferencing %<void *%> pointer");
+ warning_at (loc, 0, "dereferencing %<void *%> pointer");
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
so that we get the proper error message if the result is used
@@ -2030,7 +2030,8 @@ build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
}
}
else if (TREE_CODE (pointer) != ERROR_MARK)
- error ("invalid type argument of %qs (have %qT)", errorstring, type);
+ error_at (loc,
+ "invalid type argument of %qs (have %qT)", errorstring, type);
return error_mark_node;
}
@@ -2164,8 +2165,8 @@ build_array_ref (tree array, tree index, location_t loc)
gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
return build_indirect_ref
- (build_binary_op (loc, PLUS_EXPR, ar, index, 0),
- "array indexing", loc);
+ (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0),
+ "array indexing");
}
}
@@ -2748,8 +2749,7 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
struct c_expr result;
result.original_code = ERROR_MARK;
- result.value = build_unary_op (code, arg.value, 0);
- protected_set_expr_location (result.value, loc);
+ result.value = build_unary_op (loc, code, arg.value, 0);
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
overflow_warning (result.value);
@@ -2901,16 +2901,20 @@ pointer_diff (tree op0, tree op1)
the default promotions (such as from short to int).
For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
allows non-lvalues; this is only used to handle conversion of non-lvalue
- arrays to pointers in C99. */
+ arrays to pointers in C99.
+
+ LOCATION is the location of the operator. */
tree
-build_unary_op (enum tree_code code, tree xarg, int flag)
+build_unary_op (location_t location,
+ enum tree_code code, tree xarg, int flag)
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
tree argtype = 0;
enum tree_code typecode;
tree val;
+ tree ret = error_mark_node;
int noconvert = flag;
const char *invalid_op_diag;
@@ -2926,7 +2930,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if ((invalid_op_diag
= targetm.invalid_unary_op (code, TREE_TYPE (xarg))))
{
- error (invalid_op_diag);
+ error_at (location, invalid_op_diag);
return error_mark_node;
}
@@ -2940,7 +2944,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
|| typecode == VECTOR_TYPE))
{
- error ("wrong type argument to unary plus");
+ error_at (location, "wrong type argument to unary plus");
return error_mark_node;
}
else if (!noconvert)
@@ -2953,7 +2957,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
|| typecode == VECTOR_TYPE))
{
- error ("wrong type argument to unary minus");
+ error_at (location, "wrong type argument to unary minus");
return error_mark_node;
}
else if (!noconvert)
@@ -2972,14 +2976,14 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
else if (typecode == COMPLEX_TYPE)
{
code = CONJ_EXPR;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (location, OPT_pedantic,
"ISO C does not support %<~%> for complex conjugation");
if (!noconvert)
arg = default_conversion (arg);
}
else
{
- error ("wrong type argument to bit-complement");
+ error_at (location, "wrong type argument to bit-complement");
return error_mark_node;
}
break;
@@ -2987,7 +2991,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
case ABS_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
{
- error ("wrong type argument to abs");
+ error_at (location, "wrong type argument to abs");
return error_mark_node;
}
else if (!noconvert)
@@ -2999,7 +3003,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
{
- error ("wrong type argument to conjugation");
+ error_at (location, "wrong type argument to conjugation");
return error_mark_node;
}
else if (!noconvert)
@@ -3011,27 +3015,31 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
&& typecode != REAL_TYPE && typecode != POINTER_TYPE
&& typecode != COMPLEX_TYPE)
{
- error ("wrong type argument to unary exclamation mark");
+ error_at (location,
+ "wrong type argument to unary exclamation mark");
return error_mark_node;
}
- arg = c_objc_common_truthvalue_conversion (input_location, arg);
- return invert_truthvalue (arg);
+ arg = c_objc_common_truthvalue_conversion (location, arg);
+ ret = invert_truthvalue (arg);
+ goto return_build_unary_op;
case REALPART_EXPR:
if (TREE_CODE (arg) == COMPLEX_CST)
- return TREE_REALPART (arg);
+ ret = TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- return arg;
+ ret = arg;
+ goto return_build_unary_op;
case IMAGPART_EXPR:
if (TREE_CODE (arg) == COMPLEX_CST)
- return TREE_IMAGPART (arg);
+ ret = TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- return convert (TREE_TYPE (arg), integer_zero_node);
+ ret = convert (TREE_TYPE (arg), integer_zero_node);
+ goto return_build_unary_op;
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
@@ -3044,17 +3052,18 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
{
tree real, imag;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (location, OPT_pedantic,
"ISO C does not support %<++%> and %<--%> on complex types");
arg = stabilize_reference (arg);
- real = build_unary_op (REALPART_EXPR, arg, 1);
- imag = build_unary_op (IMAGPART_EXPR, arg, 1);
- real = build_unary_op (code, real, 1);
+ real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1);
+ imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1);
+ real = build_unary_op (EXPR_LOCATION (arg), code, real, 1);
if (real == error_mark_node || imag == error_mark_node)
return error_mark_node;
- return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
- real, imag);
+ ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg),
+ real, imag);
+ goto return_build_unary_op;
}
/* Report invalid types. */
@@ -3063,9 +3072,9 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- error ("wrong type argument to increment");
+ error_at (location, "wrong type argument to increment");
else
- error ("wrong type argument to decrement");
+ error_at (location, "wrong type argument to decrement");
return error_mark_node;
}
@@ -3086,18 +3095,20 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- error ("increment of pointer to unknown structure");
+ error_at (location,
+ "increment of pointer to unknown structure");
else
- error ("decrement of pointer to unknown structure");
+ error_at (location,
+ "decrement of pointer to unknown structure");
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"wrong type argument to increment");
else
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"wrong type argument to decrement");
}
@@ -3154,7 +3165,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
val = convert (result_type, val);
if (TREE_CODE (val) != code)
TREE_NO_WARNING (val) = 1;
- return val;
+ ret = val;
+ goto return_build_unary_op;
}
case ADDR_EXPR:
@@ -3166,7 +3178,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
/* Don't let this be an lvalue. */
if (lvalue_p (TREE_OPERAND (arg, 0)))
return non_lvalue (TREE_OPERAND (arg, 0));
- return TREE_OPERAND (arg, 0);
+ ret = TREE_OPERAND (arg, 0);
+ goto return_build_unary_op;
}
/* For &x[y], return x+y */
@@ -3175,7 +3188,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
tree op0 = TREE_OPERAND (arg, 0);
if (!c_mark_addressable (op0))
return error_mark_node;
- return build_binary_op (EXPR_LOCATION (xarg), PLUS_EXPR,
+ return build_binary_op (location, PLUS_EXPR,
(TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
? array_to_pointer_conversion (op0)
: op0),
@@ -3218,12 +3231,14 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
- return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
+ ret = fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
+ goto return_build_unary_op;
}
val = build1 (ADDR_EXPR, argtype, arg);
- return val;
+ ret = val;
+ goto return_build_unary_op;
default:
gcc_unreachable ();
@@ -3231,8 +3246,12 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if (argtype == 0)
argtype = TREE_TYPE (arg);
- return require_constant_value ? fold_build1_initializer (code, argtype, arg)
- : fold_build1 (code, argtype, arg);
+ ret = require_constant_value ? fold_build1_initializer (code, argtype, arg)
+ : fold_build1 (code, argtype, arg);
+ return_build_unary_op:
+ gcc_assert (ret != error_mark_node);
+ protected_set_expr_location (ret, location);
+ return ret;
}
/* Return nonzero if REF is an lvalue valid for this language.
@@ -3837,10 +3856,13 @@ c_cast_expr (struct c_type_name *type_name, tree expr)
/* Build an assignment expression of lvalue LHS from value RHS.
MODIFYCODE is the code for a binary operator that we use
to combine the old value of LHS with RHS to get the new value.
- Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */
+ Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
+
+ LOCATION is the location of the MODIFYCODE operator. */
tree
-build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
+build_modify_expr (location_t location,
+ tree lhs, enum tree_code modifycode, tree rhs)
{
tree result;
tree newrhs;
@@ -3867,7 +3889,7 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
if (modifycode != NOP_EXPR)
{
lhs = stabilize_reference (lhs);
- newrhs = build_binary_op (EXPR_LOCATION (lhs),
+ newrhs = build_binary_op (location,
modifycode, lhs, rhs, 1);
}
@@ -3915,13 +3937,17 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
{
result = objc_generate_write_barrier (lhs, modifycode, newrhs);
if (result)
- return result;
+ {
+ protected_set_expr_location (result, location);
+ return result;
+ }
}
/* Scan operands. */
result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs);
TREE_SIDE_EFFECTS (result) = 1;
+ protected_set_expr_location (result, location);
/* If we got the LHS in a different type for storing in,
convert the result back to the nominal type of LHS
@@ -3930,8 +3956,11 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
if (olhstype == TREE_TYPE (result))
return result;
- return convert_for_assignment (olhstype, result, ic_assign,
- NULL_TREE, NULL_TREE, 0);
+
+ result = convert_for_assignment (olhstype, result, ic_assign,
+ NULL_TREE, NULL_TREE, 0);
+ protected_set_expr_location (result, location);
+ return result;
}
/* Convert value RHS to type TYPE as preparation for an assignment
@@ -7942,6 +7971,7 @@ build_binary_op (location_t location, enum tree_code code,
tree type0, type1;
enum tree_code code0, code1;
tree op0, op1;
+ tree ret = error_mark_node;
const char *invalid_op_diag;
/* Expression code to give to the expression when it is built.
@@ -8035,9 +8065,15 @@ build_binary_op (location_t location, enum tree_code code,
case PLUS_EXPR:
/* Handle the pointer + int case. */
if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op0, op1);
+ {
+ ret = pointer_int_sum (PLUS_EXPR, op0, op1);
+ goto return_build_binary_op;
+ }
else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op1, op0);
+ {
+ ret = pointer_int_sum (PLUS_EXPR, op1, op0);
+ goto return_build_binary_op;
+ }
else
common = 1;
break;
@@ -8047,10 +8083,16 @@ build_binary_op (location_t location, enum tree_code code,
We must subtract them as integers, then divide by object size. */
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& comp_target_types (type0, type1))
- return pointer_diff (op0, op1);
+ {
+ ret = pointer_diff (op0, op1);
+ goto return_build_binary_op;
+ }
/* Handle pointer minus int. Just like pointer plus int. */
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (MINUS_EXPR, op0, op1);
+ {
+ ret = pointer_int_sum (MINUS_EXPR, op0, op1);
+ goto return_build_binary_op;
+ }
else
common = 1;
break;
@@ -8064,7 +8106,7 @@ build_binary_op (location_t location, enum tree_code code,
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|| code0 == FIXED_POINT_TYPE
@@ -8111,7 +8153,7 @@ build_binary_op (location_t location, enum tree_code code,
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
@@ -8435,7 +8477,10 @@ build_binary_op (location_t location, enum tree_code code,
= shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
if (val != 0)
- return val;
+ {
+ ret = val;
+ goto return_build_binary_op;
+ }
op0 = xop0, op1 = xop1;
converted = 1;
@@ -8477,18 +8522,19 @@ build_binary_op (location_t location, enum tree_code code,
if (build_type == NULL_TREE)
build_type = result_type;
- {
- /* Treat expressions in initializers specially as they can't trap. */
- tree result = require_constant_value ? fold_build2_initializer (resultcode,
- build_type,
- op0, op1)
- : fold_build2 (resultcode, build_type,
- op0, op1);
-
- if (final_type != 0)
- result = convert (final_type, result);
- return result;
- }
+ /* Treat expressions in initializers specially as they can't trap. */
+ ret = require_constant_value ? fold_build2_initializer (resultcode,
+ build_type,
+ op0, op1)
+ : fold_build2 (resultcode, build_type,
+ op0, op1);
+ if (final_type != 0)
+ ret = convert (final_type, ret);
+
+ return_build_binary_op:
+ gcc_assert (ret != error_mark_node);
+ protected_set_expr_location (ret, location);
+ return ret;
}
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index a778e28e386..8b9756def21 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -429,7 +429,7 @@ try_forward_edges (int mode, basic_block b)
for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
{
basic_block target, first;
- int counter;
+ int counter, goto_locus;
bool threaded = false;
int nthreaded_edges = 0;
bool may_thread = first_pass | df_get_bb_dirty (b);
@@ -447,6 +447,7 @@ try_forward_edges (int mode, basic_block b)
target = first = e->dest;
counter = NUM_FIXED_BLOCKS;
+ goto_locus = e->goto_locus;
/* If we are partitioning hot/cold basic_blocks, we don't want to mess
up jumps that cross between hot/cold sections.
@@ -476,6 +477,27 @@ try_forward_edges (int mode, basic_block b)
new_target = single_succ (target);
if (target == new_target)
counter = n_basic_blocks;
+ else if (!optimize)
+ {
+ /* When not optimizing, ensure that edges or forwarder
+ blocks with different locus are not optimized out. */
+ int locus = single_succ_edge (target)->goto_locus;
+
+ if (locus && goto_locus && locus != goto_locus)
+ counter = n_basic_blocks;
+ else if (locus)
+ goto_locus = locus;
+
+ if (INSN_P (BB_END (target)))
+ {
+ locus = INSN_LOCATOR (BB_END (target));
+
+ if (locus && goto_locus && locus != goto_locus)
+ counter = n_basic_blocks;
+ else if (locus)
+ goto_locus = locus;
+ }
+ }
}
/* Allow to thread only over one edge at time to simplify updating
@@ -539,6 +561,8 @@ try_forward_edges (int mode, basic_block b)
int edge_frequency;
int n = 0;
+ e->goto_locus = goto_locus;
+
/* Don't force if target is exit block. */
if (threaded && target != EXIT_BLOCK_PTR)
{
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 06111cc85df..e94fe356e1c 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1666,7 +1666,12 @@ expand_gimple_cond (basic_block bb, gimple stmt)
add_reg_br_prob_note (last, true_edge->probability);
maybe_dump_rtl_for_gimple_stmt (stmt, last);
if (true_edge->goto_locus)
- set_curr_insn_source_location (true_edge->goto_locus);
+ {
+ set_curr_insn_source_location (true_edge->goto_locus);
+ set_curr_insn_block (true_edge->goto_block);
+ true_edge->goto_locus = curr_insn_locator ();
+ }
+ true_edge->goto_block = NULL;
false_edge->flags |= EDGE_FALLTHRU;
ggc_free (pred);
return NULL;
@@ -1677,7 +1682,12 @@ expand_gimple_cond (basic_block bb, gimple stmt)
add_reg_br_prob_note (last, false_edge->probability);
maybe_dump_rtl_for_gimple_stmt (stmt, last);
if (false_edge->goto_locus)
- set_curr_insn_source_location (false_edge->goto_locus);
+ {
+ set_curr_insn_source_location (false_edge->goto_locus);
+ set_curr_insn_block (false_edge->goto_block);
+ false_edge->goto_locus = curr_insn_locator ();
+ }
+ false_edge->goto_block = NULL;
true_edge->flags |= EDGE_FALLTHRU;
ggc_free (pred);
return NULL;
@@ -1686,6 +1696,13 @@ expand_gimple_cond (basic_block bb, gimple stmt)
jumpif (pred, label_rtx_for_bb (true_edge->dest));
add_reg_br_prob_note (last, true_edge->probability);
last = get_last_insn ();
+ if (false_edge->goto_locus)
+ {
+ set_curr_insn_source_location (false_edge->goto_locus);
+ set_curr_insn_block (false_edge->goto_block);
+ false_edge->goto_locus = curr_insn_locator ();
+ }
+ false_edge->goto_block = NULL;
emit_jump (label_rtx_for_bb (false_edge->dest));
BB_END (bb) = last;
@@ -1708,9 +1725,6 @@ expand_gimple_cond (basic_block bb, gimple stmt)
maybe_dump_rtl_for_gimple_stmt (stmt, last2);
- if (false_edge->goto_locus)
- set_curr_insn_source_location (false_edge->goto_locus);
-
ggc_free (pred);
return new_bb;
}
@@ -1962,19 +1976,21 @@ expand_gimple_basic_block (basic_block bb)
}
}
- /* Expand implicit goto. */
+ /* Expand implicit goto and convert goto_locus. */
FOR_EACH_EDGE (e, ei, bb->succs)
{
- if (e->flags & EDGE_FALLTHRU)
- break;
- }
-
- if (e && e->dest != bb->next_bb)
- {
- emit_jump (label_rtx_for_bb (e->dest));
- if (e->goto_locus)
- set_curr_insn_source_location (e->goto_locus);
- e->flags &= ~EDGE_FALLTHRU;
+ if (e->goto_locus && e->goto_block)
+ {
+ set_curr_insn_source_location (e->goto_locus);
+ set_curr_insn_block (e->goto_block);
+ e->goto_locus = curr_insn_locator ();
+ }
+ e->goto_block = NULL;
+ if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
+ {
+ emit_jump (label_rtx_for_bb (e->dest));
+ e->flags &= ~EDGE_FALLTHRU;
+ }
}
do_pending_stack_adjust ();
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index b4ca49f4324..be1188d0b61 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -887,6 +887,46 @@ fixup_reorder_chain (void)
if (e && !can_fallthru (e->src, e->dest))
force_nonfallthru (e);
}
+
+ /* Ensure goto_locus from edges has some instructions with that locus
+ in RTL. */
+ if (!optimize)
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
+ {
+ basic_block nb;
+
+ if (simplejump_p (BB_END (e->src)))
+ {
+ if (INSN_LOCATOR (BB_END (e->src)) == (int) e->goto_locus)
+ continue;
+ if (INSN_LOCATOR (BB_END (e->src)) == 0)
+ {
+ INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
+ continue;
+ }
+ }
+ if (e->dest != EXIT_BLOCK_PTR)
+ {
+ insn = BB_HEAD (e->dest);
+ if (!INSN_P (insn))
+ insn = next_insn (insn);
+ if (insn && INSN_P (insn)
+ && INSN_LOCATOR (insn) == (int) e->goto_locus)
+ continue;
+ }
+ nb = split_edge (e);
+ if (!INSN_P (BB_END (nb)))
+ BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
+ nb);
+ INSN_LOCATOR (BB_END (nb)) = e->goto_locus;
+ }
+ }
}
/* Perform sanity checks on the insn chain.
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index f9e3e17e1a7..24469ebf30d 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1009,6 +1009,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
rtx note;
edge new_edge;
int abnormal_edge_flags = 0;
+ int loc;
/* In the case the last instruction is conditional jump to the next
instruction, first redirect the jump itself and then continue
@@ -1127,11 +1128,15 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
else
jump_block = e->src;
+ if (e->goto_locus && e->goto_block == NULL)
+ loc = e->goto_locus;
+ else
+ loc = 0;
e->flags &= ~EDGE_FALLTHRU;
if (target == EXIT_BLOCK_PTR)
{
#ifdef HAVE_return
- emit_jump_insn_after_noloc (gen_return (), BB_END (jump_block));
+ emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block), loc);
#else
gcc_unreachable ();
#endif
@@ -1139,7 +1144,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
else
{
rtx label = block_label (target);
- emit_jump_insn_after_noloc (gen_jump (label), BB_END (jump_block));
+ emit_jump_insn_after_setloc (gen_jump (label), BB_END (jump_block), loc);
JUMP_LABEL (BB_END (jump_block)) = label;
LABEL_NUSES (label)++;
}
@@ -2606,6 +2611,32 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true);
gcc_assert (!JUMP_P (BB_END (a)));
+ /* When not optimizing and the edge is the only place in RTL which holds
+ some unique locus, emit a nop with that locus in between. */
+ if (!optimize && EDGE_SUCC (a, 0)->goto_locus)
+ {
+ rtx insn = BB_END (a);
+ int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
+
+ if (NOTE_P (insn))
+ insn = prev_nonnote_insn (insn);
+ if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus)
+ goto_locus = 0;
+ else
+ {
+ insn = BB_HEAD (b);
+ if (!INSN_P (insn))
+ insn = next_insn (insn);
+ if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus)
+ goto_locus = 0;
+ }
+ if (goto_locus)
+ {
+ BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
+ INSN_LOCATOR (BB_END (a)) = goto_locus;
+ }
+ }
+
/* Possible line number notes should appear in between. */
if (b->il.rtl->header)
{
diff --git a/gcc/config.gcc b/gcc/config.gcc
index e3d170aad95..37afa852abb 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2656,7 +2656,7 @@ case "${target}" in
case "$with_abi" in
"" \
- | apcs-gnu | atpcs | aapcs | iwmmxt )
+ | apcs-gnu | atpcs | aapcs | iwmmxt | aapcs-linux )
#OK
;;
*)
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index c894bf05104..5fe55965fd1 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -22,14 +22,13 @@ extern int name_needs_quotes (const char *);
extern void machopic_validate_stub_or_non_lazy_ptr (const char *);
-extern const char *machopic_function_base_name (void);
extern void machopic_output_function_base_name (FILE *);
extern const char *machopic_indirection_name (rtx, bool);
extern const char *machopic_mcount_stub_name (void);
#ifdef RTX_CODE
-extern rtx machopic_function_base_sym (void);
+extern rtx machopic_gen_offset (rtx);
extern int machopic_operand_p (rtx);
extern enum machopic_addr_class machopic_classify_symbol (rtx);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index fe332738c54..3a4fc99c5b3 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -267,44 +267,26 @@ machopic_define_symbol (rtx mem)
SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
}
-static GTY(()) const char * function_base;
+/* Return either ORIG or:
-const char *
-machopic_function_base_name (void)
-{
- /* if dynamic-no-pic is on, we should not get here */
- gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
-
- if (function_base == NULL)
- function_base = ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
-
- crtl->uses_pic_offset_table = 1;
-
- return function_base;
-}
-
-/* Return a SYMBOL_REF for the PIC function base. */
+ (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))
+ depending on MACHO_DYNAMIC_NO_PIC_P. */
rtx
-machopic_function_base_sym (void)
+machopic_gen_offset (rtx orig)
{
- rtx sym_ref;
-
- sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
- SYMBOL_REF_FLAGS (sym_ref)
- |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
- return sym_ref;
-}
-
-/* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
- on whether pic_base is NULL or not. */
-static inline rtx
-gen_pic_offset (rtx orig, rtx pic_base)
-{
- if (!pic_base)
+ if (MACHO_DYNAMIC_NO_PIC_P)
return orig;
else
- return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
+ {
+ /* Play games to avoid marking the function as needing pic if we
+ are being called as part of the cost-estimation process. */
+ if (current_ir_type () != IR_GIMPLE)
+ crtl->uses_pic_offset_table = 1;
+ orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
+ UNSPEC_MACHOPIC_OFFSET);
+ return gen_rtx_CONST (Pmode, orig);
+ }
}
static GTY(()) const char * function_base_func_name;
@@ -528,8 +510,7 @@ machopic_indirect_data_reference (rtx orig, rtx reg)
else if (defined)
{
#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
- rtx pic_base = machopic_function_base_sym ();
- rtx offset = gen_pic_offset (orig, pic_base);
+ rtx offset = machopic_gen_offset (orig);
#endif
#if defined (TARGET_TOC) /* i.e., PowerPC */
@@ -675,8 +656,6 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
))
{
/* addr(foo) = &func+(foo-func) */
- rtx pic_base;
-
orig = machopic_indirect_data_reference (orig, reg);
if (GET_CODE (orig) == PLUS
@@ -689,12 +668,6 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
return reg;
}
- /* if dynamic-no-pic we don't have a pic base */
- if (MACHO_DYNAMIC_NO_PIC_P)
- pic_base = NULL;
- else
- pic_base = machopic_function_base_sym ();
-
if (GET_CODE (orig) == MEM)
{
if (reg == 0)
@@ -731,7 +704,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF)
{
- rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
+ rtx offset = machopic_gen_offset (XEXP (orig, 0));
#if defined (TARGET_TOC) /* i.e., PowerPC */
/* Generating a new reg may expose opportunities for
common subexpression elimination. */
@@ -787,8 +760,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
if (reload_in_progress)
df_set_regs_ever_live (REGNO (pic), true);
pic_ref = gen_rtx_PLUS (Pmode, pic,
- gen_pic_offset (XEXP (orig, 0),
- pic_base));
+ machopic_gen_offset (XEXP (orig, 0)));
}
#if !defined (TARGET_TOC)
@@ -803,7 +775,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
if (GET_CODE (orig) == SYMBOL_REF
|| GET_CODE (orig) == LABEL_REF)
{
- rtx offset = gen_pic_offset (orig, pic_base);
+ rtx offset = machopic_gen_offset (orig);
#if defined (TARGET_TOC) /* i.e., PowerPC */
rtx hi_sum_reg;
@@ -860,7 +832,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
df_set_regs_ever_live (REGNO (pic), true);
pic_ref = gen_rtx_PLUS (Pmode,
pic,
- gen_pic_offset (orig, pic_base));
+ machopic_gen_offset (orig));
}
}
}
@@ -1064,27 +1036,12 @@ int
machopic_operand_p (rtx op)
{
if (MACHOPIC_JUST_INDIRECT)
- {
- while (GET_CODE (op) == CONST)
- op = XEXP (op, 0);
-
- if (GET_CODE (op) == SYMBOL_REF)
- return machopic_symbol_defined_p (op);
- else
- return 0;
- }
-
- while (GET_CODE (op) == CONST)
- op = XEXP (op, 0);
-
- if (GET_CODE (op) == MINUS
- && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
- && machopic_symbol_defined_p (XEXP (op, 0))
- && machopic_symbol_defined_p (XEXP (op, 1)))
- return 1;
-
- return 0;
+ return (GET_CODE (op) == SYMBOL_REF
+ && machopic_symbol_defined_p (op));
+ else
+ return (GET_CODE (op) == CONST
+ && GET_CODE (XEXP (op, 0)) == UNSPEC
+ && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
}
/* This function records whether a given name corresponds to a defined
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index c2685a893f6..03955c64d0a 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -525,6 +525,9 @@ extern GTY(()) int darwin_ms_struct;
#define USER_LABEL_PREFIX "_"
+/* A dummy symbol that will be replaced with the function base name. */
+#define MACHOPIC_FUNCTION_BASE_NAME "<pic base>"
+
/* Don't output a .file directive. That is only used by the assembler for
error reporting. */
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
@@ -609,7 +612,7 @@ extern GTY(()) int darwin_ms_struct;
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
do { \
const char *xname = (NAME); \
- if (! strcmp (xname, "<pic base>")) \
+ if (! strcmp (xname, MACHOPIC_FUNCTION_BASE_NAME)) \
machopic_output_function_base_name(FILE); \
else if (xname[0] == '&' || xname[0] == '*') \
{ \
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index a1defcf9bc6..e2b6025b2c0 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -176,7 +176,7 @@ extern void darwin_x86_file_end (void);
#define TARGET_DYNAMIC_NO_PIC (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
#undef GOT_SYMBOL_NAME
-#define GOT_SYMBOL_NAME (machopic_function_base_name ())
+#define GOT_SYMBOL_NAME MACHOPIC_FUNCTION_BASE_NAME
/* Define the syntax of pseudo-ops, labels and comments. */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index de024581e80..1abd11dead7 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -272,3 +272,7 @@ extern enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code);
extern rtx construct_plt_address (rtx);
#endif
extern int asm_preferred_eh_data_format (int, int);
+
+#ifdef HAVE_ATTR_cpu
+extern enum attr_cpu ix86_schedule;
+#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 86be390a139..be371173fa2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1229,9 +1229,6 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_ZERO_EXTEND_WITH_AND */
m_486 | m_PENT,
- /* X86_TUNE_USE_BIT_TEST */
- m_386,
-
/* X86_TUNE_UNROLL_STRLEN */
m_486 | m_PENT | m_PPRO | m_AMD_MULTIPLE | m_K6 | m_CORE2 | m_GENERIC,
@@ -1693,6 +1690,9 @@ enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
enum fpmath_unit ix86_fpmath;
/* Which cpu are we scheduling for. */
+enum attr_cpu ix86_schedule;
+
+/* Which cpu are we optimizing for. */
enum processor_type ix86_tune;
/* Which instruction set architecture to use. */
@@ -2490,93 +2490,89 @@ override_options (bool main_args_p)
{
const char *const name; /* processor name or nickname. */
const enum processor_type processor;
+ const enum attr_cpu schedule;
const unsigned /*enum pta_flags*/ flags;
}
const processor_alias_table[] =
{
- {"i386", PROCESSOR_I386, 0},
- {"i486", PROCESSOR_I486, 0},
- {"i586", PROCESSOR_PENTIUM, 0},
- {"pentium", PROCESSOR_PENTIUM, 0},
- {"pentium-mmx", PROCESSOR_PENTIUM, PTA_MMX},
- {"winchip-c6", PROCESSOR_I486, PTA_MMX},
- {"winchip2", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
- {"c3", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
- {"c3-2", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE},
- {"i686", PROCESSOR_PENTIUMPRO, 0},
- {"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
- {"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
- {"pentium3", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE},
- {"pentium3m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE},
- {"pentium-m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_SSE2},
- {"pentium4", PROCESSOR_PENTIUM4, PTA_MMX |PTA_SSE | PTA_SSE2},
- {"pentium4m", PROCESSOR_PENTIUM4, PTA_MMX | PTA_SSE | PTA_SSE2},
- {"prescott", PROCESSOR_NOCONA, PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3},
- {"nocona", PROCESSOR_NOCONA, (PTA_64BIT
- | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_CX16 | PTA_NO_SAHF)},
- {"core2", PROCESSOR_CORE2, (PTA_64BIT
- | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3
- | PTA_CX16)},
- {"geode", PROCESSOR_GEODE, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- |PTA_PREFETCH_SSE)},
- {"k6", PROCESSOR_K6, PTA_MMX},
- {"k6-2", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
- {"k6-3", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
- {"athlon", PROCESSOR_ATHLON, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_PREFETCH_SSE)},
- {"athlon-tbird", PROCESSOR_ATHLON, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_PREFETCH_SSE)},
- {"athlon-4", PROCESSOR_ATHLON, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE)},
- {"athlon-xp", PROCESSOR_ATHLON, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE)},
- {"athlon-mp", PROCESSOR_ATHLON, (PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE)},
- {"x86-64", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_SSE | PTA_SSE2
- | PTA_NO_SAHF)},
- {"k8", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2
- | PTA_NO_SAHF)},
- {"k8-sse3", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_NO_SAHF)},
- {"opteron", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2
- | PTA_NO_SAHF)},
- {"opteron-sse3", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_NO_SAHF)},
- {"athlon64", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2
- | PTA_NO_SAHF)},
- {"athlon64-sse3", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_NO_SAHF)},
- {"athlon-fx", PROCESSOR_K8, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2
- | PTA_NO_SAHF)},
- {"amdfam10", PROCESSOR_AMDFAM10, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSE4A
- | PTA_CX16 | PTA_ABM)},
- {"barcelona", PROCESSOR_AMDFAM10, (PTA_64BIT
- | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A
- | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSE4A
- | PTA_CX16 | PTA_ABM)},
- {"generic32", PROCESSOR_GENERIC32, 0 /* flags are only used for -march switch. */ },
- {"generic64", PROCESSOR_GENERIC64, PTA_64BIT /* flags are only used for -march switch. */ },
+ {"i386", PROCESSOR_I386, CPU_NONE, 0},
+ {"i486", PROCESSOR_I486, CPU_NONE, 0},
+ {"i586", PROCESSOR_PENTIUM, CPU_PENTIUM, 0},
+ {"pentium", PROCESSOR_PENTIUM, CPU_PENTIUM, 0},
+ {"pentium-mmx", PROCESSOR_PENTIUM, CPU_PENTIUM, PTA_MMX},
+ {"winchip-c6", PROCESSOR_I486, CPU_NONE, PTA_MMX},
+ {"winchip2", PROCESSOR_I486, CPU_NONE, PTA_MMX | PTA_3DNOW},
+ {"c3", PROCESSOR_I486, CPU_NONE, PTA_MMX | PTA_3DNOW},
+ {"c3-2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX | PTA_SSE},
+ {"i686", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0},
+ {"pentiumpro", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0},
+ {"pentium2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX},
+ {"pentium3", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
+ PTA_MMX | PTA_SSE},
+ {"pentium3m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
+ PTA_MMX | PTA_SSE},
+ {"pentium-m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO,
+ PTA_MMX | PTA_SSE | PTA_SSE2},
+ {"pentium4", PROCESSOR_PENTIUM4, CPU_NONE,
+ PTA_MMX |PTA_SSE | PTA_SSE2},
+ {"pentium4m", PROCESSOR_PENTIUM4, CPU_NONE,
+ PTA_MMX | PTA_SSE | PTA_SSE2},
+ {"prescott", PROCESSOR_NOCONA, CPU_NONE,
+ PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3},
+ {"nocona", PROCESSOR_NOCONA, CPU_NONE,
+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
+ | PTA_CX16 | PTA_NO_SAHF},
+ {"core2", PROCESSOR_CORE2, CPU_CORE2,
+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
+ | PTA_SSSE3 | PTA_CX16},
+ {"geode", PROCESSOR_GEODE, CPU_GEODE,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
+ {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
+ {"k6-2", PROCESSOR_K6, CPU_K6, PTA_MMX | PTA_3DNOW},
+ {"k6-3", PROCESSOR_K6, CPU_K6, PTA_MMX | PTA_3DNOW},
+ {"athlon", PROCESSOR_ATHLON, CPU_ATHLON,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE},
+ {"athlon-tbird", PROCESSOR_ATHLON, CPU_ATHLON,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE},
+ {"athlon-4", PROCESSOR_ATHLON, CPU_ATHLON,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE},
+ {"athlon-xp", PROCESSOR_ATHLON, CPU_ATHLON,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE},
+ {"athlon-mp", PROCESSOR_ATHLON, CPU_ATHLON,
+ PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE},
+ {"x86-64", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_NO_SAHF},
+ {"k8", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_NO_SAHF},
+ {"k8-sse3", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF},
+ {"opteron", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_NO_SAHF},
+ {"opteron-sse3", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF},
+ {"athlon64", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_NO_SAHF},
+ {"athlon64-sse3", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_SSE3 | PTA_NO_SAHF},
+ {"athlon-fx", PROCESSOR_K8, CPU_K8,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_NO_SAHF},
+ {"amdfam10", PROCESSOR_AMDFAM10, CPU_AMDFAM10,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM},
+ {"barcelona", PROCESSOR_AMDFAM10, PROCESSOR_AMDFAM10,
+ PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE
+ | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM},
+ {"generic32", PROCESSOR_GENERIC32, CPU_PENTIUMPRO,
+ 0 /* flags are only used for -march switch. */ },
+ {"generic64", PROCESSOR_GENERIC64, CPU_GENERIC64,
+ PTA_64BIT /* flags are only used for -march switch. */ },
};
int const pta_size = ARRAY_SIZE (processor_alias_table);
@@ -2766,6 +2762,7 @@ override_options (bool main_args_p)
for (i = 0; i < pta_size; i++)
if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
{
+ ix86_schedule = processor_alias_table[i].schedule;
ix86_arch = processor_alias_table[i].processor;
/* Default cpu tuning to the architecture. */
ix86_tune = ix86_arch;
@@ -2848,6 +2845,7 @@ override_options (bool main_args_p)
for (i = 0; i < pta_size; i++)
if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
{
+ ix86_schedule = processor_alias_table[i].schedule;
ix86_tune = processor_alias_table[i].processor;
if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
{
@@ -2858,6 +2856,7 @@ override_options (bool main_args_p)
if (! strcmp (ix86_tune_string,
processor_alias_table[i].name))
break;
+ ix86_schedule = processor_alias_table[i].schedule;
ix86_tune = processor_alias_table[i].processor;
}
else
@@ -3276,11 +3275,13 @@ static void
ix86_function_specific_save (struct cl_target_option *ptr)
{
gcc_assert (IN_RANGE (ix86_arch, 0, 255));
+ gcc_assert (IN_RANGE (ix86_schedule, 0, 255));
gcc_assert (IN_RANGE (ix86_tune, 0, 255));
gcc_assert (IN_RANGE (ix86_fpmath, 0, 255));
gcc_assert (IN_RANGE (ix86_branch_cost, 0, 255));
ptr->arch = ix86_arch;
+ ptr->schedule = ix86_schedule;
ptr->tune = ix86_tune;
ptr->fpmath = ix86_fpmath;
ptr->branch_cost = ix86_branch_cost;
@@ -3301,6 +3302,7 @@ ix86_function_specific_restore (struct cl_target_option *ptr)
int i;
ix86_arch = ptr->arch;
+ ix86_schedule = ptr->schedule;
ix86_tune = ptr->tune;
ix86_fpmath = ptr->fpmath;
ix86_branch_cost = ptr->branch_cost;
@@ -7268,7 +7270,7 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
/* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This
is what will be referenced by the Mach-O PIC subsystem. */
if (!label)
- ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+ ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
#endif
(*targetm.asm_out.internal_label) (asm_out_file, "L",
@@ -7290,7 +7292,7 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
is what will be referenced by the Mach-O PIC subsystem. */
#if TARGET_MACHO
if (!label)
- ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
+ ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
else
targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (label));
@@ -8557,19 +8559,8 @@ ix86_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
static bool
darwin_local_data_pic (rtx disp)
{
- if (GET_CODE (disp) == MINUS)
- {
- if (GET_CODE (XEXP (disp, 0)) == LABEL_REF
- || GET_CODE (XEXP (disp, 0)) == SYMBOL_REF)
- if (GET_CODE (XEXP (disp, 1)) == SYMBOL_REF)
- {
- const char *sym_name = XSTR (XEXP (disp, 1), 0);
- if (! strcmp (sym_name, "<pic base>"))
- return true;
- }
- }
-
- return false;
+ return (GET_CODE (disp) == UNSPEC
+ && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
}
/* Determine if a given RTX is a valid constant. We already know this
@@ -8710,6 +8701,8 @@ legitimate_pic_operand_p (rtx x)
x = XVECEXP (inner, 0, 0);
return (GET_CODE (x) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
+ case UNSPEC_MACHOPIC_OFFSET:
+ return legitimate_pic_address_disp_p (x);
default:
return false;
}
@@ -8972,7 +8965,8 @@ legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
reason_rtx = disp;
if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == UNSPEC)
+ && GET_CODE (XEXP (disp, 0)) == UNSPEC
+ && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
switch (XINT (XEXP (disp, 0), 1))
{
/* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit when
@@ -9935,6 +9929,12 @@ output_pic_addr_const (FILE *file, rtx x, int code)
case UNSPEC_INDNTPOFF:
fputs ("@INDNTPOFF", file);
break;
+#if TARGET_MACHO
+ case UNSPEC_MACHOPIC_OFFSET:
+ putc ('-', file);
+ machopic_output_function_base_name (file);
+ break;
+#endif
default:
output_operand_lossage ("invalid UNSPEC as operand");
break;
@@ -10055,7 +10055,7 @@ ix86_delegitimize_address (rtx orig_x)
if (TARGET_MACHO && darwin_local_data_pic (x)
&& !MEM_P (orig_x))
- result = XEXP (x, 0);
+ result = XVECEXP (x, 0, 0);
if (! result)
return orig_x;
@@ -11167,6 +11167,13 @@ output_addr_const_extra (FILE *file, rtx x)
output_addr_const (file, op);
fputs ("@INDNTPOFF", file);
break;
+#if TARGET_MACHO
+ case UNSPEC_MACHOPIC_OFFSET:
+ output_addr_const (file, op);
+ putc ('-', file);
+ machopic_output_function_base_name (file);
+ break;
+#endif
default:
return false;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 3af68e9a8a6..81a282e0553 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -237,7 +237,6 @@ enum ix86_tune_indices {
X86_TUNE_USE_LEAVE,
X86_TUNE_PUSH_MEMORY,
X86_TUNE_ZERO_EXTEND_WITH_AND,
- X86_TUNE_USE_BIT_TEST,
X86_TUNE_UNROLL_STRLEN,
X86_TUNE_DEEP_BRANCH_PREDICTION,
X86_TUNE_BRANCH_PREDICTION_HINTS,
@@ -305,7 +304,6 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
#define TARGET_PUSH_MEMORY ix86_tune_features[X86_TUNE_PUSH_MEMORY]
#define TARGET_ZERO_EXTEND_WITH_AND \
ix86_tune_features[X86_TUNE_ZERO_EXTEND_WITH_AND]
-#define TARGET_USE_BIT_TEST ix86_tune_features[X86_TUNE_USE_BIT_TEST]
#define TARGET_UNROLL_STRLEN ix86_tune_features[X86_TUNE_UNROLL_STRLEN]
#define TARGET_DEEP_BRANCH_PREDICTION \
ix86_tune_features[X86_TUNE_DEEP_BRANCH_PREDICTION]
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c6fba67ffbe..88040fc2201 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -58,6 +58,7 @@
(UNSPEC_GOTNTPOFF 7)
(UNSPEC_INDNTPOFF 8)
(UNSPEC_PLTOFF 9)
+ (UNSPEC_MACHOPIC_OFFSET 10)
; Prologue support
(UNSPEC_STACK_ALLOC 11)
@@ -295,11 +296,10 @@
;; "reload_completed && TARGET_64BIT".
-;; Processor type. This attribute must exactly match the processor_type
-;; enumeration in i386.h.
-(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
- nocona,core2,generic32,generic64,amdfam10"
- (const (symbol_ref "ix86_tune")))
+;; Processor type.
+(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
+ generic64,amdfam10"
+ (const (symbol_ref "ix86_schedule")))
;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes.
@@ -2559,14 +2559,14 @@
to stack may result in unaligned memory access. */
if (misaligned_operand (operands[0], TImode)
|| misaligned_operand (operands[1], TImode))
- {
+ {
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovups\t{%1, %0|%0, %1}";
else
return "%vmovdqu\t{%1, %0|%0, %1}";
}
else
- {
+ {
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
else
@@ -2610,14 +2610,14 @@
to stack may result in unaligned memory access. */
if (misaligned_operand (operands[0], TImode)
|| misaligned_operand (operands[1], TImode))
- {
+ {
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovups\t{%1, %0|%0, %1}";
else
return "%vmovdqu\t{%1, %0|%0, %1}";
}
else
- {
+ {
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
else
@@ -5150,8 +5150,8 @@
/* Avoid store forwarding (partial memory) stall penalty
by passing DImode value through XMM registers. */
- if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
- && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
+ if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
+ && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
&& optimize_function_for_speed_p (cfun))
{
emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
@@ -20245,6 +20245,7 @@
[(label_ref (match_operand 0 "" ""))]
"!TARGET_64BIT && flag_pic"
{
+#if TARGET_MACHO
if (TARGET_MACHO)
{
rtx xops[3];
@@ -20252,13 +20253,11 @@
rtx label_rtx = gen_label_rtx ();
emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
xops[0] = xops[1] = picreg;
- xops[2] = gen_rtx_CONST (SImode,
- gen_rtx_MINUS (SImode,
- gen_rtx_LABEL_REF (SImode, label_rtx),
- gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
+ xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
ix86_expand_binary_operator (MINUS, SImode, xops);
}
else
+#endif
emit_insn (gen_set_got (pic_offset_table_rtx));
DONE;
})
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 406727139c8..2881ea255ad 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -31,6 +31,10 @@ unsigned char tune
TargetSave
unsigned char fpmath
+;; CPU schedule model
+TargetSave
+unsigned char schedule
+
;; branch cost
TargetSave
unsigned char branch_cost
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index 7a1ae9ebc6b..b4137ea1394 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3. If not see
/* Include in the mingw32 libraries with libgcc */
#undef REAL_LIBGCC_SPEC
#define REAL_LIBGCC_SPEC \
- "-lmingw32 \
+ "%{mthreads:-lmingwthrd} -lmingw32 \
%{shared-libgcc:-lgcc_s} \
%{!shared-libgcc:-lgcc_eh} \
-lgcc \
diff --git a/gcc/config/i386/ppro.md b/gcc/config/i386/ppro.md
index b971e51089e..81c0746ea1e 100644
--- a/gcc/config/i386/ppro.md
+++ b/gcc/config/i386/ppro.md
@@ -135,25 +135,25 @@
;; on decoder 0, and say that it takes a little while before the result
;; is available.
(define_insn_reservation "ppro_complex_insn" 6
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "other,multi,call,callv,str"))
"decoder0")
;; imov with memory operands does not use the integer units.
(define_insn_reservation "ppro_imov" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "imov")))
"decodern,(p0|p1)")
(define_insn_reservation "ppro_imov_load" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "imov")))
"decodern,p2")
(define_insn_reservation "ppro_imov_store" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(eq_attr "type" "imov")))
"decoder0,p4+p3")
@@ -161,20 +161,20 @@
;; imovx always decodes to one uop, and also doesn't use the integer
;; units if it has memory operands.
(define_insn_reservation "ppro_imovx" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "imovx")))
"decodern,(p0|p1)")
(define_insn_reservation "ppro_imovx_load" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "imovx")))
"decodern,p2")
;; lea executes on port 0 with latency one and throughput 1.
(define_insn_reservation "ppro_lea" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "lea")))
"decodern,p0")
@@ -183,13 +183,13 @@
;; The load and store units need to be reserved when memory operands
;; are involved.
(define_insn_reservation "ppro_shift_rotate" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "ishift,ishift1,rotate,rotate1")))
"decodern,p0")
(define_insn_reservation "ppro_shift_rotate_mem" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "!none")
(eq_attr "type" "ishift,ishift1,rotate,rotate1")))
"decoder0,p2+p0,p4+p3")
@@ -213,32 +213,32 @@
;; results because we can assume these instructions can decode on all
;; decoders.
(define_insn_reservation "ppro_branch" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "ibr")))
"decodern,p1")
;; ??? Indirect branches probably have worse latency than this.
(define_insn_reservation "ppro_indirect_branch" 6
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "!none")
(eq_attr "type" "ibr")))
"decoder0,p2+p1")
(define_insn_reservation "ppro_leave" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "leave"))
"decoder0,p2+(p0|p1),(p0|p1)")
;; imul has throughput one, but latency 4, and can only execute on port 0.
(define_insn_reservation "ppro_imul" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "imul")))
"decodern,p0")
(define_insn_reservation "ppro_imul_mem" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "!none")
(eq_attr "type" "imul")))
"decoder0,p2+p0")
@@ -247,42 +247,42 @@
;; QI, HI, and SI have issue latency 12, 21, and 37, respectively.
;; These issue latencies are modelled via the ppro_div automaton.
(define_insn_reservation "ppro_idiv_QI" 19
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "QI")
(eq_attr "type" "idiv"))))
"decoder0,(p0+idiv)*2,(p0|p1)+idiv,idiv*9")
(define_insn_reservation "ppro_idiv_QI_load" 19
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "QI")
(eq_attr "type" "idiv"))))
"decoder0,p2+p0+idiv,p0+idiv,(p0|p1)+idiv,idiv*9")
(define_insn_reservation "ppro_idiv_HI" 23
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "HI")
(eq_attr "type" "idiv"))))
"decoder0,(p0+idiv)*3,(p0|p1)+idiv,idiv*17")
(define_insn_reservation "ppro_idiv_HI_load" 23
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "HI")
(eq_attr "type" "idiv"))))
"decoder0,p2+p0+idiv,p0+idiv,(p0|p1)+idiv,idiv*18")
(define_insn_reservation "ppro_idiv_SI" 39
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SI")
(eq_attr "type" "idiv"))))
"decoder0,(p0+idiv)*3,(p0|p1)+idiv,idiv*33")
(define_insn_reservation "ppro_idiv_SI_load" 39
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SI")
(eq_attr "type" "idiv"))))
@@ -293,85 +293,85 @@
;; has throughput "1/cycle (align with FADD)". What do they
;; mean and how can we model that?
(define_insn_reservation "ppro_fop" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none,unknown")
(eq_attr "type" "fop")))
"decodern,p0")
(define_insn_reservation "ppro_fop_load" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "fop")))
"decoder0,p2+p0,p0")
(define_insn_reservation "ppro_fop_store" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(eq_attr "type" "fop")))
"decoder0,p0,p0,p0+p4+p3")
(define_insn_reservation "ppro_fop_both" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "both")
(eq_attr "type" "fop")))
"decoder0,p2+p0,p0+p4+p3")
(define_insn_reservation "ppro_fsgn" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fsgn"))
"decodern,p0")
(define_insn_reservation "ppro_fistp" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fistp"))
"decoder0,p0*2,p4+p3")
(define_insn_reservation "ppro_fcmov" 2
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fcmov"))
"decoder0,p0*2")
(define_insn_reservation "ppro_fcmp" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "fcmp")))
"decodern,p0")
(define_insn_reservation "ppro_fcmp_load" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "fcmp")))
"decoder0,p2+p0")
(define_insn_reservation "ppro_fmov" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "fmov")))
"decodern,p0")
(define_insn_reservation "ppro_fmov_load" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "!XF")
(eq_attr "type" "fmov"))))
"decodern,p2")
(define_insn_reservation "ppro_fmov_XF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "XF")
(eq_attr "type" "fmov"))))
"decoder0,(p2+p0)*2")
(define_insn_reservation "ppro_fmov_store" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(and (eq_attr "mode" "!XF")
(eq_attr "type" "fmov"))))
"decodern,p0")
(define_insn_reservation "ppro_fmov_XF_store" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(and (eq_attr "mode" "XF")
(eq_attr "type" "fmov"))))
@@ -380,13 +380,13 @@
;; fmul executes on port 0 with latency 5. It has issue latency 2,
;; but we don't model this.
(define_insn_reservation "ppro_fmul" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "fmul")))
"decoder0,p0*2")
(define_insn_reservation "ppro_fmul_load" 6
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "fmul")))
"decoder0,p2+p0,p0")
@@ -397,42 +397,42 @@
;; that. Throughput is equal to latency - 1, which we model using the
;; ppro_div automaton.
(define_insn_reservation "ppro_fdiv_SF" 18
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "fdiv,fpspc"))))
"decodern,p0+fdiv,fdiv*16")
(define_insn_reservation "ppro_fdiv_SF_load" 19
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "fdiv,fpspc"))))
"decoder0,p2+p0+fdiv,fdiv*16")
(define_insn_reservation "ppro_fdiv_DF" 32
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "DF")
(eq_attr "type" "fdiv,fpspc"))))
"decodern,p0+fdiv,fdiv*30")
(define_insn_reservation "ppro_fdiv_DF_load" 33
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "DF")
(eq_attr "type" "fdiv,fpspc"))))
"decoder0,p2+p0+fdiv,fdiv*30")
(define_insn_reservation "ppro_fdiv_XF" 38
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "XF")
(eq_attr "type" "fdiv,fpspc"))))
"decodern,p0+fdiv,fdiv*36")
(define_insn_reservation "ppro_fdiv_XF_load" 39
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "XF")
(eq_attr "type" "fdiv,fpspc"))))
@@ -450,31 +450,31 @@
;; so they behave as "simple" instructions that need no special modelling.
;; We only have to model mmxshft and mmxmul.
(define_insn_reservation "ppro_mmx_shft" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "mmxshft")))
"decodern,p1")
(define_insn_reservation "ppro_mmx_shft_load" 2
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "mmxshft")))
"decoder0,p2+p1")
(define_insn_reservation "ppro_mmx_mul" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "mmxmul")))
"decodern,p0")
(define_insn_reservation "ppro_mmx_mul_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(eq_attr "type" "mmxmul")))
"decoder0,p2+p0")
(define_insn_reservation "ppro_sse_mmxcvt" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "mode" "DI")
(eq_attr "type" "mmxcvt")))
"decodern,p1")
@@ -482,7 +482,7 @@
;; FIXME: These are Pentium III only, but we cannot tell here if
;; we're generating code for PentiumPro/Pentium II or Pentium III
;; (define_insn_reservation "ppro_sse_mmxshft" 2
-;; (and (eq_attr "cpu" "pentiumpro,generic32")
+;; (and (eq_attr "cpu" "pentiumpro")
;; (and (eq_attr "mode" "DI")
;; (eq_attr "type" "mmxshft")))
;; "decodern,p0")
@@ -493,69 +493,69 @@
;; The sfence instruction.
(define_insn_reservation "ppro_sse_sfence" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "unknown")
(eq_attr "type" "sse")))
"decoder0,p4+p3")
;; FIXME: This reservation is all wrong when we're scheduling sqrtss.
(define_insn_reservation "ppro_sse_SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "mode" "SF")
(eq_attr "type" "sse")))
"decodern,p0")
(define_insn_reservation "ppro_sse_add_SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "sseadd"))))
"decodern,p1")
(define_insn_reservation "ppro_sse_add_SF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "sseadd"))))
"decoder0,p2+p1")
(define_insn_reservation "ppro_sse_cmp_SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssecmp"))))
"decoder0,p1")
(define_insn_reservation "ppro_sse_cmp_SF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssecmp"))))
"decoder0,p2+p1")
(define_insn_reservation "ppro_sse_comi_SF" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssecomi"))))
"decodern,p0")
(define_insn_reservation "ppro_sse_comi_SF_load" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssecomi"))))
"decoder0,p2+p0")
(define_insn_reservation "ppro_sse_mul_SF" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssemul"))))
"decodern,p0")
(define_insn_reservation "ppro_sse_mul_SF_load" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssemul"))))
@@ -563,109 +563,109 @@
;; FIXME: ssediv doesn't close p0 for 17 cycles, surely???
(define_insn_reservation "ppro_sse_div_SF" 18
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssediv"))))
"decoder0,p0*17")
(define_insn_reservation "ppro_sse_div_SF_load" 18
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssediv"))))
"decoder0,(p2+p0),p0*16")
(define_insn_reservation "ppro_sse_icvt_SF" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "mode" "SF")
(eq_attr "type" "sseicvt")))
"decoder0,(p2+p1)*2")
(define_insn_reservation "ppro_sse_icvt_SI" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "mode" "SI")
(eq_attr "type" "sseicvt")))
"decoder0,(p2+p1)")
(define_insn_reservation "ppro_sse_mov_SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssemov"))))
"decoder0,(p0|p1)")
(define_insn_reservation "ppro_sse_mov_SF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssemov"))))
"decoder0,p2+(p0|p1)")
(define_insn_reservation "ppro_sse_mov_SF_store" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(and (eq_attr "mode" "SF")
(eq_attr "type" "ssemov"))))
"decoder0,p4+p3")
(define_insn_reservation "ppro_sse_V4SF" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "sse")))
"decoder0,p1*2")
(define_insn_reservation "ppro_sse_add_V4SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "sseadd"))))
"decoder0,p1*2")
(define_insn_reservation "ppro_sse_add_V4SF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "sseadd"))))
"decoder0,(p2+p1)*2")
(define_insn_reservation "ppro_sse_cmp_V4SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssecmp"))))
"decoder0,p1*2")
(define_insn_reservation "ppro_sse_cmp_V4SF_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssecmp"))))
"decoder0,(p2+p1)*2")
(define_insn_reservation "ppro_sse_cvt_V4SF" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none,unknown")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssecvt"))))
"decoder0,p1*2")
(define_insn_reservation "ppro_sse_cvt_V4SF_other" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "!none,unknown")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssecmp"))))
"decoder0,p1,p4+p3")
(define_insn_reservation "ppro_sse_mul_V4SF" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssemul"))))
"decoder0,p0*2")
(define_insn_reservation "ppro_sse_mul_V4SF_load" 5
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssemul"))))
@@ -673,49 +673,49 @@
;; FIXME: p0 really closed this long???
(define_insn_reservation "ppro_sse_div_V4SF" 48
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssediv"))))
"decoder0,p0*34")
(define_insn_reservation "ppro_sse_div_V4SF_load" 48
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssediv"))))
"decoder0,(p2+p0)*2,p0*32")
(define_insn_reservation "ppro_sse_log_V4SF" 2
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "sselog,sselog1"))))
"decodern,p1")
(define_insn_reservation "ppro_sse_log_V4SF_load" 2
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "sselog,sselog1"))))
"decoder0,(p2+p1)")
(define_insn_reservation "ppro_sse_mov_V4SF" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssemov"))))
"decoder0,(p0|p1)*2")
(define_insn_reservation "ppro_sse_mov_V4SF_load" 2
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssemov"))))
"decoder0,p2*2")
(define_insn_reservation "ppro_sse_mov_V4SF_store" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(and (eq_attr "mode" "V4SF")
(eq_attr "type" "ssemov"))))
@@ -729,7 +729,7 @@
;; reg-reg instructions produce 1 uop so they can be decoded on any of
;; the three decoders.
(define_insn_reservation "ppro_insn" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "none,unknown")
(eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
"decodern,(p0|p1)")
@@ -737,13 +737,13 @@
;; read-modify and register-memory instructions have 2 or three uops,
;; so they have to be decoded on decoder0.
(define_insn_reservation "ppro_insn_load" 3
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "load")
(eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,p2+(p0|p1)")
(define_insn_reservation "ppro_insn_store" 1
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "store")
(eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,(p0|p1),p4+p3")
@@ -751,7 +751,7 @@
;; read-modify-store instructions produce 4 uops so they have to be
;; decoded on decoder0 as well.
(define_insn_reservation "ppro_insn_both" 4
- (and (eq_attr "cpu" "pentiumpro,generic32")
+ (and (eq_attr "cpu" "pentiumpro")
(and (eq_attr "memory" "both")
(eq_attr "type" "alu,alu1,negnot,incdec,icmp,test,setcc,icmov,push,pop,fxch,sseiadd,sseishft,sseimul,mmx,mmxadd,mmxcmp")))
"decoder0,p2+(p0|p1),p4+p3")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 36a1b3a7397..bdac2102617 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -428,7 +428,8 @@
|| !CONST_INT_P (XEXP (op, 1)))
return 0;
op = XEXP (op, 0);
- if (GET_CODE (op) == UNSPEC)
+ if (GET_CODE (op) == UNSPEC
+ && XINT (op, 1) != UNSPEC_MACHOPIC_OFFSET)
return 1;
}
return 0;
diff --git a/gcc/config/mips/10000.md b/gcc/config/mips/10000.md
new file mode 100644
index 00000000000..ad21e9e936e
--- /dev/null
+++ b/gcc/config/mips/10000.md
@@ -0,0 +1,253 @@
+;; DFA-based pipeline description for the VR1x000.
+;; Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc.
+;;
+;; 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/>.
+
+
+;; R12K/R14K/R16K are derivatives of R10K, thus copy its description
+;; until specific tuning for each is added.
+
+;; R10000 has an int queue, fp queue, address queue.
+;; The int queue feeds ALU1 and ALU2.
+;; The fp queue feeds the fp-adder and fp-multiplier.
+;; The addr queue feeds the Load/Store unit.
+;;
+;; However, we define the fp-adder and fp-multiplier as
+;; separate automatons, because the fp-multiplier is
+;; divided into fp-multiplier, fp-division, and
+;; fp-squareroot units, all of which share the same
+;; issue and completion logic, yet can operate in
+;; parallel.
+;;
+;; This is based on the model described in the R10K Manual
+;; and it helps to reduce the size of the automata.
+(define_automaton "r10k_a_int, r10k_a_fpadder, r10k_a_addr,
+ r10k_a_fpmpy, r10k_a_fpdiv, r10k_a_fpsqrt")
+
+(define_cpu_unit "r10k_alu1" "r10k_a_int")
+(define_cpu_unit "r10k_alu2" "r10k_a_int")
+(define_cpu_unit "r10k_fpadd" "r10k_a_fpadder")
+(define_cpu_unit "r10k_fpmpy" "r10k_a_fpmpy")
+(define_cpu_unit "r10k_fpdiv" "r10k_a_fpdiv")
+(define_cpu_unit "r10k_fpsqrt" "r10k_a_fpsqrt")
+(define_cpu_unit "r10k_loadstore" "r10k_a_addr")
+
+
+;; R10k Loads and Stores.
+(define_insn_reservation "r10k_load" 2
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "load,prefetch,prefetchx"))
+ "r10k_loadstore")
+
+(define_insn_reservation "r10k_store" 0
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "store,fpstore,fpidxstore"))
+ "r10k_loadstore")
+
+(define_insn_reservation "r10k_fpload" 3
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "fpload,fpidxload"))
+ "r10k_loadstore")
+
+
+;; Integer add/sub + logic ops, and mt hi/lo can be done by alu1 or alu2.
+;; Miscellaneous arith goes here too (this is a guess).
+(define_insn_reservation "r10k_arith" 1
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "arith,mthilo,slt,clz,const,nop,trap,logical"))
+ "r10k_alu1 | r10k_alu2")
+
+;; We treat mfhilo differently, because we need to know when
+;; it's HI and when it's LO.
+(define_insn_reservation "r10k_mfhi" 1
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "mfhilo")
+ (not (match_operand 1 "lo_operand"))))
+ "r10k_alu1 | r10k_alu2")
+
+(define_insn_reservation "r10k_mflo" 1
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "mfhilo")
+ (match_operand 1 "lo_operand")))
+ "r10k_alu1 | r10k_alu2")
+
+
+;; ALU1 handles shifts, branch eval, and condmove.
+;;
+;; Brancher is separate, but part of ALU1, but can only
+;; do one branch per cycle (is this even implementable?).
+;;
+;; Unsure if the brancher handles jumps and calls as well, but since
+;; they're related, we'll add them here for now.
+(define_insn_reservation "r10k_brancher" 1
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "shift,branch,jump,call"))
+ "r10k_alu1")
+
+(define_insn_reservation "r10k_int_cmove" 1
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "condmove")
+ (eq_attr "mode" "SI,DI")))
+ "r10k_alu1")
+
+
+;; Coprocessor Moves.
+;; mtc1/dmtc1 are handled by ALU1.
+;; mfc1/dmfc1 are handled by the fp-multiplier.
+(define_insn_reservation "r10k_mt_xfer" 3
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "mtc"))
+ "r10k_alu1")
+
+(define_insn_reservation "r10k_mf_xfer" 2
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "mfc"))
+ "r10k_fpmpy")
+
+
+;; Only ALU2 does int multiplications and divisions.
+;;
+;; According to the Vr10000 series user manual,
+;; integer mult and div insns can be issued one
+;; cycle earlier if using register Lo. We model
+;; this by using the Lo value by default, as it
+;; is the more common value, and use a bypass
+;; for the Hi value when needed.
+;;
+;; Also of note, There are different latencies
+;; for MULT/DMULT (Lo 5/Hi 6) and MULTU/DMULTU (Lo 6/Hi 7).
+;; However, gcc does not have separate types
+;; for these insns. Thus to strike a balance,
+;; we use the Hi latency value for imul
+;; operations until the imul type can be split.
+(define_insn_reservation "r10k_imul_single" 6
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "imul,imul3")
+ (eq_attr "mode" "SI")))
+ "r10k_alu2 * 6")
+
+(define_insn_reservation "r10k_imul_double" 10
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "imul,imul3")
+ (eq_attr "mode" "DI")))
+ "r10k_alu2 * 10")
+
+;; Divides keep ALU2 busy.
+(define_insn_reservation "r10k_idiv_single" 34
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "SI")))
+ "r10k_alu2 * 35")
+
+(define_insn_reservation "r10k_idiv_double" 66
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "DI")))
+ "r10k_alu2 * 67")
+
+(define_bypass 35 "r10k_idiv_single" "r10k_mfhi")
+(define_bypass 67 "r10k_idiv_double" "r10k_mfhi")
+
+
+;; Floating point add/sub, mul, abs value, neg, comp, & moves.
+(define_insn_reservation "r10k_fp_miscadd" 2
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "fadd,fabs,fneg,fcmp"))
+ "r10k_fpadd")
+
+(define_insn_reservation "r10k_fp_miscmul" 2
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "fmul,fmove"))
+ "r10k_fpmpy")
+
+(define_insn_reservation "r10k_fp_cmove" 2
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "condmove")
+ (eq_attr "mode" "SF,DF")))
+ "r10k_fpmpy")
+
+
+;; The fcvt.s.[wl] insn has latency 4, repeat 2.
+;; All other fcvt insns have latency 2, repeat 1.
+(define_insn_reservation "r10k_fcvt_single" 4
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fcvt")
+ (eq_attr "cnv_mode" "I2S")))
+ "r10k_fpadd * 2")
+
+(define_insn_reservation "r10k_fcvt_other" 2
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fcvt")
+ (eq_attr "cnv_mode" "!I2S")))
+ "r10k_fpadd")
+
+
+;; Run the fmadd insn through fp-adder first, then fp-multiplier.
+;;
+;; The latency for fmadd is 2 cycles if the result is used
+;; by another fmadd instruction.
+(define_insn_reservation "r10k_fmadd" 4
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "fmadd"))
+ "r10k_fpadd, r10k_fpmpy")
+
+(define_bypass 2 "r10k_fmadd" "r10k_fmadd")
+
+
+;; Floating point Divisions & square roots.
+(define_insn_reservation "r10k_fdiv_single" 12
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fdiv,frdiv")
+ (eq_attr "mode" "SF")))
+ "r10k_fpdiv * 14")
+
+(define_insn_reservation "r10k_fdiv_double" 19
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fdiv,frdiv")
+ (eq_attr "mode" "DF")))
+ "r10k_fpdiv * 21")
+
+(define_insn_reservation "r10k_fsqrt_single" 18
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fsqrt")
+ (eq_attr "mode" "SF")))
+ "r10k_fpsqrt * 20")
+
+(define_insn_reservation "r10k_fsqrt_double" 33
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "fsqrt")
+ (eq_attr "mode" "DF")))
+ "r10k_fpsqrt * 35")
+
+(define_insn_reservation "r10k_frsqrt_single" 30
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "frsqrt")
+ (eq_attr "mode" "SF")))
+ "r10k_fpsqrt * 20")
+
+(define_insn_reservation "r10k_frsqrt_double" 52
+ (and (eq_attr "cpu" "r10000")
+ (and (eq_attr "type" "frsqrt")
+ (eq_attr "mode" "DF")))
+ "r10k_fpsqrt * 35")
+
+
+;; Handle unknown/multi insns here (this is a guess).
+(define_insn_reservation "r10k_unknown" 1
+ (and (eq_attr "cpu" "r10000")
+ (eq_attr "type" "unknown,multi"))
+ "r10k_alu1 + r10k_alu2")
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 20532ba3de2..597f1edd567 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -607,6 +607,10 @@ static const struct mips_cpu_info mips_cpu_info_table[] = {
/* MIPS IV processors. */
{ "r8000", PROCESSOR_R8000, 4, 0 },
+ { "r10000", PROCESSOR_R10000, 4, 0 },
+ { "r12000", PROCESSOR_R10000, 4, 0 },
+ { "r14000", PROCESSOR_R10000, 4, 0 },
+ { "r16000", PROCESSOR_R10000, 4, 0 },
{ "vr5000", PROCESSOR_R5000, 4, 0 },
{ "vr5400", PROCESSOR_R5400, 4, 0 },
{ "vr5500", PROCESSOR_R5500, 4, PTF_AVOID_BRANCHLIKELY },
@@ -1015,6 +1019,19 @@ static const struct mips_rtx_cost_data mips_rtx_cost_data[PROCESSOR_MAX] = {
1, /* branch_cost */
4 /* memory_latency */
},
+ { /* R1x000 */
+ COSTS_N_INSNS (2), /* fp_add */
+ COSTS_N_INSNS (2), /* fp_mult_sf */
+ COSTS_N_INSNS (2), /* fp_mult_df */
+ COSTS_N_INSNS (12), /* fp_div_sf */
+ COSTS_N_INSNS (19), /* fp_div_df */
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (9), /* int_mult_di */
+ COSTS_N_INSNS (34), /* int_div_si */
+ COSTS_N_INSNS (66), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
{ /* SB1 */
/* These costs are the same as the SB-1A below. */
COSTS_N_INSNS (4), /* fp_add */
@@ -10369,7 +10386,10 @@ mips_issue_rate (void)
but in reality only a maximum of 3 insns can be issued as
floating-point loads and stores also require a slot in the
AGEN pipe. */
- return 4;
+ case PROCESSOR_R10000:
+ /* All R10K Processors are quad-issue (being the first MIPS
+ processors to support this feature). */
+ return 4;
case PROCESSOR_20KC:
case PROCESSOR_R4130:
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index dc390dfe745..b0f39dc9a57 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -67,6 +67,7 @@ enum processor_type {
PROCESSOR_R7000,
PROCESSOR_R8000,
PROCESSOR_R9000,
+ PROCESSOR_R10000,
PROCESSOR_SB1,
PROCESSOR_SB1A,
PROCESSOR_SR71000,
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index f3fdaeaf45b..3f56feb2ee9 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -560,7 +560,7 @@
;; Attribute describing the processor. This attribute must match exactly
;; with the processor_type enumeration in mips.h.
(define_attr "cpu"
- "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson_2e,loongson_2f,m4k,octeon,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000,xlr"
+ "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson_2e,loongson_2f,m4k,octeon,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,r10000,sb1,sb1a,sr71000,xlr"
(const (symbol_ref "mips_tune")))
;; The type of hardware hazard associated with this instruction.
@@ -935,6 +935,7 @@
(include "6000.md")
(include "7000.md")
(include "9000.md")
+(include "10000.md")
(include "loongson2ef.md")
(include "octeon.md")
(include "sb1.md")
@@ -1366,35 +1367,21 @@
DONE;
})
-(define_insn "mulsi3_mul3"
- [(set (match_operand:SI 0 "register_operand" "=d,l")
- (mult:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "register_operand" "d,d")))
- (clobber (match_scratch:SI 3 "=l,X"))]
- "ISA_HAS_MUL3"
+(define_insn "mul<mode>3_mul3"
+ [(set (match_operand:GPR 0 "register_operand" "=d,l")
+ (mult:GPR (match_operand:GPR 1 "register_operand" "d,d")
+ (match_operand:GPR 2 "register_operand" "d,d")))
+ (clobber (match_scratch:GPR 3 "=l,X"))]
+ "ISA_HAS_<D>MUL3"
{
if (which_alternative == 1)
- return "mult\t%1,%2";
- if (TARGET_MIPS3900)
+ return "<d>mult\t%1,%2";
+ if (<MODE>mode == SImode && TARGET_MIPS3900)
return "mult\t%0,%1,%2";
- return "mul\t%0,%1,%2";
+ return "<d>mul\t%0,%1,%2";
}
[(set_attr "type" "imul3,imul")
- (set_attr "mode" "SI")])
-
-(define_insn "muldi3_mul3"
- [(set (match_operand:DI 0 "register_operand" "=d,l")
- (mult:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:DI 2 "register_operand" "d,d")))
- (clobber (match_scratch:DI 3 "=l,X"))]
- "ISA_HAS_DMUL3"
-{
- if (which_alternative == 1)
- return "dmult\t%1,%2";
- return "dmul\t%0,%1,%2";
-}
- [(set_attr "type" "imul3,imul")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "<MODE>")])
;; If a register gets allocated to LO, and we spill to memory, the reload
;; will include a move from LO to a GPR. Merge it into the multiplication
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index ed9b6c03683..f968b2f1467 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -3097,10 +3097,10 @@ altivec_resolve_overloaded_builtin (tree fndecl, tree arglist)
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (stmt, NULL, input_location);
+ stmt = build_indirect_ref (input_location, stmt, NULL);
return stmt;
}
@@ -3155,10 +3155,10 @@ altivec_resolve_overloaded_builtin (tree fndecl, tree arglist)
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (stmt, NULL, input_location);
+ stmt = build_indirect_ref (input_location, stmt, NULL);
stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
convert (TREE_TYPE (stmt), arg0));
stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index a9fb2ab237f..13e7becc526 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -77,6 +77,7 @@ extern int extract_ME (rtx);
extern void rs6000_output_function_entry (FILE *, const char *);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
+extern bool rs6000_output_addr_const_extra (FILE *, rtx);
extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
enum rtx_code);
extern void rs6000_emit_sCOND (enum rtx_code, rtx);
@@ -111,6 +112,7 @@ extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
extern bool rs6000_mode_dependent_address (rtx);
+extern rtx rs6000_find_base_term (rtx);
extern bool rs6000_offsettable_memref_p (rtx);
extern rtx rs6000_return_addr (int, rtx);
extern void rs6000_output_symbol_ref (FILE*, rtx);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d230dfd336b..9f48b611e6f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -765,7 +765,6 @@ static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int, int);
static unsigned rs6000_hash_constant (rtx);
static unsigned toc_hash_function (const void *);
static int toc_hash_eq (const void *, const void *);
-static int constant_pool_expr_1 (rtx, int *, int *);
static bool constant_pool_expr_p (rtx);
static bool legitimate_small_data_p (enum machine_mode, rtx);
static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
@@ -3505,58 +3504,28 @@ gpr_or_gpr_p (rtx op0, rtx op1)
/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
-static int
-constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF:
- if (RS6000_SYMBOL_REF_TLS_P (op))
- return 0;
- else if (CONSTANT_POOL_ADDRESS_P (op))
- {
- if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
- {
- *have_sym = 1;
- return 1;
- }
- else
- return 0;
- }
- else if (! strcmp (XSTR (op, 0), toc_label_name))
- {
- *have_toc = 1;
- return 1;
- }
- else
- return 0;
- case PLUS:
- case MINUS:
- return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
- && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
- case CONST:
- return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
- case CONST_INT:
- return 1;
- default:
- return 0;
- }
-}
-
static bool
constant_pool_expr_p (rtx op)
{
- int have_sym = 0;
- int have_toc = 0;
- return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
+ rtx base, offset;
+
+ split_const (op, &base, &offset);
+ return (GET_CODE (base) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (base)
+ && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
}
bool
toc_relative_expr_p (rtx op)
{
- int have_sym = 0;
- int have_toc = 0;
- return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+ rtx base, offset;
+
+ if (GET_CODE (op) != CONST)
+ return false;
+
+ split_const (op, &base, &offset);
+ return (GET_CODE (base) == UNSPEC
+ && XINT (base, 1) == UNSPEC_TOCREL);
}
bool
@@ -3566,7 +3535,7 @@ legitimate_constant_pool_address_p (rtx x)
&& GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
- && constant_pool_expr_p (XEXP (x, 1)));
+ && toc_relative_expr_p (XEXP (x, 1)));
}
static bool
@@ -4190,8 +4159,8 @@ rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
On Darwin, we use this to generate code for floating point constants.
A movsf_low is generated so we wind up with 2 instructions rather than 3.
- The Darwin code is inside #if TARGET_MACHO because only then is
- machopic_function_base_name() defined. */
+ The Darwin code is inside #if TARGET_MACHO because only then are the
+ machopic_* functions defined. */
rtx
rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
int opnum, int type,
@@ -4217,11 +4186,8 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& GET_CODE (XEXP (x, 0)) == PLUS
&& XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
&& XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
- && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
- && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
- && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
+ && machopic_operand_p (XEXP (x, 1)))
{
/* Result of previous invocation of this function on Darwin
floating point constant. */
@@ -4313,9 +4279,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
#if TARGET_MACHO
if (flag_pic)
{
- rtx offset = gen_rtx_CONST (Pmode,
- gen_rtx_MINUS (Pmode, x,
- machopic_function_base_sym ()));
+ rtx offset = machopic_gen_offset (x);
x = gen_rtx_LO_SUM (GET_MODE (x),
gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
gen_rtx_HIGH (Pmode, offset)), offset);
@@ -4491,6 +4455,27 @@ rs6000_mode_dependent_address (rtx addr)
return false;
}
+/* Implement FIND_BASE_TERM. */
+
+rtx
+rs6000_find_base_term (rtx op)
+{
+ rtx base, offset;
+
+ split_const (op, &base, &offset);
+ if (GET_CODE (base) == UNSPEC)
+ switch (XINT (base, 1))
+ {
+ case UNSPEC_TOCREL:
+ case UNSPEC_MACHOPIC_OFFSET:
+ /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
+ for aliasing purposes. */
+ return XVECEXP (base, 0, 0);
+ }
+
+ return op;
+}
+
/* More elaborate version of recog's offsettable_memref_p predicate
that works around the ??? note of rs6000_mode_dependent_address.
In particular it accepts
@@ -12572,45 +12557,45 @@ print_operand_address (FILE *file, rtx x)
#endif
else if (legitimate_constant_pool_address_p (x))
{
- if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
- {
- rtx contains_minus = XEXP (x, 1);
- rtx minus, symref;
- const char *name;
-
- /* Find the (minus (sym) (toc)) buried in X, and temporarily
- turn it into (sym) for output_addr_const. */
- while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
- contains_minus = XEXP (contains_minus, 0);
-
- minus = XEXP (contains_minus, 0);
- symref = XEXP (minus, 0);
- gcc_assert (GET_CODE (XEXP (minus, 1)) == SYMBOL_REF);
- XEXP (contains_minus, 0) = symref;
- if (TARGET_ELF)
- {
- char *newname;
-
- name = XSTR (symref, 0);
- newname = XALLOCAVEC (char, strlen (name) + sizeof ("@toc"));
- strcpy (newname, name);
- strcat (newname, "@toc");
- XSTR (symref, 0) = newname;
- }
- output_addr_const (file, XEXP (x, 1));
- if (TARGET_ELF)
- XSTR (symref, 0) = name;
- XEXP (contains_minus, 0) = minus;
- }
- else
- output_addr_const (file, XEXP (x, 1));
-
+ output_addr_const (file, XEXP (x, 1));
fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
}
else
gcc_unreachable ();
}
+/* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
+
+bool
+rs6000_output_addr_const_extra (FILE *file, rtx x)
+{
+ if (GET_CODE (x) == UNSPEC)
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_TOCREL:
+ x = XVECEXP (x, 0, 0);
+ gcc_assert (GET_CODE (x) == SYMBOL_REF);
+ output_addr_const (file, x);
+ if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
+ {
+ putc ('-', file);
+ assemble_name (file, toc_label_name);
+ }
+ else if (TARGET_ELF)
+ fputs ("@toc", file);
+ return true;
+
+#if TARGET_MACHO
+ case UNSPEC_MACHOPIC_OFFSET:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ putc ('-', file);
+ machopic_output_function_base_name (file);
+ return true;
+#endif
+ }
+ return false;
+}
+
/* Target hook for assembling integer objects. The PowerPC version has
to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
is defined. It also needs to handle DI-mode objects on 64-bit
@@ -15431,8 +15416,7 @@ create_TOC_reference (rtx symbol)
return gen_rtx_PLUS (Pmode,
gen_rtx_REG (Pmode, TOC_REGISTER),
gen_rtx_CONST (Pmode,
- gen_rtx_MINUS (Pmode, symbol,
- gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
+ gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
}
/* If _Unwind_* has been called from within the same module,
@@ -16707,7 +16691,7 @@ rs6000_emit_prologue (void)
&& flag_pic && crtl->uses_pic_offset_table)
{
rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
- rtx src = machopic_function_base_sym ();
+ rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
/* Save and restore LR locally around this call (in R0). */
if (!info->lr_save_p)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index e1023daa022..39fc0f6c9b6 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1856,6 +1856,8 @@ do { \
if (rs6000_mode_dependent_address (ADDR)) \
goto LABEL; \
} while (0)
+
+#define FIND_BASE_TERM rs6000_find_base_term
/* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is
@@ -2352,6 +2354,12 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
+ do \
+ if (!rs6000_output_addr_const_extra (STREAM, X)) \
+ goto FAIL; \
+ while (0)
+
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
/* #define MACHINE_no_sched_speculative */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 71a73ad4eb5..044b11765e9 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -99,6 +99,8 @@
(UNSPEC_DLMZB_CR 46)
(UNSPEC_DLMZB_STRLEN 47)
(UNSPEC_RSQRT 48)
+ (UNSPEC_TOCREL 49)
+ (UNSPEC_MACHOPIC_OFFSET 50)
])
;;
@@ -10593,12 +10595,12 @@
#if TARGET_MACHO
if (DEFAULT_ABI == ABI_DARWIN)
{
- const char *picbase = machopic_function_base_name ();
- rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (picbase));
+ rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
rtx tmplabrtx;
char tmplab[20];
+ crtl->uses_pic_offset_table = 1;
ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
CODE_LABEL_NUMBER (operands[0]));
tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index acb766f7124..bb4b6b21bed 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,37 @@
+2008-10-07 Steve Ellcey <sje@cup.hp.com>
+
+ * decl.c (start_cleanup_fn): Declare as inline.
+
+2008-10-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/37376, other mangling issues
+ * mangle.c (write_type): Update TYPE_PACK_EXPANSION mangling.
+ (write_member_name): Break out from...
+ (write_expression): ...here. Handle dependent COMPONENT_REF.
+ (write_template_arg): Wrap an argument pack in 'I'/'E'.
+ (write_builtin_type): Update char16/32_t mangling.
+ (write_nested_name, write_prefix): Don't forget template args
+ for typename types.
+ * operators.def: Add ARROW_EXPR, update COMPONENT_REF and
+ EXPR_PACK_EXPANSION.
+
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_x_indirect_ref): Add location argument.
+ (cp_build_binary_op): Pass location to warn_for_div_by_zero.
+ (cp_build_unary_op): Add location argument.
+ (cp_build_modify_expr): Same.
+ * class.c (build_base_path): Pass location to build_indirect_ref.
+ * semantics.c (handle_omp_for_class_iterator): Pass elocus to
+ build_modify_expr.
+
+2008-10-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37410
+ * cp-gimplify.c (cp_gimplify_expr): For each USING_STMT
+ make sure an IMPORTED_DECL node is added to the BLOCK_VARS list
+ of the innermost containing BLOCK.
+
2008-10-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/37719
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index ab8391b4a72..910dc291f8e 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -299,7 +299,7 @@ build_base_path (enum tree_code code,
{
expr = build_nop (build_pointer_type (target_type), expr);
if (!want_pointer)
- expr = build_indirect_ref (expr, NULL, EXPR_LOCATION (expr));
+ expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL);
return expr;
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 243b1c61bfb..a1542b9f804 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -508,6 +508,8 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
int saved_stmts_are_full_exprs_p = 0;
enum tree_code code = TREE_CODE (*expr_p);
enum gimplify_status ret;
+ tree block = NULL;
+ VEC(gimple, heap) *bind_expr_stack = NULL;
if (STATEMENT_CODE_P (code))
{
@@ -574,8 +576,37 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
break;
case USING_STMT:
- /* Just ignore for now. Eventually we will want to pass this on to
- the debugger. */
+ /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
+ BLOCK, and append an IMPORTED_DECL to its
+ BLOCK_VARS chained list. */
+
+ bind_expr_stack = gimple_bind_expr_stack ();
+ if (bind_expr_stack)
+ {
+ int i;
+ for (i = VEC_length (gimple, bind_expr_stack) - 1; i >= 0; i--)
+ if ((block = gimple_bind_block (VEC_index (gimple,
+ bind_expr_stack,
+ i))))
+ break;
+ }
+ if (block)
+ {
+ tree using_directive;
+ gcc_assert (TREE_OPERAND (*expr_p,0)
+ && NAMESPACE_DECL_CHECK (TREE_OPERAND (*expr_p, 0)));
+
+ using_directive = make_node (IMPORTED_DECL);
+ TREE_TYPE (using_directive) = void_type_node;
+
+ IMPORTED_DECL_ASSOCIATED_DECL (using_directive)
+ = TREE_OPERAND (*expr_p, 0);
+ DECL_NAME (using_directive)
+ = DECL_NAME (TREE_OPERAND (*expr_p, 0));
+ TREE_CHAIN (using_directive) = BLOCK_VARS (block);
+ BLOCK_VARS (block) = using_directive;
+ }
+ /* The USING_STMT won't appear in GIMPLE. */
*expr_p = NULL;
ret = GS_ALL_DONE;
break;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index be28e788600..b0b03a549e6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6006,6 +6006,7 @@ start_cleanup_fn (void)
actually needed. It is unlikely that it will be inlined, since
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (use_cxa_atexit)
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 7b4c30344cc..c0282d8ade5 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -887,6 +887,20 @@ write_nested_name (const tree decl)
write_template_prefix (decl);
write_template_args (TI_ARGS (template_info));
}
+ else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+ {
+ tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ write_template_prefix (decl);
+ write_template_args (TREE_OPERAND (name, 1));
+ }
+ else
+ {
+ write_prefix (CP_DECL_CONTEXT (decl));
+ write_unqualified_name (decl);
+ }
+ }
else
{
/* No, just use <prefix> */
@@ -953,6 +967,20 @@ write_prefix (const tree node)
write_template_prefix (decl);
write_template_args (TI_ARGS (template_info));
}
+ else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+ {
+ tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ write_template_prefix (decl);
+ write_template_args (TREE_OPERAND (name, 1));
+ }
+ else
+ {
+ write_prefix (CP_DECL_CONTEXT (decl));
+ write_unqualified_name (decl);
+ }
+ }
else
/* Not templated. */
{
@@ -982,6 +1010,9 @@ write_template_prefix (const tree node)
/* Find the template decl. */
if (decl_is_template_id (decl, &template_info))
templ = TI_TEMPLATE (template_info);
+ else if (TREE_CODE (type) == TYPENAME_TYPE)
+ /* For a typename type, all we have is the name. */
+ templ = DECL_NAME (decl);
else
{
gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));
@@ -1020,11 +1051,13 @@ write_template_prefix (const tree node)
return;
/* In G++ 3.2, the name of the template template parameter was used. */
- if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+ if (TREE_TYPE (templ)
+ && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
&& !abi_version_at_least (2))
G.need_abi_warning = true;
- if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+ if (TREE_TYPE (templ)
+ && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
&& abi_version_at_least (2))
write_template_param (TREE_TYPE (templ));
else
@@ -1636,7 +1669,7 @@ write_type (tree type)
break;
case TYPE_PACK_EXPANSION:
- write_string ("U10__variadic");
+ write_string ("Dp");
write_type (PACK_EXPANSION_PATTERN (type));
break;
@@ -1750,9 +1783,9 @@ write_builtin_type (tree type)
if (type == wchar_type_node)
write_char ('w');
else if (type == char16_type_node)
- write_string ("u8char16_t");
+ write_string ("Ds");
else if (type == char32_type_node)
- write_string ("u8char32_t");
+ write_string ("Di");
else if (TYPE_FOR_JAVA (type))
write_java_integer_type_codes (type);
else
@@ -2009,6 +2042,35 @@ write_template_args (tree args)
write_char ('E');
}
+/* Write out the
+ <unqualified-name>
+ <unqualified-name> <template-args>
+ part of SCOPE_REF or COMPONENT_REF mangling. */
+
+static void
+write_member_name (tree member)
+{
+ if (TREE_CODE (member) == IDENTIFIER_NODE)
+ write_source_name (member);
+ else if (DECL_P (member))
+ {
+ /* G++ 3.2 incorrectly put out both the "sr" code and
+ the nested name of the qualified name. */
+ G.need_abi_warning = 1;
+ write_unqualified_name (member);
+ }
+ else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
+ {
+ tree name = TREE_OPERAND (member, 0);
+ if (TREE_CODE (name) == OVERLOAD)
+ name = OVL_FUNCTION (name);
+ write_member_name (name);
+ write_template_args (TREE_OPERAND (member, 1));
+ }
+ else
+ write_expression (member);
+}
+
/* <expression> ::= <unary operator-name> <expression>
::= <binary operator-name> <expression> <expression>
::= <expr-primary>
@@ -2161,6 +2223,20 @@ write_expression (tree expr)
write_template_args (template_args);
}
}
+ else if (code == COMPONENT_REF)
+ {
+ tree ob = TREE_OPERAND (expr, 0);
+
+ if (TREE_CODE (ob) == ARROW_EXPR)
+ {
+ code = ARROW_EXPR;
+ ob = TREE_OPERAND (ob, 0);
+ }
+
+ write_string (operator_name_info[(int)code].mangled_name);
+ write_expression (ob);
+ write_member_name (TREE_OPERAND (expr, 1));
+ }
else
{
int i;
@@ -2198,8 +2274,12 @@ write_expression (tree expr)
case CAST_EXPR:
write_type (TREE_TYPE (expr));
if (!TREE_OPERAND (expr, 0))
- /* "T()" is mangled as "T(void)". */
+ /* "T()" is mangled as "T(void)". */
write_char ('v');
+ else if (list_length (TREE_OPERAND (expr, 0)) > 1)
+ /* FIXME the above hack for T() needs to be replaced with
+ something more general. */
+ sorry ("mangling function-style cast with more than one argument");
else
write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
break;
@@ -2213,27 +2293,7 @@ write_expression (tree expr)
/* Handle pointers-to-members specially. */
case SCOPE_REF:
write_type (TREE_OPERAND (expr, 0));
- if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
- write_source_name (TREE_OPERAND (expr, 1));
- else if (TREE_CODE (TREE_OPERAND (expr, 1)) == TEMPLATE_ID_EXPR)
- {
- tree template_id;
- tree name;
-
- template_id = TREE_OPERAND (expr, 1);
- name = TREE_OPERAND (template_id, 0);
- /* FIXME: What about operators? */
- gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
- write_source_name (TREE_OPERAND (template_id, 0));
- write_template_args (TREE_OPERAND (template_id, 1));
- }
- else
- {
- /* G++ 3.2 incorrectly put out both the "sr" code and
- the nested name of the qualified name. */
- G.need_abi_warning = 1;
- write_encoding (TREE_OPERAND (expr, 1));
- }
+ write_member_name (TREE_OPERAND (expr, 1));
break;
default:
@@ -2338,8 +2398,10 @@ write_template_arg (tree node)
/* Expand the template argument pack. */
tree args = ARGUMENT_PACK_ARGS (node);
int i, length = TREE_VEC_LENGTH (args);
+ write_char ('I');
for (i = 0; i < length; ++i)
write_template_arg (TREE_VEC_ELT (args, i));
+ write_char ('E');
}
else if (TYPE_P (node))
write_type (node);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index a04d7312216..0da373ce2a6 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3484,7 +3484,6 @@ do_using_directive (tree name_space)
if (!toplevel_bindings_p ())
{
push_using_directive (name_space);
- context = current_scope ();
}
else
{
@@ -3492,12 +3491,12 @@ do_using_directive (tree name_space)
add_using_namespace (current_namespace, name_space, 0);
if (current_namespace != global_namespace)
context = current_namespace;
- }
- /* Emit debugging info. */
- if (!processing_template_decl)
- (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
- context, false);
+ /* Emit debugging info. */
+ if (!processing_template_decl)
+ (*debug_hooks->imported_module_or_decl) (name_space, NULL_TREE,
+ context, false);
+ }
}
/* Deal with a using-directive seen by the parser. Currently we only
diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def
index 9c2dd8b2ca1..20c74d88220 100644
--- a/gcc/cp/operators.def
+++ b/gcc/cp/operators.def
@@ -125,7 +125,8 @@ DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", 2)
DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", 2)
DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", 2)
DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", 2)
-DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2)
+DEF_SIMPLE_OPERATOR ("->", ARROW_EXPR, "pt", 2)
+DEF_SIMPLE_OPERATOR (".", COMPONENT_REF, "dt", 2)
DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2)
DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2)
DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2)
@@ -152,4 +153,4 @@ DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3)
DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", -1)
/* Variadic templates extension. */
-DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "pu", 1)
+DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 13e9a0f56ab..b1bbb38dfa8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4109,7 +4109,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
cond = cp_build_binary_op (elocus,
TREE_CODE (cond), decl, diff,
tf_warning_or_error);
- incr = build_modify_expr (decl, PLUS_EXPR, incr);
+ incr = build_modify_expr (elocus, decl, PLUS_EXPR, incr);
orig_body = *body;
*body = push_stmt_list ();
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 75bcf9c6913..b115e2871d8 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2405,8 +2405,8 @@ build_x_indirect_ref (tree expr, const char *errorstring,
/* Helper function called from c-common. */
tree
-build_indirect_ref (tree ptr, const char *errorstring,
- location_t loc __attribute__ ((__unused__)))
+build_indirect_ref (location_t loc __attribute__ ((__unused__)),
+ tree ptr, const char *errorstring)
{
return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
}
@@ -3349,7 +3349,7 @@ cp_build_binary_op (location_t location,
{
enum tree_code tcode0 = code0, tcode1 = code1;
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
@@ -3385,7 +3385,7 @@ cp_build_binary_op (location_t location,
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
@@ -4642,7 +4642,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
/* Hook for the c-common bits that build a unary op. */
tree
-build_unary_op (enum tree_code code, tree xarg, int noconvert)
+build_unary_op (location_t location ATTRIBUTE_UNUSED,
+ enum tree_code code, tree xarg, int noconvert)
{
return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
}
@@ -5757,7 +5758,8 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
/* For use from the C common bits. */
tree
-build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
+build_modify_expr (location_t location ATTRIBUTE_UNUSED,
+ tree lhs, enum tree_code modifycode, tree rhs)
{
return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
}
@@ -5940,7 +5942,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
|| MAYBE_CLASS_TYPE_P (lhstype)));
lhs = stabilize_reference (lhs);
- newrhs = cp_build_binary_op (EXPR_LOCATION (lhs),
+ newrhs = cp_build_binary_op (input_location,
modifycode, lhs, rhs,
complain);
if (newrhs == error_mark_node)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6d9ebf167b6..b1b8d72bc9b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -12236,6 +12236,7 @@ The processor names are:
@samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
@samp{r4600}, @samp{r4650}, @samp{r6000}, @samp{r8000},
@samp{rm7000}, @samp{rm9000},
+@samp{r10000}, @samp{r12000}, @samp{r14000}, @samp{r16000},
@samp{sb1},
@samp{sr71000},
@samp{vr4100}, @samp{vr4111}, @samp{vr4120}, @samp{vr4130}, @samp{vr4300},
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 148e19ddc9a..a12de2152bb 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2930,9 +2930,11 @@ constituent instructions might not.
When a @code{clobber} expression for a register appears inside a
@code{parallel} with other side effects, the register allocator
guarantees that the register is unoccupied both before and after that
-insn. However, the reload phase may allocate a register used for one of
-the inputs unless the @samp{&} constraint is specified for the selected
-alternative (@pxref{Modifiers}). You can clobber either a specific hard
+insn if it is a hard register clobber or the @samp{&} constraint
+is specified for at least one alternative (@pxref{Modifiers}) of the
+clobber. However, the reload phase may allocate a register used for
+one of the inputs unless the @samp{&} constraint is specified for the
+selected alternative. You can clobber either a specific hard
register, a pseudo register, or a @code{scratch} expression; in the
latter two cases, GCC will allocate a hard register that is available
there for use as a temporary.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e39e687edbb..ed4d74d0e51 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4489,6 +4489,8 @@ static bool dwarf2out_ignore_block (const_tree);
static void dwarf2out_global_decl (tree);
static void dwarf2out_type_decl (tree, int);
static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool);
+static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
+ dw_die_ref);
static void dwarf2out_abstract_function (tree);
static void dwarf2out_var_location (rtx);
static void dwarf2out_begin_function (tree);
@@ -4746,6 +4748,10 @@ static GTY((param_is (struct dwarf_file_data))) htab_t file_table;
The key is a DECL_UID() which is a unique number identifying each decl. */
static GTY ((param_is (struct die_struct))) htab_t decl_die_table;
+/* A hash table of references to DIE's that describe COMMON blocks.
+ The key is DECL_UID() ^ die_parent. */
+static GTY ((param_is (struct die_struct))) htab_t common_block_die_table;
+
/* Node of the variable location list. */
struct var_loc_node GTY ((chain_next ("%h.next")))
{
@@ -4958,6 +4964,8 @@ static void equate_type_number_to_die (tree, dw_die_ref);
static hashval_t decl_die_table_hash (const void *);
static int decl_die_table_eq (const void *, const void *);
static dw_die_ref lookup_decl_die (tree);
+static hashval_t common_block_die_table_hash (const void *);
+static int common_block_die_table_eq (const void *, const void *);
static hashval_t decl_loc_table_hash (const void *);
static int decl_loc_table_eq (const void *, const void *);
static var_loc_list *lookup_decl_loc (const_tree);
@@ -13810,6 +13818,26 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
}
+/* Returns a hash value for X (which really is a die_struct). */
+
+static hashval_t
+common_block_die_table_hash (const void *x)
+{
+ const_dw_die_ref d = (const_dw_die_ref) x;
+ return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent);
+}
+
+/* Return nonzero if decl_id and die_parent of die_struct X is the same
+ as decl_id and die_parent of die_struct Y. */
+
+static int
+common_block_die_table_eq (const void *x, const void *y)
+{
+ const_dw_die_ref d = (const_dw_die_ref) x;
+ const_dw_die_ref e = (const_dw_die_ref) y;
+ return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
+}
+
/* Generate a DIE to represent a declared data object. */
static void
@@ -13851,6 +13879,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
tree field;
dw_die_ref com_die;
dw_loc_descr_ref loc;
+ die_node com_die_arg;
var_die = lookup_decl_die (decl);
if (var_die)
@@ -13861,21 +13890,41 @@ gen_variable_die (tree decl, dw_die_ref context_die)
if (loc)
{
if (off)
- add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
+ {
+ /* Optimize the common case. */
+ if (loc->dw_loc_opc == DW_OP_addr
+ && loc->dw_loc_next == NULL
+ && GET_CODE (loc->dw_loc_oprnd1.v.val_addr)
+ == SYMBOL_REF)
+ loc->dw_loc_oprnd1.v.val_addr
+ = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
+ else
+ add_loc_descr (&loc,
+ new_loc_descr (DW_OP_plus_uconst,
off, 0));
+ }
add_AT_loc (var_die, DW_AT_location, loc);
remove_AT (var_die, DW_AT_declaration);
}
}
return;
}
+
+ if (common_block_die_table == NULL)
+ common_block_die_table
+ = htab_create_ggc (10, common_block_die_table_hash,
+ common_block_die_table_eq, NULL);
+
field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
- com_die = lookup_decl_die (com_decl);
+ com_die_arg.decl_id = DECL_UID (com_decl);
+ com_die_arg.die_parent = context_die;
+ com_die = (dw_die_ref) htab_find (common_block_die_table, &com_die_arg);
loc = loc_descriptor_from_tree (com_decl);
if (com_die == NULL)
{
const char *cnam
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
+ void **slot;
com_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (com_die, com_decl);
@@ -13889,7 +13938,9 @@ gen_variable_die (tree decl, dw_die_ref context_die)
else if (DECL_EXTERNAL (decl))
add_AT_flag (com_die, DW_AT_declaration, 1);
add_pubname_string (cnam, com_die); /* ??? needed? */
- equate_decl_number_to_die (com_decl, com_die);
+ com_die->decl_id = DECL_UID (com_decl);
+ slot = htab_find_slot (common_block_die_table, com_die, INSERT);
+ *slot = (void *) com_die;
}
else if (get_AT (com_die, DW_AT_location) == NULL && loc)
{
@@ -13905,7 +13956,17 @@ gen_variable_die (tree decl, dw_die_ref context_die)
if (loc)
{
if (off)
- add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, off, 0));
+ {
+ /* Optimize the common case. */
+ if (loc->dw_loc_opc == DW_OP_addr
+ && loc->dw_loc_next == NULL
+ && GET_CODE (loc->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF)
+ loc->dw_loc_oprnd1.v.val_addr
+ = plus_constant (loc->dw_loc_oprnd1.v.val_addr, off);
+ else
+ add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
+ off, 0));
+ }
add_AT_loc (var_die, DW_AT_location, loc);
}
else if (DECL_EXTERNAL (decl))
@@ -14918,6 +14979,9 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
&& !(is_fortran () && TREE_PUBLIC (decl)))
;
+ else if (TREE_CODE (decl) == IMPORTED_DECL)
+ dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
+ stmt, context_die);
else
gen_decl_die (decl, context_die);
}
@@ -15309,6 +15373,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
break;
case NAMESPACE_DECL:
+ case IMPORTED_DECL:
gen_namespace_die (decl);
break;
@@ -15343,44 +15408,20 @@ dwarf2out_type_decl (tree decl, int local)
}
/* Output debug information for imported module or decl DECL.
- NAME is non-NULL name in context if the decl has been renamed.
- CHILD is true if decl is one of the renamed decls as part of
- importing whole module. */
-
+ NAME is non-NULL name in the lexical block if the decl has been renamed.
+ LEXICAL_BLOCK is the lexical block (which TREE_CODE is a BLOCK)
+ that DECL belongs to.
+ LEXICAL_BLOCK_DIE is the DIE of LEXICAL_BLOCK. */
static void
-dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
- bool child)
+dwarf2out_imported_module_or_decl_1 (tree decl,
+ tree name,
+ tree lexical_block,
+ dw_die_ref lexical_block_die)
{
- dw_die_ref imported_die, at_import_die;
- dw_die_ref scope_die;
expanded_location xloc;
+ dw_die_ref imported_die = NULL;
+ dw_die_ref at_import_die;
- if (debug_info_level <= DINFO_LEVEL_TERSE)
- return;
-
- gcc_assert (decl);
-
- /* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
- We need decl DIE for reference and scope die. First, get DIE for the decl
- itself. */
-
- /* Get the scope die for decl context. Use comp_unit_die for global module
- or decl. If die is not found for non globals, force new die. */
- if (context
- && TYPE_P (context)
- && !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
- return;
- scope_die = get_context_die (context);
-
- if (child)
- {
- gcc_assert (scope_die->die_child);
- gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module);
- gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL);
- scope_die = scope_die->die_child;
- }
-
- /* For TYPE_DECL or CONST_DECL, lookup TREE_TYPE. */
if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
{
if (is_base_type (TREE_TYPE (decl)))
@@ -15398,6 +15439,19 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
gcc_assert (at_import_die);
}
}
+ else if (TREE_CODE (decl) == IMPORTED_DECL)
+ {
+ tree imported_ns_decl;
+ /* IMPORTED_DECL nodes that are not imported namespace are just not
+ supported yet. */
+ gcc_assert (DECL_INITIAL (decl)
+ && TREE_CODE (DECL_INITIAL (decl)) == NAMESPACE_DECL);
+ imported_ns_decl = DECL_INITIAL (decl);
+ at_import_die = lookup_decl_die (imported_ns_decl);
+ if (!at_import_die)
+ at_import_die = force_decl_die (imported_ns_decl);
+ gcc_assert (at_import_die);
+ }
else
{
at_import_die = lookup_decl_die (decl);
@@ -15421,20 +15475,66 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
}
}
- /* OK, now we have DIEs for decl as well as scope. Emit imported die. */
if (TREE_CODE (decl) == NAMESPACE_DECL)
- imported_die = new_die (DW_TAG_imported_module, scope_die, context);
+ imported_die = new_die (DW_TAG_imported_module,
+ lexical_block_die,
+ lexical_block);
else
- imported_die = new_die (DW_TAG_imported_declaration, scope_die, context);
+ imported_die = new_die (DW_TAG_imported_declaration,
+ lexical_block_die,
+ lexical_block);
xloc = expand_location (input_location);
add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file));
add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line);
if (name)
- add_AT_string (imported_die, DW_AT_name, IDENTIFIER_POINTER (name));
+ add_AT_string (imported_die, DW_AT_name,
+ IDENTIFIER_POINTER (name));
add_AT_die_ref (imported_die, DW_AT_import, at_import_die);
}
+/* Output debug information for imported module or decl DECL.
+ NAME is non-NULL name in context if the decl has been renamed.
+ CHILD is true if decl is one of the renamed decls as part of
+ importing whole module. */
+
+static void
+dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
+ bool child)
+{
+ /* dw_die_ref at_import_die; */
+ dw_die_ref scope_die;
+
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+
+ gcc_assert (decl);
+
+ /* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
+ We need decl DIE for reference and scope die. First, get DIE for the decl
+ itself. */
+
+ /* Get the scope die for decl context. Use comp_unit_die for global module
+ or decl. If die is not found for non globals, force new die. */
+ if (context
+ && TYPE_P (context)
+ && !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
+ return;
+ scope_die = get_context_die (context);
+
+ if (child)
+ {
+ gcc_assert (scope_die->die_child);
+ gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module);
+ gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL);
+ scope_die = scope_die->die_child;
+ }
+
+ /* OK, now we have DIEs for decl as well as scope. Emit imported die. */
+ dwarf2out_imported_module_or_decl_1 (decl, name, context, scope_die);
+
+}
+
/* Write the debugging output for DECL. */
void
@@ -15519,6 +15619,7 @@ dwarf2out_decl (tree decl)
break;
case NAMESPACE_DECL:
+ case IMPORTED_DECL:
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
if (lookup_decl_die (decl) != NULL)
diff --git a/gcc/expmed.c b/gcc/expmed.c
index ae5ad0a2f12..5e8d7f30324 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -3075,7 +3075,8 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
{
/* If we are multiplying in DImode, it may still be a win
to try to work with shifts and adds. */
- if (CONST_DOUBLE_HIGH (op1) == 0)
+ if (CONST_DOUBLE_HIGH (op1) == 0
+ && CONST_DOUBLE_LOW (op1) > 0)
coeff = CONST_DOUBLE_LOW (op1);
else if (CONST_DOUBLE_LOW (op1) == 0
&& EXACT_POWER_OF_2_OR_ZERO_P (CONST_DOUBLE_HIGH (op1)))
diff --git a/gcc/expr.c b/gcc/expr.c
index 32c8d01fe7f..277a6e1a33a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5021,6 +5021,9 @@ count_type_elements (const_tree type, bool allow_flexarr)
case REFERENCE_TYPE:
return 1;
+ case ERROR_MARK:
+ return 0;
+
case VOID_TYPE:
case METHOD_TYPE:
case FUNCTION_TYPE:
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 53f3f0c1526..b0ef1cef8be 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ * f95-lang.c (poplevel): Don't clear BLOCK_VARS if functionbody.
+ * trans-decl.c (gfc_build_qualified_array): Build accurate debug type
+ even if nest.
+ (build_entry_thunks, gfc_generate_function_code,
+ gfc_generate_constructors): Ensure DECL_SAVED_TREE is a BIND_EXPR
+ with DECL_INITIAL as its BLOCK.
+
2008-10-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35680
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index cf0dc2d48b7..a7d6c8f66a5 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -430,14 +430,8 @@ poplevel (int keep, int reverse, int functionbody)
current_binding_level = current_binding_level->level_chain;
if (functionbody)
- {
- /* This is the top level block of a function. The ..._DECL chain stored
- in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
- leave them in the BLOCK because they are found in the FUNCTION_DECL
- instead. */
- DECL_INITIAL (current_function_decl) = block_node;
- BLOCK_VARS (block_node) = 0;
- }
+ /* This is the top level block of a function. */
+ DECL_INITIAL (current_function_decl) = block_node;
else if (current_binding_level == global_binding_level)
/* When using gfc_start_block/gfc_finish_block from middle-end hooks,
don't add newly created BLOCKs as subblocks of global_binding_level. */
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 20253e668ca..1b47f2673e6 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -704,7 +704,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
layout_type (type);
}
- if (nest || write_symbols == NO_DEBUG)
+ if (write_symbols == NO_DEBUG)
return;
if (TYPE_NAME (type) != NULL_TREE
@@ -1761,7 +1761,7 @@ build_entry_thunks (gfc_namespace * ns)
thunk_fndecl = thunk_sym->backend_decl;
- gfc_start_block (&body);
+ gfc_init_block (&body);
/* Pass extra parameter identifying this entry point. */
tmp = build_int_cst (gfc_array_index_type, el->id);
@@ -1869,8 +1869,12 @@ build_entry_thunks (gfc_namespace * ns)
/* Finish off this function and send it for code generation. */
DECL_SAVED_TREE (thunk_fndecl) = gfc_finish_block (&body);
+ tmp = getdecls ();
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (thunk_fndecl)) = thunk_fndecl;
+ DECL_SAVED_TREE (thunk_fndecl)
+ = build3_v (BIND_EXPR, tmp, DECL_SAVED_TREE (thunk_fndecl),
+ DECL_INITIAL (thunk_fndecl));
/* Output the GENERIC tree. */
dump_function (TDI_original, thunk_fndecl);
@@ -3652,7 +3656,7 @@ gfc_generate_function_code (gfc_namespace * ns)
trans_function_start (sym);
- gfc_start_block (&block);
+ gfc_init_block (&block);
if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER)
{
@@ -3886,11 +3890,16 @@ gfc_generate_function_code (gfc_namespace * ns)
saved_function_decls = NULL_TREE;
DECL_SAVED_TREE (fndecl) = gfc_finish_block (&block);
+ decl = getdecls ();
/* Finish off this function and send it for code generation. */
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ DECL_SAVED_TREE (fndecl)
+ = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
+ DECL_INITIAL (fndecl));
+
/* Output the GENERIC tree. */
dump_function (TDI_original, fndecl);
@@ -3969,9 +3978,13 @@ gfc_generate_constructors (void)
DECL_SAVED_TREE (fndecl) = build_stmt (EXPR_STMT, tmp);
}
+ decl = getdecls ();
poplevel (1, 0, 1);
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ DECL_SAVED_TREE (fndecl)
+ = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
+ DECL_INITIAL (fndecl));
free_after_parsing (cfun);
free_after_compilation (cfun);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2befb43ecff..c6a79fbe8b7 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2238,10 +2238,11 @@ maybe_with_size_expr (tree *expr_p)
/* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
- Store any side-effects in PRE_P. */
+ Store any side-effects in PRE_P. CALL_LOCATION is the location of
+ the CALL_EXPR. */
static enum gimplify_status
-gimplify_arg (tree *arg_p, gimple_seq *pre_p)
+gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
{
bool (*test) (tree);
fallback_t fb;
@@ -2259,6 +2260,10 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p)
/* If this is a variable sized type, we must remember the size. */
maybe_with_size_expr (arg_p);
+ /* Make sure arguments have the same location as the function call
+ itself. */
+ protected_set_expr_location (*arg_p, call_location);
+
/* There is a sequence point before a function call. Side effects in
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
@@ -2448,7 +2453,8 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
be the plain PARM_DECL. */
if ((i != 1) || !builtin_va_start_p)
{
- t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p);
+ t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
+ EXPR_LOCATION (*expr_p));
if (t == GS_ERROR)
ret = GS_ERROR;
@@ -3095,10 +3101,10 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
from = TREE_OPERAND (*expr_p, 1);
from_ptr = build_fold_addr_expr (from);
- gimplify_arg (&from_ptr, seq_p);
+ gimplify_arg (&from_ptr, seq_p, EXPR_LOCATION (*expr_p));
to_ptr = build_fold_addr_expr (to);
- gimplify_arg (&to_ptr, seq_p);
+ gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
@@ -3145,7 +3151,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
to = TREE_OPERAND (*expr_p, 0);
to_ptr = build_fold_addr_expr (to);
- gimplify_arg (&to_ptr, seq_p);
+ gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
t = implicit_built_in_decls[BUILT_IN_MEMSET];
gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 609708e9069..c1b2bdd6548 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -209,20 +209,15 @@ clear_allocno_live (ira_allocno_t a)
sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
}
-/* Mark the register referenced by use or def REF as live
- Store a 1 in hard_regs_live or allocnos_live for this register or
- the corresponding allocno, record how many consecutive hardware
- registers it actually needs. */
-
+/* Mark the register REG as live. Store a 1 in hard_regs_live or
+ allocnos_live for this register or the corresponding allocno,
+ record how many consecutive hardware registers it actually
+ needs. */
static void
-mark_ref_live (struct df_ref *ref)
+mark_reg_live (rtx reg)
{
- rtx reg;
int regno;
- reg = DF_REF_REG (ref);
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
gcc_assert (REG_P (reg));
regno = REGNO (reg);
@@ -269,32 +264,25 @@ mark_ref_live (struct df_ref *ref)
}
}
-/* Return true if the definition described by DEF conflicts with the
- instruction's inputs. */
-static bool
-def_conflicts_with_inputs_p (struct df_ref *def)
+/* Mark the register referenced by use or def REF as live. */
+static void
+mark_ref_live (struct df_ref *ref)
{
- /* Conservatively assume that the condition is true for all clobbers. */
- return DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER);
+ rtx reg;
+
+ reg = DF_REF_REG (ref);
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ mark_reg_live (reg);
}
-/* Mark the register referenced by definition DEF as dead, if the
- definition is a total one. Store a 0 in hard_regs_live or
+/* Mark the register REG as dead. Store a 0 in hard_regs_live or
allocnos_live for the register. */
static void
-mark_ref_dead (struct df_ref *def)
+mark_reg_dead (rtx reg)
{
- unsigned int i;
- rtx reg;
int regno;
- if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL)
- || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))
- return;
-
- reg = DF_REF_REG (def);
- if (GET_CODE (reg) == SUBREG)
- reg = SUBREG_REG (reg);
gcc_assert (REG_P (reg));
regno = REGNO (reg);
@@ -312,6 +300,7 @@ mark_ref_dead (struct df_ref *def)
}
else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
{
+ unsigned int i;
int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
enum reg_class cover_class;
@@ -343,6 +332,80 @@ mark_ref_dead (struct df_ref *def)
}
}
+/* Mark the register referenced by definition DEF as dead, if the
+ definition is a total one. */
+static void
+mark_ref_dead (struct df_ref *def)
+{
+ rtx reg;
+
+ if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL)
+ || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))
+ return;
+
+ reg = DF_REF_REG (def);
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ mark_reg_dead (reg);
+}
+
+/* Mark early clobber registers of the current INSN as live (if
+ LIVE_P) or dead. Return true if there are such registers. */
+static bool
+mark_early_clobbers (rtx insn, bool live_p)
+{
+ int alt;
+ int def;
+ struct df_ref **def_rec;
+ bool set_p = false;
+
+ for (def = 0; def < recog_data.n_operands; def++)
+ {
+ rtx dreg = recog_data.operand[def];
+
+ if (GET_CODE (dreg) == SUBREG)
+ dreg = SUBREG_REG (dreg);
+ if (! REG_P (dreg))
+ continue;
+
+ for (alt = 0; alt < recog_data.n_alternatives; alt++)
+ if ((recog_op_alt[def][alt].earlyclobber)
+ && (recog_op_alt[def][alt].cl != NO_REGS))
+ break;
+
+ if (alt >= recog_data.n_alternatives)
+ continue;
+
+ if (live_p)
+ mark_reg_live (dreg);
+ else
+ mark_reg_dead (dreg);
+ set_p = true;
+ }
+
+ for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+ if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER))
+ {
+ rtx dreg = DF_REF_REG (*def_rec);
+
+ if (GET_CODE (dreg) == SUBREG)
+ dreg = SUBREG_REG (dreg);
+ if (! REG_P (dreg) || REGNO (dreg) >= FIRST_PSEUDO_REGISTER)
+ continue;
+
+ /* Hard register clobbers are believed to be early clobber
+ because there is no way to say that non-operand hard
+ register clobbers are not early ones. */
+ if (live_p)
+ mark_ref_live (*def_rec);
+ else
+ mark_ref_dead (*def_rec);
+ set_p = true;
+ }
+
+ return set_p;
+}
+
/* Checks that CONSTRAINTS permits to use only one hard register. If
it is so, the function returns the class of the hard register.
Otherwise it returns NO_REGS. */
@@ -580,6 +643,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
bitmap_iterator bi;
bitmap reg_live_out;
unsigned int px;
+ bool set_p;
bb = loop_tree_node->bb;
if (bb != NULL)
@@ -698,6 +762,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
}
extract_insn (insn);
+ preprocess_constraints ();
process_single_reg_class_operands (false, freq);
/* See which defined values die here. */
@@ -733,19 +798,20 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
mark_ref_live (*use_rec);
- /* If any defined values conflict with the inputs, mark those
- defined values as live. */
- for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (def_conflicts_with_inputs_p (*def_rec))
- mark_ref_live (*def_rec);
+ set_p = mark_early_clobbers (insn, true);
process_single_reg_class_operands (true, freq);
- /* See which of the defined values we marked as live are dead
- before the instruction. */
- for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (def_conflicts_with_inputs_p (*def_rec))
- mark_ref_dead (*def_rec);
+ if (set_p)
+ {
+ mark_early_clobbers (insn, false);
+
+ /* Mark each used value as live again. For example, a
+ hard register can be in clobber and in an insn
+ input. */
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ mark_ref_live (*use_rec);
+ }
curr_point++;
}
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index fb9b664d2b8..f980814c07b 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,29 @@
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * objc-act.c (objc_build_string_object): Pass location to
+ build_unary_op.
+ (init_def_list): Same.
+ (init_objc_symtab): Same.
+ (init_module_descriptor): Same.
+ (build_module_initializer_routine): Same.
+ (generate_static_references): Same.
+ (build_typed_selector_reference): Same.
+ (add_objc_string): Same.
+ (objc_substitute_decl): Same.
+ (objc_build_ivar_assignment): Same.
+ (objc_build_global_assignment): Same.
+ (objc_build_strong_cast_assignment): Same.
+ (generate_protocols): Same.
+ (build_protocol_initializer): Same.
+ (build_dispatch_table_initializer): Same.
+ (generate_protocol_list): Same.
+ (build_category_initializer): Same.
+ (build_shared_structure_initializer): Same.
+ (generate_shared_structures): Same.
+ (objc_build_protocol_expr): Same.
+ (build_ivar_reference): Same.
+ (get_super_receiver): Same.
+
2008-09-23 Aldy Hernandez <aldyh@redhat.com>
* objc-act.c (next_sjlj_build_enter_and_setjmp): Call
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 9ea40eafbec..c23fb9ecba2 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -1940,10 +1940,12 @@ objc_build_string_object (tree string)
initlist
= build_tree_list (fields,
flag_next_runtime
- ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
+ ? build_unary_op (input_location,
+ ADDR_EXPR, string_class_decl, 0)
: build_int_cst (NULL_TREE, 0));
fields = TREE_CHAIN (fields);
- initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
+ initlist = tree_cons (fields, build_unary_op (input_location,
+ ADDR_EXPR, string, 1),
initlist);
fields = TREE_CHAIN (fields);
initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
@@ -1966,7 +1968,8 @@ objc_build_string_object (tree string)
}
addr = convert (build_pointer_type (constant_string_type),
- build_unary_op (ADDR_EXPR, desc->constructor, 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, desc->constructor, 1));
return addr;
}
@@ -2104,7 +2107,8 @@ init_def_list (tree type)
{
if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
@@ -2114,7 +2118,8 @@ init_def_list (tree type)
{
if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
@@ -2125,7 +2130,8 @@ init_def_list (tree type)
tree expr;
if (static_instances_decl)
- expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, static_instances_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
@@ -2155,7 +2161,7 @@ init_objc_symtab (tree type)
initlist
= tree_cons (NULL_TREE,
convert (build_pointer_type (objc_selector_type),
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_SELECTOR_TABLE_decl, 1)),
initlist);
@@ -2262,7 +2268,8 @@ init_module_descriptor (tree type)
/* symtab = { ..., _OBJC_SYMBOLS, ... } */
if (UOBJC_SYMBOLS_decl)
- expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
@@ -2345,7 +2352,7 @@ build_module_initializer_routine (void)
(execclass_decl,
build_tree_list
(NULL_TREE,
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_MODULES_decl, 0))));
add_stmt (c_end_compound_stmt (body, true));
@@ -2440,13 +2447,15 @@ generate_static_references (void)
klass = TREE_VALUE (cl_chain);
class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
initlist = build_tree_list (NULL_TREE,
- build_unary_op (ADDR_EXPR, class_name, 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_name, 1));
/* Output {..., instance, ...}. */
for (in_chain = TREE_PURPOSE (cl_chain);
in_chain; in_chain = TREE_CHAIN (in_chain))
{
- expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, TREE_VALUE (in_chain), 1);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -2456,7 +2465,8 @@ generate_static_references (void)
expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
finish_var_decl (decl, expr);
decls
- = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
+ = tree_cons (NULL_TREE, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1), decls);
}
decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
@@ -2628,7 +2638,7 @@ build_typed_selector_reference (tree ident, tree prototype)
*chain = tree_cons (prototype, ident, NULL_TREE);
return_at_index:
- expr = build_unary_op (ADDR_EXPR,
+ expr = build_unary_op (input_location, ADDR_EXPR,
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
build_int_cst (NULL_TREE, index),
input_location),
@@ -2801,7 +2811,8 @@ add_objc_string (tree ident, enum string_section section)
{
if (TREE_VALUE (*chain) == ident)
return convert (string_type_node,
- build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, TREE_PURPOSE (*chain), 1));
chain = &TREE_CHAIN (*chain);
}
@@ -2820,7 +2831,8 @@ add_objc_string (tree ident, enum string_section section)
*chain = tree_cons (decl, ident, NULL_TREE);
- return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
+ return convert (string_type_node, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1));
}
static GTY(()) int class_names_idx;
@@ -3052,10 +3064,10 @@ objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
TREE_OPERAND (expr, 1),
input_location);
case INDIRECT_REF:
- return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
+ return build_indirect_ref (input_location,
+ objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
- newexpr), "->",
- input_location);
+ newexpr), "->");
default:
return expr;
}
@@ -3077,7 +3089,8 @@ objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
? objc_assign_ivar_fast_decl
: objc_assign_ivar_decl);
- offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
+ offs = convert (integer_type_node, build_unary_op (input_location,
+ ADDR_EXPR, offs, 0));
offs = fold (offs);
func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
@@ -3095,7 +3108,7 @@ objc_build_global_assignment (tree lhs, tree rhs)
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
- build_unary_op (ADDR_EXPR, lhs, 0)),
+ build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_global_decl);
@@ -3108,7 +3121,7 @@ objc_build_strong_cast_assignment (tree lhs, tree rhs)
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
- build_unary_op (ADDR_EXPR, lhs, 0)),
+ build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
@@ -4672,7 +4685,8 @@ generate_protocols (void)
if (refs_decl)
refs_expr = convert (build_pointer_type (build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, refs_decl, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, refs_decl, 0));
else
refs_expr = build_int_cst (NULL_TREE, 0);
@@ -4709,7 +4723,8 @@ build_protocol_initializer (tree type, tree protocol_name,
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -4718,7 +4733,8 @@ build_protocol_initializer (tree type, tree protocol_name,
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5287,7 +5303,7 @@ build_dispatch_table_initializer (tree type, tree entries)
elemlist
= tree_cons (NULL_TREE,
convert (ptr_type_node,
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
METHOD_DEFINITION (entries), 1)),
elemlist);
@@ -5471,7 +5487,8 @@ generate_protocol_list (tree i_or_p)
if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
&& PROTOCOL_FORWARD_DECL (pval))
{
- e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
+ e = build_unary_op (input_location, ADDR_EXPR,
+ PROTOCOL_FORWARD_DECL (pval), 0);
initlist = tree_cons (NULL_TREE, e, initlist);
}
}
@@ -5514,7 +5531,8 @@ build_category_initializer (tree type, tree cat_name, tree class_name,
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
if (!class_methods)
@@ -5522,7 +5540,8 @@ build_category_initializer (tree type, tree cat_name, tree class_name,
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5534,7 +5553,8 @@ build_category_initializer (tree type, tree cat_name, tree class_name,
expr = convert (build_pointer_type
(build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, protocol_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5599,7 +5619,8 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
else
{
expr = convert (objc_ivar_list_ptr,
- build_unary_op (ADDR_EXPR, ivar_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ ivar_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5609,7 +5630,8 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, dispatch_table, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ dispatch_table, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5636,7 +5658,8 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
expr = convert (build_pointer_type
(build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, protocol_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5790,7 +5813,7 @@ generate_shared_structures (int cls_flags)
initlist
= build_shared_structure_initializer
(TREE_TYPE (decl),
- build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
+ build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
super_expr, name_expr,
convert (integer_type_node,
TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
@@ -6582,7 +6605,8 @@ objc_build_protocol_expr (tree protoname)
if (!PROTOCOL_FORWARD_DECL (p))
build_protocol_reference (p);
- expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
/* ??? Ideally we'd build the reference with objc_protocol_type directly,
if we have it, rather than converting it here. */
@@ -6720,8 +6744,8 @@ build_ivar_reference (tree id)
self_decl = convert (objc_instance_type, self_decl); /* cast */
}
- return objc_build_component_ref (build_indirect_ref (self_decl, "->",
- input_location), id);
+ return objc_build_component_ref (build_indirect_ref (input_location,
+ self_decl, "->"), id);
}
/* Compute a hash value for a given method SEL_NAME. */
@@ -8701,7 +8725,8 @@ get_super_receiver (void)
/* Set receiver to self. */
super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
- super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
+ super_expr = build_modify_expr (input_location,
+ super_expr, NOP_EXPR, self_decl);
super_expr_list = super_expr;
/* Set class to begin searching. */
@@ -8713,7 +8738,7 @@ get_super_receiver (void)
/* [_cls, __cls]Super are "pre-built" in
synth_forward_declarations. */
- super_expr = build_modify_expr (super_expr, NOP_EXPR,
+ super_expr = build_modify_expr (input_location, super_expr, NOP_EXPR,
((TREE_CODE (objc_method_context)
== INSTANCE_METHOD_DECL)
? ucls_super_ref
@@ -8744,8 +8769,9 @@ get_super_receiver (void)
"isa" is the first ivar in a class (which it must be). */
super_class
= build_indirect_ref
- (build_c_cast (build_pointer_type (objc_class_type),
- super_class), "unary *", input_location);
+ (input_location,
+ build_c_cast (build_pointer_type (objc_class_type),
+ super_class), "unary *");
}
else
{
@@ -8764,14 +8790,15 @@ get_super_receiver (void)
}
super_expr
- = build_modify_expr (super_expr, NOP_EXPR,
+ = build_modify_expr (input_location, super_expr, NOP_EXPR,
build_c_cast (TREE_TYPE (super_expr),
super_class));
}
super_expr_list = build_compound_expr (super_expr_list, super_expr);
- super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
+ super_expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SUPER_decl, 0);
super_expr_list = build_compound_expr (super_expr_list, super_expr);
return super_expr_list;
diff --git a/gcc/opts.c b/gcc/opts.c
index bac50b0925f..6e210ea7ceb 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1459,8 +1459,7 @@ common_handle_option (size_t scode, const char *arg, int value,
print_specific_help (0, undoc_mask, all_langs_mask);
/* Then display any remaining, non-language options. */
for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
- if (i != CL_SAVE)
- print_specific_help (i, undoc_mask, 0);
+ print_specific_help (i, undoc_mask, 0);
exit_after_options = true;
break;
}
diff --git a/gcc/opts.h b/gcc/opts.h
index 7a51a0e3b52..bc290f6457c 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -65,14 +65,13 @@ extern const unsigned int cl_options_count;
extern const char *const lang_names[];
extern const unsigned int cl_lang_count;
-#define CL_SAVE (1 << 17) /* Target-specific option for attribute. */
-#define CL_PARAMS (1 << 18) /* Fake entry. Used to display --param info with --help. */
-#define CL_WARNING (1 << 19) /* Enables an (optional) warning message. */
-#define CL_OPTIMIZATION (1 << 20) /* Enables an (optional) optimization. */
-#define CL_TARGET (1 << 21) /* Target-specific option. */
-#define CL_COMMON (1 << 22) /* Language-independent. */
-
-#define CL_MIN_OPTION_CLASS CL_SAVE
+#define CL_PARAMS (1 << 17) /* Fake entry. Used to display --param info with --help. */
+#define CL_WARNING (1 << 18) /* Enables an (optional) warning message. */
+#define CL_OPTIMIZATION (1 << 19) /* Enables an (optional) optimization. */
+#define CL_TARGET (1 << 20) /* Target-specific option. */
+#define CL_COMMON (1 << 21) /* Language-independent. */
+
+#define CL_MIN_OPTION_CLASS CL_PARAMS
#define CL_MAX_OPTION_CLASS CL_COMMON
/* From here on the bits describe attributes of the options.
@@ -80,6 +79,7 @@ extern const unsigned int cl_lang_count;
This distinction is important because --help will not list options
which only have these higher bits set. */
+#define CL_SAVE (1 << 22) /* Target-specific option for attribute. */
#define CL_DISABLED (1 << 23) /* Disabled in this configuration. */
#define CL_REPORT (1 << 24) /* Report argument with -fverbose-asm */
#define CL_JOINED (1 << 25) /* If takes joined argument. */
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 16ba3929fab..fb9f12692c6 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -926,6 +926,12 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
case TARGET_OPTION_NODE:
cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node));
break;
+ case IMPORTED_DECL:
+ fprintf (file, " imported declaration");
+ print_node_brief (file, "associated declaration",
+ IMPORTED_DECL_ASSOCIATED_DECL (node),
+ indent + 4);
+ break;
default:
if (EXCEPTIONAL_CLASS_P (node))
diff --git a/gcc/profile.c b/gcc/profile.c
index 0ece72519d9..976d91cc17b 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -960,10 +960,12 @@ branch_prob (void)
&& (LOCATION_FILE (e->goto_locus)
!= LOCATION_FILE (gimple_location (last))
|| (LOCATION_LINE (e->goto_locus)
- != LOCATION_LINE (gimple_location (last)))))
+ != LOCATION_LINE (gimple_location (last)))))
{
basic_block new_bb = split_edge (e);
- single_succ_edge (new_bb)->goto_locus = e->goto_locus;
+ edge ne = single_succ_edge (new_bb);
+ ne->goto_locus = e->goto_locus;
+ ne->goto_block = e->goto_block;
}
if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
&& e->dest != EXIT_BLOCK_PTR)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index df7ba0b1e96..cc7ec163e07 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,77 @@
+2008-10-07 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c/35437
+ * gcc.dg/struct-parse-2.c: New test.
+ * g++.dg/parse/struct-4.C: New test.
+
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/29609
+ PR debug/36690
+ PR debug/37616
+ * gcc.dg/debug/pr29609-1.c: New test.
+ * gcc.dg/debug/pr29609-2.c: New test.
+ * gcc.dg/debug/pr36690-1.c: New test.
+ * gcc.dg/debug/pr36690-2.c: New test.
+ * gcc.dg/debug/pr36690-3.c: New test.
+ * gcc.dg/debug/pr37616.c: New test.
+ * gcc.dg/debug/dwarf2/pr29609-1.c: New test.
+ * gcc.dg/debug/dwarf2/pr29609-2.c: New test.
+ * gcc.dg/debug/dwarf2/pr36690-1.c: New test.
+ * gcc.dg/debug/dwarf2/pr36690-2.c: New test.
+ * gcc.dg/debug/dwarf2/pr36690-3.c: New test.
+ * gcc.dg/debug/dwarf2/pr37616.c: New test.
+
+2008-10-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/37731
+ * gcc.dg/torture/pr37731-1.c: New.
+ * gcc.dg/torture/pr37731-2.c: Likewise.
+
+2008-10-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/37738
+ * gfortran.dg/debug/pr37738.f: New test.
+
+2008-10-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization4.adb: New test.
+ * gnat.dg/loop_optimization4_pkg.ad[sb]: New helper.
+
+2008-10-07 Bob Wilson <bob.wilson@acm.org>
+
+ * gcc.dg/compat/struct-layout-1_generate.c (dg_options): New. Moved
+ dg-options lines to this array, and added options for xtensa*-*-*.
+ (NDG_OPTIONS): Define.
+ (switchfiles): Print dg-options lines from new dg_options array.
+ * g++.dg/compat/struct-layout-1_generate.c (dg_options): Add options
+ for xtensa*-*-* targets.
+
+2008-10-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/addr4.adb: New test.
+ * gnat.dg/addr5.adb: Likewise.
+
+2008-10-06 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.target/mips/mips.exp (dg-mips-options): Set mips_new_gp to
+ 32 when -march=r3900 is passed.
+ * testsuite/gcc.target/mips/r3900-mult.c: New test.
+
+2008-10-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/gomp/for-1.c: Test column.
+ * gcc.dg/misc-column.c: Add column tests for unary arguments.
+
+2008-10-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/unchecked_convert2.adb: New test.
+
+2008-10-05 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/37410
+ * g++.dg/debug/dwarf2/imported-module.C: New test.
+
2008-10-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/35680
diff --git a/gcc/testsuite/g++.dg/abi/mangle30.C b/gcc/testsuite/g++.dg/abi/mangle30.C
new file mode 100644
index 00000000000..f0b83dbe929
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle30.C
@@ -0,0 +1,22 @@
+// Test for mangling of template args in a typename type.
+
+struct A
+{
+ template <class T>
+ struct B
+ {
+ typedef T myT;
+ };
+};
+
+struct C {};
+
+template <class T>
+void f (T t, typename T::template B<C>::myT u, typename T::template B<int>::myT v);
+
+int main()
+{
+ f (A(), C(), 1);
+}
+
+// { dg-final { scan-assembler "_Z1fI1AEvT_NS1_1BI1CE3myTENS2_IiE3myTE" } }
diff --git a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
index 8535022b7fc..589cc787fd8 100644
--- a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
@@ -46,7 +46,8 @@ const char *dg_options[] = {
"/* { dg-options \"%s-I%s\" } */\n",
"/* { dg-options \"%s-I%s -mno-mmx\" { target i?86-*-* x86_64-*-* } } */\n",
"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* } } */\n",
-"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n"
+"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
#define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto6.C b/gcc/testsuite/g++.dg/cpp0x/auto6.C
index 713583a1a48..d2bcfedb63c 100644
--- a/gcc/testsuite/g++.dg/cpp0x/auto6.C
+++ b/gcc/testsuite/g++.dg/cpp0x/auto6.C
@@ -1,3 +1,4 @@
+// Tests for late-specified return type.
// { dg-options "-std=c++0x" }
auto f() -> int
@@ -12,17 +13,81 @@ auto add(T t, U u) -> decltype (t+u)
}
template<class T, class U>
-decltype(T()+U()) add2(T t, U u);
+decltype(T()+U()) add2(T t, U u)
+{
+ return t+u;
+}
template <class T, class U>
-U g (T, U);
+U ag (T, U)
+{
+ return U();
+}
template<class T, class U>
-auto add3(T t, U u) -> decltype (g(t,u));
+auto add3(T t, U u) -> decltype (ag(t,u))
+{
+ return ag(t,u);
+}
+
+template <class T>
+struct A
+{
+ T f() {}
+ template <class U>
+ T g() {}
+ template <class V>
+ struct B
+ {
+ int MEM;
+ };
+};
+
+template <class T>
+auto f(T* t) -> decltype (t->f())
+{
+ return t->f();
+}
+
+template <class T>
+auto g(T t) -> decltype (t.f())
+{
+ return t.f();
+}
+
+template <class T, class U>
+auto h(T t, U u) -> decltype (t.template g<U>())
+{
+ return t.template g<U>();
+}
+
+struct D { };
+struct C: public A<int>::B<D>
+{
+};
+
+template <class T, class U, class V>
+auto k(T t, U u, V v) -> decltype (t.U::template B<V>::MEM)
+{
+ return t.U::template B<V>::MEM;
+}
+
+A<int> a, *p;
int main()
{
+ // { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
auto i = add(1, 2.0);
+ // { dg-final { scan-assembler "_Z4add2IidEDTplcvT_vcvT0_vES0_S1_" } }
auto i2 = add2(1, 2.0);
+ // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } }
auto i3 = add3(1, 2.0);
+ // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptsTPT_1fEES3_" } }
+ f(p);
+ // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtsTT_1fEES2_" } }
+ g(a);
+ // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_" } }
+ h(a,1.0);
+ // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } }
+ k( C(), A<int>(), D() );
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic4.C b/gcc/testsuite/g++.dg/cpp0x/variadic4.C
index 6c15a6de92d..9257a92d5b9 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic4.C
@@ -9,7 +9,7 @@ void f_two(tuple<int, float>) {}
void f_nested(tuple<int, tuple<double, char>, float>) { }
-// { dg-final { scan-assembler "_Z6f_none5tupleIE" } }
-// { dg-final { scan-assembler "_Z5f_one5tupleIiE" } }
-// { dg-final { scan-assembler "_Z5f_two5tupleIifE" } }
-// { dg-final { scan-assembler "_Z8f_nested5tupleIiS_IdcEfE" } }
+// { dg-final { scan-assembler "_Z6f_none5tupleIIEE" } }
+// { dg-final { scan-assembler "_Z5f_one5tupleIIiEE" } }
+// { dg-final { scan-assembler "_Z5f_two5tupleIIifEE" } }
+// { dg-final { scan-assembler "_Z8f_nested5tupleIIiS_IIdcEEfEE" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic42.C b/gcc/testsuite/g++.dg/cpp0x/variadic42.C
index 4c6c7673d80..47d9b66da58 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic42.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic42.C
@@ -8,5 +8,5 @@ void g()
f<int*, float*, double*>(0, 0, 0);
f<int*>(0,0,0);
}
-// { dg-final { scan-assembler "_Z1fIPiPfPdEvU10__variadicT_" } }
-// { dg-final { scan-assembler "_Z1fIPiiiEvU10__variadicT_" } }
+// { dg-final { scan-assembler "_Z1fIIPiPfPdEEvDpT_" } }
+// { dg-final { scan-assembler "_Z1fIIPiiiEEvDpT_" } }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C
new file mode 100644
index 00000000000..7b25233f1ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module.C
@@ -0,0 +1,35 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR debug/37410
+// { dg-do compile }
+
+namespace A1
+ {
+ int aaa = 1;
+ };
+namespace A2
+ {
+ int aaa = 2;
+ };
+
+int
+foo (void)
+{
+ int x;
+
+ {
+ int block_create;
+ using namespace A1;
+
+ block_create = aaa; /* break1 */
+ }
+
+ {
+ int block_create;
+ using namespace A2;
+
+ block_create = aaa; /* break2 */
+ }
+
+ return x = 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/ext/utf-mangle.C b/gcc/testsuite/g++.dg/ext/utf-mangle.C
index bb5e3822adc..a131887882a 100644
--- a/gcc/testsuite/g++.dg/ext/utf-mangle.C
+++ b/gcc/testsuite/g++.dg/ext/utf-mangle.C
@@ -8,7 +8,7 @@ void f1 (char32_t c) {}
void f2 (char16_t *s) {}
void f3 (char32_t *s) {}
-// { dg-final { scan-assembler "_Z2f0u8char16_t:" } }
-// { dg-final { scan-assembler "_Z2f1u8char32_t:" } }
-// { dg-final { scan-assembler "_Z2f2Pu8char16_t:" } }
-// { dg-final { scan-assembler "_Z2f3Pu8char32_t:" } }
+// { dg-final { scan-assembler "_Z2f0Ds:" } }
+// { dg-final { scan-assembler "_Z2f1Di:" } }
+// { dg-final { scan-assembler "_Z2f2PDs:" } }
+// { dg-final { scan-assembler "_Z2f3PDi:" } }
diff --git a/gcc/testsuite/g++.dg/parse/struct-4.C b/gcc/testsuite/g++.dg/parse/struct-4.C
new file mode 100644
index 00000000000..559411a19cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/struct-4.C
@@ -0,0 +1,13 @@
+/* PR c/35437 */
+/* { dg-do "compile" } */
+
+struct A
+{
+ int i;
+ struct A a; /* { dg-error "has incomplete type" } */
+};
+
+void foo()
+{
+ struct A b = { 0 };
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
index 097ef5053a8..d50322c9f87 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
@@ -1,5 +1,5 @@
/* Structure layout test generator.
- Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of GCC.
@@ -42,6 +42,14 @@ along with GCC; see the file COPYING3. If not see
#define COMPAT_PRLL "ll"
#endif
+const char *dg_options[] = {
+"/* { dg-options \"%s-I%s\" } */\n",
+"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* *-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
+"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
+#define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
+};
+
typedef unsigned int hashval_t;
enum TYPE
@@ -747,6 +755,8 @@ switchfiles (int fields)
{
static int filecnt;
static char *destbuf, *destptr;
+ int i;
+
++filecnt;
if (outfile)
fclose (outfile);
@@ -774,11 +784,10 @@ switchfiles (int fields)
fputs ("failed to create test files\n", stderr);
exit (1);
}
+ fprintf (outfile, "/* { dg-require-effective-target int32plus } */\n");
+ for (i = 0; i < NDG_OPTIONS; i++)
+ fprintf (outfile, dg_options[i], "", srcdir_safe);
fprintf (outfile, "\
-/* { dg-require-effective-target int32plus } */\n\
-/* { dg-options \"-I%s\" } */\n\
-/* { dg-options \"-I%s -fno-common\" { target hppa*-*-hpux* *-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n\
-/* { dg-options \"-I%s -mno-base-addresses\" { target mmix-*-* } } */\n\
#include \"struct-layout-1.h\"\n\
\n\
#define TX(n, type, attrs, fields, ops) extern void test##n (void);\n\
@@ -796,33 +805,31 @@ int main (void)\n\
abort ();\n\
}\n\
exit (0);\n\
-}\n", srcdir_safe, srcdir_safe, srcdir_safe, filecnt, filecnt);
+}\n", filecnt, filecnt);
fclose (outfile);
sprintf (destptr, "t%03d_x.c", filecnt);
outfile = fopen (destbuf, "w");
if (outfile == NULL)
goto fail;
+ for (i = 0; i < NDG_OPTIONS; i++)
+ fprintf (outfile, dg_options[i], "-w ", srcdir_safe);
fprintf (outfile, "\
-/* { dg-options \"-w -I%s\" } */\n\
-/* { dg-options \"-w -I%s -fno-common\" { target hppa*-*-hpux* *-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n\
-/* { dg-options \"-w -I%s -mno-base-addresses\" { target mmix-*-* } } */\n\
#include \"struct-layout-1_x1.h\"\n\
#include \"t%03d_test.h\"\n\
#include \"struct-layout-1_x2.h\"\n\
-#include \"t%03d_test.h\"\n", srcdir_safe, srcdir_safe, srcdir_safe, filecnt, filecnt);
+#include \"t%03d_test.h\"\n", filecnt, filecnt);
fclose (outfile);
sprintf (destptr, "t%03d_y.c", filecnt);
outfile = fopen (destbuf, "w");
if (outfile == NULL)
goto fail;
+ for (i = 0; i < NDG_OPTIONS; i++)
+ fprintf (outfile, dg_options[i], "-w ", srcdir_safe);
fprintf (outfile, "\
-/* { dg-options \"-w -I%s\" } */\n\
-/* { dg-options \"-w -I%s -fno-common\" { target hppa*-*-hpux* *-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n\
-/* { dg-options \"-w -I%s -mno-base-addresses\" { target mmix-*-* } } */\n\
#include \"struct-layout-1_y1.h\"\n\
#include \"t%03d_test.h\"\n\
#include \"struct-layout-1_y2.h\"\n\
-#include \"t%03d_test.h\"\n", srcdir_safe, srcdir_safe, srcdir_safe, filecnt, filecnt);
+#include \"t%03d_test.h\"\n", filecnt, filecnt);
fclose (outfile);
sprintf (destptr, "t%03d_test.h", filecnt);
outfile = fopen (destbuf, "w");
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c
new file mode 100644
index 00000000000..5476aac0afd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c
@@ -0,0 +1,32 @@
+/* PR debug/29609 */
+/* Verify that breakpoint on the break is hit. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+void abort (void);
+
+int
+foo (void)
+{
+ int a, i;
+
+ for (i = 1; i <= 10; i++)
+ {
+ if (i < 3)
+ a = 1;
+ else
+ break;
+ a = 5;
+ }
+ return a;
+}
+
+int
+main (void)
+{
+ if (foo () != 5)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr29609-1.c:18" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c
new file mode 100644
index 00000000000..43bc54524a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c
@@ -0,0 +1,53 @@
+/* PR debug/29609 */
+/* Verify that breakpoint on both goto failure; stmts is hit. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+extern void abort (void);
+int x;
+
+int
+foo (void)
+{
+ return 0 ^ x;
+}
+
+int
+bar (void)
+{
+ return 1 ^ x;
+}
+
+int
+baz (void)
+{
+ int c;
+
+ if (!foo ())
+ goto failure;
+
+ if (!bar ())
+ goto failure;
+
+ return 0;
+
+failure:
+ return 1;
+}
+
+int
+main (void)
+{
+ if (baz () != 1)
+ abort ();
+ x = 1;
+ if (baz () != 1)
+ abort ();
+ x = 2;
+ if (baz () != 0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr29609-2.c:27" } } */
+/* { dg-final { scan-assembler "pr29609-2.c:30" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c
new file mode 100644
index 00000000000..de90acb81bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c
@@ -0,0 +1,22 @@
+/* PR debug/36690 */
+/* Verify that break func is hit. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+int i;
+
+void
+func (void)
+{
+ while (i == 1)
+ i = 0;
+}
+
+int
+main (void)
+{
+ func ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr36690-1.c:11" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c
new file mode 100644
index 00000000000..2330f53858e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c
@@ -0,0 +1,39 @@
+/* PR debug/36690 */
+/* Verify that breakpoint can be put on goto f1, it is hit and
+ varz at that spot is defined and contains 5. Nowhere else
+ in the function should be varz in the scope. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+int cnt;
+
+void
+bar (int i)
+{
+ cnt += i;
+}
+
+void
+foo (int i)
+{
+ if (!i)
+ bar (0);
+ else
+ {
+ static int varz = 5;
+ goto f1;
+ }
+ bar (1);
+f1:
+ bar (2);
+}
+
+int
+main (void)
+{
+ foo (0);
+ foo (1);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr36690-2.c:24" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c
new file mode 100644
index 00000000000..234ad1263b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c
@@ -0,0 +1,53 @@
+/* PR debug/36690 */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+int cnt;
+
+void
+bar (int i)
+{
+ cnt += i;
+}
+
+void
+foo (int i, int j)
+{
+ if (j)
+ {
+ bar (i + 1);
+ goto f1;
+ }
+ bar (i + 2);
+ goto f2;
+f1:
+ if (i > 10)
+ goto f3;
+f2:
+ if (i > 40)
+ goto f4;
+ else
+ goto f5;
+f3:
+ bar (i);
+f4:
+ bar (i);
+f5:
+ bar (i);
+}
+
+int
+main (void)
+{
+ foo (0, 1);
+ foo (11, 1);
+ foo (21, 0);
+ foo (41, 0);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr36690-3.c:19" } } */
+/* { dg-final { scan-assembler "pr36690-3.c:22" } } */
+/* { dg-final { scan-assembler "pr36690-3.c:25" } } */
+/* { dg-final { scan-assembler "pr36690-3.c:28" } } */
+/* { dg-final { scan-assembler "pr36690-3.c:30" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c
new file mode 100644
index 00000000000..badff447a8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c
@@ -0,0 +1,41 @@
+/* PR debug/37616 */
+/* Test that one can put breakpoints onto continue, exitlab and break
+ and actually see program reaching those breakpoints. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2 -dA" } */
+
+extern void abort (void);
+
+int
+foo (int parm)
+{
+ int varj, varm;
+
+ for (varj = 0; varj < 10; varj++)
+ {
+ if (varj == 5)
+ continue;
+ if (varj == 7 && !parm)
+ goto exitlab;
+ if (varj == 9)
+ break;
+ varm = varj;
+ }
+
+exitlab:
+ return varm;
+}
+
+int
+main (void)
+{
+ if (foo (0) != 6)
+ abort ();
+ if (foo (1) != 8)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "pr37616.c:17" } } */
+/* { dg-final { scan-assembler "pr37616.c:19" } } */
+/* { dg-final { scan-assembler "pr37616.c:21" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/pr29609-1.c b/gcc/testsuite/gcc.dg/debug/pr29609-1.c
new file mode 100644
index 00000000000..85069ebd650
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr29609-1.c
@@ -0,0 +1,33 @@
+/* PR debug/29609 */
+/* Verify that breakpoint on the break is hit.
+ This version of the test just checks that it can be compiled, linked
+ and executed, further testing is done in corresponding gcc.dg/dwarf2/
+ test and hopefully in gdb testsuite. */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+extern void abort (void);
+
+int
+foo (void)
+{
+ int a, i;
+
+ for (i = 1; i <= 10; i++)
+ {
+ if (i < 3)
+ a = 1;
+ else
+ break;
+ a = 5;
+ }
+ return a;
+}
+
+int
+main (void)
+{
+ if (foo () != 5)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/pr29609-2.c b/gcc/testsuite/gcc.dg/debug/pr29609-2.c
new file mode 100644
index 00000000000..1ae1a738d97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr29609-2.c
@@ -0,0 +1,53 @@
+/* PR debug/29609 */
+/* Verify that breakpoint on both goto failure; stmts is hit.
+ This version of the test just checks that it can be compiled, linked
+ and executed, further testing is done in corresponding gcc.dg/dwarf2/
+ test and hopefully in gdb testsuite. */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+extern void abort (void);
+int x;
+
+int
+foo (void)
+{
+ return 0 ^ x;
+}
+
+int
+bar (void)
+{
+ return 1 ^ x;
+}
+
+int
+baz (void)
+{
+ int c;
+
+ if (!foo ())
+ goto failure;
+
+ if (!bar ())
+ goto failure;
+
+ return 0;
+
+failure:
+ return 1;
+}
+
+int
+main (void)
+{
+ if (baz () != 1)
+ abort ();
+ x = 1;
+ if (baz () != 1)
+ abort ();
+ x = 2;
+ if (baz () != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/pr36690-1.c b/gcc/testsuite/gcc.dg/debug/pr36690-1.c
new file mode 100644
index 00000000000..e3c913b6bb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr36690-1.c
@@ -0,0 +1,23 @@
+/* PR debug/36690 */
+/* Verify that break func is hit.
+ This version of the test just checks that it can be compiled, linked
+ and executed, further testing is done in corresponding gcc.dg/dwarf2/
+ test and hopefully in gdb testsuite. */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+int i;
+
+void
+func (void)
+{
+ while (i == 1)
+ i = 0;
+}
+
+int
+main (void)
+{
+ func ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/pr36690-2.c b/gcc/testsuite/gcc.dg/debug/pr36690-2.c
new file mode 100644
index 00000000000..ddda18cf73c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr36690-2.c
@@ -0,0 +1,40 @@
+/* PR debug/36690 */
+/* Verify that breakpoint can be put on goto f1, it is hit and
+ varz at that spot is defined and contains 5. Nowhere else
+ in the function should be varz in the scope.
+ This version of the test just checks that it can be compiled, linked
+ and executed, further testing is done in corresponding gcc.dg/dwarf2/
+ test and hopefully in gdb testsuite. */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+int cnt;
+
+void
+bar (int i)
+{
+ cnt += i;
+}
+
+void
+foo (int i)
+{
+ if (!i)
+ bar (0);
+ else
+ {
+ static int varz = 5;
+ goto f1;
+ }
+ bar (1);
+f1:
+ bar (2);
+}
+
+int
+main (void)
+{
+ foo (0);
+ foo (1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/pr36690-3.c b/gcc/testsuite/gcc.dg/debug/pr36690-3.c
new file mode 100644
index 00000000000..62d3494dacd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr36690-3.c
@@ -0,0 +1,47 @@
+/* PR debug/36690 */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+int cnt;
+
+void
+bar (int i)
+{
+ cnt += i;
+}
+
+void
+foo (int i, int j)
+{
+ if (j)
+ {
+ bar (i + 1);
+ goto f1;
+ }
+ bar (i + 2);
+ goto f2;
+f1:
+ if (i > 10)
+ goto f3;
+f2:
+ if (i > 40)
+ goto f4;
+ else
+ goto f5;
+f3:
+ bar (i);
+f4:
+ bar (i);
+f5:
+ bar (i);
+}
+
+int
+main (void)
+{
+ foo (0, 1);
+ foo (11, 1);
+ foo (21, 0);
+ foo (41, 0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/debug/pr37616.c b/gcc/testsuite/gcc.dg/debug/pr37616.c
new file mode 100644
index 00000000000..3bbaebbdf78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr37616.c
@@ -0,0 +1,40 @@
+/* PR debug/37616 */
+/* Test that one can put breakpoints onto continue, exitlab and break
+ and actually see program reaching those breakpoints.
+ This version of the test just checks that it can be compiled, linked
+ and executed, further testing is done in corresponding gcc.dg/dwarf2/
+ test and hopefully in gdb testsuite. */
+/* { dg-do run } */
+/* { dg-options "-O0 -g -dA" } */
+
+extern void abort (void);
+
+int
+foo (int parm)
+{
+ int varj, varm;
+
+ for (varj = 0; varj < 10; varj++)
+ {
+ if (varj == 5)
+ continue;
+ if (varj == 7 && !parm)
+ goto exitlab;
+ if (varj == 9)
+ break;
+ varm = varj;
+ }
+
+exitlab:
+ return varm;
+}
+
+int
+main (void)
+{
+ if (foo (0) != 6)
+ abort ();
+ if (foo (1) != 8)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/for-1.c b/gcc/testsuite/gcc.dg/gomp/for-1.c
index bf50f25f458..840f9478499 100644
--- a/gcc/testsuite/gcc.dg/gomp/for-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/for-1.c
@@ -44,6 +44,6 @@ void foo (int j, int k)
baz (i);
#pragma omp for
- for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "invalid increment expression" } */
+ for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "23:invalid increment expression" } */
baz (i);
}
diff --git a/gcc/testsuite/gcc.dg/misc-column.c b/gcc/testsuite/gcc.dg/misc-column.c
index f84a553959d..a24427e4baa 100644
--- a/gcc/testsuite/gcc.dg/misc-column.c
+++ b/gcc/testsuite/gcc.dg/misc-column.c
@@ -1,5 +1,6 @@
/* { dg-options "-fshow-column -Wall -Wfloat-equal -pedantic" } */
+int i, j;
float a, b;
int *p;
@@ -26,4 +27,14 @@ void foo (void)
if (p < 0) /* { dg-warning "9:ordered comparison of pointer with" } */
bar();
+
+ -q; /* { dg-error "3:wrong type argument to unary" } */
+
+ ~q; /* { dg-error "3:wrong type argument to bit" } */
+
+ ++*q; /* { dg-error "3:wrong type argument to increment" } */
+
+ i = j / 0; /* { dg-warning "9:division by zero" } */
+
+ i /= 0; /* { dg-warning "5:division by zero" } */
}
diff --git a/gcc/testsuite/gcc.dg/struct-parse-2.c b/gcc/testsuite/gcc.dg/struct-parse-2.c
new file mode 100644
index 00000000000..559411a19cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct-parse-2.c
@@ -0,0 +1,13 @@
+/* PR c/35437 */
+/* { dg-do "compile" } */
+
+struct A
+{
+ int i;
+ struct A a; /* { dg-error "has incomplete type" } */
+};
+
+void foo()
+{
+ struct A b = { 0 };
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr37731-1.c b/gcc/testsuite/gcc.dg/torture/pr37731-1.c
new file mode 100644
index 00000000000..5c156b1f9a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr37731-1.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+extern void abort ();
+
+unsigned long long xh = 1;
+
+int
+main ()
+{
+ unsigned long long yh = 0xffffffffull;
+ unsigned long long z = xh * yh;
+
+ if (z != yh)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr37731-2.c b/gcc/testsuite/gcc.dg/torture/pr37731-2.c
new file mode 100644
index 00000000000..a7f8f1e02e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr37731-2.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+extern void abort ();
+
+long long xh = 1;
+
+int
+main ()
+{
+ long long yh = 0xffffffffll;
+ long long z = xh * yh;
+
+ if (z != yh)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 832633900c9..8e66e0a1901 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -261,6 +261,7 @@ proc dg-mips-options {args} {
-mips[12] -
-mips32* -
-march=mips32* -
+ -march=r3900 -
-march=24k* -
-mabi=32 -
-mgp32 {
diff --git a/gcc/testsuite/gcc.target/mips/r3900-mult.c b/gcc/testsuite/gcc.target/mips/r3900-mult.c
new file mode 100644
index 00000000000..393f1086e07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/r3900-mult.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-march=r3900" } */
+/* { dg-final { scan-assembler "\tmult\t\[^\n\]*,\[^\n\]*," } } */
+
+NOMIPS16 int
+f (int a, int b)
+{
+ return a * b;
+}
diff --git a/gcc/testsuite/gfortran.dg/debug/pr37738.f b/gcc/testsuite/gfortran.dg/debug/pr37738.f
new file mode 100644
index 00000000000..b0a787b2e52
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/debug/pr37738.f
@@ -0,0 +1,30 @@
+C PR debug/37738
+C { dg-do compile }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-options "-dA" }
+
+ subroutine a
+ integer*4 a_i, c_i
+ common /block/a_i, c_i
+ a_i = 1
+ c_i = 4
+ end subroutine a
+ subroutine b
+ integer*4 b_i
+ common /block/b_i, d_i
+ b_i = 2
+ d_i = 5
+ end subroutine b
+ subroutine c
+ integer*4 a_i, c_i
+ common /block/a_i, c_i
+ if (a_i .ne. 2) call abort
+ if (c_i .ne. 5) call abort
+ end subroutine c
+ program abc
+ call a
+ call b
+ call c
+ end program abc
+
+C { dg-final { scan-assembler-times "DIE\[^\n\]*DW_TAG_common_block" 3 } }
diff --git a/gcc/testsuite/gnat.dg/addr4.adb b/gcc/testsuite/gnat.dg/addr4.adb
new file mode 100644
index 00000000000..8bb3f2c9723
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/addr4.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-g" }
+
+procedure Addr4 is
+ function F return String is begin return ""; end F;
+ S1 : String renames F;
+ subtype ST is String (1 .. S1'Length);
+ S2 : ST;
+ for S2'Address use S1'Address;
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/addr5.adb b/gcc/testsuite/gnat.dg/addr5.adb
new file mode 100644
index 00000000000..e331dfdc09e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/addr5.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+-- { dg-options "-g" }
+
+procedure Addr5 (Len : Integer) is
+ S : aliased String (1 .. Len) := (others => ' ');
+ C : Character;
+ for C'Address use S'Address;
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization4.adb b/gcc/testsuite/gnat.dg/loop_optimization4.adb
new file mode 100644
index 00000000000..a6799f393e7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization4.adb
@@ -0,0 +1,9 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Loop_Optimization4_Pkg; use Loop_Optimization4_Pkg;
+
+procedure Loop_Optimization4 is
+begin
+ Add ("Nothing");
+end;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization4_pkg.adb b/gcc/testsuite/gnat.dg/loop_optimization4_pkg.adb
new file mode 100644
index 00000000000..ba372f6bddd
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization4_pkg.adb
@@ -0,0 +1,17 @@
+package body Loop_Optimization4_Pkg is
+
+ procedure Add (Phrase : String) is
+ begin
+ if Debug_Buffer_Len = Max_Debug_Buffer_Len then
+ return;
+ end if;
+ for I in Phrase'Range loop
+ Debug_Buffer_Len := Debug_Buffer_Len + 1;
+ Debug_Buffer (Debug_Buffer_Len) := Phrase (I);
+ if Debug_Buffer_Len = Max_Debug_Buffer_Len then
+ exit;
+ end if;
+ end loop;
+ end Add;
+
+end Loop_Optimization4_Pkg;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization4_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization4_pkg.ads
new file mode 100644
index 00000000000..a07c4e568c6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization4_pkg.ads
@@ -0,0 +1,9 @@
+package Loop_Optimization4_Pkg is
+
+ Max_Debug_Buffer_Len : Natural := 8 * 1024;
+ Debug_Buffer : String (1 .. Max_Debug_Buffer_Len);
+ Debug_Buffer_Len : Natural range 0 .. Max_Debug_Buffer_Len;
+
+ procedure Add (Phrase : String);
+
+end Loop_Optimization4_Pkg;
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert2.adb b/gcc/testsuite/gnat.dg/unchecked_convert2.adb
new file mode 100644
index 00000000000..f542af7c343
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unchecked_convert2.adb
@@ -0,0 +1,34 @@
+-- { dg-do run }
+
+with Ada.Unchecked_Conversion;
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Unchecked_Convert2 is
+
+ subtype Day_Number is Integer range 0 .. 31;
+
+ subtype Byte_Array_Of_Integer is Stream_Element_Array
+ (1 .. Integer'Size / Stream_Element_Array'Component_Size);
+
+ function To_Byte_Array is
+ new Ada.Unchecked_Conversion (Integer, Byte_Array_Of_Integer);
+
+ Day_Now : Day_Number;
+ Pragma Volatile (Day_Now);
+
+ Arr : Stream_Element_Array (1 .. 12) := (others => 16#ff#);
+
+ procedure Test (Arr : Stream_Element_Array) is
+ begin
+ if Arr(5) /= 0 or Arr(6) /= 0 or Arr(7) /= 0 or Arr(8) /= 0 then
+ raise Program_Error;
+ end if;
+ end;
+
+begin
+ Day_Now := 0;
+ Arr (5 .. 8) := To_Byte_Array (Day_Now);
+ Test (Arr);
+ Arr (1) := 16#ff#;
+end Unchecked_Convert2;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e9f315c53a2..505ee700057 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -658,9 +658,13 @@ make_cond_expr_edges (basic_block bb)
e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
e->goto_locus = gimple_location (then_stmt);
+ e->goto_block = gimple_block (then_stmt);
e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
if (e)
- e->goto_locus = gimple_location (else_stmt);
+ {
+ e->goto_locus = gimple_location (else_stmt);
+ e->goto_block = gimple_block (else_stmt);
+ }
/* We do not need the labels anymore. */
gimple_cond_set_true_label (entry, NULL_TREE);
@@ -849,6 +853,7 @@ make_goto_expr_edges (basic_block bb)
tree dest = gimple_goto_dest (goto_t);
edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
e->goto_locus = gimple_location (goto_t);
+ e->goto_block = gimple_block (goto_t);
gsi_remove (&last, true);
return;
}
@@ -5743,6 +5748,23 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
update_stmt (stmt);
pop_cfun ();
}
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->goto_locus)
+ {
+ tree block = e->goto_block;
+ if (d->orig_block == NULL_TREE
+ || block == d->orig_block)
+ e->goto_block = d->new_block;
+#ifdef ENABLE_CHECKING
+ else if (block != d->new_block)
+ {
+ while (block && block != d->orig_block)
+ block = BLOCK_SUPERCONTEXT (block);
+ gcc_assert (block);
+ }
+#endif
+ }
}
/* Examine the statements in BB (which is in SRC_CFUN); find and return
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 4639588a162..c924a7631db 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1558,7 +1558,7 @@ may_be_nonaddressable_p (tree expr)
non-addressability may be uncovered again, causing ADDR_EXPRs
of inappropriate objects to be built. */
if (is_gimple_reg (TREE_OPERAND (expr, 0))
- || is_gimple_min_invariant (TREE_OPERAND (expr, 0)))
+ || !is_gimple_addressable (TREE_OPERAND (expr, 0)))
return true;
/* ... fall through ... */
diff --git a/gcc/tree.c b/gcc/tree.c
index 4b178d5073f..33ab8b7078b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -343,6 +343,8 @@ init_ttree (void)
tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1;
tree_contains_struct[TYPE_DECL][TS_TYPE_DECL] = 1;
tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL] = 1;
+ tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL] = 1;
+ tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON] = 1;
lang_hooks.init_ts ();
}
diff --git a/gcc/tree.def b/gcc/tree.def
index ef103cdba50..bde59b7016c 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -371,6 +371,17 @@ DEFTREECODE (MEMORY_PARTITION_TAG, "memory_partition_tag", tcc_declaration, 0)
_DECLs, providing a hierarchy of names. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0)
+/* A declaration import.
+ The C++ FE uses this to represent a using-directive; eg:
+ "using namespace foo".
+ But it could be used to represent any declaration import construct.
+ Whenever a declaration import appears in a lexical block, the BLOCK node
+ representing that lexical block in GIMPLE will contain an IMPORTED_DECL
+ node, linked via BLOCK_VARS accessor of the said BLOCK.
+ For a given NODE which code is IMPORTED_DECL,
+ IMPORTED_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration. */
+DEFTREECODE (IMPORTED_DECL, "imported_decl", tcc_declaration, 0)
+
/* A translation unit. This is not technically a declaration, since it
can't be looked up, but it's close enough. */
DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\
diff --git a/gcc/tree.h b/gcc/tree.h
index 4c046c29d64..44bc3f0f282 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2559,7 +2559,7 @@ struct tree_memory_partition_tag GTY(())
/* For a FUNCTION_DECL, holds the tree of BINDINGs.
For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK.
For a VAR_DECL, holds the initial value.
- For a PARM_DECL, not used--default
+ For a PARM_DECL, used for DECL_ARG_TYPE--default
values for parameters are encoded in the type of the function,
not in the PARM_DECL slot.
For a FIELD_DECL, this is used for enumeration values and the C
@@ -3334,6 +3334,11 @@ struct tree_function_decl GTY(())
#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
(TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_2)
+/* Getter of the imported declaration associated to the
+ IMPORTED_DECL node. */
+#define IMPORTED_DECL_ASSOCIATED_DECL(NODE) \
+(DECL_INITIAL (IMPORTED_DECL_CHECK (NODE)))
+
struct tree_type_decl GTY(())
{
struct tree_decl_non_common common;
diff --git a/include/ChangeLog b/include/ChangeLog
index 64b0a6caeeb..20da6186ff0 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-06 Jason Merrill <jason@redhat.com>
+
+ * demangle.h (enum demangle_component_type): Add
+ DEMANGLE_COMPONENT_PACK_EXPANSION.
+
2008-09-09 Jason Merrill <jason@redhat.com>
* demangle.h (enum demangle_component_type): Add
diff --git a/include/demangle.h b/include/demangle.h
index 146d778e097..0ea639d62ba 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -372,7 +372,9 @@ enum demangle_component_type
/* A name formed by a single character. */
DEMANGLE_COMPONENT_CHARACTER,
/* A decltype type. */
- DEMANGLE_COMPONENT_DECLTYPE
+ DEMANGLE_COMPONENT_DECLTYPE,
+ /* A pack expansion. */
+ DEMANGLE_COMPONENT_PACK_EXPANSION
};
/* Types which are only used internally. */
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index e6980aea132..c79b3b75098 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,28 @@
+2008-10-07 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * configure.ac: Call AC_SYS_LARGEFILE.
+ * config.in: Regenerated.
+ * configure: Likewise.
+
+2008-10-06 Jason Merrill <jason@redhat.com>
+
+ * cp-demangle.c (struct d_print_info): Add pack_index.
+ (d_dump): Add DEMANGLE_COMPONENT_PACK_EXPANSION.
+ (d_make_comp): Likewise. DEMANGLE_COMPONENT_ARGLIST and
+ DEMANGLE_COMPONENT_TEMPLATE_ARGLIST can have two null args.
+ (cplus_demangle_builtin_types): Add char16/32_t.
+ (cplus_demangle_type): Recognize them.
+ (d_template_args): Handle empty argument packs.
+ (d_template_arg): Handle argument packs.
+ (d_expression): Handle dependent name.
+ (d_index_template_argument): New fn.
+ (d_lookup_template_argument): New fn.
+ (d_find_pack, d_pack_length): New fn.
+ (d_print_subexpr): Split out...
+ (d_print_comp): ...from here. Use d_*_template_argument.
+ Handle empty arg lists. Support pack expansions.
+ * cp-demangle.h (D_BUILTIN_TYPE_COUNT): Increase to 32.
+
2008-09-09 Jason Merrill <jason@redhat.com>
* cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_DECLTYPE.
diff --git a/libiberty/config.in b/libiberty/config.in
index 436a58d7e79..9260d560a6e 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -425,6 +425,12 @@
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/libiberty/configure b/libiberty/configure
index 50e9ba3699e..71b6ccd95b5 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -849,6 +849,7 @@ Optional Features:
enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-multilib build many library versions (default)
+ --disable-largefile omit support for large files
--enable-install-libiberty Install headers for end users
Optional Packages:
@@ -2741,6 +2742,371 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval="$enable_largefile"
+
+fi;
+if test "$enable_largefile" != no; then
+
+ echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
+echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_largefile_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_largefile_CC=' -n32'; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
+echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_file_offset_bits+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ ac_cv_sys_file_offset_bits=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_file_offset_bits=64; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
+echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
+if test "$ac_cv_sys_file_offset_bits" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+
+fi
+rm -f conftest*
+ echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
+echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
+if test "${ac_cv_sys_large_files+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ while :; do
+ ac_cv_sys_large_files=no
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_sys_large_files=1; break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ break
+done
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
+echo "${ECHO_T}$ac_cv_sys_large_files" >&6
+if test "$ac_cv_sys_large_files" != no; then
+
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+
+fi
+rm -f conftest*
+fi
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2980,7 +3346,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_c_preproc_warn_flag=yes
-
ac_libiberty_warn_cflags=
save_CFLAGS="$CFLAGS"
for option in -W -Wall -Wwrite-strings -Wc++-compat \
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 419351bbb93..ff0ae6a81e4 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -130,6 +130,7 @@ fi
GCC_NO_EXECUTABLES
AC_PROG_CC
+AC_SYS_LARGEFILE
AC_PROG_CPP_WERROR
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wc++-compat \
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 3d292f07d0a..3fa5f1f21d3 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -299,6 +299,9 @@ struct d_print_info
struct d_print_mod *modifiers;
/* Set to 1 if we saw a demangling error. */
int demangle_failure;
+ /* The current index into any template argument packs we are using
+ for printing. */
+ int pack_index;
};
#ifdef CP_DEMANGLE_DEBUG
@@ -663,6 +666,9 @@ d_dump (struct demangle_component *dc, int indent)
case DEMANGLE_COMPONENT_DECLTYPE:
printf ("decltype\n");
break;
+ case DEMANGLE_COMPONENT_PACK_EXPANSION:
+ printf ("pack expansion\n");
+ break;
}
d_dump (d_left (dc), indent + 2);
@@ -806,11 +812,10 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
case DEMANGLE_COMPONENT_VENDOR_TYPE:
- case DEMANGLE_COMPONENT_ARGLIST:
- case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
case DEMANGLE_COMPONENT_CAST:
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_DECLTYPE:
+ case DEMANGLE_COMPONENT_PACK_EXPANSION:
if (left == NULL)
return NULL;
break;
@@ -831,6 +836,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
+ case DEMANGLE_COMPONENT_ARGLIST:
+ case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
break;
/* Other types should not be seen here. */
@@ -1433,6 +1440,7 @@ const struct demangle_operator_info cplus_demangle_operators[] =
{ "da", NL ("delete[]"), 1 },
{ "de", NL ("*"), 1 },
{ "dl", NL ("delete"), 1 },
+ { "dt", NL ("."), 2 },
{ "dv", NL ("/"), 2 },
{ "eO", NL ("^="), 2 },
{ "eo", NL ("^"), 2 },
@@ -1875,21 +1883,24 @@ cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
/* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT },
/* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
D_PRINT_DEFAULT },
- /* The decimal floating point and half-precision floating point types
- don't use the normal builtin type encoding, they're just stuck into
- holes in the table for convenience. */
- /* p */ { NL ("decimal32"), NL ("decimal32"), D_PRINT_DEFAULT },
- /* q */ { NL ("decimal64"), NL ("decimal64"), D_PRINT_DEFAULT },
- /* r */ { NL ("decimal128"), NL ("decimal128"), D_PRINT_DEFAULT },
+ /* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT },
/* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
- /* u */ { NL ("half"), NL ("half"), D_PRINT_FLOAT },
+ /* u */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* v */ { NL ("void"), NL ("void"), D_PRINT_VOID },
/* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT },
/* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG },
/* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
D_PRINT_UNSIGNED_LONG_LONG },
/* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },
+ /* 26 */ { NL ("decimal32"), NL ("decimal32"), D_PRINT_DEFAULT },
+ /* 27 */ { NL ("decimal64"), NL ("decimal64"), D_PRINT_DEFAULT },
+ /* 28 */ { NL ("decimal128"), NL ("decimal128"), D_PRINT_DEFAULT },
+ /* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT },
+ /* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT },
+ /* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT },
};
CP_STATIC_IF_GLIBCPP_V3
@@ -2070,30 +2081,38 @@ cplus_demangle_type (struct d_info *di)
case 'p':
/* Pack expansion. */
- return NULL;
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
+ cplus_demangle_type (di), NULL);
+ break;
case 'f':
- /* 32-bit DFP */
- ret = d_make_builtin_type (di,
- &cplus_demangle_builtin_types['p' - 'a']);
+ /* 32-bit decimal floating point */
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'd':
- /* 64-bit decimal floating point */
- ret = d_make_builtin_type (di,
- &cplus_demangle_builtin_types['q' - 'a']);
+ /* 64-bit DFP */
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'e':
/* 128-bit DFP */
- ret = d_make_builtin_type (di,
- &cplus_demangle_builtin_types['r' - 'a']);
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
di->expansion += ret->u.s_builtin.type->len;
break;
case 'h':
/* 16-bit half-precision FP */
- ret = d_make_builtin_type (di,
- &cplus_demangle_builtin_types['u' - 'a']);
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
+ di->expansion += ret->u.s_builtin.type->len;
+ break;
+ case 's':
+ /* char16_t */
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
+ di->expansion += ret->u.s_builtin.type->len;
+ break;
+ case 'i':
+ /* char32_t */
+ ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
di->expansion += ret->u.s_builtin.type->len;
break;
}
@@ -2390,6 +2409,13 @@ d_template_args (struct d_info *di)
if (! d_check_char (di, 'I'))
return NULL;
+ if (d_peek_char (di) == 'E')
+ {
+ /* An argument pack can be empty. */
+ d_advance (di, 1);
+ return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
+ }
+
al = NULL;
pal = &al;
while (1)
@@ -2439,6 +2465,10 @@ d_template_arg (struct d_info *di)
case 'L':
return d_expr_primary (di);
+ case 'I':
+ /* An argument pack. */
+ return d_template_args (di);
+
default:
return cplus_demangle_type (di);
}
@@ -2452,6 +2482,12 @@ d_exprlist (struct d_info *di)
struct demangle_component *list = NULL;
struct demangle_component **p = &list;
+ if (d_peek_char (di) == 'E')
+ {
+ d_advance (di, 1);
+ return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
+ }
+
while (1)
{
struct demangle_component *arg = d_expression (di);
@@ -2515,6 +2551,19 @@ d_expression (struct d_info *di)
d_advance (di, 2);
return cplus_demangle_type (di);
}
+ else if (IS_DIGIT (peek))
+ {
+ /* We can get an unqualified name as an expression in the case of
+ a dependent member access, i.e. decltype(T().i). */
+ struct demangle_component *name = d_unqualified_name (di);
+ if (name == NULL)
+ return NULL;
+ if (d_peek_char (di) == 'I')
+ return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
+ d_template_args (di));
+ else
+ return name;
+ }
else
{
struct demangle_component *op;
@@ -3067,6 +3116,123 @@ cplus_demangle_print (int options, const struct demangle_component *dc,
return dgs.buf;
}
+/* Returns the I'th element of the template arglist ARGS, or NULL on
+ failure. */
+
+static struct demangle_component *
+d_index_template_argument (struct demangle_component *args, int i)
+{
+ struct demangle_component *a;
+
+ for (a = args;
+ a != NULL;
+ a = d_right (a))
+ {
+ if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+ return NULL;
+ if (i <= 0)
+ break;
+ --i;
+ }
+ if (i != 0 || a == NULL)
+ return NULL;
+
+ return d_left (a);
+}
+
+/* Returns the template argument from the current context indicated by DC,
+ which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL. */
+
+static struct demangle_component *
+d_lookup_template_argument (struct d_print_info *dpi,
+ const struct demangle_component *dc)
+{
+ if (dpi->templates == NULL)
+ {
+ d_print_error (dpi);
+ return NULL;
+ }
+
+ return d_index_template_argument
+ (d_right (dpi->templates->template_decl),
+ dc->u.s_number.number);
+}
+
+/* Returns a template argument pack used in DC (any will do), or NULL. */
+
+static struct demangle_component *
+d_find_pack (struct d_print_info *dpi,
+ const struct demangle_component *dc)
+{
+ struct demangle_component *a;
+ if (dc == NULL)
+ return NULL;
+
+ switch (dc->type)
+ {
+ case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+ a = d_lookup_template_argument (dpi, dc);
+ if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+ return a;
+ return NULL;
+
+ case DEMANGLE_COMPONENT_PACK_EXPANSION:
+ return NULL;
+
+ case DEMANGLE_COMPONENT_NAME:
+ case DEMANGLE_COMPONENT_OPERATOR:
+ case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+ case DEMANGLE_COMPONENT_SUB_STD:
+ case DEMANGLE_COMPONENT_CHARACTER:
+ return NULL;
+
+ case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+ return d_find_pack (dpi, dc->u.s_extended_operator.name);
+ case DEMANGLE_COMPONENT_CTOR:
+ return d_find_pack (dpi, dc->u.s_ctor.name);
+ case DEMANGLE_COMPONENT_DTOR:
+ return d_find_pack (dpi, dc->u.s_dtor.name);
+
+ default:
+ a = d_find_pack (dpi, d_left (dc));
+ if (a)
+ return a;
+ return d_find_pack (dpi, d_right (dc));
+ }
+}
+
+/* Returns the length of the template argument pack DC. */
+
+static int
+d_pack_length (const struct demangle_component *dc)
+{
+ int count = 0;
+ while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
+ && d_left (dc) != NULL)
+ {
+ ++count;
+ dc = d_right (dc);
+ }
+ return count;
+}
+
+/* DC is a component of a mangled expression. Print it, wrapped in parens
+ if needed. */
+
+static void
+d_print_subexpr (struct d_print_info *dpi,
+ const struct demangle_component *dc)
+{
+ int simple = 0;
+ if (dc->type == DEMANGLE_COMPONENT_NAME)
+ simple = 1;
+ if (!simple)
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, dc);
+ if (!simple)
+ d_append_char (dpi, ')');
+}
+
/* Subroutine to handle components. */
static void
@@ -3252,30 +3418,13 @@ d_print_comp (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
{
- long i;
- struct demangle_component *a;
struct d_print_template *hold_dpt;
+ struct demangle_component *a = d_lookup_template_argument (dpi, dc);
- if (dpi->templates == NULL)
- {
- d_print_error (dpi);
- return;
- }
- i = dc->u.s_number.number;
- for (a = d_right (dpi->templates->template_decl);
- a != NULL;
- a = d_right (a))
- {
- if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
- {
- d_print_error (dpi);
- return;
- }
- if (i <= 0)
- break;
- --i;
- }
- if (i != 0 || a == NULL)
+ if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+ a = d_index_template_argument (a, dpi->pack_index);
+
+ if (a == NULL)
{
d_print_error (dpi);
return;
@@ -3289,7 +3438,7 @@ d_print_comp (struct d_print_info *dpi,
hold_dpt = dpi->templates;
dpi->templates = hold_dpt->next;
- d_print_comp (dpi, d_left (a));
+ d_print_comp (dpi, a);
dpi->templates = hold_dpt;
@@ -3578,7 +3727,8 @@ d_print_comp (struct d_print_info *dpi,
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
- d_print_comp (dpi, d_left (dc));
+ if (d_left (dc) != NULL)
+ d_print_comp (dpi, d_left (dc));
if (d_right (dc) != NULL)
{
d_append_string (dpi, ", ");
@@ -3618,11 +3768,12 @@ d_print_comp (struct d_print_info *dpi,
d_print_cast (dpi, d_left (dc));
d_append_char (dpi, ')');
}
- d_append_char (dpi, '(');
- if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST
- || d_right (dc)->type != DEMANGLE_COMPONENT_BUILTIN_TYPE)
- d_print_comp (dpi, d_right (dc));
- d_append_char (dpi, ')');
+ if (d_left (dc)->type == DEMANGLE_COMPONENT_CAST
+ && d_right (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
+ /* type() -- FIXME what about type(multiple,args) */
+ d_append_string (dpi, "()");
+ else
+ d_print_subexpr (dpi, d_right (dc));
return;
case DEMANGLE_COMPONENT_BINARY:
@@ -3632,15 +3783,6 @@ d_print_comp (struct d_print_info *dpi,
return;
}
- if (!strcmp (d_left (dc)->u.s_operator.op->code, "cl"))
- {
- d_print_comp (dpi, d_left (d_right (dc)));
- d_append_string (dpi, " (");
- d_print_comp (dpi, d_right (d_right (dc)));
- d_append_char (dpi, ')');
- return;
- }
-
/* We wrap an expression which uses the greater-than operator in
an extra layer of parens so that it does not get confused
with the '>' which ends the template parameters. */
@@ -3649,13 +3791,10 @@ d_print_comp (struct d_print_info *dpi,
&& d_left (dc)->u.s_operator.op->name[0] == '>')
d_append_char (dpi, '(');
- d_append_char (dpi, '(');
- d_print_comp (dpi, d_left (d_right (dc)));
- d_append_string (dpi, ") ");
- d_print_expr_op (dpi, d_left (dc));
- d_append_string (dpi, " (");
- d_print_comp (dpi, d_right (d_right (dc)));
- d_append_char (dpi, ')');
+ d_print_subexpr (dpi, d_left (d_right (dc)));
+ if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
+ d_print_expr_op (dpi, d_left (dc));
+ d_print_subexpr (dpi, d_right (d_right (dc)));
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
&& d_left (dc)->u.s_operator.op->len == 1
@@ -3676,15 +3815,11 @@ d_print_comp (struct d_print_info *dpi,
d_print_error (dpi);
return;
}
- d_append_char (dpi, '(');
- d_print_comp (dpi, d_left (d_right (dc)));
- d_append_string (dpi, ") ");
+ d_print_subexpr (dpi, d_left (d_right (dc)));
d_print_expr_op (dpi, d_left (dc));
- d_append_string (dpi, " (");
- d_print_comp (dpi, d_left (d_right (d_right (dc))));
- d_append_string (dpi, ") : (");
- d_print_comp (dpi, d_right (d_right (d_right (dc))));
- d_append_char (dpi, ')');
+ d_print_subexpr (dpi, d_left (d_right (d_right (dc))));
+ d_append_string (dpi, " : ");
+ d_print_subexpr (dpi, d_right (d_right (d_right (dc))));
return;
case DEMANGLE_COMPONENT_TRINARY_ARG1:
@@ -3797,6 +3932,23 @@ d_print_comp (struct d_print_info *dpi,
d_append_char (dpi, ')');
return;
+ case DEMANGLE_COMPONENT_PACK_EXPANSION:
+ {
+ struct demangle_component *a = d_find_pack (dpi, d_left (dc));
+ int len = d_pack_length (a);
+ int i;
+
+ dc = d_left (dc);
+ for (i = 0; i < len; ++i)
+ {
+ dpi->pack_index = i;
+ d_print_comp (dpi, dc);
+ if (i < len-1)
+ d_append_string (dpi, ", ");
+ }
+ }
+ return;
+
default:
d_print_error (dpi);
return;
diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h
index 8622f29ca89..aad37437400 100644
--- a/libiberty/cp-demangle.h
+++ b/libiberty/cp-demangle.h
@@ -147,7 +147,7 @@ struct d_info
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif
-#define D_BUILTIN_TYPE_COUNT (26)
+#define D_BUILTIN_TYPE_COUNT (32)
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 9358204d2bd..d9efbc0d24e 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3345,7 +3345,7 @@ f<X>
#
--format=gnu-v3 --no-params
_ZngILi42EEvN1AIXplT_Li2EEE1TE
-void operator-<42>(A<(42) + (2)>::T)
+void operator-<42>(A<(42)+(2)>::T)
operator-<42>
#
--format=gnu-v3 --no-params
@@ -3385,7 +3385,7 @@ int* const volatile restrict _far
#
--format=gnu-v3 --no-params
_Z3fooILi2EEvRAplT_Li1E_i
-void foo<2>(int (&) [(2) + (1)])
+void foo<2>(int (&) [(2)+(1)])
foo<2>
#
--format=gnu-v3 --no-params
@@ -3612,13 +3612,13 @@ hairyfunc5
# This is from gcc PR 8861
--format=gnu-v3 --no-params
_Z1fILi1ELc120EEv1AIXplT_cviLd810000000000000000703DAD7A370C5EEE
-void f<1, (char)120>(A<(1) + ((int)((double)[810000000000000000703DAD7A370C5]))>)
+void f<1, (char)120>(A<(1)+((int)((double)[810000000000000000703DAD7A370C5]))>)
f<1, (char)120>
#
# This is also from gcc PR 8861
--format=gnu-v3 --no-params
_Z1fILi1EEv1AIXplT_cvingLf3f800000EEE
-void f<1>(A<(1) + ((int)(-((float)[3f800000])))>)
+void f<1>(A<(1)+((int)(-((float)[3f800000])))>)
f<1>
#
# This is from a libstdc++ debug mode patch.
@@ -3643,7 +3643,7 @@ f
# confusion with the '>' which ends the template parameters.
--format=gnu-v3 --no-params
_Z4dep9ILi3EEvP3fooIXgtT_Li2EEE
-void dep9<3>(foo<((3) > (2))>*)
+void dep9<3>(foo<((3)>(2))>*)
dep9<3>
#
# Watch out for templated version of `operator<'--it needs an extra
@@ -3885,16 +3885,20 @@ java resource java/util/iso4217.properties
# decltype/param placeholder test
--format=gnu-v3
_Z3addIidEDTplsTT_sTT0_ES0_S1_
-decltype ((int) + (double)) add<int, double>(int, double)
-# decltype/T() test
---format=gnu-v3
-_Z4add2IidEDTplcvT_vcvT0_vES0_S1_
-decltype (((int)()) + ((double)())) add2<int, double>(int, double)
+decltype ((int)+(double)) add<int, double>(int, double)
# decltype/fn call test
--format=gnu-v3
_Z4add3IidEDTclL_Z1gEsTT_sTT0_EES0_S1_
-decltype (g (int, double)) add3<int, double>(int, double)
-# Extended floating point types test
+decltype (g(int, double)) add3<int, double>(int, double)
+# new (2008) built in types test
+--format=gnu-v3
+_Z1fDfDdDeDhDsDi
+f(decimal32, decimal64, decimal128, half, char16_t, char32_t)
+# pack expansion test
+--format=gnu-v3
+_Z1fIIPiPfPdEEvDpT_
+void f<int*, float*, double*>(int*, float*, double*)
+# '.' test
--format=gnu-v3
-_Z1fDfDdDeDh
-f(decimal32, decimal64, decimal128, half)
+_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_
+decltype (((A<int>).(g<double>))()) h<A<int>, double>(A<int>, double)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 153e6947eb7..3b2762620f7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,22 @@
+2008-10-07 Jason Merrill <jason@redhat.com>
+
+ PR libstdc++/37761
+ * testsuite/abi/demangle/abi_examples/20.cc: Adjust expected spacing.
+ * testsuite/abi/demangle/abi_text/02.cc: Likewise.
+ * testsuite/abi/demangle/regression/cw-16.cc: Likewise.
+
+2008-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/stl_iterator.h (operator-(const reverse_iterator<>&,
+ const reverse_iterator<>&), operator-(const __normal_iterator<>&,
+ const __normal_iterator<>&), operator-(const move_iterator<>&,
+ const move_iterator<>&)): Use the auto -> return type syntax,
+ implement DR 685.
+
+2008-10-06 Jason Merrill <jason@redhat.com>
+
+ * config/abi/pre/gnu.ver: Update char16/32_t manglings.
+
2008-10-05 Paolo Carlini <paolo.carlini@oracle.com>
* testsuite/20_util/reference_wrapper/invoke.cc: New.
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 56fa9be3e6e..024fcfd4086 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1104,12 +1104,12 @@ CXXABI_1.3.2 {
CXXABI_1.3.3 {
# typeinfo for char16_t and char32_t
- _ZTIu8char16_t;
- _ZTIPu8char16_t;
- _ZTIPKu8char16_t;
- _ZTIu8char32_t;
- _ZTIPu8char32_t;
- _ZTIPKu8char32_t;
+ _ZTIDs;
+ _ZTIPDs;
+ _ZTIPKDs;
+ _ZTIDi;
+ _ZTIPDi;
+ _ZTIPKDi;
# exception_ptr
_ZNSt15__exception_ptr13exception_ptrC1Ev;
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 0d66129fb80..d161e303e30 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -365,9 +365,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ return !(__x < __y); }
template<typename _IteratorL, typename _IteratorR>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // DR 685.
+ inline auto
+ operator-(const reverse_iterator<_IteratorL>& __x,
+ const reverse_iterator<_IteratorR>& __y)
+ -> decltype(__y.base() - __x.base())
+#else
inline typename reverse_iterator<_IteratorL>::difference_type
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
+#endif
{ return __y.base() - __x.base(); }
//@}
@@ -835,9 +843,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// operators but also operator- must accept mixed iterator/const_iterator
// parameters.
template<typename _IteratorL, typename _IteratorR, typename _Container>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // DR 685.
+ inline auto
+ operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
+ const __normal_iterator<_IteratorR, _Container>& __rhs)
+ -> decltype(__lhs.base() - __rhs.base())
+#else
inline typename __normal_iterator<_IteratorL, _Container>::difference_type
operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
+#endif
{ return __lhs.base() - __rhs.base(); }
template<typename _Iterator, typename _Container>
@@ -1001,10 +1017,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const move_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
+ // DR 685.
template<typename _IteratorL, typename _IteratorR>
- inline typename move_iterator<_IteratorL>::difference_type
+ inline auto
operator-(const move_iterator<_IteratorL>& __x,
const move_iterator<_IteratorR>& __y)
+ -> decltype(__x.base() - __y.base())
{ return __x.base() - __y.base(); }
template<typename _Iterator>
diff --git a/libstdc++-v3/testsuite/abi/demangle/abi_examples/20.cc b/libstdc++-v3/testsuite/abi/demangle/abi_examples/20.cc
index eaa5db0430f..1bef745b197 100644
--- a/libstdc++-v3/testsuite/abi/demangle/abi_examples/20.cc
+++ b/libstdc++-v3/testsuite/abi/demangle/abi_examples/20.cc
@@ -29,7 +29,7 @@ int main()
using namespace __gnu_test;
verify_demangle("_ZngILi42EEvN1AIXplT_Li2EEE1TE",
- "void operator-<42>(A<(42) + (2)>::T)");
+ "void operator-<42>(A<(42)+(2)>::T)");
return 0;
}
diff --git a/libstdc++-v3/testsuite/abi/demangle/abi_text/02.cc b/libstdc++-v3/testsuite/abi/demangle/abi_text/02.cc
index 28a617aef7d..9a41fe55c20 100644
--- a/libstdc++-v3/testsuite/abi/demangle/abi_text/02.cc
+++ b/libstdc++-v3/testsuite/abi/demangle/abi_text/02.cc
@@ -33,7 +33,7 @@ int main()
// Equivalent, but formatting difference in void argument and parentheses.
// icc, __cxa_demangle
verify_demangle("_Z3fooILi2EEvRAplT_Li1E_i",
- "void foo<2>(int (&) [(2) + (1)])");
+ "void foo<2>(int (&) [(2)+(1)])");
// cplus-dem
// verify_demangle("_Z3fooILi2EEvRAplT_Li1E_i",
// "void foo<(int)2>(int (&) [((int)2)+((int)1)])");
diff --git a/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc b/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc
index 0c8c29f28af..0db740e991a 100644
--- a/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc
+++ b/libstdc++-v3/testsuite/abi/demangle/regression/cw-16.cc
@@ -32,9 +32,9 @@ verify_demangle("_Z3fooIA6_KiEvA9_KT_rVPrS4_",
"void foo<int const [6]>(int const [9][6], int restrict const (* volatile restrict) [9][6])");
// 2003/11/12, libstdc++/12947
verify_demangle("_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE",
- "void f<5, A>(C<(((5) > (0))) ? (1) : (2)>::q)");
+ "void f<5, A>(C<(((5)>(0)))?(1) : (2)>::q)");
verify_demangle("_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE",
- "void f<5>(A<(int)((5) * (22))>::q)");
+ "void f<5>(A<(int)((5)*(22))>::q)");
verify_demangle("_Z1fPFYPFiiEiE",
"f(int (*(*)(int))(int))");
verify_demangle("_Z1fI1XENT_1tES2_",
@@ -43,9 +43,9 @@ verify_demangle("_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE",
"void f<5, A>(C<sizeof (T::t), sizeof (T::t)>::q)");
// 2003/12/03, libstdc++/13045
verify_demangle("_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE",
- "void f<1, (char)120>(A<(1) + ((int)((double)[4028ae147ae147ae]))>)");
+ "void f<1, (char)120>(A<(1)+((int)((double)[4028ae147ae147ae]))>)");
verify_demangle("_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE",
- "void f<1, (char)120>(A<(1) + ((int)((float)[3f800000]))>)");
+ "void f<1, (char)120>(A<(1)+((int)((float)[3f800000]))>)");
verify_demangle("_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE",
"hairyfunc(int (* const (X::** (* restrict (* volatile* (Y::*)(int) const)(char*)) [2])(long) const) [3])");