From 8104ea26587b5f32d0dc3682faf89ef8f2576474 Mon Sep 17 00:00:00 2001 From: jakub Date: Mon, 21 Nov 2005 14:12:55 +0000 Subject: [PATCH] svn merge -r102224:107263 svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-3_4-branch git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-3_4-rhl-branch@107307 138bc75d-0d04-0410-961f-82ee72b054a4 --- contrib/ChangeLog | 14 + contrib/gcc_update | 53 +-- gcc/ChangeLog | 488 ++++++++++++++++++++- gcc/c-common.c | 12 + gcc/c-common.h | 2 + gcc/c-decl.c | 79 ++-- gcc/c-objc-common.c | 15 +- gcc/c-pch.c | 2 +- gcc/c-typeck.c | 35 +- gcc/cfgcleanup.c | 2 +- gcc/combine.c | 2 +- gcc/config.host | 17 +- gcc/config/arm/arm-protos.h | 6 +- gcc/config/arm/arm.c | 150 +++---- gcc/config/arm/arm.md | 23 +- gcc/config/host-linux.c | 219 +++++++++ gcc/config/host-solaris.c | 79 ++++ gcc/config/i386/i386.c | 1 + gcc/config/i386/i386.md | 6 +- gcc/config/ia64/hpux.h | 7 - gcc/config/m68k/m68k-protos.h | 1 + gcc/config/m68k/m68k.c | 33 ++ gcc/config/m68k/m68k.h | 12 +- gcc/config/m68k/m68k.md | 2 +- gcc/config/mips/mips-protos.h | 2 +- gcc/config/mips/mips.c | 103 ++--- gcc/config/mips/mips.md | 35 +- gcc/config/pa/pa-host.c | 136 ++++++ gcc/config/pa/pa.c | 53 ++- gcc/config/pa/pa.md | 22 +- gcc/config/pa/pa32-regs.h | 69 ++- gcc/config/pa/pa64-regs.h | 28 +- gcc/config/pa/som.h | 4 - gcc/config/pa/x-hpux | 9 + gcc/config/pa/x-linux | 4 + gcc/config/rs6000/host-darwin.c | 36 +- gcc/config/rs6000/rs6000.c | 9 +- gcc/config/rs6000/rs6000.md | 22 +- gcc/config/rs6000/sysv4.h | 10 +- gcc/config/sparc/gmon-sol2.c | 3 +- gcc/config/sparc/sparc.h | 2 +- gcc/config/x-linux | 4 + gcc/config/x-solaris | 4 + gcc/cp/ChangeLog | 261 +++++++++++ gcc/cp/call.c | 21 +- gcc/cp/cvt.c | 2 + gcc/cp/decl.c | 36 +- gcc/cp/decl2.c | 14 +- gcc/cp/error.c | 3 + gcc/cp/init.c | 3 - gcc/cp/lex.c | 24 +- gcc/cp/method.c | 8 +- gcc/cp/name-lookup.c | 48 +- gcc/cp/name-lookup.h | 1 + gcc/cp/parser.c | 231 ++++++---- gcc/cp/pt.c | 27 +- gcc/cp/semantics.c | 4 +- gcc/cp/typeck.c | 18 +- gcc/cppfiles.c | 21 +- gcc/cpphash.h | 2 +- gcc/cppinit.c | 6 +- gcc/doc/hostconfig.texi | 44 +- gcc/doc/install.texi | 15 +- gcc/doc/invoke.texi | 13 +- gcc/fixinc/check.tpl | 3 +- gcc/fixinc/fixincl.x | 35 +- gcc/fixinc/inclhack.def | 2 + gcc/flow.c | 18 +- gcc/fold-const.c | 14 +- gcc/ggc-common.c | 189 ++++---- gcc/global.c | 9 +- gcc/hooks.c | 15 - gcc/hooks.h | 2 - gcc/hosthooks-def.h | 14 +- gcc/hosthooks.h | 12 +- gcc/local-alloc.c | 13 +- gcc/loop.c | 18 - gcc/mklibgcc.in | 25 ++ gcc/po/ChangeLog | 5 + gcc/po/{gcc-3.4.3.rw.po => rw.po} | 0 gcc/reg-stack.c | 2 +- gcc/regrename.c | 6 +- gcc/regs.h | 7 + gcc/simplify-rtx.c | 2 +- gcc/stmt.c | 6 + gcc/testsuite/ChangeLog | 307 +++++++++++++ gcc/testsuite/g++.dg/conversion/const3.C | 7 + gcc/testsuite/g++.dg/eh/synth2.C | 24 + gcc/testsuite/g++.dg/expr/ptrmem7.C | 21 + gcc/testsuite/g++.dg/expr/return1.C | 9 + gcc/testsuite/g++.dg/ext/label5.C | 7 + gcc/testsuite/g++.dg/ext/packed8.C | 20 + gcc/testsuite/g++.dg/ext/stmtexpr4.C | 2 +- gcc/testsuite/g++.dg/lookup/ambig4.C | 14 + gcc/testsuite/g++.dg/lookup/ambig5.C | 13 + gcc/testsuite/g++.dg/lookup/crash5.C | 9 + gcc/testsuite/g++.dg/lookup/error1.C | 9 + gcc/testsuite/g++.dg/lookup/forscope2.C | 9 + gcc/testsuite/g++.dg/lookup/koenig1.C | 2 +- .../g++.dg/lookup/used-before-declaration.C | 4 +- gcc/testsuite/g++.dg/opt/pr23478.C | 211 +++++++++ gcc/testsuite/g++.dg/other/do1.C | 2 +- gcc/testsuite/g++.dg/other/semicolon.C | 9 + gcc/testsuite/g++.dg/overload/koenig1.C | 2 +- gcc/testsuite/g++.dg/parse/crash11.C | 2 +- gcc/testsuite/g++.dg/parse/crash13.C | 4 +- gcc/testsuite/g++.dg/parse/crash30.C | 18 + gcc/testsuite/g++.dg/parse/error18.C | 7 + gcc/testsuite/g++.dg/parse/error21.C | 2 +- gcc/testsuite/g++.dg/parse/explicit1.C | 2 +- gcc/testsuite/g++.dg/parse/friend2.C | 2 +- gcc/testsuite/g++.dg/parse/typename10.C | 8 + gcc/testsuite/g++.dg/parse/typename8.C | 11 + gcc/testsuite/g++.dg/parse/typename9.C | 3 + gcc/testsuite/g++.dg/template/array11.C | 17 + gcc/testsuite/g++.dg/template/crash25.C | 3 + gcc/testsuite/g++.dg/template/crash29.C | 8 + gcc/testsuite/g++.dg/template/crash42.C | 10 + gcc/testsuite/g++.dg/template/error1.C | 2 +- gcc/testsuite/g++.dg/template/error17.C | 8 + gcc/testsuite/g++.dg/template/local5.C | 12 + gcc/testsuite/g++.dg/template/nontype13.C | 29 ++ gcc/testsuite/g++.dg/template/operator5.C | 14 + gcc/testsuite/g++.dg/template/param1.C | 12 + gcc/testsuite/g++.dg/template/ttp5.C | 2 +- gcc/testsuite/g++.dg/template/typedef2.C | 3 + gcc/testsuite/g++.dg/template/typename8.C | 10 + gcc/testsuite/g++.old-deja/g++.other/decl5.C | 4 +- gcc/testsuite/g++.old-deja/g++.other/friend7.C | 2 +- gcc/testsuite/gcc.c-torture/compile/20050721-1.c | 57 +++ gcc/testsuite/gcc.c-torture/compile/pr22589-1.c | 4 + gcc/testsuite/gcc.c-torture/execute/20051021-1.c | 28 ++ gcc/testsuite/gcc.c-torture/execute/pr20187-1.c | 15 + gcc/testsuite/gcc.c-torture/execute/pr20621-1.c | 6 + gcc/testsuite/gcc.c-torture/execute/pr21964-1.c | 16 + gcc/testsuite/gcc.c-torture/execute/pr22061-1.c | 16 + gcc/testsuite/gcc.c-torture/execute/pr22061-2.c | 7 + gcc/testsuite/gcc.c-torture/execute/pr22061-3.c | 18 + gcc/testsuite/gcc.c-torture/execute/pr22061-4.c | 22 + gcc/testsuite/gcc.dg/Wredundant-decls-2.c | 27 ++ gcc/testsuite/gcc.dg/altivec-pr18583.c | 8 + gcc/testsuite/gcc.dg/char-compare.c | 23 + gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-altivec1.c | 16 + gcc/testsuite/gcc.dg/decl-3.c | 2 +- gcc/testsuite/gcc.dg/dg.exp | 2 +- gcc/testsuite/gcc.dg/init-excess-1.c | 48 ++ gcc/testsuite/gcc.dg/nested-redef-1.c | 44 ++ gcc/testsuite/gcc.dg/pch/pch.exp | 15 + gcc/testsuite/gcc.dg/pr17188-1.c | 31 ++ gcc/testsuite/gcc.dg/pr19340.c | 26 ++ gcc/testsuite/gcc.dg/pr22458-1.c | 4 + gcc/testsuite/gcc.dg/pr24101-1.i | 4 + gcc/testsuite/gcc.dg/pr24101-2.i | 4 + gcc/testsuite/gcc.dg/pr24315.c | 9 + gcc/testsuite/gcc.dg/torture/pr18582-1.c | 37 ++ gcc/toplev.c | 6 +- gcc/tree.c | 52 ++- gcc/version.c | 2 +- libffi/ChangeLog | 7 + libffi/src/powerpc/ffi.c | 6 +- libstdc++-v3/ChangeLog | 29 ++ libstdc++-v3/include/bits/c++config | 2 +- libstdc++-v3/include/c_std/std_cmath.h | 66 +-- libstdc++-v3/include/ext/hashtable.h | 4 +- .../21_strings/char_traits/requirements/char/1.cc | 17 +- .../char_traits/requirements/wchar_t/1.cc | 11 +- .../26_numerics/c99_classification_macros_c.cc | 4 +- libstdc++-v3/testsuite/ext/23528.cc | 43 ++ 168 files changed, 3760 insertions(+), 868 deletions(-) create mode 100644 gcc/config/host-linux.c create mode 100644 gcc/config/host-solaris.c create mode 100644 gcc/config/pa/pa-host.c create mode 100644 gcc/config/pa/x-hpux create mode 100644 gcc/config/pa/x-linux create mode 100644 gcc/config/x-linux create mode 100644 gcc/config/x-solaris rename gcc/po/{gcc-3.4.3.rw.po => rw.po} (100%) create mode 100644 gcc/testsuite/g++.dg/conversion/const3.C create mode 100644 gcc/testsuite/g++.dg/eh/synth2.C create mode 100644 gcc/testsuite/g++.dg/expr/ptrmem7.C create mode 100644 gcc/testsuite/g++.dg/expr/return1.C create mode 100644 gcc/testsuite/g++.dg/ext/label5.C create mode 100644 gcc/testsuite/g++.dg/ext/packed8.C create mode 100644 gcc/testsuite/g++.dg/lookup/ambig4.C create mode 100644 gcc/testsuite/g++.dg/lookup/ambig5.C create mode 100644 gcc/testsuite/g++.dg/lookup/crash5.C create mode 100644 gcc/testsuite/g++.dg/lookup/error1.C create mode 100644 gcc/testsuite/g++.dg/lookup/forscope2.C create mode 100644 gcc/testsuite/g++.dg/opt/pr23478.C create mode 100644 gcc/testsuite/g++.dg/other/semicolon.C create mode 100644 gcc/testsuite/g++.dg/parse/crash30.C create mode 100644 gcc/testsuite/g++.dg/parse/error18.C create mode 100644 gcc/testsuite/g++.dg/parse/typename10.C create mode 100644 gcc/testsuite/g++.dg/parse/typename8.C create mode 100644 gcc/testsuite/g++.dg/parse/typename9.C create mode 100644 gcc/testsuite/g++.dg/template/array11.C create mode 100644 gcc/testsuite/g++.dg/template/crash25.C create mode 100644 gcc/testsuite/g++.dg/template/crash29.C create mode 100644 gcc/testsuite/g++.dg/template/crash42.C create mode 100644 gcc/testsuite/g++.dg/template/error17.C create mode 100644 gcc/testsuite/g++.dg/template/local5.C create mode 100644 gcc/testsuite/g++.dg/template/nontype13.C create mode 100644 gcc/testsuite/g++.dg/template/operator5.C create mode 100644 gcc/testsuite/g++.dg/template/param1.C create mode 100644 gcc/testsuite/g++.dg/template/typedef2.C create mode 100644 gcc/testsuite/g++.dg/template/typename8.C create mode 100644 gcc/testsuite/gcc.c-torture/compile/20050721-1.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr22589-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/20051021-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr20187-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr20621-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr21964-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr22061-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr22061-2.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr22061-3.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr22061-4.c create mode 100644 gcc/testsuite/gcc.dg/Wredundant-decls-2.c create mode 100644 gcc/testsuite/gcc.dg/altivec-pr18583.c create mode 100644 gcc/testsuite/gcc.dg/char-compare.c create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-altivec1.c create mode 100644 gcc/testsuite/gcc.dg/init-excess-1.c create mode 100644 gcc/testsuite/gcc.dg/nested-redef-1.c create mode 100644 gcc/testsuite/gcc.dg/pr17188-1.c create mode 100644 gcc/testsuite/gcc.dg/pr19340.c create mode 100644 gcc/testsuite/gcc.dg/pr22458-1.c create mode 100644 gcc/testsuite/gcc.dg/pr24101-1.i create mode 100644 gcc/testsuite/gcc.dg/pr24101-2.i create mode 100644 gcc/testsuite/gcc.dg/pr24315.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr18582-1.c create mode 100644 libstdc++-v3/testsuite/ext/23528.cc diff --git a/contrib/ChangeLog b/contrib/ChangeLog index a665fa5b5e7..9e7315d3683 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,17 @@ +2005-11-17 Eric Botcazou + + Backport from mainline: + * gcc_update: When svn update is called and --silent is used, pass -q. + +2005-11-01 Joseph S. Myers + + * gcc_update: Include revision number in LAST_UPDATED. + +2005-10-28 Daniel Berlin + Ben Elliston + + * gcc_update: Update for svn. + 2005-06-05 Gerald Pfeifer * gennews (files): Update for egcs-1.0 release pages consolidation. diff --git a/contrib/gcc_update b/contrib/gcc_update index 29094e86f2d..b89a9af6a43 100755 --- a/contrib/gcc_update +++ b/contrib/gcc_update @@ -1,10 +1,18 @@ #! /bin/sh # -# Update a local CVS tree from the GCC repository, with an emphasis +# Update a local Subversion tree from the GCC repository, with an emphasis # on treating generated files correctly, so that autoconf, gperf et # al are not required for the ``end'' user. # -# By default all command-line options are passed to `cvs update` in +# (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation +# Originally by Gerald Pfeifer , August 1998. +# +# This script is Free Software, and it can be copied, distributed and +# modified as defined in the GNU General Public License. A copy of +# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html +# +# +# By default all command-line options are passed to `svn update` in # addition to $UPDATE_OPTIONS (defined below). If the first parameter # reads --nostdflags, $UPDATE_OPTIONS as well as this parameter itself # are omitted. @@ -12,7 +20,7 @@ # If the first parameter reads --patch, the second parameter is considered # a patch file. # -# If the first parameter is --touch, no cvs operation will be performed, +# If the first parameter is --touch, no svn operation will be performed, # only generated files that appear to be out of date in the local tree # will be touched. # @@ -24,30 +32,16 @@ # # Examples: # -# contrib/gcc_update -r gcc_latest_snapshot -# contrib/gcc_update -A -# contrib/gcc_update --nostdflags -P -r gcc-2_95-branch gcc/testsuite +# contrib/gcc_update -r 8712 # contrib/gcc_update --patch some-patch # contrib/gcc_update --touch # contrib/gcc_update --list -# -# -# (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation -# Originally by Gerald Pfeifer , August 1998. -# -# This script is Free Software, and it can be copied, distributed and -# modified as defined in the GNU General Public License. A copy of -# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html -# CVS command -GCC_CVS=${GCC_CVS-${CVS-cvs}} -# Default options used when updating via CVS. -UPDATE_OPTIONS=-Pd -# Use -P to prune empty directories. -# Use -d to create any directories that exist in the repository but not -# locally. -# Use -A to reset any sticky tags, dates, or `-k' options. +# SVN command +GCC_SVN=${GCC_SVN-${SVN-svn}} +# Default options used when updating via SVN (none). +UPDATE_OPTIONS="" ######## Anything below shouldn't be changed by regular users. @@ -214,9 +208,9 @@ p esac -# Check whether this indeed looks like a local CVS tree. -if [ ! -d CVS ]; then - echo "This does not seem to be a GCC CVS tree!" +# Check whether this indeed looks like a local SVN tree. +if [ ! -d .svn ]; then + echo "This does not seem to be a GCC SVN tree!" exit fi @@ -227,16 +221,17 @@ else set -- $UPDATE_OPTIONS ${1+"$@"} fi -chat "Updating CVS tree" -$GCC_CVS -q ${silent+-Q} update -r gcc-3_4-branch ${1+"$@"} +chat "Updating SVN tree" + +$GCC_SVN ${silent+-q} --non-interactive update ${1+"$@"} if [ $? -ne 0 ]; then (touch_files_reexec) - echo "CVS update of full tree failed." >&2 + echo "SVN update of full tree failed." >&2 exit 1 fi { date - TZ=UTC date + echo "`TZ=UTC date` (revision `svnversion .`)" } > LAST_UPDATED touch_files_reexec diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e72e751dfdf..95dc73c57db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,485 @@ +2005-11-16 Steve Ellcey + + PR target/24718 + * mklibgcc.in: Create dummy object for libgcc_eh.a + * config/ia64/hpux.h (LIBGCC_SPEC): Remove. + +2005-11-13 Andreas Jaeger + + * fixinc/check.tpl: Handle CVS additionally. + +2005-11-10 Uros Bizjak + + PR target/24315 + * config/i386/i386.md (*pushdi2_rex64 splitter) + (*movdi_1_rex64 splitter): Delay splitting after + flow2 pass only when (optimize > 0 && flag_peephole2). + +2005-11-10 Uros Bizjak + + PR target/19340 + * reg-stack.c (reg_to_stack): Update register liveness also + for flag_sched2_use_traces. + +2005-11-09 Per Bothner + Uros Bizjak + + PR c/24101 + * toplev.c (process_options): Initialize debug_hooks early + in case lang_hooks.post_options ends up calling a debug_hook. + * cppinit.c (read_original_filename): Temporarily set + state.in_directive before calling _cpp_lex_direct for + CPP_HASH tokens. + +2005-11-07 Steve Ellcey + + PR bootstrap/24688 + * fixinc/inclhack.def (sco_math): Add bypass. + * fixinc/fixincl.x: Regenerate. + +2005-11-07 James E Wilson + + PR preprocessor/15220 + * cppfiles.c (_cpp_find_file): New parameter angle_brackets. Fix all + callers. Pass to open_file_failed. + (open_file_failed): New parameter angle_brackets. Fix + all callers. use in print_dep assignment. + * cpphash.h (_cpp_find_file): Add new parm to declaration. + * cppinit.c (cpp_read_main_file): Pass another arg to _cpp_find_file. + +2005-11-05 Andreas Jaeger + + * fixinc/check.tpl: Adopt for move to subversion. + +2005-11-03 Richard Guenther + + PR middle-end/24470 + * fold-const.c (fold): Avoid running in circles if we + got some un-folded subtree. + +2005-10-30 Alan Modra + + PR target/23070 + * config/rs6000/rs6000.c (function_arg): For ABI_V4 calls to + stdarg functions, set/clear the fp marker even when no variable + args are passed. + * config/rs6000/sysv4.h (SUBTARGET_SWITCHES): Describe + -mprototype and -mno-prototype. + +2005-10-21 Alan Modra + + PR target/24465 + * config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Always + use r2 for 64-bit tls .got access. + +2005-10-19 Paolo Bonzini + + * dojump.c (do_jump): Revert the last patch as it breaks Ada. + +2005-10-19 Paolo Bonzini + + PR #19672 + * dojump.c (do_jump): Handle TRUTH_AND_EXPR and TRUTH_OR_EXPR + like TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR, if the branch cost + is low enough. + +2005-10-09 Eric Botcazou + + * config/sparc/gmon-sol2.c (internal_mcount): Mark as used. + +2005-10-08 Janis Johnson + + PR debug/24267 + Partial backport from mainline + 2004-05-04 Paolo Bonzini + Richard Henderson + * tree.c (make_or_reuse_type): New. + (build_common_tree_nodes): Use it. + + PR target/18583 + Partial backport from mainline + 2004-05-04 Paolo Bonzini + Richard Henderson + * c-common.c (vector_types_convertible_p): New function. + * c-common.h: Declare it. + * c-typeck.c (digest_init): Use it. + +2005-10-07 James E Wilson + + PR target/23644 + * doc/invoke.texi (IA-64 Options, item -mtune): Renamed from + -mtune-arch. + +2005-10-01 Richard Earnshaw + + PR target/23985 + Back-port 2004-08-19 Richard Henderson + * config/arm/arm.c (arm_gen_load_multiple): Use + adjust_automodify_address. Take base memory and offset instead + of unchanging/struct/scalar bits. + (arm_gen_store_multiple): Likewise. + (arm_gen_movstrqi): Use adjust_automodify_address. + * config/arm/arm-protos.h: Update decls. + * config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call. + (store_multiple): Similarly. + +2005-09-29 Alan Modra + + PR target/24102 + * config/rs6000/rs6000.md (floatdisf2_internal2): Correct range + check for numbers that need no bit twiddle. + +2005-09-09 Richard Guenther + + PR c/20239 + * cppinit.c (cpp_read_main_file): Avoid segfaulting on + NULL pfile->map. + +2005-09-09 Richard Guenther + + PR c++/23624 + * fold-const.c (fold): Check truth_value_p before calling + invert_truthvalue. + +2005-09-08 Craig Rodrigues + + Backport from mainline + 2005-09-01 Craig Rodrigues + + * c-decl.c (diagnose_mismatched_decls): With -Wredundant-decls, + do not issue warning for a variable definition following + a declaration. + +2005-09-02 Richard Sandiford + + PR c/22061 + * c-decl.c (push_parm_decl): Push and pop x_dont_save_pending_sizes_p + around the call to grokdeclarator. Call grokdeclarator with the + field set to 0. + (store_parm_decls): Always store the pending_sizes in cfun. + (c_expand_body_1): Call put_pending_sizes. + * c-objc-common.c (c_cannot_inline_tree_fn): Always check + pending_sizes. + +2005-09-01 Jakub Jelinek + + PR rtl-optimization/23478 + * regs.h (reg_info): Add throw_calls_crossed. + (REG_N_THROWING_CALLS_CROSSED): Define. + * flow.c (allocate_reg_life_data): Initialize + REG_N_THROWING_CALLS_CROSSED. + (propagate_one_insn, attempt_auto_inc): Update + REG_N_THROWING_CALLS_CROSSED. + * local-alloc.c (struct qty): Add n_throwing_calls_crossed field. + (alloc_qty): Initialize it. + (update_equiv_regs): Clear REG_N_THROWING_CALLS_CROSSED. + (combine_regs): Combine also n_throwing_calls_crossed fields. + (find_free_reg): Don't attempt to caller-save pseudos crossing + calls that might throw. + * global.c (struct allocno): Add throwing_calls_crossed field. + (global_alloc): Initialize throwing_calls_crossed. + (find_reg): Don't attempt to caller-save pseudos crossing calls that + might throw. + +2005-09-01 Richard Earnshaw + + PR rtl-optimization/17810 target/15342 + * regrename.c: Fix polluted patch in previous change. + +2005-09-01 Richard Earnshaw + + PR rtl-optimization/17810 + Backport + 2004-11-04 Richard Sandiford + PR target/15342 + * regrename.c (scan_rtx): Treat the destinations of SETs and CLOBBERs + as OP_INOUT if the instruction is predicated. + +2005-08-31 David Edelsohn + + PR target/23539 + Backport from mainline: + + 2005-08-27 David Edelsohn + * config/rs6000/rs6000.c (expand_block_move): Use HImode when + bytes >= 2 not bytes == 2. + +2005-08-21 Jakub Jelinek + + * simplify-rtx.c (simplify_immed_subreg) : Only + clear up to elem_bitsize bits, not max_bitsize. + +2005-07-20 Steve Ellcey + + PR target/21841 + * doc/invoke.texi (-mgnu-ld): Update description. + (-mhp-ld): Ditto. + +2005-08-09 Paolo Bonzini + + PR rtl-optimization/17860 + * loop.c (check_dbra_loop): Do not try to use an end condition + like "i != 0" in the reversed loop. + +2005-08-08 Josh Conner + + PR rtl-optimization/23241 + * combine.c (simplify_comparison): Fix error in determining + whether to lift a subreg from comparison. + +2005-08-08 Richard Sandiford + + PR middle-end/21964 + * stmt.c (tail_recursion_args): Insert a call to emit_queue. + +2005-08-08 Richard Sandiford + + PR c/22458 + * c-decl.c (c_begin_compound_stmt): Set the initial body to + error_mark_node, not NULL. + +2005-08-07 John David Anglin + + * pa64-regs.h (CONDITIONAL_REGISTER_USAGE): Fix loop upper bound. + +2005-08-06 John David Anglin + + PR pch/14940 + Backport from mainline: + + * config.host (hppa*-*-hpux*, hppa*-*-linux): Define out_host_hook_obj + and host_xmake_file using new host configuration files. + * config/pa/pa-host.c, config/pa/x-hpux, config/pa/x-linux: New files. + +2005-08-06 Christian Joensson + + PR target/20673 + Backport from mainline: + + 2005-04-15 David S. Miller + + * config/sparc/sparc.h (sparc_hard_reg_printed): Mark as GTY(()). + +2005-08-05 John David Anglin + + * pa.c (function_arg): Fix typo in last change. + + * pa.c (function_value): Handle small aggregates on 32-bit targets. + (function_arg): Pass small aggregates in general registers on 32-bit + targets. + * som.h (MEMBER_TYPE_FORCES_BLK): Delete define. + +2005-08-04 Gerald Pfeifer + + * doc/install.texi (Specific): Adjust link to openavr.org. + (Specific): Remove broken reference to GCC 2.8.1 for OS/2. + (Binaries): Adjust HP-UX Porting Center link. + (Binaries): Adjust Free Software Foundation ordering link. + (Binaries): Remove broken link to Sinix/Reliant Unix binaries. + +2005-08-04 Eric Botcazou + + * doc/invoke.texi (Optimize Options): Document that -funswitch-loops + is enabled at -O3. + +2005-08-03 John David Anglin + + PR target/21723 + * pa.md: Remove fcpy alternative from movhi and movqi patterns. + * pa32-regs.h (HARD_REGNO_NREGS): Return two floating point registers + for complex modes when generating code for PA 1.0. + (VALID_FP_MODE_P): New macro. + (HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P. Use non-overlapping register + sets for all general and floating point modes. Align wide floating + point modes to even register boundaries to comply with architectural + requirements. + (CLASS_MAX_NREGS): Update to align with change to HARD_REGNO_NREGS. + * pa64-regs.h (HARD_REGNO_NREGS): Update comment and formatting. + (VALID_FP_MODE_P): New macro. + (HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P. Use non-overlapping register + sets for all general and floating point modes. Align wide floating + point modes to even register boundaries to comply with architectural + requirements. + +2005-08-03 Richard Sandiford + + PR target/18582 + * config/i386/i386.c (ix86_expand_unop_builtin): Force the target + to be a register if do_load is true. + +2005-08-02 Ian Lance Taylor + + PR pch/14400 + Backport from mainline: + + 2005-08-01 Ian Lance Taylor + + * config/host-linux.c (linux_gt_pch_get_address): Add new name + randomize_va_space for virtual address randomization control. + + 2005-02-15 James A. Morrison + + PR pch/14940 + PR target/19300 + * config/host-linux.c (linux_gt_pch_use_address): Copy from + config/pa/pa-host.c:pa_gt_pch_use_address. + + 2004-11-09 James A. Morrison + + PR pch/14940 + * config/host-linux.c (TRY_EMPTY_VM_SPACE): Add __sparc__ + definitions. + + 2004-10-15 Jon Grimm + + * config/host-linux.c (TRY_EMPTY_VM_SPACE): Add __powerpc__ + definition. + + 2004-04-24 Ulrich Weigand + + * config/host-linux.c (TRY_EMPTY_VM_SPACE): Define for __s390__ + and __s390x__ hosts. + + 2004-04-08 Ian Lance Taylor + + * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address): + Return 1 if file was successfully mapped. + + 2004-03-15 Ian Lance Taylor + + * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address): + Fix the check for abort and only do the mmap if we can. + + 2004-03-12 Andrew Pinski + + * config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address): + Use ret instead of result. Use addr instead of base. + + 2004-03-10 Richard Henderson + + * c-pch.c (c_common_no_more_pch): Update for gt_pch_use_address + extra arguments. + * config.host (*-*-solaris2*, *-*-linux*): Add out_host_hook_obj + and host_xmake_file fragments. + * ggc-common.c (gt_pch_save): Update for gt_pch_get_address change. + (gt_pch_restore): Similarly for gt_pch_use_address. + (default_gt_pch_get_address): New. + (mmap_gt_pch_get_address): Split out of gt_pch_save. + (default_gt_pch_use_address): Split out of gt_pch_restore. + (mmap_gt_pch_use_address): Likewise. + * hooks.c (hook_voidp_size_t_null): Remove. + (hook_bool_voidp_size_t_false): Remove. + * hooks.h: Likewise. + * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): Use one of the + default_ or mmap_ definitions. + (HOST_HOOKS_GT_PCH_USE_ADDRESS): Likewise. + * hosthooks.h (struct host_hooks): Update gt_pch_get_address + and gt_pch_use_address. + * config/host-linux.c, config/host-solaris.c: New files. + * config/x-linux, config/x-solaris: New files. + * config/rs6000/host-darwin.c darwin_rs6000_gt_pch_get_address): + Update for changed definition. + (darwin_rs6000_gt_pch_use_address): Likewise. + * doc/hostconfig.texi: Update docs. + +2005-07-31 Richard Sandiford + + PR target/20621 + Backport from mainline: + + 2004-08-01 Richard Sandiford + * config/mips/mips.md (cprestore): Provide two alternatives, one for + an in-range offset and one for an out-of-range offset. Wrap the latter + in .set macro/.set nomacro if it's inside a .set nomacro block. + + 2004-08-01 Richard Sandiford + * config/mips/mips-protos.h (mips_gp_save_slot): Remove. + (mips_restore_gp): Declare. + * config/mips/mips.c (mips_add_offset): Add a scratch register + argument. Reimplement in rtl only, reusing MIPS16 logic from + mips_output_mi_thunk. + (mips_legitimize_address, mips_legitimize_const_move): Adjust calls + to mips_add_offset. + (mips_gp_save_slot): Delete. + (mips_restore_gp): New function. + (mips_set_return_address, mips_output_mi_thunk): Use mips_add_offset. + * config/mips/mips.md (exception_receiver): Turn into a + define_insn_and_split. Use mips_restore_gp to do the split. + (call_internal, call_value_internal, call_value_multiple_internal): Use + mips_restore_gp to restore $gp. + +2005-07-29 Alan Modra + + * config/rs6000/sysv4.h (TARGET_ASM_EXCEPTION_SECTION): Delete. + +2005-07-28 Richard Henderson + + PR rtl-opt/22619 + * cfgcleanup.c (try_forward_edges): Watch out for end of + insn chain. + +2005-07-28 Joseph S. Myers + + PR c/17188 + PR c/21899 + * c-decl.c (diagnose_mismatched_decls): Check for duplicate + declarations of enumerators. + (start_struct): Check TYPE_SIZE rather than TYPE_FIELDS to check + for redefinition. Check for nested redefinition. + (finish_struct): Don't check for nested redefinition. + (start_enum): Check for nested redefinition. + +2005-07-28 Joseph S. Myers + + PR c/21873 + * c-typeck.c (push_init_level): Don't pop levels without braces if + implicit == 1. + +2005-07-28 Gerald Pfeifer + + * doc/install.texi (Configuration): Update Valgrind homepage. + +2005-07-28 Richard Sandiford + + PR c/20187 + * fold-const.c (fold): When shortening comparisons of widened operands, + check whether the tree returned by get_unwidened really is wider. + +2005-07-28 Richard Sandiford + + PR c/22589 + Backport from mainline: + + 2004-06-16 Alexandre Oliva + * tree.c (get_narrower): Don't narrow integral types into + non-integral types. + +2005-07-26 Bernardo Innocenti + + Backport from mainline: + 2005-07-12 Peter Barada + PR middle-end/16719 + PR middle-end/18421 + * config/m68k/m68k.h (HARD_REGNO_MODE_OK): Disallow bytes + in address registers. + * config/m68k/m68k.c (hard_regno_mode_ok): Likewise. + * config/m68k/m68k.md: Replace 's' with 'i' in 4th + alternative of addsi3_5200. + +2005-07-21 Janis Johnson + + PR target/20191 + Backport from mainline: + + 2004-04-23 Dale Johannesen + + * config/rs6000.md (movsf_hardfloat): Add POWER form of nop. + (movdf_hardfloat64): Ditto. + (movdf_softfloat64): Ditto. + + * config/rs6000.md (movsf_hardfloat): Accept CTR-to-CTR copy. + (movdf_hardfloat64): Ditto. + 2005-07-21 Richard Sandiford PR rtl-optimization/22167 @@ -41,9 +523,9 @@ 2005-06-04 Richard Henderson - PR target/21888 - * config/alpha/alpha.c (alpha_align_insns): Don't insert nops - until we've passed initial ldgp. + PR target/21888 + * config/alpha/alpha.c (alpha_align_insns): Don't insert nops + until we've passed initial ldgp. 2005-06-01 Richard Henderson diff --git a/gcc/c-common.c b/gcc/c-common.c index eaf54beedd9..8515c70c2f4 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1278,6 +1278,18 @@ constant_fits_type_p (tree c, tree type) return !TREE_OVERFLOW (c); } +/* Nonzero if vector types T1 and T2 can be converted to each other + without an explicit cast. */ +int +vector_types_convertible_p (tree t1, tree t2) +{ + return targetm.vector_opaque_p (t1) + || targetm.vector_opaque_p (t2) + || (tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2)) + && INTEGRAL_TYPE_P (TREE_TYPE (t1)) + == INTEGRAL_TYPE_P (TREE_TYPE (t2))); +} + /* Convert EXPR to TYPE, warning about conversion problems with constants. Invoke this function on every expression that is converted implicitly, i.e. because of language rules and not because of an explicit cast. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 3b37c9330be..1cd9c2c4848 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -1266,6 +1266,8 @@ extern tree finish_label_address_expr (tree); different implementations. Used in c-common.c. */ extern tree lookup_label (tree); +extern int vector_types_convertible_p (tree t1, tree t2); + extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *); extern int c_safe_from_p (rtx, tree); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index a38b09a760c..c017806c4d4 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -955,6 +955,15 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, return false; } + /* Enumerators have no linkage, so may only be declared once in a + given scope. */ + if (TREE_CODE (olddecl) == CONST_DECL) + { + error ("%Jredeclaration of enumerator `%D'", newdecl, newdecl); + locate_old_decl (olddecl, error); + return false; + } + if (!comptypes (oldtype, newtype, COMPARE_STRICT)) { if (TREE_CODE (olddecl) == FUNCTION_DECL @@ -1261,7 +1270,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl)) /* Don't warn about forward parameter decls. */ && !(TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))) + && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)) + /* Don't warn about a variable definition following a declaration. */ + && !(TREE_CODE (newdecl) == VAR_DECL + && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))) { warning ("%Jredundant redeclaration of '%D'", newdecl, newdecl); warned = true; @@ -2953,12 +2965,21 @@ void push_parm_decl (tree parm) { tree decl; + int old_dont_save_pending_sizes_p = 0; /* Don't attempt to expand sizes while parsing this decl. (We can get here with i_s_e 1 somehow from Objective-C.) */ int save_immediate_size_expand = immediate_size_expand; immediate_size_expand = 0; + /* If this is a nested function, we do want to keep SAVE_EXPRs for + the argument sizes, regardless of the parent's setting. */ + if (cfun) + { + old_dont_save_pending_sizes_p = cfun->x_dont_save_pending_sizes_p; + cfun->x_dont_save_pending_sizes_p = 0; + } + decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)), TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0, NULL); @@ -2968,6 +2989,8 @@ push_parm_decl (tree parm) finish_decl (decl, NULL_TREE, NULL_TREE); + if (cfun) + cfun->x_dont_save_pending_sizes_p = old_dont_save_pending_sizes_p; immediate_size_expand = save_immediate_size_expand; } @@ -4781,13 +4804,22 @@ start_struct (enum tree_code code, tree name) ref = lookup_tag (code, name, 1); if (ref && TREE_CODE (ref) == code) { - if (TYPE_FIELDS (ref)) + if (TYPE_SIZE (ref)) { if (code == UNION_TYPE) error ("redefinition of `union %s'", IDENTIFIER_POINTER (name)); else error ("redefinition of `struct %s'", IDENTIFIER_POINTER (name)); } + else if (C_TYPE_BEING_DEFINED (ref)) + { + if (code == UNION_TYPE) + error ("nested redefinition of `union %s'", + IDENTIFIER_POINTER (name)); + else + error ("nested redefinition of `struct %s'", + IDENTIFIER_POINTER (name)); + } } else { @@ -5002,11 +5034,6 @@ finish_struct (tree t, tree fieldlist, tree attributes) if (C_DECL_VARIABLE_SIZE (x)) C_TYPE_VARIABLE_SIZE (t) = 1; - /* Detect invalid nested redefinition. */ - if (TREE_TYPE (x) == t) - error ("nested redefinition of `%s'", - IDENTIFIER_POINTER (TYPE_NAME (t))); - if (DECL_INITIAL (x)) { unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1); @@ -5204,6 +5231,9 @@ start_enum (tree name) pushtag (name, enumtype); } + if (C_TYPE_BEING_DEFINED (enumtype)) + error ("nested redefinition of `enum %s'", IDENTIFIER_POINTER (name)); + C_TYPE_BEING_DEFINED (enumtype) = 1; if (TYPE_VALUES (enumtype) != 0) @@ -5976,9 +6006,6 @@ store_parm_decls (void) { tree fndecl = current_function_decl; - /* The function containing FNDECL, if any. */ - tree context = decl_function_context (fndecl); - /* True if this definition is written with a prototype. */ bool prototype = (current_function_parms && TREE_CODE (current_function_parms) != TREE_LIST); @@ -6003,20 +6030,9 @@ store_parm_decls (void) /* Begin the statement tree for this function. */ begin_stmt_tree (&DECL_SAVED_TREE (fndecl)); - /* If this is a nested function, save away the sizes of any - variable-size types so that we can expand them when generating - RTL. */ - if (context) - { - tree t; - - DECL_LANG_SPECIFIC (fndecl)->pending_sizes - = nreverse (get_pending_sizes ()); - for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes; - t; - t = TREE_CHAIN (t)) - SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = context; - } + /* Save away the sizes of any variable-size types so that we can + expand them when generating RTL. */ + DECL_LANG_SPECIFIC (fndecl)->pending_sizes = get_pending_sizes (); /* This function is being processed in whole-function mode. */ cfun->x_whole_function_mode_p = 1; @@ -6167,15 +6183,12 @@ static void c_expand_body_1 (tree fndecl, int nested_p) { if (nested_p) - { - /* Make sure that we will evaluate variable-sized types involved - in our function's type. */ - expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes); - - /* Squirrel away our current state. */ - push_function_context (); - } + /* Squirrel away our current state. */ + push_function_context (); + /* Make sure that we will evaluate variable-sized types involved + in our function's type. */ + put_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes); tree_rest_of_compilation (fndecl, nested_p); if (nested_p) @@ -6396,7 +6409,7 @@ c_begin_compound_stmt (void) tree stmt; /* Create the COMPOUND_STMT. */ - stmt = add_stmt (build_stmt (COMPOUND_STMT, NULL_TREE)); + stmt = add_stmt (build_stmt (COMPOUND_STMT, error_mark_node)); return stmt; } diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c index fe0c0d5b933..0efa2adc372 100644 --- a/gcc/c-objc-common.c +++ b/gcc/c-objc-common.c @@ -118,17 +118,12 @@ c_cannot_inline_tree_fn (tree *fnp) } } - if (! DECL_FILE_SCOPE_P (fn)) + if (DECL_LANG_SPECIFIC (fn)->pending_sizes) { - /* If a nested function has pending sizes, we may have already - saved them. */ - if (DECL_LANG_SPECIFIC (fn)->pending_sizes) - { - if (do_warning) - warning ("%Jnested function '%F' can never be inlined because it " - "has possibly saved pending sizes", fn, fn); - goto cannot_inline; - } + if (do_warning) + warning ("%Jfunction '%F' can never be inlined because it has " + "pending sizes", fn, fn); + goto cannot_inline; } return 0; diff --git a/gcc/c-pch.c b/gcc/c-pch.c index 8e4b6024359..45898642966 100644 --- a/gcc/c-pch.c +++ b/gcc/c-pch.c @@ -428,6 +428,6 @@ c_common_no_more_pch (void) if (cpp_get_callbacks (parse_in)->valid_pch) { cpp_get_callbacks (parse_in)->valid_pch = NULL; - host_hooks.gt_pch_use_address (NULL, 0); + host_hooks.gt_pch_use_address (NULL, 0, -1, 0); } } diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index c9479f08d12..42c7b77609b 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4098,7 +4098,8 @@ digest_init (tree type, tree init, int require_constant) vector constructor is not constant (e.g. {1,2,3,foo()}) then punt below and handle as a constructor. */ if (code == VECTOR_TYPE - && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT) + && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE + && vector_types_convertible_p (TREE_TYPE (inside_init), type) && TREE_CONSTANT (inside_init)) { if (TREE_CODE (inside_init) == VECTOR_CST @@ -4634,19 +4635,27 @@ push_init_level (int implicit) tree value = NULL_TREE; /* If we've exhausted any levels that didn't have braces, - pop them now. */ - while (constructor_stack->implicit) + pop them now. If implicit == 1, this will have been done in + process_init_element; do not repeat it here because in the case + of excess initializers for an empty aggregate this leads to an + infinite cycle of popping a level and immediately recreating + it. */ + if (implicit != 1) { - if ((TREE_CODE (constructor_type) == RECORD_TYPE - || TREE_CODE (constructor_type) == UNION_TYPE) - && constructor_fields == 0) - process_init_element (pop_init_level (1)); - else if (TREE_CODE (constructor_type) == ARRAY_TYPE - && constructor_max_index - && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1)); - else - break; + while (constructor_stack->implicit) + { + if ((TREE_CODE (constructor_type) == RECORD_TYPE + || TREE_CODE (constructor_type) == UNION_TYPE) + && constructor_fields == 0) + process_init_element (pop_init_level (1)); + else if (TREE_CODE (constructor_type) == ARRAY_TYPE + && constructor_max_index + && tree_int_cst_lt (constructor_max_index, + constructor_index)) + process_init_element (pop_init_level (1)); + else + break; + } } /* Unless this is an explicit brace, we need to preserve previous diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 06fb9131a0d..7321b073403 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -521,7 +521,7 @@ try_forward_edges (int mode, basic_block b) && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) break; - if (GET_CODE (insn) == NOTE) + if (insn && GET_CODE (insn) == NOTE) break; /* Do not clean up branches to just past the end of a loop diff --git a/gcc/combine.c b/gcc/combine.c index ba7ff5384af..cd7d369b178 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -10739,7 +10739,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1) /* (A - C1) always sign-extends, like C2. */ && num_sign_bit_copies (a, inner_mode) > (unsigned int) (GET_MODE_BITSIZE (inner_mode) - - mode_width - 1))) + - (mode_width - 1)))) { op0 = SUBREG_REG (op0); continue; diff --git a/gcc/config.host b/gcc/config.host index fa6bced73db..e4f035731a9 100644 --- a/gcc/config.host +++ b/gcc/config.host @@ -103,7 +103,12 @@ case ${host} in hppa1.0-*-hpux10* | hppa1.1-*-hpux10* | hppa2*-*-hpux10* | \ hppa1.0-*-hpux11* | hppa1.1-*-hpux11* | hppa2*-*-hpux11* | \ hppa*64*-*-hpux11*) - host_xmake_file="pa/x-ada" + out_host_hook_obj=pa-host.o + host_xmake_file=pa/x-hpux + ;; + hppa*-*-linux*) + out_host_hook_obj=pa-host.o + host_xmake_file=pa/x-linux ;; i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture host_xm_defines='FATAL_EXIT_CODE=12' @@ -113,6 +118,8 @@ case ${host} in ;; i[34567]86-*-solaris2*) host_xm_defines="SMALL_ARG_MAX" + out_host_hook_obj=host-solaris.o + host_xmake_file=x-solaris ;; i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4 host_xm_defines="SMALL_ARG_MAX" @@ -152,4 +159,12 @@ case ${host} in out_host_hook_obj=host-darwin.o host_xmake_file=rs6000/x-darwin ;; + *-*-solaris2*) + out_host_hook_obj=host-solaris.o + host_xmake_file=x-solaris + ;; + *-*-linux*) + out_host_hook_obj=host-linux.o + host_xmake_file=x-linux + ;; esac diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 2da99b82d67..0b28e74ea4f 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -105,8 +105,10 @@ extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); extern const char *emit_ldm_seq (rtx *, int); extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *); extern const char * emit_stm_seq (rtx *, int); -extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int); -extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int); +extern rtx arm_gen_load_multiple (int, int, rtx, int, int, + rtx, HOST_WIDE_INT *); +extern rtx arm_gen_store_multiple (int, int, rtx, int, int, + rtx, HOST_WIDE_INT *); extern int arm_gen_movstrqi (rtx *); extern rtx arm_gen_rotated_half_load (rtx); extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 95188944be3..2f0eaedbe13 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5158,13 +5158,13 @@ multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) rtx arm_gen_load_multiple (int base_regno, int count, rtx from, int up, - int write_back, int unchanging_p, int in_struct_p, - int scalar_p) + int write_back, rtx basemem, HOST_WIDE_INT *offsetp) { + HOST_WIDE_INT offset = *offsetp; int i = 0, j; rtx result; int sign = up ? 1 : -1; - rtx mem; + rtx mem, addr; /* XScale has load-store double instructions, but they have stricter alignment requirements than load-store multiple, so we can not @@ -5202,15 +5202,17 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up, for (i = 0; i < count; i++) { - mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign)); - RTX_UNCHANGING_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (from, i * 4 * sign); + mem = adjust_automodify_address (basemem, SImode, addr, offset); emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem); + offset += 4 * sign; } if (write_back) - emit_move_insn (from, plus_constant (from, count * 4 * sign)); + { + emit_move_insn (from, plus_constant (from, count * 4 * sign)); + *offsetp = offset; + } seq = get_insns (); end_sequence (); @@ -5231,26 +5233,28 @@ arm_gen_load_multiple (int base_regno, int count, rtx from, int up, for (j = 0; i < count; i++, j++) { - mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign)); - RTX_UNCHANGING_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (from, j * 4 * sign); + mem = adjust_automodify_address_nv (basemem, SImode, addr, offset); XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem); + offset += 4 * sign; } + if (write_back) + *offsetp = offset; + return result; } rtx arm_gen_store_multiple (int base_regno, int count, rtx to, int up, - int write_back, int unchanging_p, int in_struct_p, - int scalar_p) + int write_back, rtx basemem, HOST_WIDE_INT *offsetp) { + HOST_WIDE_INT offset = *offsetp; int i = 0, j; rtx result; int sign = up ? 1 : -1; - rtx mem; + rtx mem, addr; /* See arm_gen_load_multiple for discussion of the pros/cons of ldm/stm usage for XScale. */ @@ -5262,15 +5266,17 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up, for (i = 0; i < count; i++) { - mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign)); - RTX_UNCHANGING_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; + addr = plus_constant (to, i * 4 * sign); + mem = adjust_automodify_address (basemem, SImode, addr, offset); emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i)); + offset += 4 * sign; } if (write_back) - emit_move_insn (to, plus_constant (to, count * 4 * sign)); + { + emit_move_insn (to, plus_constant (to, count * 4 * sign)); + *offsetp = offset; + } seq = get_insns (); end_sequence (); @@ -5291,15 +5297,16 @@ arm_gen_store_multiple (int base_regno, int count, rtx to, int up, for (j = 0; i < count; i++, j++) { - mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign)); - RTX_UNCHANGING_P (mem) = unchanging_p; - MEM_IN_STRUCT_P (mem) = in_struct_p; - MEM_SCALAR_P (mem) = scalar_p; - + addr = plus_constant (to, j * 4 * sign); + mem = adjust_automodify_address_nv (basemem, SImode, addr, offset); XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j)); + offset += 4 * sign; } + if (write_back) + *offsetp = offset; + return result; } @@ -5307,13 +5314,11 @@ int arm_gen_movstrqi (rtx *operands) { HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes; + HOST_WIDE_INT srcoffset, dstoffset; int i; - rtx src, dst; - rtx st_src, st_dst, fin_src, fin_dst; + rtx src, dst, srcbase, dstbase; rtx part_bytes_reg = NULL; rtx mem; - int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p; - int dst_scalar_p, src_scalar_p; if (GET_CODE (operands[2]) != CONST_INT || GET_CODE (operands[3]) != CONST_INT @@ -5321,23 +5326,17 @@ arm_gen_movstrqi (rtx *operands) || INTVAL (operands[3]) & 3) return 0; - st_dst = XEXP (operands[0], 0); - st_src = XEXP (operands[1], 0); - - dst_unchanging_p = RTX_UNCHANGING_P (operands[0]); - dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]); - dst_scalar_p = MEM_SCALAR_P (operands[0]); - src_unchanging_p = RTX_UNCHANGING_P (operands[1]); - src_in_struct_p = MEM_IN_STRUCT_P (operands[1]); - src_scalar_p = MEM_SCALAR_P (operands[1]); - - fin_dst = dst = copy_to_mode_reg (SImode, st_dst); - fin_src = src = copy_to_mode_reg (SImode, st_src); + dstbase = operands[0]; + srcbase = operands[1]; + + dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0)); + src = copy_to_mode_reg (SImode, XEXP (srcbase, 0)); in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2])); out_words_to_go = INTVAL (operands[2]) / 4; last_bytes = INTVAL (operands[2]) & 3; - + dstoffset = srcoffset = 0; + if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0) part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3); @@ -5345,38 +5344,32 @@ arm_gen_movstrqi (rtx *operands) { if (in_words_to_go > 4) emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE, - src_unchanging_p, - src_in_struct_p, - src_scalar_p)); + srcbase, &srcoffset)); else emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, - FALSE, src_unchanging_p, - src_in_struct_p, src_scalar_p)); + FALSE, srcbase, &srcoffset)); if (out_words_to_go) { if (out_words_to_go > 4) emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE, - dst_unchanging_p, - dst_in_struct_p, - dst_scalar_p)); + dstbase, &dstoffset)); + else if (out_words_to_go != 1) emit_insn (arm_gen_store_multiple (0, out_words_to_go, dst, TRUE, (last_bytes == 0 ? FALSE : TRUE), - dst_unchanging_p, - dst_in_struct_p, - dst_scalar_p)); + dstbase, &dstoffset)); else { - mem = gen_rtx_MEM (SImode, dst); - RTX_UNCHANGING_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset); emit_move_insn (mem, gen_rtx_REG (SImode, 0)); if (last_bytes != 0) - emit_insn (gen_addsi3 (dst, dst, GEN_INT (4))); + { + emit_insn (gen_addsi3 (dst, dst, GEN_INT (4))); + dstoffset += 4; + } } } @@ -5388,20 +5381,12 @@ arm_gen_movstrqi (rtx *operands) if (out_words_to_go) { rtx sreg; - - mem = gen_rtx_MEM (SImode, src); - RTX_UNCHANGING_P (mem) = src_unchanging_p; - MEM_IN_STRUCT_P (mem) = src_in_struct_p; - MEM_SCALAR_P (mem) = src_scalar_p; - emit_move_insn (sreg = gen_reg_rtx (SImode), mem); - emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4)); - - mem = gen_rtx_MEM (SImode, dst); - RTX_UNCHANGING_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + + mem = adjust_automodify_address (srcbase, SImode, src, srcoffset); + sreg = copy_to_reg (mem); + + mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset); emit_move_insn (mem, sreg); - emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4)); in_words_to_go--; if (in_words_to_go) /* Sanity check */ @@ -5413,10 +5398,7 @@ arm_gen_movstrqi (rtx *operands) if (in_words_to_go < 0) abort (); - mem = gen_rtx_MEM (SImode, src); - RTX_UNCHANGING_P (mem) = src_unchanging_p; - MEM_IN_STRUCT_P (mem) = src_in_struct_p; - MEM_SCALAR_P (mem) = src_scalar_p; + mem = adjust_automodify_address (srcbase, SImode, src, srcoffset); part_bytes_reg = copy_to_mode_reg (SImode, mem); } @@ -5434,10 +5416,9 @@ arm_gen_movstrqi (rtx *operands) while (last_bytes) { - mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1)); - RTX_UNCHANGING_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, QImode, + plus_constant (dst, last_bytes - 1), + dstoffset + last_bytes - 1); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); if (--last_bytes) @@ -5453,10 +5434,7 @@ arm_gen_movstrqi (rtx *operands) { if (last_bytes > 1) { - mem = gen_rtx_MEM (HImode, dst); - RTX_UNCHANGING_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset); emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg)); last_bytes -= 2; if (last_bytes) @@ -5466,15 +5444,13 @@ arm_gen_movstrqi (rtx *operands) emit_insn (gen_addsi3 (dst, dst, GEN_INT (2))); emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16))); part_bytes_reg = tmp; + dstoffset += 2; } } if (last_bytes) { - mem = gen_rtx_MEM (QImode, dst); - RTX_UNCHANGING_P (mem) = dst_unchanging_p; - MEM_IN_STRUCT_P (mem) = dst_in_struct_p; - MEM_SCALAR_P (mem) = dst_scalar_p; + mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset); emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg)); } } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 57926ba6b9b..0a5e647aed0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5043,7 +5043,9 @@ (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "TARGET_ARM" - " +{ + HOST_WIDE_INT offset = 0; + /* Support only fixed point registers. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 14 @@ -5057,11 +5059,9 @@ operands[3] = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), force_reg (SImode, XEXP (operands[1], 0)), - TRUE, FALSE, RTX_UNCHANGING_P(operands[1]), - MEM_IN_STRUCT_P(operands[1]), - MEM_SCALAR_P (operands[1])); - " -) + TRUE, FALSE, operands[1], &offset); + +}) ;; Load multiple with write-back @@ -5165,7 +5165,9 @@ (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "TARGET_ARM" - " +{ + HOST_WIDE_INT offset = 0; + /* Support only fixed point registers. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 14 @@ -5179,11 +5181,8 @@ operands[3] = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), force_reg (SImode, XEXP (operands[0], 0)), - TRUE, FALSE, RTX_UNCHANGING_P (operands[0]), - MEM_IN_STRUCT_P(operands[0]), - MEM_SCALAR_P (operands[0])); - " -) + TRUE, FALSE, operands[0], &offset); +}) ;; Store multiple with write-back diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c new file mode 100644 index 00000000000..d5fea9d79b3 --- /dev/null +++ b/gcc/config/host-linux.c @@ -0,0 +1,219 @@ +/* Linux host-specific hook definitions. + Copyright (C) 2004, 2005 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 2, 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 COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include +#include +#include "hosthooks.h" +#include "hosthooks-def.h" + + +/* Linux has a feature called exec-shield-randomize that perturbs the + address of non-fixed mapped segments by a (relatively) small amount. + The feature is intended to make it harder to attack the system with + buffer overflow attacks, since every invocation of a program will + have its libraries and data segments at slightly different addresses. + + This feature causes us problems with PCH because it makes it that + much harder to acquire a stable location at which to map our PCH + data file. + + [ The feature causes other points of non-determinism within the + compiler as well, so we'd *really* like to be able to have the + driver disable exec-shield-randomize for the process group, but + that isn't possible at present. ] + + We're going to try several things: + + * Select an architecture specific address as "likely" and see + if that's free. For our 64-bit hosts, we can easily choose + an address in Never Never Land. + + * If exec-shield-randomize is disabled, then just use the + address chosen by mmap in step one. + + * If exec-shield-randomize is enabled, then temporarily allocate + 32M of memory as a buffer, then allocate PCH memory, then + free the buffer. The theory here is that the perturbation is + no more than 16M, and so by allocating our buffer larger than + that we make it considerably more likely that the address will + be free when we want to load the data back. +*/ + +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS +#define HOST_HOOKS_GT_PCH_GET_ADDRESS linux_gt_pch_get_address + +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS +#define HOST_HOOKS_GT_PCH_USE_ADDRESS linux_gt_pch_use_address + +/* For various ports, try to guess a fixed spot in the vm space + that's probably free. */ +#if defined(__alpha) +# define TRY_EMPTY_VM_SPACE 0x10000000000 +#elif defined(__ia64) +# define TRY_EMPTY_VM_SPACE 0x2000000100000000 +#elif defined(__x86_64) +# define TRY_EMPTY_VM_SPACE 0x1000000000 +#elif defined(__i386) +# define TRY_EMPTY_VM_SPACE 0x60000000 +#elif defined(__powerpc__) +# define TRY_EMPTY_VM_SPACE 0x60000000 +#elif defined(__s390x__) +# define TRY_EMPTY_VM_SPACE 0x8000000000 +#elif defined(__s390__) +# define TRY_EMPTY_VM_SPACE 0x60000000 +#elif defined(__sparc__) && defined(__LP64__) +# define TRY_EMPTY_VM_SPACE 0x8000000000 +#elif defined(__sparc__) +# define TRY_EMPTY_VM_SPACE 0x60000000 +#else +# define TRY_EMPTY_VM_SPACE 0 +#endif + +/* Determine a location where we might be able to reliably allocate SIZE + bytes. FD is the PCH file, though we should return with the file + unmapped. */ + +static void * +linux_gt_pch_get_address (size_t size, int fd) +{ + size_t buffer_size = 32 * 1024 * 1024; + void *addr, *buffer; + FILE *f; + bool randomize_on; + + addr = mmap ((void *)TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); + + /* If we failed the map, that means there's *no* free space. */ + if (addr == (void *) MAP_FAILED) + return NULL; + /* Unmap the area before returning. */ + munmap (addr, size); + + /* If we got the exact area we requested, then that's great. */ + if (TRY_EMPTY_VM_SPACE && addr == (void *) TRY_EMPTY_VM_SPACE) + return addr; + + /* If we didn't, then we need to look to see if virtual address + randomization is on. That is recorded in + kernel.randomize_va_space. An older implementation used + kernel.exec-shield-randomize. */ + f = fopen ("/proc/sys/kernel/randomize_va_space", "r"); + if (f == NULL) + f = fopen ("/proc/sys/kernel/exec-shield-randomize", "r"); + randomize_on = false; + if (f != NULL) + { + char buf[100]; + size_t c; + + c = fread (buf, 1, sizeof buf - 1, f); + if (c > 0) + { + buf[c] = '\0'; + randomize_on = (atoi (buf) > 0); + } + fclose (f); + } + + /* If it isn't, then accept the address that mmap selected as fine. */ + if (!randomize_on) + return addr; + + /* Otherwise, we need to try again with buffer space. */ + buffer = mmap (0, buffer_size, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); + addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (buffer != (void *) MAP_FAILED) + munmap (buffer, buffer_size); + if (addr == (void *) MAP_FAILED) + return NULL; + munmap (addr, size); + + return addr; +} + +/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at + mapping the data at BASE, -1 if we couldn't. + + It's not possibly to reliably mmap a file using MAP_PRIVATE to + a specific START address on either hpux or linux. First we see + if mmap with MAP_PRIVATE works. If it does, we are off to the + races. If it doesn't, we try an anonymous private mmap since the + kernel is more likely to honor the BASE address in anonymous maps. + We then copy the data to the anonymous private map. This assumes + of course that we don't need to change the data in the PCH file + after it is created. + + This approach obviously causes a performance penalty but there is + little else we can do given the current PCH implementation. */ + +static int +linux_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) +{ + void *addr; + + /* We're called with size == 0 if we're not planning to load a PCH + file at all. This allows the hook to free any static space that + we might have allocated at link time. */ + if (size == 0) + return -1; + + /* Try to map the file with MAP_PRIVATE. */ + addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset); + + if (addr == base) + return 1; + + if (addr != (void *) MAP_FAILED) + munmap (addr, size); + + /* Try to make an anonymous private mmap at the desired location. */ + addr = mmap (base, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (addr != base) + { + if (addr != (void *) MAP_FAILED) + munmap (addr, size); + return -1; + } + + if (lseek (fd, offset, SEEK_SET) == (off_t)-1) + return -1; + + while (size) + { + ssize_t nbytes; + + nbytes = read (fd, base, MIN (size, SSIZE_MAX)); + if (nbytes <= 0) + return -1; + base = (char *) base + nbytes; + size -= nbytes; + } + + return 1; +} + + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/host-solaris.c b/gcc/config/host-solaris.c new file mode 100644 index 00000000000..4fa7a5b1ad0 --- /dev/null +++ b/gcc/config/host-solaris.c @@ -0,0 +1,79 @@ +/* Solaris host-specific hook definitions. + Copyright (C) 2004 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 2, 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 COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include +#include "hosthooks.h" +#include "hosthooks-def.h" + + +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS +#define HOST_HOOKS_GT_PCH_USE_ADDRESS sol_gt_pch_use_address + +/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at + mapping the data at BASE, -1 if we couldn't. */ + +static int +sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) +{ + void *addr; + + /* We're called with size == 0 if we're not planning to load a PCH + file at all. This allows the hook to free any static space that + we might have allocated at link time. */ + if (size == 0) + return -1; + + addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, offset); + + /* Solaris isn't good about honoring the mmap START parameter + without MAP_FIXED set. Before we give up, search the desired + address space with mincore to see if the space is really free. */ + if (addr != base) + { + size_t page_size = getpagesize(); + char one_byte; + size_t i; + + if (addr != (void *) MAP_FAILED) + munmap (addr, size); + + errno = 0; + for (i = 0; i < size; i += page_size) + if (mincore ((char *)base + i, page_size, (void *)&one_byte) == -1 + && errno == ENOMEM) + continue; /* The page is not mapped. */ + else + break; + + if (i >= size) + addr = mmap (base, size, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, + fd, offset); + } + + return addr == base ? 1 : -1; +} + + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2ce11256cb4..7345d936a90 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13961,6 +13961,7 @@ ix86_expand_unop_builtin (enum insn_code icode, tree arglist, if (! target || GET_MODE (target) != tmode + || (do_load && GET_CODE (target) == MEM) || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) target = gen_reg_rtx (tmode); if (do_load) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 60e27aafbbb..bc0b8c7693b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -1850,7 +1850,8 @@ (define_split [(set (match_operand:DI 0 "push_operand" "") (match_operand:DI 1 "immediate_operand" ""))] - "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + "TARGET_64BIT && ((optimize > 0 && flag_peephole2) + ? flow2_completed : reload_completed) && !symbolic_operand (operands[1], DImode) && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 0) (match_dup 1)) @@ -2105,7 +2106,8 @@ (define_split [(set (match_operand:DI 0 "memory_operand" "") (match_operand:DI 1 "immediate_operand" ""))] - "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2)) + "TARGET_64BIT && ((optimize > 0 && flag_peephole2) + ? flow2_completed : reload_completed) && !symbolic_operand (operands[1], DImode) && !x86_64_immediate_operand (operands[1], DImode)" [(set (match_dup 2) (match_dup 3)) diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h index f76cbd23216..09fb53f44b0 100644 --- a/gcc/config/ia64/hpux.h +++ b/gcc/config/ia64/hpux.h @@ -84,13 +84,6 @@ do { \ %{mlp64:-L/usr/lib/hpux64/libp} -lgprof} \ %{!symbolic:-lc}}" -#ifndef CROSS_COMPILE -#undef LIBGCC_SPEC -#define LIBGCC_SPEC \ - "%{shared-libgcc:%{!mlp64:-lgcc_s}%{mlp64:-lgcc_s_hpux64} -lgcc} \ - %{!shared-libgcc:-lgcc}" -#endif - #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ { "ilp32", MASK_ILP32, "Generate ILP32 code" }, \ diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index 52aa89726db..9a55d314c2b 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -62,6 +62,7 @@ extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); #endif /* RTX_CODE */ +extern bool m68k_regno_mode_ok (int, enum machine_mode); extern int flags_in_68881 (void); extern bool use_return_insn (void); extern void override_options (void); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index c1595f98e5f..800fa3962c4 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -3541,3 +3541,36 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, return 1; } + +/* Value is true if hard register REGNO can hold a value of machine-mode MODE. + On the 68000, the cpu registers can hold any mode except bytes in address + registers, but the 68881 registers can hold only SFmode or DFmode. */ +bool +m68k_regno_mode_ok (int regno, enum machine_mode mode) +{ + if (regno < 8) + { + /* Data Registers, can hold aggregate if fits in. */ + if (regno + GET_MODE_SIZE (mode) / 4 <= 8) + return true; + } + else if (regno < 16) + { + /* Address Registers, can't hold bytes, can hold aggregate if + fits in. */ + if (GET_MODE_SIZE (mode) == 1) + return false; + if (regno + GET_MODE_SIZE (mode) / 4 <= 16) + return true; + } + else if (regno < 24) + { + /* FPU registers, hold float or complex float of long double or + smaller. */ + if ((GET_MODE_CLASS (mode) == MODE_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) + && GET_MODE_UNIT_SIZE (mode) <= 12) + return true; + } + return false; +} diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index e2252446e8f..f5fb1914a50 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -555,17 +555,11 @@ extern int target_flags; m68k_hard_regno_rename_ok (OLD_REG, NEW_REG) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the 68000, the cpu registers can hold any mode but the 68881 registers - can hold only SFmode or DFmode. */ + On the 68000, the cpu registers can hold any mode except bytes in + address registers, the 68881 registers can hold only SFmode or DFmode. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ - (((REGNO) < 16 \ - && !((REGNO) < 8 && (REGNO) + GET_MODE_SIZE (MODE) / 4 > 8)) \ - || ((REGNO) >= 16 && (REGNO) < 24 \ - && (GET_MODE_CLASS (MODE) == MODE_FLOAT \ - || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \ - && GET_MODE_UNIT_SIZE (MODE) <= 12)) - + m68k_regno_mode_ok ((REGNO), (MODE)) /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index f6bea19c75a..68ea933007d 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -1981,7 +1981,7 @@ (define_insn "*addsi3_5200" [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?a,?a,r") (plus:SI (match_operand:SI 1 "general_operand" "%0,a,rJK,0") - (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLs")))] + (match_operand:SI 2 "general_src_operand" "d,rJK,a,mrIKLi")))] "TARGET_COLDFIRE" "* return output_addsi3 (operands);") diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 2045f2e48a0..bca8f3b449a 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -62,7 +62,7 @@ extern rtx mips_subword (rtx, int); extern bool mips_split_64bit_move_p (rtx, rtx); extern void mips_split_64bit_move (rtx, rtx); extern const char *mips_output_move (rtx, rtx); -extern rtx mips_gp_save_slot (void); +extern void mips_restore_gp (void); #ifdef RTX_CODE extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *); extern void gen_conditional_branch (rtx *, enum rtx_code); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index bb4359e49bf..0aa24f6a3c1 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -206,7 +206,7 @@ static rtx mips_split_symbol (rtx, rtx); static rtx mips_unspec_address (rtx, enum mips_symbol_type); static rtx mips_unspec_offset_high (rtx, rtx, rtx, enum mips_symbol_type); static rtx mips_load_got (rtx, rtx, enum mips_symbol_type); -static rtx mips_add_offset (rtx, HOST_WIDE_INT); +static rtx mips_add_offset (rtx, rtx, HOST_WIDE_INT); static unsigned int mips_build_shift (struct mips_integer_op *, HOST_WIDE_INT); static unsigned int mips_build_lower (struct mips_integer_op *, unsigned HOST_WIDE_INT); @@ -1787,18 +1787,33 @@ mips_load_got_global (rtx base, rtx addr) } -/* Return a legitimate address for REG + OFFSET. This function will - create a temporary register if OFFSET is not a SMALL_OPERAND. */ +/* Return a legitimate address for REG + OFFSET. TEMP is as for + mips_force_temporary; it is only needed when OFFSET is not a + SMALL_OPERAND. */ static rtx -mips_add_offset (rtx reg, HOST_WIDE_INT offset) +mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset) { if (!SMALL_OPERAND (offset)) - reg = expand_simple_binop (GET_MODE (reg), PLUS, - GEN_INT (CONST_HIGH_PART (offset)), - reg, NULL, 0, OPTAB_WIDEN); - - return plus_constant (reg, CONST_LOW_PART (offset)); + { + rtx high; + if (TARGET_MIPS16) + { + /* Load the full offset into a register so that we can use + an unextended instruction for the address itself. */ + high = GEN_INT (offset); + offset = 0; + } + else + { + /* Leave OFFSET as a 16-bit offset and put the excess in HIGH. */ + high = GEN_INT (CONST_HIGH_PART (offset)); + offset = CONST_LOW_PART (offset); + } + high = mips_force_temporary (temp, high); + reg = mips_force_temporary (temp, gen_rtx_PLUS (Pmode, high, reg)); + } + return plus_constant (reg, offset); } @@ -1829,7 +1844,7 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode) reg = XEXP (*xloc, 0); if (!mips_valid_base_register_p (reg, mode, 0)) reg = copy_to_mode_reg (Pmode, reg); - *xloc = mips_add_offset (reg, INTVAL (XEXP (*xloc, 1))); + *xloc = mips_add_offset (0, reg, INTVAL (XEXP (*xloc, 1))); return true; } @@ -2007,7 +2022,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) && (!no_new_pseudos || SMALL_OPERAND (offset))) { base = mips_force_temporary (dest, base); - emit_move_insn (dest, mips_add_offset (base, offset)); + emit_move_insn (dest, mips_add_offset (0, base, offset)); return; } @@ -2772,25 +2787,28 @@ mips_output_move (rtx dest, rtx src) abort (); } -/* Return an rtx for the gp save slot. Valid only when using o32 or +/* Restore $gp from its save slot. Valid only when using o32 or o64 abicalls. */ -rtx -mips_gp_save_slot (void) +void +mips_restore_gp (void) { - rtx loc; + rtx address, slot; if (!TARGET_ABICALLS || TARGET_NEWABI) abort (); - if (frame_pointer_needed) - loc = hard_frame_pointer_rtx; - else - loc = stack_pointer_rtx; - loc = plus_constant (loc, current_function_outgoing_args_size); - loc = gen_rtx_MEM (Pmode, loc); - RTX_UNCHANGING_P (loc) = 1; - return loc; + address = mips_add_offset (pic_offset_table_rtx, + frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx, + current_function_outgoing_args_size); + slot = gen_rtx_MEM (Pmode, address); + RTX_UNCHANGING_P (slot) = 1; + + emit_move_insn (pic_offset_table_rtx, slot); + if (!TARGET_EXPLICIT_RELOCS) + emit_insn (gen_blockage ()); } /* Make normal rtx_code into something we can index from an array */ @@ -3403,26 +3421,15 @@ mips_emit_fcc_reload (rtx dest, rtx src, rtx scratch) void mips_set_return_address (rtx address, rtx scratch) { - HOST_WIDE_INT gp_offset; + rtx slot_address; compute_frame_size (get_frame_size ()); if (((cfun->machine->frame.mask >> 31) & 1) == 0) abort (); - gp_offset = cfun->machine->frame.gp_sp_offset; - - /* Reduce SP + GP_OFSET to a legitimate address and put it in SCRATCH. */ - if (gp_offset < 32768) - scratch = plus_constant (stack_pointer_rtx, gp_offset); - else - { - emit_move_insn (scratch, GEN_INT (gp_offset)); - if (Pmode == DImode) - emit_insn (gen_adddi3 (scratch, scratch, stack_pointer_rtx)); - else - emit_insn (gen_addsi3 (scratch, scratch, stack_pointer_rtx)); - } + slot_address = mips_add_offset (scratch, stack_pointer_rtx, + cfun->machine->frame.gp_sp_offset); - emit_move_insn (gen_rtx_MEM (GET_MODE (address), scratch), address); + emit_move_insn (gen_rtx_MEM (GET_MODE (address), slot_address), address); } /* Emit straight-line code to move LENGTH bytes from SRC to DEST. @@ -7190,25 +7197,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, emit_move_insn (temp1, gen_rtx_MEM (Pmode, this)); /* Set ADDR to a legitimate address for *THIS + VCALL_OFFSET. */ - if (SMALL_OPERAND (vcall_offset)) - addr = gen_rtx_PLUS (Pmode, temp1, GEN_INT (vcall_offset)); - else if (TARGET_MIPS16) - { - /* Load the full offset into a register so that we can use - an unextended instruction for the load itself. */ - emit_move_insn (temp2, GEN_INT (vcall_offset)); - emit_insn (gen_add3_insn (temp1, temp1, temp2)); - addr = temp1; - } - else - { - /* Load the high part of the offset into a register and - leave the low part for the address. */ - emit_move_insn (temp2, GEN_INT (CONST_HIGH_PART (vcall_offset))); - emit_insn (gen_add3_insn (temp1, temp1, temp2)); - addr = gen_rtx_PLUS (Pmode, temp1, - GEN_INT (CONST_LOW_PART (vcall_offset))); - } + addr = mips_add_offset (temp2, temp1, vcall_offset); /* Load the offset and add it to THIS. */ emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr)); diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 35f89f0a1b4..50545423560 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -5160,16 +5160,21 @@ dsrl\t%3,%3,1\n\ (set_attr "mode" "none") (set_attr "length" "0")]) -;; Emit a .cprestore directive, which expands to a single store instruction. -;; Note that we continue to use .cprestore for explicit reloc code so that -;; jals inside inlines asms will work correctly. +;; Emit a .cprestore directive, which normally expands to a single store +;; instruction. Note that we continue to use .cprestore for explicit reloc +;; code so that jals inside inline asms will work correctly. (define_insn "cprestore" - [(unspec_volatile [(match_operand 0 "const_int_operand" "")] + [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")] UNSPEC_CPRESTORE)] "" - ".cprestore\t%0" +{ + if (set_nomacro && which_alternative == 1) + return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro"; + else + return ".cprestore\t%0"; +} [(set_attr "type" "store") - (set_attr "length" "4")]) + (set_attr "length" "4,12")]) ;; Block moves, see mips.c for more details. ;; Argument 0 is the destination @@ -8367,17 +8372,19 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/" DONE; }) -(define_insn "exception_receiver" +(define_insn_and_split "exception_receiver" [(set (reg:SI 28) (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))] "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)" + "#" + "&& reload_completed" + [(const_int 0)] { - operands[0] = pic_offset_table_rtx; - operands[1] = mips_gp_save_slot (); - return mips_output_move (operands[0], operands[1]); + mips_restore_gp (); + DONE; } [(set_attr "type" "load") - (set_attr "length" "8")]) + (set_attr "length" "12")]) ;; ;; .................... @@ -8548,7 +8555,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/" { emit_call_insn (gen_call_split (operands[0], operands[1])); if (!find_reg_note (operands[2], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") @@ -8589,7 +8596,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/" emit_call_insn (gen_call_value_split (operands[0], operands[1], operands[2])); if (!find_reg_note (operands[3], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") @@ -8622,7 +8629,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2%/" emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], operands[2], operands[3])); if (!find_reg_note (operands[4], REG_NORETURN, 0)) - emit_move_insn (pic_offset_table_rtx, mips_gp_save_slot ()); + mips_restore_gp (); DONE; } [(set_attr "jal" "indirect,direct") diff --git a/gcc/config/pa/pa-host.c b/gcc/config/pa/pa-host.c new file mode 100644 index 00000000000..73f546aef82 --- /dev/null +++ b/gcc/config/pa/pa-host.c @@ -0,0 +1,136 @@ +/* PA host-specific hook definitions. + Copyright (C) 2004 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 2, 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 COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include +#include +#include "hosthooks.h" +#include "hosthooks-def.h" + +#ifndef MAP_FAILED +#define MAP_FAILED (void *)-1L +#endif + +static void *pa_gt_pch_get_address (size_t, int); +static int pa_gt_pch_use_address (void *, size_t, int, size_t); + +#undef HOST_HOOKS_GT_PCH_GET_ADDRESS +#define HOST_HOOKS_GT_PCH_GET_ADDRESS pa_gt_pch_get_address +#undef HOST_HOOKS_GT_PCH_USE_ADDRESS +#define HOST_HOOKS_GT_PCH_USE_ADDRESS pa_gt_pch_use_address + +/* For various ports, try to guess a fixed spot in the vm space + that's probably free. */ +#if defined(__hppa__) && defined(__LP64__) +# define TRY_EMPTY_VM_SPACE 0x8000000000000000 +#elif defined(__hppa__) +# define TRY_EMPTY_VM_SPACE 0x60000000 +#else +# define TRY_EMPTY_VM_SPACE 0 +#endif + +/* Determine a location where we might be able to reliably allocate + SIZE bytes. FD is the PCH file, though we should return with the + file unmapped. */ + +static void * +pa_gt_pch_get_address (size_t size, int fd) +{ + void *addr; + + addr = mmap ((void *)TRY_EMPTY_VM_SPACE, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); + + /* If we failed the map, that means there's *no* free space. */ + if (addr == (void *) MAP_FAILED) + return NULL; + /* Unmap the area before returning. */ + munmap (addr, size); + + return addr; +} + +/* Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at + mapping the data at BASE, -1 if we couldn't. + + It's not possibly to reliably mmap a file using MAP_PRIVATE to + a specific START address on either hpux or linux. First we see + if mmap with MAP_PRIVATE works. If it does, we are off to the + races. If it doesn't, we try an anonymous private mmap since the + kernel is more likely to honor the BASE address in anonymous maps. + We then copy the data to the anonymous private map. This assumes + of course that we don't need to change the data in the PCH file + after it is created. + + This approach obviously causes a performance penalty but there is + little else we can do given the current PCH implementation. */ + +static int +pa_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) +{ + void *addr; + + /* We're called with size == 0 if we're not planning to load a PCH + file at all. This allows the hook to free any static space that + we might have allocated at link time. */ + if (size == 0) + return -1; + + /* Try to map the file with MAP_PRIVATE. */ + addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset); + + if (addr == base) + return 1; + + if (addr != (void *) MAP_FAILED) + munmap (addr, size); + + /* Try to make an anonymous private mmap at the desired location. */ + addr = mmap (base, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (addr != base) + { + if (addr != (void *) MAP_FAILED) + munmap (addr, size); + return -1; + } + + if (lseek (fd, offset, SEEK_SET) == (off_t)-1) + return -1; + + while (size) + { + ssize_t nbytes; + + nbytes = read (fd, base, MIN (size, SSIZE_MAX)); + if (nbytes <= 0) + return -1; + base = (char *) base + nbytes; + size -= nbytes; + } + + return 1; +} + + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 661eff59cca..3a5d003114e 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -8800,24 +8800,40 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED) { enum machine_mode valmode; - /* Aggregates with a size less than or equal to 128 bits are returned - in GR 28(-29). They are left justified. The pad bits are undefined. - Larger aggregates are returned in memory. */ - if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype)) + if (AGGREGATE_TYPE_P (valtype)) { - rtx loc[2]; - int i, offset = 0; - int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2; + if (TARGET_64BIT) + { + /* Aggregates with a size less than or equal to 128 bits are + returned in GR 28(-29). They are left justified. The pad + bits are undefined. Larger aggregates are returned in + memory. */ + rtx loc[2]; + int i, offset = 0; + int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2; + + for (i = 0; i < ub; i++) + { + loc[i] = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, 28 + i), + GEN_INT (offset)); + offset += 8; + } - for (i = 0; i < ub; i++) + return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc)); + } + else if (int_size_in_bytes (valtype) > UNITS_PER_WORD) { - loc[i] = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (DImode, 28 + i), - GEN_INT (offset)); - offset += 8; + /* Aggregates 5 to 8 bytes in size are returned in general + registers r28-r29 in the same manner as other non + floating-point objects. The data is right-justified and + zero-extended to 64 bits. This is opposite to the normal + justification used on big endian targets and requires + special treatment. */ + rtx loc = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (DImode, 28), const0_rtx); + return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc)); } - - return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc)); } if ((INTEGRAL_TYPE_P (valtype) @@ -8828,6 +8844,7 @@ function_value (tree valtype, tree func ATTRIBUTE_UNUSED) valmode = TYPE_MODE (valtype); if (TREE_CODE (valtype) == REAL_TYPE + && !AGGREGATE_TYPE_P (valtype) && TYPE_MODE (valtype) != TFmode && !TARGET_SOFT_FLOAT) return gen_rtx_REG (valmode, 32); @@ -8965,12 +8982,12 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, justification of BLKmode data when it has a size greater than one word. Splitting the operation into two SImode loads or returning a DImode REG results in left justified data. */ - if (mode == BLKmode) + if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type))) { rtx loc = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (DImode, gpr_reg_base), const0_rtx); - return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc)); + return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, loc)); } } else @@ -9031,7 +9048,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, && cum->indirect) /* If the parameter is not a floating point parameter, then it belongs in GPRs. */ - || !FLOAT_MODE_P (mode)) + || !FLOAT_MODE_P (mode) + /* Structure with single SFmode field belongs in GPR. */ + || (type && AGGREGATE_TYPE_P (type))) retval = gen_rtx_REG (mode, gpr_reg_base); else retval = gen_rtx_REG (mode, fpr_reg_base); diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 5b3a612c72d..c440967ff4c 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2877,9 +2877,9 @@ (define_insn "" [(set (match_operand:HI 0 "move_dest_operand" - "=r,r,r,r,r,Q,!*q,!r,!*f") + "=r,r,r,r,r,Q,!*q,!r") (match_operand:HI 1 "move_src_operand" - "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))] + "r,J,N,K,RQ,rM,!rM,!*q"))] "register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode)" "@ @@ -2890,11 +2890,10 @@ ldh%M1 %1,%0 sth%M0 %r1,%0 mtsar %r1 - {mfctl|mfctl,w} %sar,%0 - fcpy,sgl %f1,%0" - [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu") + {mfctl|mfctl,w} %sar,%0" + [(set_attr "type" "move,move,move,shift,load,store,move,move") (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4")]) + (set_attr "length" "4,4,4,4,4,4,4,4")]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") @@ -3002,9 +3001,9 @@ (define_insn "" [(set (match_operand:QI 0 "move_dest_operand" - "=r,r,r,r,r,Q,!*q,!r,!*f") + "=r,r,r,r,r,Q,!*q,!r") (match_operand:QI 1 "move_src_operand" - "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))] + "r,J,N,K,RQ,rM,!rM,!*q"))] "register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode)" "@ @@ -3015,11 +3014,10 @@ ldb%M1 %1,%0 stb%M0 %r1,%0 mtsar %r1 - {mfctl|mfctl,w} %%sar,%0 - fcpy,sgl %f1,%0" - [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu") + {mfctl|mfctl,w} %%sar,%0" + [(set_attr "type" "move,move,move,shift,load,store,move,move") (set_attr "pa_combine_type" "addmove") - (set_attr "length" "4,4,4,4,4,4,4,4,4")]) + (set_attr "length" "4,4,4,4,4,4,4,4")]) (define_insn "" [(set (match_operand:QI 0 "register_operand" "=r") diff --git a/gcc/config/pa/pa32-regs.h b/gcc/config/pa/pa32-regs.h index ac23a69173a..9cf5825f99c 100644 --- a/gcc/config/pa/pa32-regs.h +++ b/gcc/config/pa/pa32-regs.h @@ -155,32 +155,69 @@ This is ordinarily the length in words of a value of mode MODE but can be less for certain modes in special long registers. - On the HP-PA, ordinary registers hold 32 bits worth; - The floating point registers are 64 bits wide. Snake fp regs are 32 - bits wide */ + On the HP-PA, general registers are 32 bits wide. The floating + point registers are 64 bits wide. Snake fp regs are treated as + 32 bits wide since the left and right parts are independently + accessible. */ #define HARD_REGNO_NREGS(REGNO, MODE) \ (FP_REGNO_P (REGNO) \ - ? (!TARGET_PA_11 ? 1 : (GET_MODE_SIZE (MODE) + 4 - 1) / 4) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + ? (!TARGET_PA_11 \ + ? COMPLEX_MODE_P (MODE) ? 2 : 1 \ + : (GET_MODE_SIZE (MODE) + 4 - 1) / 4) \ + : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + +/* There are no instructions that use DImode in PA 1.0, so we only + allow it in PA 1.1 and later. */ +#define VALID_FP_MODE_P(MODE) \ + ((MODE) == SFmode || (MODE) == DFmode \ + || (MODE) == SCmode || (MODE) == DCmode \ + || (MODE) == SImode || (TARGET_PA_11 && (MODE) == DImode)) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the HP-PA, the cpu registers can hold any mode. For DImode, we - choose a set of general register that includes the incoming arguments - and the return value. We specify a set with no overlaps so that we don't - have to specify that the destination register in patterns using this mode - is an early clobber. */ + + On the HP-PA, the cpu registers can hold any mode that fits in 32 bits. + For the 64-bit modes, we choose a set of non-overlapping general registers + that includes the incoming arguments and the return value. We specify a + set with no overlaps so that we don't have to specify that the destination + register is an early clobber in patterns using this mode. Except for the + return value, the starting registers are odd. For 128 and 256 bit modes, + we similarly specify non-overlapping sets of cpu registers. However, + there aren't any patterns defined for modes larger than 64 bits at the + moment. + + We limit the modes allowed in the floating point registers to the + set of modes used in the machine definition. In addition, we allow + the complex modes SCmode and DCmode. The real and imaginary parts + of complex modes are allocated to separate registers. This might + allow patterns to be defined in the future to operate on these values. + + The PA 2.0 architecture specifies that quad-precision floating-point + values should start on an even floating point register. Thus, we + choose non-overlapping sets of registers starting on even register + boundaries for large modes. However, there is currently no support + in the machine definition for modes larger than 64 bits. TFmode is + supported under HP-UX using libcalls. Since TFmode values are passed + by reference, they never need to be loaded into the floating-point + registers. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode \ - /* On 1.0 machines, don't allow wide non-fp modes in fp regs. */ \ : !TARGET_PA_11 && FP_REGNO_P (REGNO) \ - ? GET_MODE_SIZE (MODE) <= 4 || GET_MODE_CLASS (MODE) == MODE_FLOAT \ + ? (VALID_FP_MODE_P (MODE) \ + && (GET_MODE_SIZE (MODE) <= 8 \ + || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 3) == 0))) \ : FP_REGNO_P (REGNO) \ - ? GET_MODE_SIZE (MODE) <= 4 || ((REGNO) & 1) == 0 \ + ? (VALID_FP_MODE_P (MODE) \ + && (GET_MODE_SIZE (MODE) <= 4 \ + || (GET_MODE_SIZE (MODE) == 8 && ((REGNO) & 1) == 0) \ + || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 3) == 0) \ + || (GET_MODE_SIZE (MODE) == 32 && ((REGNO) & 7) == 0))) \ : (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \ || (GET_MODE_SIZE (MODE) == 2 * UNITS_PER_WORD \ && ((((REGNO) & 1) == 1 && (REGNO) <= 25) || (REGNO) == 28)) \ || (GET_MODE_SIZE (MODE) == 4 * UNITS_PER_WORD \ - && (((REGNO) & 3) == 3 && (REGNO) <= 23)))) + && ((REGNO) & 3) == 3 && (REGNO) <= 23) \ + || (GET_MODE_SIZE (MODE) == 8 * UNITS_PER_WORD \ + && ((REGNO) & 7) == 3 && (REGNO) <= 19))) /* How to renumber registers for dbx and gdb. @@ -275,7 +312,9 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS, needed to represent mode MODE in a register of class CLASS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS \ - ? (!TARGET_PA_11 ? 1 : (GET_MODE_SIZE (MODE) + 4 - 1) / 4) \ + ? (!TARGET_PA_11 \ + ? COMPLEX_MODE_P (MODE) ? 2 : 1 \ + : (GET_MODE_SIZE (MODE) + 4 - 1) / 4) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* 1 if N is a possible register number for function argument passing. */ diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h index 456a4bf01a2..0cce22000da 100644 --- a/gcc/config/pa/pa64-regs.h +++ b/gcc/config/pa/pa64-regs.h @@ -106,7 +106,7 @@ Boston, MA 02111-1307, USA. */ int i; \ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)\ { \ - for (i = FP_REG_FIRST; i < FP_REG_LAST; i++)\ + for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)\ fixed_regs[i] = call_used_regs[i] = 1; \ } \ if (flag_pic) \ @@ -149,11 +149,19 @@ Boston, MA 02111-1307, USA. */ This is ordinarily the length in words of a value of mode MODE but can be less for certain modes in special long registers. - For PA64, GPRs and FPRs hold 64 bits worth (we ignore the 32bit - addressability of the FPRs). ie, we pretend each register holds - precisely WORD_SIZE bits. */ + For PA64, GPRs and FPRs hold 64 bits worth. We ignore the 32-bit + addressability of the FPRs and pretend each register holds precisely + WORD_SIZE bits. Note that SCmode values are placed in a single FPR. + Thus, any patterns defined to operate on these values would have to + use the 32-bit addressability of the FPR registers. */ #define HARD_REGNO_NREGS(REGNO, MODE) \ - ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + +/* These are the valid FP modes. */ +#define VALID_FP_MODE_P(MODE) \ + ((MODE) == SFmode || (MODE) == DFmode \ + || (MODE) == SCmode || (MODE) == DCmode \ + || (MODE) == SImode || (MODE) == DImode) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. On the HP-PA, the cpu registers can hold any mode. We @@ -162,8 +170,16 @@ Boston, MA 02111-1307, USA. */ ((REGNO) == 0 \ ? (MODE) == CCmode || (MODE) == CCFPmode \ /* Make wide modes be in aligned registers. */ \ + : FP_REGNO_P (REGNO) \ + ? (VALID_FP_MODE_P (MODE) \ + && (GET_MODE_SIZE (MODE) <= 8 \ + || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 1) == 0) \ + || (GET_MODE_SIZE (MODE) == 32 && ((REGNO) & 3) == 0))) \ : (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \ - || (GET_MODE_SIZE (MODE) <= 2 * UNITS_PER_WORD && ((REGNO) & 1) == 0))) + || (GET_MODE_SIZE (MODE) == 2 * UNITS_PER_WORD \ + && ((((REGNO) & 1) == 1 && (REGNO) <= 25) || (REGNO) == 28)) \ + || (GET_MODE_SIZE (MODE) == 4 * UNITS_PER_WORD \ + && ((REGNO) & 3) == 3 && (REGNO) <= 23))) /* How to renumber registers for dbx and gdb. diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h index 1680ecbcba3..a403a47fa97 100644 --- a/gcc/config/pa/som.h +++ b/gcc/config/pa/som.h @@ -312,10 +312,6 @@ do { \ cannot be moved after installation using a symlink. */ #define ALWAYS_STRIP_DOTDOT 1 -/* Aggregates with a single float or double field should be passed and - returned in the general registers. */ -#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (MODE==SFmode || MODE==DFmode) - /* If GAS supports weak, we can support weak when we have working linker support for secondary definitions and are generating code for GAS. */ #ifdef HAVE_GAS_WEAK diff --git a/gcc/config/pa/x-hpux b/gcc/config/pa/x-hpux new file mode 100644 index 00000000000..2f16d317039 --- /dev/null +++ b/gcc/config/pa/x-hpux @@ -0,0 +1,9 @@ +# The ada virtual array implementation requires that indexing be disabled on +# hosts such as hpux that use a segmented memory architecture. Both the c +# and ada files need to be compiled with this option for correct operation. +X_ADA_CFLAGS=-mdisable-indexing + +pa-host.o : $(srcdir)/config/pa/pa-host.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/pa/pa-host.c diff --git a/gcc/config/pa/x-linux b/gcc/config/pa/x-linux new file mode 100644 index 00000000000..8a5bc6fcf36 --- /dev/null +++ b/gcc/config/pa/x-linux @@ -0,0 +1,4 @@ +pa-host.o : $(srcdir)/config/pa/pa-host.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/pa/pa-host.c diff --git a/gcc/config/rs6000/host-darwin.c b/gcc/config/rs6000/host-darwin.c index 7e8055690e4..d04270c3675 100644 --- a/gcc/config/rs6000/host-darwin.c +++ b/gcc/config/rs6000/host-darwin.c @@ -1,5 +1,5 @@ /* Darwin/powerpc host-specific hook definitions. - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -137,22 +137,18 @@ darwin_rs6000_extra_signals (void) fatal_error ("While setting up signal handler: %m"); } -static void * darwin_rs6000_gt_pch_get_address (size_t); -static bool darwin_rs6000_gt_pch_use_address (void *, size_t); - #undef HOST_HOOKS_GT_PCH_GET_ADDRESS #define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address #undef HOST_HOOKS_GT_PCH_USE_ADDRESS #define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address - /* Yes, this is really supposed to work. */ static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096))); /* Return the address of the PCH address space, if the PCH will fit in it. */ static void * -darwin_rs6000_gt_pch_get_address (size_t sz) +darwin_rs6000_gt_pch_get_address (size_t sz, int fd ATTRIBUTE_UNUSED) { if (sz <= sizeof (pch_address_space)) return pch_address_space; @@ -163,18 +159,19 @@ darwin_rs6000_gt_pch_get_address (size_t sz) /* Check ADDR and SZ for validity, and deallocate (using munmap) that part of pch_address_space beyond SZ. */ -static bool -darwin_rs6000_gt_pch_use_address (void *addr, size_t sz) +static int +darwin_rs6000_gt_pch_use_address (void *addr, size_t sz, int fd, size_t off) { const size_t pagesize = getpagesize(); - bool result; + void *mmap_result; + int ret; if ((size_t)pch_address_space % pagesize != 0 || sizeof (pch_address_space) % pagesize != 0) abort (); - result = (addr == pch_address_space && sz <= sizeof (pch_address_space)); - if (! result) + ret = (addr == pch_address_space && sz <= sizeof (pch_address_space)); + if (! ret) sz = 0; /* Round the size to a whole page size. Normally this is a no-op. */ @@ -183,7 +180,22 @@ darwin_rs6000_gt_pch_use_address (void *addr, size_t sz) if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0) fatal_error ("couldn't unmap pch_address_space: %m\n"); - return result; + if (ret) + { + mmap_result = mmap (addr, sz, + PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, + fd, off); + + /* The file might not be mmap-able. */ + ret = mmap_result != (void *) MAP_FAILED; + + /* Sanity check for broken MAP_FIXED. */ + if (ret && mmap_result != addr) + abort (); + } + + return ret; } + const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4c29dbcb9f3..735a9fc5542 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2997,7 +2997,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) rtx r3, got, tga, tmp1, tmp2, eqv; if (TARGET_64BIT) - got = gen_rtx_REG (Pmode, TOC_REGISTER); + got = gen_rtx_REG (Pmode, 2); else { if (flag_pic == 1) @@ -4377,9 +4377,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (mode == VOIDmode) { if (abi == ABI_V4 - && cum->nargs_prototype < 0 && (cum->call_cookie & CALL_LIBCALL) == 0 - && (cum->prototype || TARGET_NO_PROTOTYPE)) + && (cum->stdarg + || (cum->nargs_prototype < 0 + && (cum->prototype || TARGET_NO_PROTOTYPE)))) { /* For the SPE, we need to crxor CR6 always. */ if (TARGET_SPE_ABI) @@ -7864,7 +7865,7 @@ expand_block_move (rtx operands[]) mode = SImode; gen_func.mov = gen_movsi; } - else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT)) + else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT)) { /* move 2 bytes */ move_bytes = 2; mode = HImode; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3b062ce7cde..e530dd94fee 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5236,7 +5236,7 @@ (set (match_dup 0) (plus:DI (match_dup 0) (const_int 2047))) (set (match_dup 4) (compare:CCUNS (match_dup 3) - (const_int 3))) + (const_int 2))) (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 1))) (parallel [(set (match_dup 0) (and:DI (match_dup 0) @@ -7839,8 +7839,8 @@ }") (define_insn "*movsf_hardfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!r,!r") - (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,G,Fn"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!h,!r,!r") + (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) && (TARGET_HARD_FLOAT && TARGET_FPRS)" @@ -7854,10 +7854,11 @@ mt%0 %1 mt%0 %1 mf%1 %0 + {cror 0,0,0|nop} # #" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")]) + [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,8")]) (define_insn "*movsf_softfloat" [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h") @@ -8114,8 +8115,8 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!r,!r,!r") - (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,G,H,F"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!h,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,0,G,H,F"))] "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -8129,11 +8130,12 @@ stfd%U0%X0 %1,%0 mt%0 %1 mf%1 %0 + {cror 0,0,0|nop} # # #" - [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*") - (set_attr "length" "4,4,8,4,4,4,4,4,4,8,12,16")]) + [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*,*") + (set_attr "length" "4,4,8,4,4,4,4,4,4,4,8,12,16")]) (define_split [(set (match_operand:DF 0 "base_reg_operand" "") @@ -8191,7 +8193,7 @@ # # # - nop" + {cror 0,0,0|nop}" [(set_attr "type" "load,store,*,*,*,*,*,*,*") (set_attr "length" "4,4,4,4,4,8,12,16,4")]) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index 9c624f35a3e..abd2f38458f 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -1,6 +1,6 @@ /* Target definitions for GNU compiler for PowerPC running System V.4 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004 Free Software Foundation, Inc. + 2004, 2005 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GCC. @@ -123,8 +123,10 @@ extern const char *rs6000_tls_size_string; /* For -mtls-size= */ { "no-toc", 0, N_("no description yet") }, \ { "toc", MASK_MINIMAL_TOC, N_("no description yet") }, \ { "full-toc", MASK_MINIMAL_TOC, N_("no description yet") }, \ - { "prototype", MASK_PROTOTYPE, N_("no description yet") }, \ - { "no-prototype", -MASK_PROTOTYPE, N_("no description yet") }, \ + { "prototype", MASK_PROTOTYPE, \ + N_("Assume all variable arg functions are prototyped") }, \ + { "no-prototype", -MASK_PROTOTYPE, \ + N_("Non-prototyped functions might take a variable number of args") }, \ { "no-traceback", 0, N_("no description yet") }, \ { "eabi", MASK_EABI, N_("Use EABI") }, \ { "no-eabi", -MASK_EABI, N_("Don't use EABI") }, \ @@ -1359,8 +1361,6 @@ ncrtn.o%s" ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \ : DW_EH_PE_absptr) -#define TARGET_ASM_EXCEPTION_SECTION readonly_data_section - #define DOUBLE_INT_ASM_OP "\t.quad\t" /* Generate entries in .fixup for relocatable addresses. */ diff --git a/gcc/config/sparc/gmon-sol2.c b/gcc/config/sparc/gmon-sol2.c index 9f9f019e38b..aeead8922fa 100644 --- a/gcc/config/sparc/gmon-sol2.c +++ b/gcc/config/sparc/gmon-sol2.c @@ -267,8 +267,7 @@ _mcleanup(void) * -- [eichin:19920702.1107EST] */ -static void internal_mcount (char *, unsigned short *) - __attribute__ ((__unused__)); +static void internal_mcount (char *, unsigned short *) __attribute__ ((used)); /* i7 == last ret, -> frompcindex */ /* o7 == current ret, -> selfpc */ diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 3202359755f..9f72bc80525 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1892,7 +1892,7 @@ extern GTY(()) rtx sparc_compare_op1; case of a global register variable occupying more than one register we prefix the second and following registers with .gnu.part1. etc. */ -extern char sparc_hard_reg_printed[8]; +extern GTY(()) char sparc_hard_reg_printed[8]; #ifdef HAVE_AS_REGISTER_PSEUDO_OP #define ASM_DECLARE_REGISTER_GLOBAL(FILE, DECL, REGNO, NAME) \ diff --git a/gcc/config/x-linux b/gcc/config/x-linux new file mode 100644 index 00000000000..d14586b0b36 --- /dev/null +++ b/gcc/config/x-linux @@ -0,0 +1,4 @@ +host-linux.o : $(srcdir)/config/host-linux.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h hosthooks.h hosthooks-def.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/host-linux.c diff --git a/gcc/config/x-solaris b/gcc/config/x-solaris new file mode 100644 index 00000000000..782f4a36802 --- /dev/null +++ b/gcc/config/x-solaris @@ -0,0 +1,4 @@ +host-solaris.o : $(srcdir)/config/host-solaris.c $(CONFIG_H) $(SYSTEM_H) \ + coretypes.h hosthooks.h hosthooks-def.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/host-solaris.c diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f213edd8752..2c162b1bf17 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,264 @@ +2005-11-15 Jason Merrill + + PR c++/24580 + * method.c (locate_copy): Also use skip_artificial_parms here. + (synthesize_exception_spec): Use CLASS_TYPE_P rather than checking + for RECORD_TYPE. + +2005-11-16 Volker Reichelt + + Backport from mainline: + 2005-10-12 Nathan Sidwell + + PR c++/23797 + * parser.c (cp_parser_functional_cast): Cope when TYPE is not a + TYPE_DECL. Use dependent_type_p to check type. + * pt.c (uses_template_parms_p): Use dependent_type_p for a + TYPE_DECL. + (type_dependent_expression_p): Assert we've not been given a + TYPE_DECL. + +2005-11-15 Volker Reichelt + + PR c++/19253 + PR c++/22172 + Backport from mainline: + 2005-11-02 Mark Mitchell + + * parser.c (cp_parser_postfix_expression): Use + cp_parser_elaborated_type_specifier to handle typename-types in + functional casts. + (cp_parser_enclosed_argument_list): Skip ahead to the end of the + template argument list if the closing ">" is not found. + +2005-11-14 Jason Merrill + + PR c++/24580 + * method.c (locate_ctor): Skip all artificial parms, not just + 'this'. + +2005-10-28 Josh Conner + + PR c++/22153 + * parser.c (cp_parser_member_declaration): Detect and handle + a template specialization. + +2005-10-20 Volker Reichelt + + PR c++/22508 + * init.c (build_new_1): Remove misleading comment. + +2005-10-12 Paolo Bonzini + + PR c++/24052 + * error.c (dump_expr): Pass LABEL_DECL to dump_decl. Print + an ADDR_EXPR of a LABEL_DECL as &&. + +2005-10-11 Volker Reichelt + + Backport: + 2004-09-23 Andrew Pinski + PR c++/17618 + * cvt.c (cp_convert_to_pointer): Return early when the type is + an error_mark_node. + + 2004-05-22 Roger Sayle + * name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by + returning when TREE_TYPE is error_mark_node. + * typeck.c (require_complete_type): Return error_mark_node if + value's type is an error_mark_node. + + 2004-11-02 Mark Mitchell + PR c++/18177 + * typeck.c (build_const_cast): Use error_operand_p. + +2005-10-06 Volker Reichelt + + * call.c (resolve_args): Remove redundant test. + +2005-09-21 Volker Reichelt + + PR c++/23965 + * call.c (resolve_args): Return error_mark_node on arguments + whose TREE_TYPE is error_mark_node. + +2005-09-21 Volker Reichelt + + PR c++/17609 + Backport: + + 2004-03-08 Mark Mitchell + * lex.c (unqualified_name_lookup_error): Create a dummy VAR_DECL + in the innermost scope, rather than at namespace scope. + * name-lookup.c (push_local_binding): Give it external linkage. + * name-lookup.h (push_local_binding): Declare it. + +2005-09-17 Volker Reichelt + + Backport: + + 2004-11-27 Mark Mitchell + PR c++/18368 + * parser.c (cp_parser_check_for_definition_in_return_type): Take + the defined type as a parameter, and inform the user about the + possibility of a missing semicolon. + (cp_parser_explicit_instantiation): Adjust call to + cp_parser_check_for_definition_in_return_type. + (cp_parser_init_declarator): Likewise. + (cp_parser_member_declaration): Likewise. + +2005-09-17 Volker Reichelt + + PR c++/18803 + Revert: + + 2005-09-02 Volker Reichelt + PR c++/18445 + * class.c (instantiate_type): Treat NON_DEPENDENT_EXPRs with + unknown_type as non matching. + * pt.c (build_non_dependent_expr): Do not build a + NON_DEPENDENT_EXPR for a VAR_DECL. + +2005-09-06 Volker Reichelt + + Backport: + + 2004-12-14 Mark Mitchell + PR c++/18738 + * decl.c (make_typename_type): Do not handle namespace-scoped + names here. + (tag_name): Handle typename_type. + (check_elaborated_type_specifier): Handle typenames. + * parser.c (cp_parser_diagnose_invalid_type_name): Do not call + make_typename_type for namespace-scoped names here. + (cp_parser_elaborated_type_specifier): Use + cp_parser_diagnose_invalid_type_name. + +2005-09-03 Volker Reichelt + + Backport: + + 2005-08-26 Mark Mitchell + PR c++/19004 + * pt.c (uses_template_parms): Handle IDENTIFIER_NODE. + (type_dependent_expression_p): Allow BASELINKs whose associated + functions are simply a FUNCTION_DECL. + +2005-09-02 Volker Reichelt + + PR c++/22233 + * pt.c (push_template_decl_real): Return error_mark_node if the + number of template parameters does not match previous definition. + * decl.c (start_function): Handle error_mark_node returned by + push_template_decl. + +2005-09-02 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18466 + * decl.c (grokvardecl): Keep track of whether or not a there was + explicit qualification. + * name-lookup.c (set_decl_namespace): Complain about explicit + qualification of a name within its own namespace. + +2005-09-02 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18445 + * class.c (instantiate_type): Treat NON_DEPENDENT_EXPRs with + unknown_type as non matching. + * pt.c (build_non_dependent_expr): Do not build a + NON_DEPENDENT_EXPR for a VAR_DECL. + +2005-09-01 Volker Reichelt + + Backport: + + 2004-11-27 Mark Mitchell + PR c++/18512 + * parser.c (cp_parser_postfix_expression): Robustify. + +2005-09-01 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18545 + * typeck.c (check_return_expr): Robustify. + +2005-09-01 Volker Reichelt + + Backport: + + 2005-02-22 Mark Mitchell + PR c++/20153 + * decl2.c (build_anon_union_vars): Add type parameter. + (finish_anon_union): Pass it. + + 2005-07-28 Mark Mitchell + PR c++/22545 + * call.c (add_builtin_candidate): Adjust for changes in + representation of pointer-to-member types. + +2005-09-01 Volker Reichelt + + PR c++/13377 + * parser.c (cp_parser_lookup_name): Pass LOOKUP_COMPLAIN to + lookup_name_real on final parse. + +2005-08-31 Volker Reichelt + + PR c++/23586 + * parser.c (cp_parser_namespace_name): Move diagnostic for + invalid namespace-name to here from ... + * name-lookup.c (do_namespace_alias): ... here and ... + (do_using_directive): ... here. Remove dead code. + +2005-08-31 Volker Reichelt + + PR c++/23639 + * semantics.c (qualified_name_lookup_error): Do not complain again + on invalid scope. + +2005-07-28 Giovanni Bajo + + Backport: + + 2004-09-16 Mark Mitchell + PR c++/16002 + * parser.c (cp_parser_simple_declaration): Commit to tentative + parses after seeing a decl-specifier. + (cp_parser_simple_declaration): Eliminate spurious message. + (cp_parser_init_declarator): Adjust error message. + + 2005-06-17 Geoffrey Keating + PR c++/17413 + * pt.c (type_unification_real): Apply template type deduction even + to procedure parameters that are not dependent on a template + parameter. + + 2004-11-02 Mark Mitchell + PR c++/18124 + * parser.c (cp_parser_type_parameter): Robustify. + PR c++/18155 + * parser.c (cp_parser_single_declaration): Disallow template + typedefs. + (cp_parser_typedef_p): New function. + + 2004-12-21 Mark Mitchell + PR c++/18378 + * call.c (convert_like_real): Do not permit the use of a copy + constructor to copy a packed field. + +2005-07-25 Giovanni Bajo + + PR c++/19208 + * pt.c (tsubst): Use fold_non_dependent_expr to fold array domains. + 2005-06-14 Mark Mitchell PR c++/21987 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index aeed3155df4..01c8926b076 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1556,7 +1556,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1) && (TYPE_PTRMEMFUNC_P (type2) - || is_complete (TREE_TYPE (TREE_TYPE (type2))))) + || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2)))) break; } return; @@ -2544,7 +2544,7 @@ resolve_args (tree args) { tree arg = TREE_VALUE (t); - if (arg == error_mark_node) + if (error_operand_p (arg)) return error_mark_node; else if (VOID_TYPE_P (TREE_TYPE (arg))) { @@ -4080,13 +4080,12 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr)) { tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); + cp_lvalue_kind lvalue = real_lvalue_p (expr); if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))) { /* If the reference is volatile or non-const, we cannot create a temporary. */ - cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (lvalue & clk_bitfield) error ("cannot bind bitfield `%E' to `%T'", expr, ref_type); @@ -4097,6 +4096,20 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, error ("cannot bind rvalue `%E' to `%T'", expr, ref_type); return error_mark_node; } + /* If the source is a packed field, and we must use a copy + constructor, then building the target expr will require + binding the field to the reference parameter to the + copy constructor, and we'll end up with an infinite + loop. If we can use a bitwise copy, then we'll be + OK. */ + if ((lvalue & clk_packed) + && CLASS_TYPE_P (type) + && !TYPE_HAS_TRIVIAL_INIT_REF (type)) + { + error ("cannot bind packed field `%E' to `%T'", + expr, ref_type); + return error_mark_node; + } expr = build_target_expr_with_type (expr, type); } diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 8276451cb10..2071c260299 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -79,6 +79,8 @@ cp_convert_to_pointer (tree type, tree expr, bool force) tree intype = TREE_TYPE (expr); enum tree_code form; tree rval; + if (intype == error_mark_node) + return error_mark_node; if (IS_AGGR_TYPE (intype)) { diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 103daac1266..fab8cd4cf45 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2650,16 +2650,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain) return error_mark_node; } my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030802); - - if (TREE_CODE (context) == NAMESPACE_DECL) - { - /* We can get here from typename_sub0 in the explicit_template_type - expansion. Just fail. */ - if (complain & tf_error) - error ("no class template named `%#T' in `%#T'", - name, context); - return error_mark_node; - } + my_friendly_assert (TYPE_P (context), 20050905); if (!dependent_type_p (context) || currently_open_class (context)) @@ -5924,6 +5915,7 @@ grokvardecl (tree type, tree scope) { tree decl; + tree explicit_scope; RID_BIT_TYPE specbits; my_friendly_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE, @@ -5931,7 +5923,9 @@ grokvardecl (tree type, specbits = *specbits_in; - /* Compute the scope in which to place the variable. */ + /* Compute the scope in which to place the variable, but remember + whether or not that scope was explicitly specified by the user. */ + explicit_scope = scope; if (!scope) { /* An explicit "extern" specifier indicates a namespace-scope @@ -5960,8 +5954,8 @@ grokvardecl (tree type, else decl = build_decl (VAR_DECL, name, type); - if (scope && TREE_CODE (scope) == NAMESPACE_DECL) - set_decl_namespace (decl, scope, 0); + if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL) + set_decl_namespace (decl, explicit_scope, 0); else DECL_CONTEXT (decl) = scope; @@ -9362,9 +9356,11 @@ tag_name (enum tag_types code) case class_type: return "class"; case union_type: - return "union "; + return "union"; case enum_type: return "enum"; + case typename_type: + return "typename"; default: abort (); } @@ -9402,7 +9398,8 @@ check_elaborated_type_specifier (enum tag_types tag_code, In other words, the only legitimate declaration to use in the elaborated type specifier is the implicit typedef created when the type is declared. */ - if (!DECL_IMPLICIT_TYPEDEF_P (decl)) + if (!DECL_IMPLICIT_TYPEDEF_P (decl) + && tag_code != typename_type) { error ("using typedef-name `%D' after `%s'", decl, tag_name (tag_code)); return IS_AGGR_TYPE (type) ? type : error_mark_node; @@ -9416,7 +9413,8 @@ check_elaborated_type_specifier (enum tag_types tag_code, } else if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE - && tag_code != enum_type) + && tag_code != enum_type + && tag_code != typename_type) { error ("`%T' referred to as `%s'", type, tag_name (tag_code)); return error_mark_node; @@ -10341,7 +10339,11 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags) class scope, current_class_type will be NULL_TREE until set above by push_nested_class.) */ if (processing_template_decl) - decl1 = push_template_decl (decl1); + { + tree newdecl1 = push_template_decl (decl1); + if (newdecl1 != error_mark_node) + decl1 = newdecl1; + } /* We are now in the scope of the function being defined. */ current_function_decl = decl1; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1c997111b86..37b8f2b7128 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -64,7 +64,6 @@ typedef struct priority_info_s { static void mark_vtable_entries (tree); static void grok_function_init (tree, tree); static bool maybe_emit_vtables (tree); -static tree build_anon_union_vars (tree); static bool acceptable_java_type (tree); static tree start_objects (int, int); static void finish_objects (int, int, tree); @@ -1131,14 +1130,13 @@ defer_fn (tree fn) VARRAY_PUSH_TREE (deferred_fns, fn); } -/* Walks through the namespace- or function-scope anonymous union OBJECT, - building appropriate ALIAS_DECLs. Returns one of the fields for use in - the mangled name. */ +/* Walks through the namespace- or function-scope anonymous union + OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs. + Returns one of the fields for use in the mangled name. */ static tree -build_anon_union_vars (tree object) +build_anon_union_vars (tree type, tree object) { - tree type = TREE_TYPE (object); tree main_decl = NULL_TREE; tree field; @@ -1185,7 +1183,7 @@ build_anon_union_vars (tree object) decl = pushdecl (decl); } else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) - decl = build_anon_union_vars (ref); + decl = build_anon_union_vars (TREE_TYPE (field), ref); else decl = 0; @@ -1225,7 +1223,7 @@ finish_anon_union (tree anon_union_decl) return; } - main_decl = build_anon_union_vars (anon_union_decl); + main_decl = build_anon_union_vars (type, anon_union_decl); if (main_decl == NULL_TREE) { warning ("anonymous union with no members"); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 5b83c607460..381b5bec666 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1307,6 +1307,7 @@ dump_expr (tree t, int flags) case FUNCTION_DECL: case TEMPLATE_DECL: case NAMESPACE_DECL: + case LABEL_DECL: case OVERLOAD: case IDENTIFIER_NODE: dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS); @@ -1547,6 +1548,8 @@ dump_expr (tree t, int flags) || (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)) dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL) + dump_unary_op ("&&", t, flags); else dump_unary_op ("&", t, flags); break; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 732d4a0c84d..8064e4f5891 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2075,9 +2075,6 @@ build_new_1 (tree exp) fns = lookup_fnfields (true_type, fnname, /*protect=*/2); if (!fns) { - /* See PR 15967. This should never happen (and it is - fixed correctly in mainline), but on the release branch - we prefer this less-intrusive approacch. */ error ("no suitable or ambiguous `%D' found in class `%T'", fnname, true_type); return error_mark_node; diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 2239c76ca87..66e45ed905a 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -627,26 +627,18 @@ unqualified_name_lookup_error (tree name) if (name != ansi_opname (ERROR_MARK)) error ("`%D' not defined", name); } - else if (current_function_decl == 0) - error ("`%D' was not declared in this scope", name); else { - if (IDENTIFIER_NAMESPACE_VALUE (name) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (name) != current_function_decl) + error ("`%D' was not declared in this scope", name); + /* Prevent repeated error messages by creating a VAR_DECL with + this NAME in the innermost block scope. */ + if (current_function_decl) { - static int undeclared_variable_notice; - - error ("`%D' undeclared (first use this function)", name); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once for each function it appears in.)"); - undeclared_variable_notice = 1; - } + tree decl; + decl = build_decl (VAR_DECL, name, error_mark_node); + DECL_CONTEXT (decl) = current_function_decl; + push_local_binding (name, decl, 0); } - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node); - SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl); } return error_mark_node; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 6ad3ab17165..174b7314ef5 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -853,7 +853,7 @@ synthesize_exception_spec (tree type, tree (*extractor) (tree, void*), continue; while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); - if (TREE_CODE (type) != RECORD_TYPE) + if (!CLASS_TYPE_P (type)) continue; fn = (*extractor) (type, client); @@ -898,7 +898,9 @@ locate_ctor (tree type, void *client ATTRIBUTE_UNUSED) tree fn = OVL_CURRENT (fns); tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); - if (sufficient_parms_p (TREE_CHAIN (parms))) + parms = skip_artificial_parms_for (fn, parms); + + if (sufficient_parms_p (parms)) return fn; } return NULL_TREE; @@ -942,7 +944,7 @@ locate_copy (tree type, void *client_) int excess; int quals; - parms = TREE_CHAIN (parms); + parms = skip_artificial_parms_for (fn, parms); if (!parms) continue; src_type = non_reference (TREE_VALUE (parms)); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 06f0cc912d2..adfc26d8162 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -35,7 +35,6 @@ static cxx_scope *innermost_nonclass_level (void); static tree select_decl (cxx_binding *, int); static cxx_binding *binding_for_name (cxx_scope *, tree); static tree lookup_name_current_level (tree); -static void push_local_binding (tree, tree, int); static tree push_overloaded_decl (tree, int); static bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int); @@ -1052,7 +1051,7 @@ maybe_push_decl (tree decl) doesn't really belong to this binding level, that it got here through a using-declaration. */ -static void +void push_local_binding (tree id, tree decl, int flags) { struct cp_binding_level *b; @@ -1180,6 +1179,10 @@ check_for_out_of_scope_variable (tree decl) return decl; DECL_ERROR_REPORTED (decl) = 1; + + if (TREE_TYPE (decl) == error_mark_node) + return decl; + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) { error ("name lookup of `%D' changed for new ISO `for' scoping", @@ -3022,7 +3025,13 @@ set_decl_namespace (tree decl, tree scope, bool friendp) return; } else - return; + { + /* Writing "int N::i" to declare a variable within "N" is invalid. */ + if (at_namespace_scope_p ()) + error ("explicit qualification in declaration of `%D'", decl); + return; + } + complain: error ("`%D' should have been declared inside `%D'", decl, scope); @@ -3200,12 +3209,10 @@ namespace_ancestor (tree ns1, tree ns2) void do_namespace_alias (tree alias, tree namespace) { - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - /* The parser did not find it, so it's not there. */ - error ("unknown namespace `%D'", namespace); - return; - } + if (namespace == error_mark_node) + return; + + my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 20050830); namespace = ORIGINAL_NAMESPACE (namespace); @@ -3346,26 +3353,15 @@ do_toplevel_using_decl (tree decl, tree scope, tree name) void do_using_directive (tree namespace) { + if (namespace == error_mark_node) + return; + + my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 20050830); + if (building_stmt_tree ()) add_stmt (build_stmt (USING_STMT, namespace)); - - /* using namespace A::B::C; */ - if (TREE_CODE (namespace) == SCOPE_REF) - namespace = TREE_OPERAND (namespace, 1); - if (TREE_CODE (namespace) == IDENTIFIER_NODE) - { - /* Lookup in lexer did not find a namespace. */ - if (!processing_template_decl) - error ("namespace `%T' undeclared", namespace); - return; - } - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - if (!processing_template_decl) - error ("`%T' is not a namespace", namespace); - return; - } namespace = ORIGINAL_NAMESPACE (namespace); + if (!toplevel_bindings_p ()) push_using_directive (namespace); else diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 83775752053..1ade1a91f3f 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -287,6 +287,7 @@ extern tree lookup_namespace_name (tree, tree); extern tree lookup_qualified_name (tree, tree, bool, bool); extern tree lookup_name_nonclass (tree); extern tree lookup_function_nonclass (tree, tree); +extern void push_local_binding (tree, tree, int); extern int push_class_binding (tree, tree); extern bool pushdecl_class_level (tree); extern tree pushdecl_namespace_level (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ed6031c0a62..c04ba670531 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1672,6 +1672,8 @@ static bool cp_parser_declares_only_class_p (cp_parser *); static bool cp_parser_friend_p (tree); +static bool cp_parser_typedef_p + (tree); static cp_token *cp_parser_require (cp_parser *, enum cpp_ttype, const char *); static cp_token *cp_parser_require_keyword @@ -1717,7 +1719,7 @@ static bool cp_parser_simulate_error static void cp_parser_check_type_definition (cp_parser *); static void cp_parser_check_for_definition_in_return_type - (tree, int); + (tree, tree); static void cp_parser_check_for_invalid_template_id (cp_parser *, tree); static bool cp_parser_non_integral_constant_expression @@ -1849,14 +1851,13 @@ cp_parser_check_type_definition (cp_parser* parser) error ("%s", parser->type_definition_forbidden_message); } -/* This function is called when a declaration is parsed. If - DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM - indicates that a type was defined in the decl-specifiers for DECL, - then an error is issued. */ +/* This function is called when the DECLARATOR is processed. The TYPE + was a type defined in the decl-specifiers. If it is invalid to + define a type in the decl-specifiers for DECLARATOR, an error is + issued. */ static void -cp_parser_check_for_definition_in_return_type (tree declarator, - int declares_class_or_enum) +cp_parser_check_for_definition_in_return_type (tree declarator, tree type) { /* [dcl.fct] forbids type definitions in return types. Unfortunately, it's not easy to know whether or not we are @@ -1866,9 +1867,12 @@ cp_parser_check_for_definition_in_return_type (tree declarator, || TREE_CODE (declarator) == ADDR_EXPR)) declarator = TREE_OPERAND (declarator, 0); if (declarator - && TREE_CODE (declarator) == CALL_EXPR - && declares_class_or_enum & 2) - error ("new types may not be defined in a return type"); + && TREE_CODE (declarator) == CALL_EXPR) + { + error ("new types may not be defined in a return type"); + inform ("(perhaps a semicolon is missing after the definition of `%T')", + type); + } } /* A type-specifier (TYPE) has been parsed which cannot be followed by @@ -3548,52 +3552,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) case RID_TYPENAME: { - bool template_p = false; - tree id; tree type; - tree scope; - - /* Consume the `typename' token. */ - cp_lexer_consume_token (parser->lexer); - /* Look for the optional `::' operator. */ - cp_parser_global_scope_opt (parser, - /*current_scope_valid_p=*/false); - /* Look for the nested-name-specifier. In case of error here, - consume the trailing id to avoid subsequent error messages - for usual cases. */ - scope = cp_parser_nested_name_specifier (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/true, - /*type_p=*/true, - /*is_declaration=*/true); - - /* Look for the optional `template' keyword. */ - template_p = cp_parser_optional_template_keyword (parser); - /* We don't know whether we're looking at a template-id or an - identifier. */ - cp_parser_parse_tentatively (parser); - /* Try a template-id. */ - id = cp_parser_template_id (parser, template_p, - /*check_dependency_p=*/true, - /*is_declaration=*/true); - /* If that didn't work, try an identifier. */ - if (!cp_parser_parse_definitely (parser)) - id = cp_parser_identifier (parser); - - /* Don't process id if nested name specifier is invalid. */ - if (scope == error_mark_node) - return error_mark_node; - /* If we look up a template-id in a non-dependent qualifying - scope, there's no need to create a dependent type. */ - else if (TREE_CODE (id) == TYPE_DECL - && !dependent_type_p (parser->scope)) - type = TREE_TYPE (id); - /* Create a TYPENAME_TYPE to represent the type to which the - functional cast is being performed. */ - else - type = make_typename_type (parser->scope, id, - /*complain=*/1); + /* The syntax permitted here is the same permitted for an + elaborated-type-specifier. */ + type = cp_parser_elaborated_type_specifier (parser, + /*is_friend=*/false, + /*is_declaration=*/false); postfix_expression = cp_parser_functional_cast (parser, type); } break; @@ -3964,20 +3929,29 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) if (parser->scope) idk = CP_ID_KIND_QUALIFIED; - if (name != error_mark_node - && !BASELINK_P (name) - && parser->scope) + /* If the name is a template-id that names a type, we will + get a TYPE_DECL here. That is invalid code. */ + if (TREE_CODE (name) == TYPE_DECL) { - name = build_nt (SCOPE_REF, parser->scope, name); - parser->scope = NULL_TREE; - parser->qualifying_scope = NULL_TREE; - parser->object_scope = NULL_TREE; + error ("invalid use of `%D'", name); + postfix_expression = error_mark_node; + } + else + { + if (name != error_mark_node && !BASELINK_P (name) + && parser->scope) + { + name = build_nt (SCOPE_REF, parser->scope, name); + parser->scope = NULL_TREE; + parser->qualifying_scope = NULL_TREE; + parser->object_scope = NULL_TREE; + } + if (scope && name && BASELINK_P (name)) + adjust_result_of_qualified_name_lookup + (name, BINFO_TYPE (BASELINK_BINFO (name)), scope); + postfix_expression = finish_class_member_access_expr + (postfix_expression, name); } - if (scope && name && BASELINK_P (name)) - adjust_result_of_qualified_name_lookup - (name, BINFO_TYPE (BASELINK_BINFO (name)), scope); - postfix_expression - = finish_class_member_access_expr (postfix_expression, name); } /* We no longer need to look up names in the scope of the @@ -6528,6 +6502,13 @@ cp_parser_simple_declaration (cp_parser* parser, /* Give up. */ goto done; } + + /* If we have seen at least one decl-specifier, and the next token + is not a parenthesis, then we must be looking at a declaration. + (After "int (" we might be looking at a functional cast.) */ + if (decl_specifiers + && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + cp_parser_commit_to_tentative_parse (parser); /* Keep going until we hit the `;' at the end of the simple declaration. */ @@ -6581,7 +6562,12 @@ cp_parser_simple_declaration (cp_parser* parser, /* Anything else is an error. */ else { - cp_parser_error (parser, "expected `,' or `;'"); + /* If we have already issued an error message we don't need + to issue another one. */ + if (decl != error_mark_node + || (cp_parser_parsing_tentatively (parser) + && !cp_parser_committed_to_tentative_parse (parser))) + cp_parser_error (parser, "expected `,' or `;'"); /* Skip tokens until we reach the end of the statement. */ cp_parser_skip_to_end_of_statement (parser); /* If the next token is now a `;', consume it. */ @@ -7807,9 +7793,15 @@ cp_parser_type_parameter (cp_parser* parser) if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ) && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER) && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) - identifier = cp_parser_identifier (parser); + { + identifier = cp_parser_identifier (parser); + /* Treat invalid names as if the parameter were nameless. */ + if (identifier == error_mark_node) + identifier = NULL_TREE; + } else identifier = NULL_TREE; + /* Create the template parameter. */ parameter = finish_template_template_parm (class_type_node, identifier); @@ -7851,15 +7843,13 @@ cp_parser_type_parameter (cp_parser* parser) /* Create the combined representation of the parameter and the default argument. */ - parameter = build_tree_list (default_argument, parameter); + parameter = build_tree_list (default_argument, parameter); } break; default: - /* Anything else is an error. */ - cp_parser_error (parser, - "expected `class', `typename', or `template'"); - parameter = error_mark_node; + abort (); + break; } return parameter; @@ -8615,8 +8605,9 @@ cp_parser_explicit_instantiation (cp_parser* parser) /*ctor_dtor_or_conv_p=*/NULL, /*parenthesized_p=*/NULL, /*member_p=*/false); - cp_parser_check_for_definition_in_return_type (declarator, - declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); if (declarator != error_mark_node) { decl = grokdeclarator (declarator, decl_specifiers, @@ -9223,7 +9214,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, } /* For a `typename', we needn't call xref_tag. */ - if (tag_type == typename_type) + if (tag_type == typename_type + && TREE_CODE (parser->scope) != NAMESPACE_DECL) return make_typename_type (parser->scope, identifier, /*complain=*/1); /* Look up a qualified name in the usual way. */ @@ -9267,7 +9259,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser, if (TREE_CODE (decl) != TYPE_DECL) { - error ("expected type-name"); + cp_parser_diagnose_invalid_type_name (parser); return error_mark_node; } @@ -9519,6 +9511,9 @@ cp_parser_namespace_name (cp_parser* parser) if (namespace_decl == error_mark_node || TREE_CODE (namespace_decl) != NAMESPACE_DECL) { + if (!cp_parser_parsing_tentatively (parser) + || cp_parser_committed_to_tentative_parse (parser)) + error ("`%D' is not a namespace-name", identifier); cp_parser_error (parser, "expected namespace-name"); namespace_decl = error_mark_node; } @@ -9987,8 +9982,9 @@ cp_parser_init_declarator (cp_parser* parser, if (declarator == error_mark_node) return error_mark_node; - cp_parser_check_for_definition_in_return_type (declarator, - declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); /* Figure out what scope the entity declared by the DECLARATOR is located in. `grokdeclarator' sometimes changes the scope, so @@ -10074,7 +10070,7 @@ cp_parser_init_declarator (cp_parser* parser, && token->type != CPP_COMMA && token->type != CPP_SEMICOLON) { - cp_parser_error (parser, "expected init-declarator"); + cp_parser_error (parser, "expected initializer"); return error_mark_node; } @@ -12488,8 +12484,13 @@ cp_parser_member_declaration (cp_parser* parser) /* Check for a template-declaration. */ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE)) { - /* Parse the template-declaration. */ - cp_parser_template_declaration (parser, /*member_p=*/true); + /* An explicit specialization here is an error condition, and we + expect the specialization handler to detect and report this. */ + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS + && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER) + cp_parser_explicit_specialization (parser); + else + cp_parser_template_declaration (parser, /*member_p=*/true); return; } @@ -12690,8 +12691,9 @@ cp_parser_member_declaration (cp_parser* parser) return; } - cp_parser_check_for_definition_in_return_type - (declarator, declares_class_or_enum); + if (declares_class_or_enum & 2) + cp_parser_check_for_definition_in_return_type + (declarator, TREE_VALUE (decl_specifiers)); /* Look for an asm-specification. */ asm_specification = cp_parser_asm_specification_opt (parser); @@ -13697,6 +13699,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool is_type, bool is_template, bool is_namespace, bool check_dependency) { + int flags = 0; tree decl; tree object_type = parser->context->object_type; @@ -13708,6 +13711,10 @@ cp_parser_lookup_name (cp_parser *parser, tree name, if (name == error_mark_node) return error_mark_node; + if (!cp_parser_parsing_tentatively (parser) + || cp_parser_committed_to_tentative_parse (parser)) + flags |= LOOKUP_COMPLAIN; + /* A template-id has already been resolved; there is no lookup to do. */ if (TREE_CODE (name) == TEMPLATE_ID_EXPR) @@ -13821,8 +13828,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*protect=*/0, is_type); /* Look it up in the enclosing context, too. */ decl = lookup_name_real (name, is_type, /*nonclass=*/0, - is_namespace, - /*flags=*/0); + is_namespace, flags); parser->object_scope = object_type; parser->qualifying_scope = NULL_TREE; if (object_decl) @@ -13831,8 +13837,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, else { decl = lookup_name_real (name, is_type, /*nonclass=*/0, - is_namespace, - /*flags=*/0); + is_namespace, flags); parser->qualifying_scope = NULL_TREE; parser->object_scope = NULL_TREE; } @@ -14516,6 +14521,12 @@ cp_parser_single_declaration (cp_parser* parser, tree attributes; bool function_definition_p = false; + /* This function is only used when processing a template + declaration. */ + if (innermost_scope_kind () != sk_template_parms + && innermost_scope_kind () != sk_template_spec) + abort (); + /* Defer access checks until we know what is being declared. */ push_deferring_access_checks (dk_deferred); @@ -14528,6 +14539,14 @@ cp_parser_single_declaration (cp_parser* parser, &declares_class_or_enum); if (friend_p) *friend_p = cp_parser_friend_p (decl_specifiers); + + /* There are no template typedefs. */ + if (cp_parser_typedef_p (decl_specifiers)) + { + error ("template declaration of `typedef'"); + decl = error_mark_node; + } + /* Gather up the access checks that occurred the decl-specifier-seq. */ stop_deferring_access_checks (); @@ -14544,8 +14563,6 @@ cp_parser_single_declaration (cp_parser* parser, decl = error_mark_node; } } - else - decl = NULL_TREE; /* If it's not a template class, try for a template function. If the next token is a `;', then this declaration does not declare anything. But, if there were errors in the decl-specifiers, then @@ -14571,7 +14588,8 @@ cp_parser_single_declaration (cp_parser* parser, parser->object_scope = NULL_TREE; /* Look for a trailing `;' after the declaration. */ if (!function_definition_p - && !cp_parser_require (parser, CPP_SEMICOLON, "`;'")) + && (decl == error_mark_node + || !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))) cp_parser_skip_to_end_of_block_or_statement (parser); return decl; @@ -14601,8 +14619,10 @@ cp_parser_functional_cast (cp_parser* parser, tree type) cast = build_functional_cast (type, expression_list); /* [expr.const]/1: In an integral constant expression "only type conversions to integral or enumeration type can be used". */ - if (cast != error_mark_node && !type_dependent_expression_p (type) - && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (type))) + if (TREE_CODE (type) == TYPE_DECL) + type = TREE_TYPE (type); + if (cast != error_mark_node && !dependent_type_p (type) + && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) { if (cp_parser_non_integral_constant_expression (parser, "a call to a constructor")) @@ -14724,8 +14744,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) cp_lexer_consume_token (parser->lexer); } } - else if (!cp_parser_require (parser, CPP_GREATER, "`>'")) - error ("missing `>' to terminate the template argument list"); + else + cp_parser_skip_until_found (parser, CPP_GREATER, "`>'"); /* The `>' token might be a greater-than operator again now. */ parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; @@ -15037,6 +15057,27 @@ cp_parser_friend_p (tree decl_specifiers) return false; } +/* DECL_SPECIFIERS is the representation of a decl-specifier-seq. + Returns TRUE iff `typedef' appears among the DECL_SPECIFIERS. */ + +static bool +cp_parser_typedef_p (tree decl_specifiers) +{ + while (decl_specifiers) + { + /* See if this decl-specifier is `typedef'. */ + if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE + && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_TYPEDEF) + return true; + + /* Go on to the next decl-specifier. */ + decl_specifiers = TREE_CHAIN (decl_specifiers); + } + + return false; +} + + /* If the next token is of the indicated TYPE, consume it. Otherwise, issue an error message indicating that TOKEN_DESC was expected. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 723346d8342..d826c74eee3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2978,6 +2978,7 @@ push_template_decl_real (tree decl, int is_friend) error ("got %d template parameters for `%#T'", TREE_VEC_LENGTH (a), current); error (" but %d required", TREE_VEC_LENGTH (t)); + return error_mark_node; } /* Perhaps we should also check that the parms are used in the @@ -4804,11 +4805,14 @@ uses_template_parms (tree t) else if (TREE_CODE (t) == TREE_LIST) dependent_p = (uses_template_parms (TREE_VALUE (t)) || uses_template_parms (TREE_CHAIN (t))); + else if (TREE_CODE (t) == TYPE_DECL) + dependent_p = dependent_type_p (TREE_TYPE (t)); else if (DECL_P (t) || EXPR_P (t) || TREE_CODE (t) == TEMPLATE_PARM_INDEX || TREE_CODE (t) == OVERLOAD || TREE_CODE (t) == BASELINK + || TREE_CODE (t) == IDENTIFIER_NODE || TREE_CODE_CLASS (TREE_CODE (t)) == 'c') dependent_p = (type_dependent_expression_p (t) || value_dependent_expression_p (t)); @@ -6720,8 +6724,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* The array dimension behaves like a non-type template arg, in that we want to fold it as much as possible. */ max = tsubst_template_arg (omax, args, complain, in_decl); - if (!processing_template_decl) - max = decl_constant_value (max); + max = fold_non_dependent_expr (max); if (integer_zerop (omax)) { @@ -9167,17 +9170,12 @@ type_unification_real (tree tparms, else type = arg; - if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ + if (same_type_p (parm, type)) continue; - + if (strict != DEDUCE_EXACT + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + continue; + return 1; } @@ -12026,7 +12024,8 @@ type_dependent_expression_p (tree expression) return true; expression = TREE_OPERAND (expression, 0); } - if (TREE_CODE (expression) == OVERLOAD) + if (TREE_CODE (expression) == OVERLOAD + || TREE_CODE (expression) == FUNCTION_DECL) { while (expression) { @@ -12039,6 +12038,8 @@ type_dependent_expression_p (tree expression) abort (); } + my_friendly_assert (TREE_CODE (expression) != TYPE_DECL, 20051116); + return (dependent_type_p (TREE_TYPE (expression))); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bb2f3c925ad..55984b75ade 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2295,7 +2295,9 @@ check_multiple_declarators (void) void qualified_name_lookup_error (tree scope, tree name) { - if (TYPE_P (scope)) + if (scope == error_mark_node) + ; /* We already complained. */ + else if (TYPE_P (scope)) { if (!COMPLETE_TYPE_P (scope)) error ("incomplete type `%T' used in nested name specifier", scope); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e0f6868a6d7..b13fb857d69 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -95,6 +95,9 @@ require_complete_type (tree value) else type = TREE_TYPE (value); + if (type == error_mark_node) + return error_mark_node; + /* First, detect a valid value with a complete type. */ if (COMPLETE_TYPE_P (type)) return value; @@ -4794,7 +4797,7 @@ build_const_cast (tree type, tree expr) { tree intype; - if (type == error_mark_node || expr == error_mark_node) + if (type == error_mark_node || error_operand_p (expr)) return error_mark_node; if (processing_template_decl) @@ -6084,6 +6087,15 @@ check_return_expr (tree retval) /* Remember that this function did return a value. */ current_function_returns_value = 1; + /* Check for erroneous operands -- but after giving ourselves a + chance to provide an error about returning a value from a void + function. */ + if (error_operand_p (retval)) + { + current_function_return_value = error_mark_node; + return error_mark_node; + } + /* Only operator new(...) throw(), can return NULL [expr.new/13]. */ if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR || DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR) @@ -6140,8 +6152,8 @@ check_return_expr (tree retval) /* We don't need to do any conversions when there's nothing being returned. */ - if (!retval || retval == error_mark_node) - return retval; + if (!retval) + return NULL_TREE; /* Do any required conversions. */ if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl)) diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 9aea34c4b36..c5587bcdaed 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -164,7 +164,7 @@ static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import); static struct cpp_dir *search_path_head (cpp_reader *, const char *fname, int angle_brackets, enum include_type); static const char *dir_name_of_file (_cpp_file *file); -static void open_file_failed (cpp_reader *pfile, _cpp_file *file); +static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int); static struct file_hash_entry *search_cache (struct file_hash_entry *head, const cpp_dir *start_dir); static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname); @@ -330,7 +330,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (file->err_no != ENOENT) { - open_file_failed (pfile, file); + open_file_failed (pfile, file, 0); return true; } @@ -360,7 +360,7 @@ _cpp_find_failed (_cpp_file *file) to open_file(). */ _cpp_file * -_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake) +_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake, int angle_brackets) { struct file_hash_entry *entry, **hash_slot; _cpp_file *file; @@ -391,7 +391,7 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f file->dir = file->dir->next; if (file->dir == NULL) { - open_file_failed (pfile, file); + open_file_failed (pfile, file, angle_brackets); if (invalid_pch) { cpp_error (pfile, CPP_DL_ERROR, @@ -533,7 +533,7 @@ read_file (cpp_reader *pfile, _cpp_file *file) if (file->fd == -1 && !open_file (file)) { - open_file_failed (pfile, file); + open_file_failed (pfile, file, 0); return false; } @@ -757,16 +757,17 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, if (!dir) return false; - return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false), + return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false, + angle_brackets), type == IT_IMPORT); } /* Could not open FILE. The complication is dependency output. */ static void -open_file_failed (cpp_reader *pfile, _cpp_file *file) +open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) { int sysp = pfile->map ? pfile->map->sysp: 0; - bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp; + bool print_dep = CPP_OPTION (pfile, deps.style) > (angle_brackets || !!sysp); errno = file->err_no; if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT) @@ -948,7 +949,7 @@ _cpp_cleanup_files (cpp_reader *pfile) void _cpp_fake_include (cpp_reader *pfile, const char *fname) { - _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true); + _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 0); } /* Not everyone who wants to set system-header-ness on a buffer can @@ -1030,7 +1031,7 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname, if (!dir) return -1; - file = _cpp_find_file (pfile, fname, dir, false); + file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); if (file->err_no) return -1; diff --git a/gcc/cpphash.h b/gcc/cpphash.h index e30cdcad63a..8c814b90fb6 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -516,7 +516,7 @@ extern void _cpp_destroy_hashtable (cpp_reader *); /* In cppfiles.c */ typedef struct _cpp_file _cpp_file; extern _cpp_file *_cpp_find_file (cpp_reader *, const char *fname, - cpp_dir *start_dir, bool fake); + cpp_dir *start_dir, bool fake, int); extern bool _cpp_find_failed (_cpp_file *); extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *); extern void _cpp_fake_include (cpp_reader *, const char *); diff --git a/gcc/cppinit.c b/gcc/cppinit.c index ae30568699c..647fbbf5f52 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -466,7 +466,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname) } pfile->main_file - = _cpp_find_file (pfile, fname, &pfile->no_search_path, false); + = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0); if (_cpp_find_failed (pfile->main_file)) return NULL; @@ -477,6 +477,8 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname) if (CPP_OPTION (pfile, preprocessed)) { read_original_filename (pfile); + if (!pfile->map) + return NULL; fname = pfile->map->to_file; } return fname; @@ -496,8 +498,10 @@ read_original_filename (cpp_reader *pfile) token = _cpp_lex_direct (pfile); if (token->type == CPP_HASH) { + pfile->state.in_directive = 1; token1 = _cpp_lex_direct (pfile); _cpp_backup_tokens (pfile, 1); + pfile->state.in_directive = 0; /* If it's a #line directive, handle it. */ if (token1->type == CPP_NUMBER) diff --git a/gcc/doc/hostconfig.texi b/gcc/doc/hostconfig.texi index 5c38313efd2..8830c6b8ac1 100644 --- a/gcc/doc/hostconfig.texi +++ b/gcc/doc/hostconfig.texi @@ -42,35 +42,31 @@ This host hook is used to set up handling for extra signals. The most common thing to do in this hook is to detect stack overflow. @end deftypefn -@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size}) -This host hook returns the address of some space in which a PCH may be -loaded with @samp{HOST_HOOKS_PCH_LOAD_PCH}. The space will need to -have @var{size} bytes. If insufficient space is available, -@samp{NULL} may be returned; the PCH machinery will try to find a -suitable address using a heuristic. - -The memory does not have to be available now. In fact, usually -@samp{HOST_HOOKS_PCH_LOAD_PCH} will already have been called. The memory -need only be available in future invocations of GCC. +@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size}, int @var{fd}) +This host hook returns the address of some space that is likely to be +free in some subsequent invocation of the compiler. We intend to load +the PCH data at this address such that the data need not be relocated. +The area should be able to hold @var{size} bytes. If the host uses +@code{mmap}, @var{fd} is an open file descriptor that can be used for +probing. @end deftypefn -@deftypefn {Host Hook} bool HOST_HOOKS_GT_PCH_USE_ADDRESS (size_t @var{size}, void * @var{address}) -This host hook is called when a PCH file is about to be loaded. If -@var{address} is the address that would have been returned by -@samp{HOST_HOOKS_PCH_MEMORY_ADDRESS}, and @var{size} is smaller than -the maximum than @samp{HOST_HOOKS_PCH_MEMORY_ADDRESS} would have -accepted, return true, otherwise return false. +@deftypefn {Host Hook} int HOST_HOOKS_GT_PCH_USE_ADDRESS (void * @var{address}, size_t @var{size}, int @var{fd}, size_t @var{offset}) +This host hook is called when a PCH file is about to be loaded. +We want to load @var{size} bytes from @var{fd} at @var{offset} +into memory at @var{address}. The given address will be the result of +a previous invocation of @code{HOST_HOOKS_GT_PCH_GET_ADDRESS}. +Return @minus{}1 if we couldn't allocate @var{size} bytes at @var{address}. +Return 0 if the memory is allocated but the data is not loaded. Return 1 +if the hook has performed everything. -In addition, free any address space reserved that isn't needed to hold -@var{size} bytes (whether or not true is returned). The PCH machinery will -use @samp{mmap} with @samp{MAP_FIXED} to load the PCH if @samp{HAVE_MMAP_FILE}, -or will use @samp{fread} otherwise. - -If no PCH will be loaded, this hook may be called with @var{size} -zero, in which case all reserved address space should be freed. +If the implementation uses reserved address space, free any reserved +space beyond @var{size}, regardless of the return value. If no PCH will +be loaded, this hook may be called with @var{size} zero, in which case +all reserved address space should be freed. Do not try to handle values of @var{address} that could not have been -returned by this executable; just return false. Such values usually +returned by this executable; just return @minus{}1. Such values usually indicate an out-of-date PCH file (built by some other GCC executable), and such a PCH file won't work. @end deftypefn diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 610ce994e95..85df858eb18 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1085,7 +1085,7 @@ specifying @var{list}; the categories of checks available are @samp{misc}, @samp{tree}, @samp{gc}, @samp{rtl}, @samp{rtlflag}, @samp{fold}, @samp{gcac} and @samp{valgrind}. The check @samp{valgrind} requires the external @command{valgrind} simulator, available from -@uref{http://valgrind.kde.org/}. The default when @var{list} is +@uref{http://valgrind.org/}. The default when @var{list} is not specified is @samp{misc,tree,gc,rtlflag}; the checks @samp{rtl}, @samp{gcac} and @samp{valgrind} are very expensive. @@ -2030,7 +2030,7 @@ Development Tools for the Renesas H8/300[HS] Series}. HP-UX: @itemize @item -@uref{http://hpux.cae.wisc.edu/,,HP-UX Porting Center}; +@uref{http://hpux.cs.utah.edu/,,HP-UX Porting Center}; @item @uref{ftp://sunsite.informatik.rwth-aachen.de/pub/packages/gcc_hpux/,,Binaries for HP-UX 11.00 at Aachen University of Technology}. @@ -2045,9 +2045,6 @@ Development Tools for the Motorola 68HC11/68HC12}. OpenServer/Unixware}. @item -Sinix/Reliant Unix---@uref{ftp://ftp.fujitsu-siemens.com/pub/pd/gnu/gcc/,,Siemens}. - -@item Solaris 2 (SPARC, Intel)---@uref{http://www.sunfreeware.com/,,Sunfreeware}. @item @@ -2079,7 +2076,7 @@ number of platforms. In addition to those specific offerings, you can get a binary distribution CD-ROM from the -@uref{http://www.fsf.org/order/order.html,,Free Software Foundation}. +@uref{http://www.gnu.org/order/order.html,,Free Software Foundation}. It contains binaries for a number of platforms, and includes not only GCC, but other stuff as well. The current CD does not contain the latest version of GCC, but it should allow @@ -2427,7 +2424,7 @@ can also be obtained from: @itemize @bullet @item -@uref{http://www.openavr.org,,http://www.openavr.org} +@uref{http://www.nongnu.org/avr/,,http://www.nongnu.org/avr/} @item @uref{http://home.overta.ru/users/denisc/,,http://home.overta.ru/users/denisc/} @item @@ -3780,10 +3777,6 @@ GCC does not currently support OS/2. However, Andrew Zabolotny has been working on a generic OS/2 port with pgcc. The current code can be found at @uref{http://www.goof.com/pcg/os2/,,http://www.goof.com/pcg/os2/}. -An older copy of GCC 2.8.1 is included with the EMX tools available at -@uref{ftp://ftp.leo.org/pub/comp/os/os2/leo/devtools/emx+gcc/,, -ftp://ftp.leo.org/pub/comp/os/os2/leo/devtools/emx+gcc/}. - @html
@end html diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 257a5336466..a42ec404668 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3688,7 +3688,8 @@ invoking @option{-O2} on programs that use computed gotos. @opindex O3 Optimize yet more. @option{-O3} turns on all optimizations specified by @option{-O2} and also turns on the @option{-finline-functions}, -@option{-fweb} and @option{-frename-registers} options. +@option{-fweb}, @option{-frename-registers} and @option{-funswitch-loops} +options. @item -O0 @opindex O0 @@ -8741,7 +8742,8 @@ have any affect on which ld is called, it only changes what parameters are passed to that ld. The ld that is called is determined by the @option{--with-ld} configure option, GCC's program search path, and finally by the user's @env{PATH}. The linker used by GCC can be printed -using @samp{which `gcc -print-prog-name=ld`}. +using @samp{which `gcc -print-prog-name=ld`}. This option is only available +on the 64 bit HP-UX GCC, i.e. configured with @samp{hppa*64*-*-hpux*}. @item -mhp-ld @opindex hp-ld @@ -8753,7 +8755,8 @@ which ld is called, it only changes what parameters are passed to that ld. The ld that is called is determined by the @option{--with-ld} configure option, GCC's program search path, and finally by the user's @env{PATH}. The linker used by GCC can be printed using @samp{which -`gcc -print-prog-name=ld`}. +`gcc -print-prog-name=ld`}. This option is only available on the 64 bit +HP-UX GCC, i.e. configured with @samp{hppa*64*-*-hpux*}. @item -mlong-calls @opindex mno-long-calls @@ -10125,8 +10128,8 @@ specified separated by a comma. Specify bit size of immediate TLS offsets. Valid values are 14, 22, and 64. -@item -mtune-arch=@var{cpu-type} -@opindex mtune-arch +@item -mtune=@var{cpu-type} +@opindex mtune Tune the instruction scheduling for a particular CPU, Valid values are itanium, itanium1, merced, itanium2, and mckinley. diff --git a/gcc/fixinc/check.tpl b/gcc/fixinc/check.tpl index 9f8750b8bac..bb93bcc3eee 100644 --- a/gcc/fixinc/check.tpl +++ b/gcc/fixinc/check.tpl @@ -144,7 +144,8 @@ echo $exitok` cd $TESTBASE find * -type f -print | \ -fgrep -v 'CVS/' > ${TESTDIR}/LIST +fgrep -v 'CVS/' | \ +fgrep -v '.svn/' > ${TESTDIR}/LIST exitok=` exec < ${TESTDIR}/LIST diff --git a/gcc/fixinc/fixincl.x b/gcc/fixinc/fixincl.x index e943e4c6a06..b9eb929b4b9 100644 --- a/gcc/fixinc/fixincl.x +++ b/gcc/fixinc/fixincl.x @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed Saturday May 21, 2005 at 05:04:48 PM CEST + * It has been AutoGen-ed Monday November 7, 2005 at 02:33:08 PM PST * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT CVS-MERGE THIS FILE, EITHER Sat May 21 17:04:48 CEST 2005 +/* DO NOT CVS-MERGE THIS FILE, EITHER Mon Nov 7 14:33:08 PST 2005 * * You must regenerate it. Use the ./genfixes script. * @@ -26,7 +26,8 @@ * * You may redistribute it and/or modify it under the terms of the * GNU General Public License, as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. + * Foundation; either version 2 of the License, or (at your option) + * any later version. * * inclhack is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -34,10 +35,10 @@ * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with inclhack. See the file "COPYING". If not, - * write to: The Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * along with inclhack. If not, write to: + * The Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301, USA. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * @@ -4380,8 +4381,15 @@ tSCC zSco_MathList[] = tSCC zSco_MathSelect0[] = "inline double abs"; -#define SCO_MATH_TEST_CT 1 +/* + * content bypass pattern - skip fix if pattern found + */ +tSCC zSco_MathBypass0[] = + "__GNUG__"; + +#define SCO_MATH_TEST_CT 2 static tTestDesc aSco_MathTests[] = { + { TT_NEGREP, zSco_MathBypass0, (regex_t*)NULL }, { TT_EGREP, zSco_MathSelect0, (regex_t*)NULL }, }; /* @@ -6141,8 +6149,15 @@ tSCC zSysz_Stdlib_For_SunList[] = tSCC zSysz_Stdlib_For_SunSelect0[] = "char[ \t]*\\*[ \t]*(calloc|malloc|realloc|bsearch)[ \t]*\\("; -#define SYSZ_STDLIB_FOR_SUN_TEST_CT 1 +/* + * content bypass pattern - skip fix if pattern found + */ +tSCC zSysz_Stdlib_For_SunBypass0[] = + "_CLASSIC_ANSI_TYPES"; + +#define SYSZ_STDLIB_FOR_SUN_TEST_CT 2 static tTestDesc aSysz_Stdlib_For_SunTests[] = { + { TT_NEGREP, zSysz_Stdlib_For_SunBypass0, (regex_t*)NULL }, { TT_EGREP, zSysz_Stdlib_For_SunSelect0, (regex_t*)NULL }, }; /* @@ -7538,7 +7553,7 @@ static const char* apzX11_SprintfPatch[] = { * * List of all fixes */ -#define REGEX_COUNT 221 +#define REGEX_COUNT 223 #define MACH_LIST_SIZE_LIMIT 261 #define FIX_COUNT 188 diff --git a/gcc/fixinc/inclhack.def b/gcc/fixinc/inclhack.def index bc0a6ff553f..3bd13ad06aa 100644 --- a/gcc/fixinc/inclhack.def +++ b/gcc/fixinc/inclhack.def @@ -2422,6 +2422,7 @@ fix = { files = ods_30_compat/math.h; files = oldstyle/math.h; select = "inline double abs"; + bypass = "__GNUG__"; sed = "/#define.*__fp_class(a) \\\\/i\\\n" "#ifndef __GNUC__\n"; sed = @@ -3668,6 +3669,7 @@ fix = { fix = { hackname = sysz_stdlib_for_sun; files = stdlib.h; + bypass = "_CLASSIC_ANSI_TYPES"; select = "char[ \t]*\\*[ \t]*(calloc|malloc|realloc|bsearch)[ \t]*\\("; c_fix = format; diff --git a/gcc/flow.c b/gcc/flow.c index fed908dc451..9f1e1b79ad4 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -104,7 +104,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA life_analysis fills in certain vectors containing information about register usage: REG_N_REFS, REG_N_DEATHS, REG_N_SETS, REG_LIVE_LENGTH, - REG_N_CALLS_CROSSED and REG_BASIC_BLOCK. + REG_N_CALLS_CROSSED, REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK. life_analysis sets current_function_sp_is_unchanging if the function doesn't modify the stack pointer. */ @@ -1470,6 +1470,7 @@ allocate_reg_life_data (void) REG_N_REFS (i) = 0; REG_N_DEATHS (i) = 0; REG_N_CALLS_CROSSED (i) = 0; + REG_N_THROWING_CALLS_CROSSED (i) = 0; REG_LIVE_LENGTH (i) = 0; REG_FREQ (i) = 0; REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN; @@ -1688,8 +1689,13 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn) record this for them. */ if (GET_CODE (insn) == CALL_INSN && (flags & PROP_REG_INFO)) - EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, - { REG_N_CALLS_CROSSED (i)++; }); + { + EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, + { REG_N_CALLS_CROSSED (i)++; }); + if (can_throw_internal (insn)) + EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, + { REG_N_THROWING_CALLS_CROSSED (i)++; }); + } /* Record sets. Do this even for dead instructions, since they would have killed the values if they hadn't been deleted. */ @@ -3365,7 +3371,11 @@ attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn, that REGNO now crosses them. */ for (temp = insn; temp != incr; temp = NEXT_INSN (temp)) if (GET_CODE (temp) == CALL_INSN) - REG_N_CALLS_CROSSED (regno)++; + { + REG_N_CALLS_CROSSED (regno)++; + if (can_throw_internal (temp)) + REG_N_THROWING_CALLS_CROSSED (regno)++; + } /* Invalidate alias info for Q since we just changed its value. */ clear_reg_alias_info (q); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 82056f454a0..394d1cad4e6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7607,6 +7607,8 @@ fold (tree expr) else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE && TREE_CODE (arg0) == NOP_EXPR && (tem = get_unwidened (arg0, NULL_TREE)) != arg0 + && (TYPE_PRECISION (TREE_TYPE (tem)) + > TYPE_PRECISION (TREE_TYPE (arg0))) && (code == EQ_EXPR || code == NE_EXPR || TREE_UNSIGNED (TREE_TYPE (arg0)) == TREE_UNSIGNED (TREE_TYPE (tem))) @@ -8247,7 +8249,12 @@ fold (tree expr) if (INTEGRAL_TYPE_P (type) && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST - && TREE_CODE (arg2) == INTEGER_CST) + && TREE_CODE (arg2) == INTEGER_CST + /* ??? We somehow can end up here with + (unsigned int)1 == 1 ? 1U : 2U + for which we won't make any progress but recurse + indefinitely. Just stop here in this case. */ + && TREE_CODE (arg1) != INTEGER_CST) switch (comp_code) { case EQ_EXPR: @@ -8304,8 +8311,9 @@ fold (tree expr) /* If the second operand is simpler than the third, swap them since that produces better jump optimization results. */ - if (tree_swap_operands_p (TREE_OPERAND (t, 1), - TREE_OPERAND (t, 2), false)) + if (truth_value_p (TREE_CODE (arg0)) + && tree_swap_operands_p (TREE_OPERAND (t, 1), + TREE_OPERAND (t, 2), false)) { /* See if this can be inverted. If it can't, possibly because it was a floating-point inequality comparison, don't do diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index ecd6624487c..583059173be 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "toplev.h" #include "params.h" #include "hosthooks.h" +#include "hosthooks-def.h" #ifdef HAVE_SYS_RESOURCE_H # include @@ -458,21 +459,8 @@ gt_pch_save (FILE *f) and on the rest it's a lot of work to do better. (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and HOST_HOOKS_GT_PCH_USE_ADDRESS.) */ - mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size); + mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f)); -#if HAVE_MMAP_FILE - if (mmi.preferred_base == NULL) - { - mmi.preferred_base = mmap (NULL, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, - fileno (state.f), 0); - if (mmi.preferred_base == (void *) MAP_FAILED) - mmi.preferred_base = NULL; - else - munmap (mmi.preferred_base, mmi.size); - } -#endif /* HAVE_MMAP_FILE */ - ggc_pch_this_base (state.d, mmi.preferred_base); state.ptrs = xmalloc (state.count * sizeof (*state.ptrs)); @@ -526,7 +514,8 @@ gt_pch_save (FILE *f) state.ptrs[i]->note_ptr_cookie, relocate_ptrs, &state); ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj, - state.ptrs[i]->new_addr, state.ptrs[i]->size, state.ptrs[i]->note_ptr_fn == gt_pch_p_S); + state.ptrs[i]->new_addr, state.ptrs[i]->size, + state.ptrs[i]->note_ptr_fn == gt_pch_p_S); if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S) memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size); } @@ -546,8 +535,7 @@ gt_pch_restore (FILE *f) const struct ggc_root_tab *rti; size_t i; struct mmap_info mmi; - void *addr; - bool needs_read; + int result; /* Delete any deletable objects. This makes ggc_pch_read much faster, as it can be sure that no GCable objects remain other @@ -580,110 +568,95 @@ gt_pch_restore (FILE *f) if (fread (&mmi, sizeof (mmi), 1, f) != 1) fatal_error ("can't read PCH file: %m"); - if (host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size)) - { -#if HAVE_MMAP_FILE - void *mmap_result; - - mmap_result = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, - fileno (f), mmi.offset); - - /* The file might not be mmap-able. */ - needs_read = mmap_result == (void *) MAP_FAILED; - - /* Sanity check for broken MAP_FIXED. */ - if (! needs_read && mmap_result != mmi.preferred_base) - abort (); -#else - needs_read = true; -#endif - addr = mmi.preferred_base; - } - else - { -#if HAVE_MMAP_FILE - addr = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, - fileno (f), mmi.offset); - -#if HAVE_MINCORE - if (addr != mmi.preferred_base) - { - size_t page_size = getpagesize(); - char one_byte; - - if (addr != (void *) MAP_FAILED) - munmap (addr, mmi.size); - - /* We really want to be mapped at mmi.preferred_base - so we're going to resort to MAP_FIXED. But before, - make sure that we can do so without destroying a - previously mapped area, by looping over all pages - that would be affected by the fixed mapping. */ - errno = 0; - - for (i = 0; i < mmi.size; i+= page_size) - if (mincore ((char *)mmi.preferred_base + i, page_size, - (void *)&one_byte) == -1 - && errno == ENOMEM) - continue; /* The page is not mapped. */ - else - break; - - if (i >= mmi.size) - addr = mmap (mmi.preferred_base, mmi.size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, - fileno (f), mmi.offset); - } -#endif /* HAVE_MINCORE */ - - needs_read = addr == (void *) MAP_FAILED; - -#else /* HAVE_MMAP_FILE */ - needs_read = true; -#endif /* HAVE_MMAP_FILE */ - if (needs_read) - addr = xmalloc (mmi.size); - } - - if (needs_read) + result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size, + fileno (f), mmi.offset); + if (result < 0) + fatal_error ("had to relocate PCH"); + if (result == 0) { if (fseek (f, mmi.offset, SEEK_SET) != 0 - || fread (&mmi, mmi.size, 1, f) != 1) + || fread (mmi.preferred_base, mmi.size, 1, f) != 1) fatal_error ("can't read PCH file: %m"); } else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0) fatal_error ("can't read PCH file: %m"); - ggc_pch_read (f, addr); + ggc_pch_read (f, mmi.preferred_base); - if (addr != mmi.preferred_base) - { - for (rt = gt_ggc_rtab; *rt; rt++) - for (rti = *rt; rti->base != NULL; rti++) - for (i = 0; i < rti->nelt; i++) - { - char **ptr = (char **)((char *)rti->base + rti->stride * i); - if (*ptr != NULL) - *ptr += (size_t)addr - (size_t)mmi.preferred_base; - } + gt_pch_restore_stringpool (); +} - for (rt = gt_pch_cache_rtab; *rt; rt++) - for (rti = *rt; rti->base != NULL; rti++) - for (i = 0; i < rti->nelt; i++) - { - char **ptr = (char **)((char *)rti->base + rti->stride * i); - if (*ptr != NULL) - *ptr += (size_t)addr - (size_t)mmi.preferred_base; - } +/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present. + Select no address whatsoever, and let gt_pch_save choose what it will with + malloc, presumably. */ - sorry ("had to relocate PCH"); - } +void * +default_gt_pch_get_address (size_t size ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED) +{ + return NULL; +} - gt_pch_restore_stringpool (); +/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is not present. + Allocate SIZE bytes with malloc. Return 0 if the address we got is the + same as base, indicating that the memory has been allocated but needs to + be read in from the file. Return -1 if the address differs, to relocation + of the PCH file would be required. */ + +int +default_gt_pch_use_address (void *base, size_t size, int fd ATTRIBUTE_UNUSED, + size_t offset ATTRIBUTE_UNUSED) +{ + void *addr = xmalloc (size); + return (addr == base) - 1; } +#if HAVE_MMAP_FILE +/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present. + We temporarily allocate SIZE bytes, and let the kernel place the data + whereever it will. If it worked, that's our spot, if not we're likely + to be in trouble. */ + +void * +mmap_gt_pch_get_address (size_t size, int fd) +{ + void *ret; + + ret = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (ret == (void *) MAP_FAILED) + ret = NULL; + else + munmap (ret, size); + + return ret; +} + +/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is present. + Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at + mapping the data at BASE, -1 if we couldn't. + + This version assumes that the kernel honors the START operand of mmap + even without MAP_FIXED if START through START+SIZE are not currently + mapped with something. */ + +int +mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) +{ + void *addr; + + /* We're called with size == 0 if we're not planning to load a PCH + file at all. This allows the hook to free any static space that + we might have allocated at link time. */ + if (size == 0) + return -1; + + addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, offset); + + return addr == base ? 1 : -1; + } +#endif /* HAVE_MMAP_FILE */ + /* Modify the bound based on rlimits. Keep the smallest number found. */ static double ggc_rlimit_bound (double limit) diff --git a/gcc/global.c b/gcc/global.c index de765b36731..13e41cbb550 100644 --- a/gcc/global.c +++ b/gcc/global.c @@ -96,6 +96,9 @@ struct allocno /* Number of calls crossed by each allocno. */ int calls_crossed; + /* Number of calls that might throw crossed by each allocno. */ + int throwing_calls_crossed; + /* Number of refs to each allocno. */ int n_refs; @@ -469,6 +472,8 @@ global_alloc (FILE *file) allocno[num].reg = i; allocno[num].size = PSEUDO_REGNO_SIZE (i); allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i); + allocno[num].throwing_calls_crossed + += REG_N_THROWING_CALLS_CROSSED (i); allocno[num].n_refs += REG_N_REFS (i); allocno[num].freq += REG_FREQ (i); if (allocno[num].live_length < REG_LIVE_LENGTH (i)) @@ -1187,9 +1192,11 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere { /* Did not find a register. If it would be profitable to allocate a call-clobbered register and save and restore it - around calls, do that. */ + around calls, do that. Don't do this if it crosses any calls + that might throw. */ if (! accept_call_clobbered && allocno[num].calls_crossed != 0 + && allocno[num].throwing_calls_crossed == 0 && CALLER_SAVE_PROFITABLE (allocno[num].n_refs, allocno[num].calls_crossed)) { diff --git a/gcc/hooks.c b/gcc/hooks.c index 06a5732eae3..9179938fe3b 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -213,21 +213,6 @@ hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED) return NULL; } -/* Generic hook that takes a size_t and returns NULL. */ -void * -hook_voidp_size_t_null (size_t a ATTRIBUTE_UNUSED) -{ - return NULL; -} - -/* Generic hook that takes a size_t and a pointer and returns false. */ -bool -hook_bool_voidp_size_t_false (void * a ATTRIBUTE_UNUSED, - size_t b ATTRIBUTE_UNUSED) -{ - return false; -} - /* Generic hook that takes a tree and returns a NULL string. */ const char * hook_constcharptr_tree_null (tree t ATTRIBUTE_UNUSED) diff --git a/gcc/hooks.h b/gcc/hooks.h index 8f4c24f85bb..4547e04bc4f 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -58,7 +58,5 @@ extern bool hook_bool_tree_tree_false (tree, tree); extern rtx hook_rtx_rtx_identity (rtx); extern rtx hook_rtx_rtx_null (rtx); extern rtx hook_rtx_tree_int_null (tree, int); -extern void * hook_voidp_size_t_null (size_t); -extern bool hook_bool_voidp_size_t_false (void *, size_t); extern const char *hook_constcharptr_tree_null (tree); #endif diff --git a/gcc/hosthooks-def.h b/gcc/hosthooks-def.h index b1a41e72988..537ac6f2624 100644 --- a/gcc/hosthooks-def.h +++ b/gcc/hosthooks-def.h @@ -24,8 +24,18 @@ Boston, MA 02111-1307, USA. */ #include "hooks.h" #define HOST_HOOKS_EXTRA_SIGNALS hook_void_void -#define HOST_HOOKS_GT_PCH_GET_ADDRESS hook_voidp_size_t_null -#define HOST_HOOKS_GT_PCH_USE_ADDRESS hook_bool_voidp_size_t_false +#if HAVE_MMAP_FILE +#define HOST_HOOKS_GT_PCH_GET_ADDRESS mmap_gt_pch_get_address +#define HOST_HOOKS_GT_PCH_USE_ADDRESS mmap_gt_pch_use_address +#else +#define HOST_HOOKS_GT_PCH_GET_ADDRESS default_gt_pch_get_address +#define HOST_HOOKS_GT_PCH_USE_ADDRESS default_gt_pch_use_address +#endif + +extern void* default_gt_pch_get_address (size_t, int); +extern int default_gt_pch_use_address (void *, size_t, int, size_t); +extern void* mmap_gt_pch_get_address (size_t, int); +extern int mmap_gt_pch_use_address (void *, size_t, int, size_t); /* The structure is defined in hosthooks.h. */ #define HOST_HOOKS_INITIALIZER { \ diff --git a/gcc/hosthooks.h b/gcc/hosthooks.h index bbc28f69d4d..a3fc0c7c430 100644 --- a/gcc/hosthooks.h +++ b/gcc/hosthooks.h @@ -25,8 +25,16 @@ struct host_hooks { void (*extra_signals) (void); - void * (*gt_pch_get_address) (size_t); - bool (*gt_pch_use_address) (void *, size_t); + /* Identify an address that's likely to be free in a subsequent invocation + of the compiler. The area should be able to hold SIZE bytes. FD is an + open file descriptor if the host would like to probe with mmap. */ + void * (*gt_pch_get_address) (size_t size, int fd); + + /* ADDR is an address returned by gt_pch_get_address. Attempt to allocate + SIZE bytes at the same address and load it with the data from FD at + OFFSET. Return -1 if we couldn't allocate memory at ADDR, return 0 + if the memory is allocated but the data not loaded, return 1 if done. */ + int (*gt_pch_use_address) (void *addr, size_t size, int fd, size_t offset); /* Whenever you add entries here, make sure you adjust hosthooks-def.h. */ }; diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 61ff7fbc6b2..6b1203d15af 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -120,6 +120,11 @@ struct qty int n_calls_crossed; + /* Number of times a reg tied to given qty lives across a CALL_INSN + that might throw. */ + + int n_throwing_calls_crossed; + /* The register number of one pseudo register whose reg_qty value is Q. This register should be the head of the chain maintained in reg_next_in_qty. */ @@ -317,6 +322,7 @@ alloc_qty (int regno, enum machine_mode mode, int size, int birth) qty[qtyno].mode = mode; qty[qtyno].birth = birth; qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno); + qty[qtyno].n_throwing_calls_crossed = REG_N_THROWING_CALLS_CROSSED (regno); qty[qtyno].min_class = reg_preferred_class (regno); qty[qtyno].alternate_class = reg_alternate_class (regno); qty[qtyno].n_refs = REG_N_REFS (regno); @@ -1119,6 +1125,7 @@ update_equiv_regs (void) REG_BASIC_BLOCK (regno) = bb->index; REG_N_CALLS_CROSSED (regno) = 0; + REG_N_THROWING_CALLS_CROSSED (regno) = 0; REG_LIVE_LENGTH (regno) = 2; if (insn == BB_HEAD (bb)) @@ -1946,6 +1953,8 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number, /* Update info about quantity SQTY. */ qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg); + qty[sqty].n_throwing_calls_crossed + += REG_N_THROWING_CALLS_CROSSED (sreg); qty[sqty].n_refs += REG_N_REFS (sreg); qty[sqty].freq += REG_FREQ (sreg); if (usize < ssize) @@ -2251,12 +2260,14 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno, /* We need not check to see if the current function has nonlocal labels because we don't put any pseudos that are live over calls in - registers in that case. */ + registers in that case. Avoid putting pseudos crossing calls that + might throw into call used registers. */ if (! accept_call_clobbered && flag_caller_saves && ! just_try_suggested && qty[qtyno].n_calls_crossed != 0 + && qty[qtyno].n_throwing_calls_crossed == 0 && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs, qty[qtyno].n_calls_crossed)) { diff --git a/gcc/loop.c b/gcc/loop.c index 4ddd77acf79..fa74b8e3230 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -8396,17 +8396,6 @@ check_dbra_loop (struct loop *loop, int insn_count) /* First check if we can do a vanilla loop reversal. */ if (initial_value == const0_rtx - /* If we have a decrement_and_branch_on_count, - prefer the NE test, since this will allow that - instruction to be generated. Note that we must - use a vanilla loop reversal if the biv is used to - calculate a giv or has a non-counting use. */ -#if ! defined (HAVE_decrement_and_branch_until_zero) \ -&& defined (HAVE_decrement_and_branch_on_count) - && (! (add_val == 1 && loop->vtop - && (bl->biv_count == 0 - || no_use_except_counting))) -#endif && GET_CODE (comparison_value) == CONST_INT /* Now do postponed overflow checks on COMPARISON_VAL. */ && ! (((comparison_val - add_val) ^ INTVAL (comparison_value)) @@ -8418,13 +8407,6 @@ check_dbra_loop (struct loop *loop, int insn_count) nonneg = 1; cmp_code = GE; } - else if (add_val == 1 && loop->vtop - && (bl->biv_count == 0 - || no_use_except_counting)) - { - add_adjust = 0; - cmp_code = NE; - } else return 0; diff --git a/gcc/mklibgcc.in b/gcc/mklibgcc.in index 143b4e83ba1..8fafce4b020 100644 --- a/gcc/mklibgcc.in +++ b/gcc/mklibgcc.in @@ -246,6 +246,9 @@ for file in $LIB2ADDEH; do fi done +# Flag whether we need eh_dummy.c +need_eh_dummy= + if [ "$SHLIB_LINK" ]; then # Those should be in libgcc_eh.a. for file in $LIB2ADDEHSTATIC; do @@ -260,6 +263,23 @@ if [ "$SHLIB_LINK" ]; then oname=`echo $name | sed -e 's,.*/,,'` libgcc2_eh_shared_objs="$libgcc2_eh_shared_objs ${oname}${objext}" done + + # If nothing went into libgcc_eh.a, create a dummy object - + # some linkers don't like totally empty archives. + if [ -z "$LIB2ADDEHSTATIC" ]; then + file=eh_dummy.c + libgcc2_eh_static_objs="$libgcc2_eh_static_objs eh_dummy${objext}" + need_eh_dummy=1 + + for ml in $MULTILIBS; do + dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'` + flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; + out="libgcc/${dir}/eh_dummy${objext}" + + echo $out: stmp-dirs $file + echo " $gcc_compile" $flags -fexceptions -c $file -o $out + done + fi fi for file in $LIB2ADD_ST; do @@ -649,6 +669,11 @@ done echo "" echo "all: $all" +if [ "$need_eh_dummy" ]; then + echo "eh_dummy.c:" + echo " echo 'int __libgcc_eh_dummy;' > \$@" +fi + echo "" echo "install: $all" for ml in $MULTILIBS; do diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index a940050d557..1d213fd21d1 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,8 @@ +2005-08-15 Matthias Klose + + * gcc-3.4.3.rw.po: Remove. + * rw.po: Add. + 2005-05-19 Release Manager * GCC 3.4.4 released. diff --git a/gcc/po/gcc-3.4.3.rw.po b/gcc/po/rw.po similarity index 100% rename from gcc/po/gcc-3.4.3.rw.po rename to gcc/po/rw.po diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 84dc1d9495d..f10abe9642a 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -429,7 +429,7 @@ reg_to_stack (rtx first, FILE *file) Also need to rebuild life when superblock scheduling is done as it don't update liveness yet. */ if (!optimize - || (flag_sched2_use_superblocks + || ((flag_sched2_use_superblocks || flag_sched2_use_traces) && flag_schedule_insns_after_reload)) { count_or_remove_death_notes (NULL, 1); diff --git a/gcc/regrename.c b/gcc/regrename.c index 8c326c030ec..1183f44a03e 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -675,7 +675,8 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class class, case SET: scan_rtx (insn, &SET_SRC (x), class, action, OP_IN, 0); - scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 0); + scan_rtx (insn, &SET_DEST (x), class, action, + GET_CODE (PATTERN (insn)) == COND_EXEC ? OP_INOUT : OP_OUT, 0); return; case STRICT_LOW_PART: @@ -700,7 +701,8 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class class, abort (); case CLOBBER: - scan_rtx (insn, &SET_DEST (x), class, action, OP_OUT, 1); + scan_rtx (insn, &SET_DEST (x), class, action, + GET_CODE (PATTERN (insn)) == COND_EXEC ? OP_INOUT : OP_OUT, 1); return; case EXPR_LIST: diff --git a/gcc/regs.h b/gcc/regs.h index bb1f43d0ded..e9ab2d80864 100644 --- a/gcc/regs.h +++ b/gcc/regs.h @@ -59,6 +59,7 @@ typedef struct reg_info_def int deaths; /* # of times (REG n) dies */ int live_length; /* # of instructions (REG n) is live */ int calls_crossed; /* # of calls (REG n) is live across */ + int throw_calls_crossed; /* # of calls that may throw (REG n) is live across */ int basic_block; /* # of basic blocks (REG n) is used in */ char changes_mode; /* whether (SUBREG (REG n)) exists and is illegal. */ @@ -125,6 +126,12 @@ extern varray_type reg_n_info; #define REG_N_CALLS_CROSSED(N) (VARRAY_REG (reg_n_info, N)->calls_crossed) +/* Indexed by N, gives number of CALL_INSNS that may throw, across which + (REG n) is live. */ + +#define REG_N_THROWING_CALLS_CROSSED(N) \ + (VARRAY_REG (reg_n_info, N)->throw_calls_crossed) + /* Total number of instructions at which (REG n) is live. The larger this is, the less priority (REG n) gets for allocation in a hard register (in global-alloc). diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 71ffceb7a5d..69e7ee60a69 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -3172,7 +3172,7 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op, } /* It shouldn't matter what's done here, so fill it with zero. */ - for (; i < max_bitsize; i += value_bit) + for (; i < elem_bitsize; i += value_bit) *vp++ = 0; } else if (GET_MODE_CLASS (GET_MODE (el)) == MODE_FLOAT) diff --git a/gcc/stmt.c b/gcc/stmt.c index 5afcae068ac..a8b738d698f 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -3354,6 +3354,12 @@ tail_recursion_args (tree actuals, tree formals) argvec[i] = copy_to_reg (argvec[i]); } + /* Insert the pre-call sequence point. This is important in cases + where the actual values post-modify the formals: we want the final + values of the formals to be the ones that we assign below, not the + result of the post-modification. */ + emit_queue (); + /* Store the values of the actuals into the formals. */ for (f = formals, a = actuals, i = 0; f; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b4e02982f52..0b99fd35ed8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,310 @@ +2005-11-16 Volker Reichelt + + PR c++/23797 + Backport from mainline: + * g++.dg/parse/typename8.C: New test. + * g++.dg/parse/typename9.C: Likewise. + +2005-11-15 Volker Reichelt + + Backport from mainline: + 2005-11-02 Mark Mitchell + + PR c++/19253 + * g++.dg/parse/typename10.C: New test. + + Backport from mainline: + 2005-10-08 James A. Morrison + + PR c++/22172 + * g++.dg/parse/crash30.C: New test. + +2005-11-10 Uros Bizjak + + PR target/24315 + * gcc.dg/pr24315.c: New test. + +2005-11-10 Uros Bizjak + + PR target/19340 + * gcc.dg/pr19340.c: New test. + +2005-11-09 Uros Bizjak + + PR c/24101 + * gcc.dg/pr24101-1.i, gcc.dg/pr24101-2.i: New tests. + * gcc.dg/dg.exp: Run main loop also for *.i files. + +2005-11-02 Josh Conner + + * g++.dg/crash38.C: moved into proper directory... + * g++.dg/template/crash42.C: ...here + +2005-10-28 Josh Conner + + PR c++/22153 + * g++.dg/template/crash38.C: New test. + * g++.dg/parse/explicit1.C: Change expected errors. + +2005-10-21 Eric Botcazou + + * gcc.c-torture/execute/20051021-1.c: New test. + +2005-10-12 Paolo Bonzini + + PR c++/24052 + * g++.dg/ext/label5.C: New. + +2005-10-11 Volker Reichelt + + Backport: + 2004-09-23 Andrew Pinski + PR c++/17618 + * g++.dg/lookup/crash5.C: New test. + + 2004-05-22 Wolfgang Bangerth + Roger Sayle + * g++.dg/lookup/forscope2.C: New test case. + + 2004-11-02 Mark Mitchell + PR c++/18177 + * g++.dg/conversion/const3.C: New test. + +2005-10-08 Janis Johnson + + PR debug/24267 + * gcc.dg/debug/dwarf2/dwarf-altivec1.c: New test. + + PR target/18583 + * gcc.dg/altivec-pr18583.c: New test. + +2005-09-21 Volker Reichelt + + PR c++/23965 + * g++.dg/template/error1.C: Reject "no matching function" message. + +2005-09-21 Volker Reichelt + + PR c++/17609 + * g++.dg/lookup/error1.C: New test. + * g++.dg/lookup/ambig4.C: Tweak error messages. + * g++.dg/ext/stmtexpr4.C: Likewise. + * g++.dg/parse/error21.C: Tweak testcase. + + Backport: + 2004-03-02 Mark Mitchell + + * g++.dg/lookup/koenig1.C: Tweak error messages. + * g++.dg/lookup/used-before-declaration.C: Likewise. + * g++.dg/other/do1.C: Likewise. + * g++.dg/overload/koenig1.C: Likewise. + * g++.dg/parse/crash13.C: Likewise. + +2005-09-17 Volker Reichelt + + PR c++/18368 + * g++.dg/other/semicolon.C: New test. + +2005-09-17 Volker Reichelt + + PR c++/18803 + g++.dg/template/operator5.C: New test. + + PR c++/18445 + g++.dg/template/crash28.C: Remove. + +2005-09-08 Craig Rodrigues + + Backport from mainline: + 2005-09-01 Craig Rodrigues + * gcc.dg/Wredundant-decls-2.c: New test to check that + -Wredundant-decls does not issue warning for a variable + definition following a declaration. + +2005-09-06 Volker Reichelt + + Backport: + + 2004-12-14 Mark Mitchell + PR c++/18738 + * g++.dg/template/typename8.C: New test. + * g++.dg/parse/friend2.C: Tweak error message. + +2005-09-03 Volker Reichelt + + Backport: + + 2005-08-26 Mark Mitchell + PR c++/19004 + * g++.dg/template/nontype13.C: New test. + +2005-09-02 Richard Sandiford + + PR c/22061 + * gcc.c-torture/execute/pr22061-1.c, + * gcc.c-torture/execute/pr22061-2.c, + * gcc.c-torture/execute/pr22061-3.c, + * gcc.c-torture/execute/pr22061-4.c: New tests. + +2005-09-02 Volker Reichelt + + PR c++/22233 + * g++.dg/template/param1.C: New test. + +2005-09-02 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18466 + * g++.dg/parse/qualified3.C: New test. + * g++.old-deja/g++.other/friend7.C: Remove bogus qualification. + + 2004-11-29 Ben Elliston + * g++.old-deja/g++.other/decl5.C: Remove remaining XFAILs. + +2005-09-02 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18445 + * g++.dg/template/crash28.C: New test. + +2005-09-01 Jakub Jelinek + + PR rtl-optimization/23478 + * g++.dg/opt/pr23478.C: New test. + +2005-09-01 Volker Reichelt + + Backport: + + 2004-11-27 Mark Mitchell + PR c++/18512 + * g++.dg/template/crash29.C: New test. + +2005-09-01 Volker Reichelt + + Backport: + + 2004-11-25 Mark Mitchell + PR c++/18545 + * g++.dg/expr/return1.C: New test. + +2005-09-01 Volker Reichelt + + Backport: + + 2005-02-22 Mark Mitchell + PR c++/20153 + * g++.dg/template/error17.C: New test. + + 2005-07-28 Mark Mitchell + PR c++/22545 + * g++.dg/expr/ptrmem7.C: New test. + +2005-09-01 Volker Reichelt + + PR c++/13377 + * g++.dg/lookup/ambig4.C: New test. + * g++.dg/lookup/ambig5.C: New test. + +2005-08-31 Volker Reichelt + + PR c++/23639 + * g++.dg/template/ttp5.C: Adjust error markers. + +2005-08-08 Josh Conner + + PR rtl-optimization/23241 + * gcc.dg/char-compare.c: New test. + +2005-08-08 Richard Sandiford + + PR middle-end/21964 + * gcc.c-torture/execute/pr21964-1.c: New test. + +2005-08-08 Richard Sandiford + + PR c/22458 + * gcc.dg/pr22458-1.c: New test. + +2005-08-03 Richard Sandiford + + PR target/18582 + * testsuite/gcc.dg/torture/pr18582-1.c: New test. + +2005-08-02 Ian Lance Taylor + + PR pch/14400 + Backport from mainline: + + 2004-04-07 Ian Lance Taylor + + * gcc.dg/pch/pch.exp: Add largefile test. + +2005-07-31 Richard Sandiford + + PR target/20621 + * gcc.c-torture/execute/pr20621-1.c: New test. + +2005-07-28 Joseph S. Myers + + PR c/17188 + PR c/21899 + * gcc.dg/nested-redef-1.c, gcc.dg/pr17188-1.c: New tests. + * gcc.dg/decl-3.c: Adjust expected message. + +2005-07-28 Joseph S. Myers + + PR c/21873 + * gcc.dg/init-excess-1.c: New test. + +2005-07-28 Richard Sandiford + + PR c/20187 + * gcc.c-torture/execute/pr20187-1.c: New test. + +2005-07-28 Giovanni Bajo + + Backport: + + 2004-09-16 Mark Mitchell + PR c++/16002 + * g++.dg/parse/error18.C: New test. + * g++.dg/parse/crash11.C: Adjust error markers. + + 2005-06-17 Geoffrey Keating + PR c++/17413 + * g++.dg/template/local5.C: New. + + 2004-11-02 Mark Mitchell + PR c++/18124 + * g++.dg/template/crash25.C: New test. + PR c++/18155 + * g++.dg/template/typedef2.C: New test. + * g++.dg/parse/crash13.C: Adjust error markers. + + 2004-12-21 Mark Mitchell + PR c++/18378 + * g++.dg/ext/packed8.C: New test. + +2005-07-28 Richard Sandiford + + PR c/22589 + * gcc.c-torture/compile/pr22589-1.c: New test. + +2005-07-25 Giovanni Bajo + + PR c++/19208 + * g++.dg/template/array11.C: New test. + +2005-07-21 Janis Johnson + + PR target/20191 + * gcc.c-torture/compile/20050721-1.c: New test. + 2005-07-21 Richard Sandiford PR rtl-optimization/22167 diff --git a/gcc/testsuite/g++.dg/conversion/const3.C b/gcc/testsuite/g++.dg/conversion/const3.C new file mode 100644 index 00000000000..faa9f810c19 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/const3.C @@ -0,0 +1,7 @@ +// PR c++/18177 + +void foo() +{ + X; // { dg-error "" } + const_cast(X); +} diff --git a/gcc/testsuite/g++.dg/eh/synth2.C b/gcc/testsuite/g++.dg/eh/synth2.C new file mode 100644 index 00000000000..2da814db9d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/synth2.C @@ -0,0 +1,24 @@ +// PR c++/24580 +// { dg-do run } + +struct vbase {}; + +struct foo : virtual vbase +{ + foo() + { + throw "exception in foo ctor"; + } +}; + +struct bar : public foo {}; + +int main() +{ + try + { + bar a; + } + catch ( ... ) { } + return 0; +} diff --git a/gcc/testsuite/g++.dg/expr/ptrmem7.C b/gcc/testsuite/g++.dg/expr/ptrmem7.C new file mode 100644 index 00000000000..a94990e54b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/ptrmem7.C @@ -0,0 +1,21 @@ +// PR c++/22545 + +struct A { + int member; + A() : member(13) {} +}; + +A a; + +struct B { + operator A*() { return &a; } +}; + +B b; + +int A::* member_pntr = &A::member; + +int main() +{ + return b ->* member_pntr; +} diff --git a/gcc/testsuite/g++.dg/expr/return1.C b/gcc/testsuite/g++.dg/expr/return1.C new file mode 100644 index 00000000000..74fb32f192f --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/return1.C @@ -0,0 +1,9 @@ +// PR c++/18545 + +struct A; + +A foo() +{ // { dg-error "incomplete" } + A a; // { dg-error "incomplete" } + return a; +} diff --git a/gcc/testsuite/g++.dg/ext/label5.C b/gcc/testsuite/g++.dg/ext/label5.C new file mode 100644 index 00000000000..0032b0f8e67 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label5.C @@ -0,0 +1,7 @@ +// { dg-options "" } +// PR c++/24052 + +struct A { }; +int main() { b: A() && && b; } // { dg-error "A\\(\\) && && *b" } + +// { dg-error "candidate" "additional" { target *-*-* } 5 } diff --git a/gcc/testsuite/g++.dg/ext/packed8.C b/gcc/testsuite/g++.dg/ext/packed8.C new file mode 100644 index 00000000000..a68fa2c8a41 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/packed8.C @@ -0,0 +1,20 @@ +// PR c++/18378 + +class A +{ +public: + int i; + + A() {} + A(const A& a) { i = a.i; } +}; + +class B +{ + A a __attribute__((packed)); + +public: + B() {} + A GetA() { return a; } // { dg-error "" } +}; + diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr4.C b/gcc/testsuite/g++.dg/ext/stmtexpr4.C index 0257939aa37..a37c33ae086 100644 --- a/gcc/testsuite/g++.dg/ext/stmtexpr4.C +++ b/gcc/testsuite/g++.dg/ext/stmtexpr4.C @@ -4,5 +4,5 @@ void foo() { - ({x;}); // { dg-error "undeclared" } + ({x;}); // { dg-error "was not declared" } } diff --git a/gcc/testsuite/g++.dg/lookup/ambig4.C b/gcc/testsuite/g++.dg/lookup/ambig4.C new file mode 100644 index 00000000000..ab1a14518d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/ambig4.C @@ -0,0 +1,14 @@ +// PR c++/13377 +// Origin: Volker Reichelt +// { dg-do compile } + +namespace N +{ + int i; // { dg-error "declared" } +} + +int i; // { dg-error "declared" } + +using namespace N; + +void foo() { i; } // { dg-error "in this scope|ambiguous" } diff --git a/gcc/testsuite/g++.dg/lookup/ambig5.C b/gcc/testsuite/g++.dg/lookup/ambig5.C new file mode 100644 index 00000000000..8f74efc7518 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/ambig5.C @@ -0,0 +1,13 @@ +// PR c++/13377 +// Origin: Boris Kolpackov +// { dg-do compile } + +namespace N +{ + namespace M {} // { dg-error "declared" } +} + +namespace M {} // { dg-error "declared" } + +using namespace N; +using namespace M; // { dg-error "namespace-name|ambiguous" } diff --git a/gcc/testsuite/g++.dg/lookup/crash5.C b/gcc/testsuite/g++.dg/lookup/crash5.C new file mode 100644 index 00000000000..6584ee64505 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/crash5.C @@ -0,0 +1,9 @@ +// { dg-do compile } +// +// PR 17618 + +void foo() +{ + p; // { dg-error "not declared" } + (void*) p; +} diff --git a/gcc/testsuite/g++.dg/lookup/error1.C b/gcc/testsuite/g++.dg/lookup/error1.C new file mode 100644 index 00000000000..2264b238403 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/error1.C @@ -0,0 +1,9 @@ +// PR c++/17609 +// Origin: +// { dg-do compile } + +namespace N { int i; } +void foo() { i; } // { dg-error "not declared" } + +using namespace N; +void bar() { i; } diff --git a/gcc/testsuite/g++.dg/lookup/forscope2.C b/gcc/testsuite/g++.dg/lookup/forscope2.C new file mode 100644 index 00000000000..1fed957a041 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/forscope2.C @@ -0,0 +1,9 @@ +// { dg-do compile } + +struct S { + void foo() { + for (_ptr; ;) {} // { dg-error "not declared" } + _ptr = 0; + } +}; + diff --git a/gcc/testsuite/g++.dg/lookup/koenig1.C b/gcc/testsuite/g++.dg/lookup/koenig1.C index 697a322e3fb..7273727194c 100644 --- a/gcc/testsuite/g++.dg/lookup/koenig1.C +++ b/gcc/testsuite/g++.dg/lookup/koenig1.C @@ -9,5 +9,5 @@ class X; void foo() { X x(1); // { dg-error "incomplete type" "" } - bar(x); // { dg-error "undeclared" "" } + bar(x); // { dg-error "not declared" "" } } diff --git a/gcc/testsuite/g++.dg/lookup/used-before-declaration.C b/gcc/testsuite/g++.dg/lookup/used-before-declaration.C index c1469ead01f..b51d270c74a 100644 --- a/gcc/testsuite/g++.dg/lookup/used-before-declaration.C +++ b/gcc/testsuite/g++.dg/lookup/used-before-declaration.C @@ -1,5 +1,5 @@ // Copyroght (C) 2003 Free Software Foundation // Origin: PR/12832, Jonathan Wakely -void f() { g(); } // { dg-error "undeclared" "" } -void g() { } // { dg-error "used" "" } +void f() { g(); } // { dg-error "not declared" "" } +void g() { } diff --git a/gcc/testsuite/g++.dg/opt/pr23478.C b/gcc/testsuite/g++.dg/opt/pr23478.C new file mode 100644 index 00000000000..da1371d2514 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr23478.C @@ -0,0 +1,211 @@ +// PR rtl-optimization/23478 +// { dg-do run } +// { dg-options "-O2" } + +extern "C" void abort (); +bool tthrow; +struct C3 { int i; }; +class C14 {}; +struct C7 +{ + virtual ~C7 (); +}; + +C7::~C7 () +{ + asm volatile ("" : : : "memory"); +} +class C2 : public C7 {}; + +template class C13 +{ + bool ma; + X *mb; +public: + explicit C13 (X *p = 0) throw () : ma (p != 0), mb (p) {} + ~C13 (); +}; + +template +C13::~C13 () +{ + asm volatile ("" : : "r" (ma), "r" (mb) : "memory"); +} + +struct C1 +{ + C1 (const C3 &, const C3 &, const C3 &, const C3 *&); +}; + +C1::C1 (const C3 &, const C3 &, const C3 &, const C3 *&) +{ + if (!tthrow) + throw 24; +} + +struct C8 +{ + struct C15 {}; + typedef C15 *C9; + virtual void f1 (C2 &, long *, void *, C3 &, void *, bool) = 0; + virtual C13 f3 () const = 0; + virtual ~C8 () {} +}; + +bool +xx14 () +{ + bool b = false; + if (tthrow) + throw 6; + asm volatile ("" : : "r" (&b) : "memory"); + return b; +} + +bool +xx2 () +{ + bool b = false; + if (tthrow) + throw 6; + asm volatile ("" : : "r" (&b) : "memory"); + return b; +} + +C13 +xx9 () +{ + return C13(); +} + +C2 & +xx10 () +{ + static C2 c2; + return c2; +} + +C3 & +xx12 () +{ + static C3 c3 = { 1 }; + return c3; +} + +const C3 & +xx5 () +{ + static const C3 c3 = { 2 }; + return c3; +} + +const C3 *& +xx4 () +{ + static const C3 *p; + if (tthrow) + throw 6; + return p; +} + +long ll13; + +long +xx13 () +{ + long ret; + asm volatile ("" : "=r" (ret) : "r" (ll13)); + return ret; +} + +void +xx15 (C3 &x, C13 &y) +{ + asm volatile ("" : : "r" (&x), "r" (&y) : "memory"); +} + +long +xx16 (const void *x) +{ + long ret; + asm volatile ("" : "=r" (ret) : "0" (1), "r" (x) : "memory"); + return ret; +} + +void +xx1 (C13 x) +{ + asm volatile ("" : : "r" (&x) : "memory"); + if (tthrow) + throw 6; +} + +void +xx3 (const C7 *x) +{ + if (x) + abort (); +} + +void +xx7 () +{ + asm volatile ("" : : : "memory"); +} + +struct C5 +{ + C13 f2 (C3 &v1, const void *v2, C8 *v6); + C7 *m2[2]; + long m1[2]; +}; + +C13 +C5::f2 (C3 &v1, const void *v2, C8 *v6) +{ + C13 v13 = xx9 (); + C2 &v9 = xx10 (); + for (long i = 1; i < 2; i++) + xx3 (m2[i]); + const C3 &ld = xx5 (); + xx7 (); + if (xx2 ()) + throw ""; + xx4 (); + C3 &si = xx12 (); + for (long i = 0; i < xx16 (v2); ++i) + { + C13 sk (new C1 (xx5 (), ld, xx5 (), xx4 ())); + xx15 (si, sk); + } + long v4 = xx13 (); + for (long i = v4 - 1; i >= 0; --i) + m1[i] = i; + bool v8 = xx2 (); + for (long i = 0; i < 2 && !xx14 (); i++) + { + v6[i].f1 (v9, 0, __null, v1, __null, v8); + if (v8) + xx1 (v6[i].f3 ()); + } + return v13; +} + +int +main (void) +{ + C5 c5 = { { __null, __null }, { 0, 0 } }; + bool seen = false; + try + { + c5.f2 (xx12 (), __null, __null); + } + catch (int n) + { + if (n != 24) + abort (); + seen = true; + } + if (!seen) + abort (); +} diff --git a/gcc/testsuite/g++.dg/other/do1.C b/gcc/testsuite/g++.dg/other/do1.C index 8cbd1a35f1f..720358568f1 100644 --- a/gcc/testsuite/g++.dg/other/do1.C +++ b/gcc/testsuite/g++.dg/other/do1.C @@ -8,6 +8,6 @@ void init () { do { } while (0) - obj = 0; // { dg-error "expected|undeclared" "" } + obj = 0; // { dg-error "expected|not declared" "" } } diff --git a/gcc/testsuite/g++.dg/other/semicolon.C b/gcc/testsuite/g++.dg/other/semicolon.C new file mode 100644 index 00000000000..6bc3d95217b --- /dev/null +++ b/gcc/testsuite/g++.dg/other/semicolon.C @@ -0,0 +1,9 @@ +// PR c++/18368 +// Origin: Chris Lattner +// { dg-do compile } + +struct A +{ + struct B { int i; } + void foo(); // { dg-error "two or more|return type" } +}; // { dg-error "semicolon is missing" "" { target *-*-* } 8 } diff --git a/gcc/testsuite/g++.dg/overload/koenig1.C b/gcc/testsuite/g++.dg/overload/koenig1.C index dd38e720acf..1ed7bce0b14 100644 --- a/gcc/testsuite/g++.dg/overload/koenig1.C +++ b/gcc/testsuite/g++.dg/overload/koenig1.C @@ -13,6 +13,6 @@ void g () { B *bp; N::A *ap; - f (bp); // { dg-error "undeclared" } + f (bp); // { dg-error "not declared" } f (ap); } diff --git a/gcc/testsuite/g++.dg/parse/crash11.C b/gcc/testsuite/g++.dg/parse/crash11.C index 4893678d46f..f988fa8a0bd 100644 --- a/gcc/testsuite/g++.dg/parse/crash11.C +++ b/gcc/testsuite/g++.dg/parse/crash11.C @@ -30,5 +30,5 @@ struct C }; int main() { - typedef B::Template::Type Type; // { dg-error "init-declarator|;" } + typedef B::Template::Type Type; // { dg-error "initializer" } } diff --git a/gcc/testsuite/g++.dg/parse/crash13.C b/gcc/testsuite/g++.dg/parse/crash13.C index d81b6a55e7a..3c298ec8ede 100644 --- a/gcc/testsuite/g++.dg/parse/crash13.C +++ b/gcc/testsuite/g++.dg/parse/crash13.C @@ -13,10 +13,10 @@ struct A template void func(A::B* ) // { dg-error "variable|template|expression" } -{ // { dg-error ";" } +{ } int main() { - func(0); // { dg-error "undeclared|expression|;" } + func(0); // { dg-error "not declared|expression|;" } } diff --git a/gcc/testsuite/g++.dg/parse/crash30.C b/gcc/testsuite/g++.dg/parse/crash30.C new file mode 100644 index 00000000000..9b68535faa4 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash30.C @@ -0,0 +1,18 @@ +// { dg-do compile } +namespace N { template struct A { operator int() const; }; } +namespace M { template struct A {}; } +namespace P { typedef int I; } + +template void foo() +{ + +typename N::A<0>(); // { dg-bogus "expected" } +} + +template void bar() +{ + +typename M::A<0>; // { dg-error "expected" } +} + +template void baz() { + typename P::I i; // { dg-bogus "expected" } +} diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C new file mode 100644 index 00000000000..363aae99879 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error18.C @@ -0,0 +1,7 @@ +// PR c++/16002 + +void f() +{ + double Q *= 5.0; // { dg-error "initializer" } +} + diff --git a/gcc/testsuite/g++.dg/parse/error21.C b/gcc/testsuite/g++.dg/parse/error21.C index 038c8b84871..c697683507f 100644 --- a/gcc/testsuite/g++.dg/parse/error21.C +++ b/gcc/testsuite/g++.dg/parse/error21.C @@ -7,6 +7,6 @@ void foo() { // Check that we do not complain about an unused // compiler-generated variable. - A& = a; // { dg-error "token|declarator|undeclared" } + A& = 1; // { dg-error "token|declarator" } } diff --git a/gcc/testsuite/g++.dg/parse/explicit1.C b/gcc/testsuite/g++.dg/parse/explicit1.C index ced2adc3dc0..35358749e1d 100644 --- a/gcc/testsuite/g++.dg/parse/explicit1.C +++ b/gcc/testsuite/g++.dg/parse/explicit1.C @@ -7,5 +7,5 @@ struct foo { template void bar (T &t) {} - template<> void bar(double &t) {} // { dg-error "explicit|non-namespace|member" } + template<> void bar(double &t) {} // { dg-error "non-namespace|template|function" } }; diff --git a/gcc/testsuite/g++.dg/parse/friend2.C b/gcc/testsuite/g++.dg/parse/friend2.C index 2e88845cceb..1a2ad8bfad9 100644 --- a/gcc/testsuite/g++.dg/parse/friend2.C +++ b/gcc/testsuite/g++.dg/parse/friend2.C @@ -10,7 +10,7 @@ namespace NS { } template class X { - friend class NS::C; // { dg-error "expected|friend" } + friend class NS::C; // { dg-error "template|friend" } }; X c; diff --git a/gcc/testsuite/g++.dg/parse/typename10.C b/gcc/testsuite/g++.dg/parse/typename10.C new file mode 100644 index 00000000000..759a3c9b997 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename10.C @@ -0,0 +1,8 @@ +// PR c++/19253 + +namespace N { struct X; } + +template struct A +{ + A a; // { dg-error "invalid|declaration" } +}; diff --git a/gcc/testsuite/g++.dg/parse/typename8.C b/gcc/testsuite/g++.dg/parse/typename8.C new file mode 100644 index 00000000000..e8e762709b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename8.C @@ -0,0 +1,11 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 12 Oct 2005 + +// PR 23797:ICE +// Origin: Volker Reichelt + +// { dg-options "-fpermissive -w" } + +struct A { typedef int X; }; + +int i = typename A::X(); diff --git a/gcc/testsuite/g++.dg/parse/typename9.C b/gcc/testsuite/g++.dg/parse/typename9.C new file mode 100644 index 00000000000..aa72cd6c584 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename9.C @@ -0,0 +1,3 @@ +struct A { typedef int X; }; + +int i = typename A::X(); // { dg-error "typename" } diff --git a/gcc/testsuite/g++.dg/template/array11.C b/gcc/testsuite/g++.dg/template/array11.C new file mode 100644 index 00000000000..cac087aece5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array11.C @@ -0,0 +1,17 @@ +// { dg-do compile } +// Origin: Giovanni Bajo +// PR c++/19208: Fold dependent array domains + +template struct if_t { typedef int type; }; +template struct hhhh { static const bool value = true; }; +template struct gggg { static const bool value = hhhh::value; }; +template struct ffff { static const bool value = gggg::value; }; +template +struct bound_member_action +{ + typedef char f[ffff::value ? 1 : 2]; + template + bound_member_action(CT i, typename if_t::type g) {} +}; + +bound_member_action a(0, 1); diff --git a/gcc/testsuite/g++.dg/template/crash25.C b/gcc/testsuite/g++.dg/template/crash25.C new file mode 100644 index 00000000000..fa77f0d4fb6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash25.C @@ -0,0 +1,3 @@ +// PR c++/18124 + +template