summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.melt3
-rw-r--r--gcc/ChangeLog580
-rw-r--r--gcc/ChangeLog.melt3
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in15
-rw-r--r--gcc/alloc-pool.c8
-rw-r--r--gcc/auto-inc-dec.c3
-rw-r--r--gcc/bb-reorder.c5
-rw-r--r--gcc/bitmap.c10
-rw-r--r--gcc/builtins.c106
-rw-r--r--gcc/c-common.c132
-rw-r--r--gcc/calls.c15
-rw-r--r--gcc/cfgexpand.c10
-rw-r--r--gcc/cfglayout.c3
-rw-r--r--gcc/cfgrtl.c9
-rw-r--r--gcc/cgraph.c218
-rw-r--r--gcc/cgraph.h23
-rw-r--r--gcc/combine.c9
-rw-r--r--gcc/config.gcc23
-rw-r--r--gcc/config.in18
-rw-r--r--gcc/config/alpha/vms_tramp.asm1
-rw-r--r--gcc/config/arm/aout.h3
-rw-r--r--gcc/config/arm/arm.c76
-rw-r--r--gcc/config/arm/crti.asm2
-rw-r--r--gcc/config/arm/crtn.asm2
-rw-r--r--gcc/config/bfin/crti.s1
-rw-r--r--gcc/config/bfin/crtlibid.s1
-rw-r--r--gcc/config/bfin/crtn.s1
-rw-r--r--gcc/config/fr30/crti.asm2
-rw-r--r--gcc/config/fr30/crtn.asm2
-rw-r--r--gcc/config/frv/lib1funcs.asm10
-rw-r--r--gcc/config/host-solaris.c8
-rw-r--r--gcc/config/i386/cross-stdarg.h76
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.c354
-rw-r--r--gcc/config/i386/i386.h7
-rw-r--r--gcc/config/i386/i386.md30
-rw-r--r--gcc/config/i386/libgcc-glibc.ver (renamed from gcc/config/i386/libgcc-x86_64-glibc.ver)85
-rw-r--r--gcc/config/i386/linux.h6
-rw-r--r--gcc/config/i386/linux64.h2
-rw-r--r--gcc/config/i386/sfp-machine.h144
-rw-r--r--gcc/config/i386/sol2-c1.asm1
-rw-r--r--gcc/config/i386/sol2-ci.asm1
-rw-r--r--gcc/config/i386/sol2-cn.asm1
-rw-r--r--gcc/config/i386/sol2-gc1.asm1
-rw-r--r--gcc/config/i386/t-darwin3
-rw-r--r--gcc/config/i386/t-darwin643
-rw-r--r--gcc/config/i386/t-fprules-softfp (renamed from gcc/config/i386/t-fprules-softfp64)0
-rw-r--r--gcc/config/i386/t-linux5
-rw-r--r--gcc/config/i386/t-linux649
-rw-r--r--gcc/config/ia64/crti.asm2
-rw-r--r--gcc/config/ia64/crtn.asm2
-rw-r--r--gcc/config/ia64/ia64.c4
-rw-r--r--gcc/config/libgcc-glibc.ver14
-rw-r--r--gcc/config/m32r/libgcc-glibc.ver10
-rw-r--r--gcc/config/m68hc11/larith.asm2
-rw-r--r--gcc/config/m68hc11/m68hc11-crt0.S1
-rw-r--r--gcc/config/m68k/crti.s1
-rw-r--r--gcc/config/m68k/crtn.s1
-rw-r--r--gcc/config/m68k/lb1sf68.asm36
-rw-r--r--gcc/config/m68k/m68k-devices.def30
-rw-r--r--gcc/config/m68k/m68k.c4
-rw-r--r--gcc/config/m68k/t-cf3
-rw-r--r--gcc/config/m68k/t-linux11
-rw-r--r--gcc/config/mcore/crti.asm2
-rw-r--r--gcc/config/mcore/crtn.asm2
-rw-r--r--gcc/config/mips/mips.c40
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/mips/t-libgcc-mips163
-rw-r--r--gcc/config/pa/pa.c3
-rw-r--r--gcc/config/rs6000/crtresfpr.asm1
-rw-r--r--gcc/config/rs6000/crtresgpr.asm1
-rw-r--r--gcc/config/rs6000/crtresxfpr.asm1
-rw-r--r--gcc/config/rs6000/crtresxgpr.asm1
-rw-r--r--gcc/config/rs6000/crtsavfpr.asm1
-rw-r--r--gcc/config/rs6000/crtsavgpr.asm1
-rw-r--r--gcc/config/rs6000/crtsavres.asm1
-rw-r--r--gcc/config/rs6000/e500crtres32gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtres64gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtres64gprctr.asm1
-rw-r--r--gcc/config/rs6000/e500crtrest32gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtrest64gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtresx32gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtresx64gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsav32gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsav64gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsav64gprctr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsavg32gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsavg64gpr.asm1
-rw-r--r--gcc/config/rs6000/e500crtsavg64gprctr.asm1
-rw-r--r--gcc/config/rs6000/eabi-ci.asm1
-rw-r--r--gcc/config/rs6000/eabi-cn.asm1
-rw-r--r--gcc/config/rs6000/eabi.asm1
-rw-r--r--gcc/config/rs6000/host-darwin.c5
-rw-r--r--gcc/config/rs6000/rs6000.md149
-rw-r--r--gcc/config/rs6000/sol-ci.asm1
-rw-r--r--gcc/config/rs6000/sol-cn.asm1
-rw-r--r--gcc/config/rs6000/tramp.asm1
-rw-r--r--gcc/config/s390/libgcc-glibc.ver24
-rw-r--r--gcc/config/sh/libgcc-glibc.ver11
-rw-r--r--gcc/config/sh/sh.c10
-rw-r--r--gcc/config/sh/sh.h6
-rw-r--r--gcc/config/sparc/libgcc-sparc-glibc.ver14
-rw-r--r--gcc/config/sparc/sol2-ci.asm2
-rw-r--r--gcc/config/sparc/sol2-cn.asm2
-rw-r--r--gcc/config/sync.c185
-rwxr-xr-xgcc/configure98
-rw-r--r--gcc/configure.ac3
-rw-r--r--gcc/cp/ChangeLog79
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/cp/call.c375
-rw-r--r--gcc/cp/cp-tree.h30
-rw-r--r--gcc/cp/cvt.c6
-rw-r--r--gcc/cp/decl.c173
-rw-r--r--gcc/cp/error.c18
-rw-r--r--gcc/cp/init.c4
-rw-r--r--gcc/cp/name-lookup.c3
-rw-r--r--gcc/cp/parser.c307
-rw-r--r--gcc/cp/pt.c37
-rw-r--r--gcc/cp/rtti.c14
-rw-r--r--gcc/cp/semantics.c34
-rw-r--r--gcc/cp/tree.c8
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/cp/typeck2.c85
-rw-r--r--gcc/df-problems.c2
-rw-r--r--gcc/doc/install.texi8
-rw-r--r--gcc/doc/invoke.texi13
-rw-r--r--gcc/doc/tm.texi26
-rw-r--r--gcc/emit-rtl.c41
-rw-r--r--gcc/expr.c5
-rw-r--r--gcc/expr.h3
-rw-r--r--gcc/fold-const.c3
-rw-r--r--gcc/fortran/ChangeLog36
-rw-r--r--gcc/fortran/check.c16
-rw-r--r--gcc/fortran/decl.c42
-rw-r--r--gcc/fortran/expr.c12
-rw-r--r--gcc/fortran/f95-lang.c4
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/fortran/interface.c11
-rw-r--r--gcc/fortran/iresolve.c2
-rw-r--r--gcc/fortran/match.c6
-rw-r--r--gcc/fortran/match.h2
-rw-r--r--gcc/fortran/parse.c5
-rw-r--r--gcc/fortran/primary.c27
-rw-r--r--gcc/fortran/resolve.c7
-rw-r--r--gcc/fortran/symbol.c71
-rw-r--r--gcc/fortran/trans-decl.c44
-rw-r--r--gcc/fortran/trans-expr.c17
-rw-r--r--gcc/function.c5
-rw-r--r--gcc/gcc.c22
-rw-r--r--gcc/gcse.c5
-rw-r--r--gcc/ggc-common.c34
-rw-r--r--gcc/ggc-zone.c30
-rw-r--r--gcc/haifa-sched.c6
-rw-r--r--gcc/ipa-cp.c10
-rw-r--r--gcc/ipa-prop.c221
-rw-r--r--gcc/ipa-prop.h81
-rw-r--r--gcc/java/ChangeLog18
-rw-r--r--gcc/java/Make-lang.in6
-rw-r--r--gcc/java/jcf-io.c144
-rw-r--r--gcc/java/jcf.h10
-rw-r--r--gcc/jump.c3
-rw-r--r--gcc/libgcc-std.ver85
-rw-r--r--gcc/loop-doloop.c17
-rw-r--r--gcc/loop-unswitch.c4
-rw-r--r--gcc/lower-subreg.c3
-rw-r--r--gcc/mkmap-symver.awk16
-rw-r--r--gcc/optabs.c3
-rw-r--r--gcc/opts.c3
-rw-r--r--gcc/predict.c17
-rw-r--r--gcc/recog.c12
-rw-r--r--gcc/reg-stack.c7
-rw-r--r--gcc/regmove.c5
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/reload1.c14
-rw-r--r--gcc/reorg.c11
-rw-r--r--gcc/resource.c5
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c28
-rw-r--r--gcc/target-def.h4
-rw-r--r--gcc/target.h6
-rw-r--r--gcc/testsuite/ChangeLog261
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle24.C1
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle25.C2
-rw-r--r--gcc/testsuite/g++.dg/cdce3.C74
-rw-r--r--gcc/testsuite/g++.dg/compat/struct-layout-1.exp2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist1.C69
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist2.C32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist3.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist4.C32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist5.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist6.C30
-rw-r--r--gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C1
-rw-r--r--gcc/testsuite/g++.dg/inherit/error4.C6
-rw-r--r--gcc/testsuite/g++.dg/init/brace2.C2
-rw-r--r--gcc/testsuite/g++.dg/init/brace6.C6
-rw-r--r--gcc/testsuite/g++.dg/opt/temp1.C5
-rw-r--r--gcc/testsuite/g++.dg/opt/vt1.C1
-rw-r--r--gcc/testsuite/g++.dg/other/builtin1.C6
-rw-r--r--gcc/testsuite/g++.dg/parse/crash36.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/ctor3.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C27
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/comdat5.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20001226-1.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20080625-1.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030222-1.x6
-rw-r--r--gcc/testsuite/gcc.dg/20030702-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/callabi/callabi.h50
-rw-r--r--gcc/testsuite/gcc.dg/callabi/func-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-1.c47
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-2.c47
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-3.c47
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-16_x.c10
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-16_y.c5
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-16a_main.c14
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-16a_x.c37
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-16a_y.c22
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-17_x.c10
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-17_y.c5
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-17a_main.c14
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-17a_x.c37
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-17a_y.c22
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-18_x.c10
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-18_y.c5
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-18a_main.c14
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-18a_x.c37
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-by-value-18a_y.c22
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1.exp2
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c12
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_main.c21
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_x.c7
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_y.c7
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1_x.c8
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1_y.c4
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_main.c26
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_x.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_y.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2_x.c4
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2_y.c2
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_main.c26
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_x.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_y.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-defs.h14
-rw-r--r--gcc/testsuite/gcc.dg/const-float128-ped.c2
-rw-r--r--gcc/testsuite/gcc.dg/const-float128.c2
-rw-r--r--gcc/testsuite/gcc.dg/const-float80-ped.c1
-rw-r--r--gcc/testsuite/gcc.dg/const-float80.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/20000519-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/avoidpaste1.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/avoidpaste2.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/c90-empty-macro-args.c19
-rw-r--r--gcc/testsuite/gcc.dg/cpp/c99-empty-macro-args.c19
-rw-r--r--gcc/testsuite/gcc.dg/lower-subreg-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/nrv3.c5
-rw-r--r--gcc/testsuite/gcc.dg/pr27095.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr28243.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr35736.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr36227.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/ipa-pta-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr25947-1.c1
-rw-r--r--[-rwxr-xr-x]gcc/testsuite/gcc.dg/torture/pr35842.c0
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr36373-10.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/neon/polytypes.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/float128-1.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/float128-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr32191.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr32268.c1
-rw-r--r--gcc/testsuite/gcc.target/m68k/interrupt-2.c22
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c23
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_tests_3.f906
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr36726.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_2.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_3.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_4.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_5.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/proc_decl_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_1.f9073
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_2.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_3.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_4.f9057
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_5.f9033
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_6.f9039
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_7.c10
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_7.f9047
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_8.c14
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_8.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/product_sum_bounds_1.f908
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3.adb15
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb8
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads5
-rw-r--r--gcc/testsuite/lib/compat.exp12
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp5
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp2
-rw-r--r--gcc/tree-dump.c1
-rw-r--r--gcc/tree-flow-inline.h10
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-nrv.c2
-rw-r--r--gcc/tree-outof-ssa.c2
-rw-r--r--gcc/tree-sra.c24
-rw-r--r--gcc/tree-ssa-alias.c1
-rw-r--r--gcc/tree-ssa-ccp.c18
-rw-r--r--gcc/tree-ssa-loop-ivopts.c41
-rw-r--r--gcc/tree-ssa-loop-niter.c2
-rw-r--r--gcc/tree-ssa-structalias.c788
-rw-r--r--gcc/tree-ssa-structalias.h4
-rw-r--r--gcc/tree-stdarg.c12
-rw-r--r--gcc/tree-switch-conversion.c27
-rw-r--r--gcc/tree-tailcall.c4
-rw-r--r--gcc/tree.c37
-rw-r--r--gcc/tree.h7
-rw-r--r--gcc/unwind-pe.h3
-rw-r--r--gcc/varray.c6
-rw-r--r--gcc/vec.h18
-rw-r--r--include/ChangeLog11
-rw-r--r--include/safe-ctype.h39
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/macro.c11
-rw-r--r--libgcc/ChangeLog88
-rw-r--r--libgcc/Makefile.in50
-rw-r--r--libgcc/config.host18
-rw-r--r--libgcc/config/i386/32/sfp-machine.h209
-rw-r--r--libgcc/config/i386/32/t-fprules-softfp8
-rw-r--r--libgcc/config/i386/32/tf-signs.c64
-rw-r--r--libgcc/config/i386/64/_divtc3.c14
-rw-r--r--libgcc/config/i386/64/_multc3.c14
-rw-r--r--libgcc/config/i386/64/_powitf2.c14
-rw-r--r--libgcc/config/i386/64/eqtf2.c13
-rw-r--r--libgcc/config/i386/64/getf2.c13
-rw-r--r--libgcc/config/i386/64/letf2.c13
-rw-r--r--libgcc/config/i386/64/sfp-machine.h143
-rw-r--r--libgcc/config/i386/64/t-softfp-compat15
-rw-r--r--libgcc/configure15
-rw-r--r--libgcc/configure.ac15
-rw-r--r--libgfortran/ChangeLog29
-rw-r--r--libgfortran/acinclude.m46
-rwxr-xr-xlibgfortran/configure10
-rw-r--r--libgfortran/generated/matmul_c10.c41
-rw-r--r--libgfortran/generated/matmul_c16.c41
-rw-r--r--libgfortran/generated/matmul_c4.c41
-rw-r--r--libgfortran/generated/matmul_c8.c41
-rw-r--r--libgfortran/generated/matmul_i1.c41
-rw-r--r--libgfortran/generated/matmul_i16.c41
-rw-r--r--libgfortran/generated/matmul_i2.c41
-rw-r--r--libgfortran/generated/matmul_i4.c41
-rw-r--r--libgfortran/generated/matmul_i8.c41
-rw-r--r--libgfortran/generated/matmul_l16.c41
-rw-r--r--libgfortran/generated/matmul_l4.c41
-rw-r--r--libgfortran/generated/matmul_l8.c41
-rw-r--r--libgfortran/generated/matmul_r10.c41
-rw-r--r--libgfortran/generated/matmul_r16.c41
-rw-r--r--libgfortran/generated/matmul_r4.c41
-rw-r--r--libgfortran/generated/matmul_r8.c41
-rw-r--r--libgfortran/m4/matmul.m441
-rw-r--r--libgfortran/m4/matmull.m441
-rw-r--r--libjava/ChangeLog13
-rw-r--r--libjava/Makefile.am3
-rw-r--r--libjava/Makefile.in5
-rw-r--r--libjava/gnu/gcj/convert/gen-from-JIS.c16
-rw-r--r--libjava/gnu/gcj/convert/make-trie.c1
-rw-r--r--libjava/libtool-version2
-rw-r--r--libobjc/ChangeLog4
-rw-r--r--libobjc/Makefile.in5
-rw-r--r--libstdc++-v3/ChangeLog95
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/postypes.h10
-rw-r--r--libstdc++-v3/include/bits/stl_map.h15
-rw-r--r--libstdc++-v3/include/std/ratio288
-rw-r--r--libstdc++-v3/include/std/system_error4
-rw-r--r--libstdc++-v3/include/std/type_traits39
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am5
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in3
-rw-r--r--libstdc++-v3/libsupc++/initializer_list72
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc46
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc118
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc82
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc51
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc55
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc75
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc73
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc72
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc48
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc3
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc3
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc3
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc3
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc30
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc30
-rw-r--r--libstdc++-v3/testsuite/lib/dg-options.exp9
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp64
-rw-r--r--maintainer-scripts/ChangeLog10
-rw-r--r--maintainer-scripts/crontab1
-rwxr-xr-xmaintainer-scripts/gcc_release35
-rwxr-xr-xmaintainer-scripts/update_version113
-rwxr-xr-xmaintainer-scripts/update_version_svn45
-rwxr-xr-xmaintainer-scripts/update_web_docs_svn1
408 files changed, 9338 insertions, 2118 deletions
diff --git a/ChangeLog.melt b/ChangeLog.melt
index 784cc14cbe7..72c68b3c0b1 100644
--- a/ChangeLog.melt
+++ b/ChangeLog.melt
@@ -1,3 +1,6 @@
+2008-07-08 Basile Starynkevitch <basile@starynkevitch.net>
+ MELT branch merged with trunk r137620
+
2008-07-02 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r137357
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 916d1b0244a..4a126ecef43 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,555 @@
+2008-07-08 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (ipcp_init_cloned_node): Call ipa_check_create_node_params
+ instead of ipa_create_node_params.
+ (ipcp_driver): Allocate infos with ipa_check_create_node_params and
+ ipa_check_create_edge_args, free them with
+ free_all_ipa_structures_after_ipa_cp, call ipa_register_cgraph_hooks.
+
+ * ipa-prop.c: Include flags.h and tree-inline.h.
+ (ipa_node_params_vector): New variable.
+ (ipa_edge_args_vector): New variable.
+ (edge_removal_hook_holder): New variable.
+ (node_removal_hook_holder): New variable.
+ (edge_duplication_hook_holder): New variable.
+ (node_duplication_hook_holder): New variable.
+ (ipa_detect_param_modifications): Check for presence of modified flags.
+ (ipa_compute_jump_functions): Check for presence of jump functions.
+ (ipa_free_edge_args_substructures): New function.
+ (ipa_create_node_params): Removed.
+ (ipa_free_all_edge_args): Changed to deallocate the on-the-side vector.
+ (ipa_free_node_params_substructures): New function.
+ (ipa_free_all_node_params): Changed to deallocate the on-the-side
+ vector.
+ (ipa_edge_removal_hook): New function.
+ (ipa_node_removal_hook): New function.
+ (duplicate_array): New function.
+ (ipa_edge_duplication_hook): New function.
+ (ipa_node_duplication_hook): New function.
+ (ipa_register_cgraph_hooks): New function.
+ (ipa_unregister_cgraph_hooks): New function.
+ (free_all_ipa_structures_after_ipa_cp): New function.
+
+ * ipa-prop.h: Include vec.h.
+ (ipa_node_params_t): New typedef with vector types for it.
+ (ipa_edge_args_t): New typedef with vector types for it.
+ (IPA_NODE_REF): Changed to access an on-the-side vector.
+ (IPA_EDGE_REF): Changed to access an on-the-side vector.
+ (ipa_check_create_node_params): New function.
+ (ipa_check_create_edge_args): New function.
+
+ * Makefile.in (IPA_PROP_H): New variable for ipa-prop.h. Converted
+ all users.
+
+2008-07-07 Tom Tromey <tromey@redhat.com>
+
+ * configure, config.in: Rebuilt.
+ * configure.ac: Don't check for scandir or alphasort.
+
+2008-07-07 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/arm.c (arm_init_neon_builtins): Register built-in
+ types immediately after creating them.
+
+2008-07-07 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/aout.h (DOLLARS_IN_IDENTIFIERS): Remove.
+
+2008-07-07 Fernando Pereira <fernando@cs.ucla.edu>
+
+ * tree-ssa-structalias.c (compute_points_to_sets): Add call to
+ dump_constraint_graph.
+ (dump_constraint_edge): New function.
+ (dump_constraint_graph): New function.
+ (debug_constraint_graph): New function.
+ (dump_constraint): Removed useless comparison.
+ * tree-ssa-structalias.h (dump_constraint_edge): Declare.
+ (dump_constraint_graph): Declare.
+ (debug_constraint_graph): Declare.
+ * tree-dump.c (struct dump_option_value_info): Declare
+ TDF_GRAPH.
+
+2008-07-07 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/i386.c (is_va_list_char_pointer): New.
+ (ix86_va_start): Replace compare with ms_va_list_type_node
+ by is_va_list_char_pointer.
+ (ix86_gimplify_va_arg): Likewise.
+
+2008-07-07 Martin Jambor <mjambor@suse.cz>
+
+ * cgraph.c (cgraph_edge_max_uid): New variable.
+ (struct cgraph_edge_hook_list): New type.
+ (struct cgraph_node_hook_list): New type.
+ (struct cgraph_2edge_hook_list): New type.
+ (struct cgraph_2node_hook_list): New type.
+ (first_cgraph_edge_removal_hook): New variable.
+ (first_cgraph_node_removal_hook): New variable.
+ (first_cgraph_edge_duplicated_hook): New variable.
+ (first_cgraph_node_duplicated_hook): New variable.
+ (cgraph_add_edge_removal_hook): New function.
+ (cgraph_remove_edge_removal_hook): New function.
+ (cgraph_call_edge_removal_hooks): New function.
+ (cgraph_add_node_removal_hook): New function.
+ (cgraph_remove_node_removal_hook): New function.
+ (cgraph_call_node_removal_hooks): New function.
+ (cgraph_add_edge_duplication_hook): New function.
+ (cgraph_remove_edge_duplication_hook): New function.
+ (cgraph_call_edge_duplication_hooks): New function.
+ (cgraph_add_node_duplication_hook): New function.
+ (cgraph_remove_node_duplication_hook): New function.
+ (cgraph_call_node_duplication_hooks): New function.
+ (cgraph_create_edge): Assign to edge uid.
+ (cgraph_remove_edge): Call edge removal hooks.
+ (cgraph_node_remove_callees): Call edge removal hooks.
+ (cgraph_node_remove_callers): Call edge removal hooks.
+ (cgraph_remove_node): Call node removal hooks.
+ (cgraph_clone_edge): Call edge duplication hooks.
+ (cgraph_clone_node): Call node duplication hooks.
+
+ * cgraph.h (cgraph_edge): New field uid.
+ (cgraph_edge_hook): New type.
+ (cgraph_node_hook): New type.
+ (cgraph_2edge_hook): New type.
+ (cgraph_2node_hook): New type.
+
+2008-07-07 Andreas Tobler <a.tobler@schweiz.org>
+
+ * config.in: Regenerate.
+
+2008-07-07 Vladimir Prus <vladimir@codesourcery.com>
+
+ * gcc.c (print_sysroot): New.
+ (option_map, display_help, process_command): Handle the
+ -print-sysroot option.
+ (main): Print the sysroot if requested.
+ * doc/invoke.texi (Debugging Options): Document -print-sysroot.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR target/34780
+ * unwind-pe.h (size_of_encoded_value): add attribute unused.
+
+2008-07-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * function.c (assign_parm_remove_parallels): Check mode of
+ entry_parm.
+ (assign_parm_setup_block_p): Also check mode of entry_parm.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.h (set_used_smts): Remove.
+ * tree-ssa-structalias.c (used_smts): Likewise.
+ (set_used_smts): Likewise.
+ * tree-ssa-alias.c (compute_flow_sensitive_aliasing): Remove
+ call to set_used_smts.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (struct variable_info): Add is_full_var flag.
+ (new_var_info): Set it to false.
+ (solution_set_add): Correctly handle pointers outside a var and
+ inside a field.
+ (type_safe): Treat variables with is_full_var properly.
+ (do_sd_constraint): Likewise.
+ (do_ds_constraint): Likewise.
+ (process_constraint): Remove zeroing offset for !use_field_sensitive.
+ (get_constraint_for_ptr_offset): New function.
+ (get_constraint_for_component_ref): For addresses at least include
+ the last field of the variable. Handle is_full_vars properly.
+ (get_constraint_for_1): Factor common code, handle POINTER_PLUS_EXPR.
+ (handle_ptr_arith): Remove.
+ (find_func_aliases): Simplify assignment handling.
+ (create_function_info_for): For parameter and result varinfos set
+ is_full_var flag.
+ (create_variable_info_for): Set is_full_var flag whenever we
+ just created a single varinfo for a decl.
+ (init_alias_vars): Initialize use_field_sensitive from
+ max-fields-for-field-sensitive parameter.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36713
+ * tree-flow-inline.h (is_call_used): New function.
+ * tree-nrv.c (dest_safe_for_nrv_p): Use it.
+ * tree-tailcall.c (suitable_for_tail_opt_p): Likewise.
+ * tree-outof-ssa.c (create_temp): Set call-used flag if required.
+
+2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types.
+
+2008-07-07 Mark Shinwell <shinwell@codesourcery.com>
+
+ * config/m68k/lb1sf68.asm: Add PIC macros for Linux targets.
+
+2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config.gcc (m68k-*-linux*): Add with_arch. Add sysroot-suffix.h
+ to tm_file. Add m68k/t-floatlib, m68k/t-linux & m68k/t-mlibs to
+ tmake_file.
+ * config/m68k/t-linux: New.
+ * doc/install.texi: Document m68k-*-linux is now multilibbed by
+ default.
+
+2008-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/m68k/t-cf (MULTILIB_EXTRA_OPTS): Add no-mac.
+ * config/m68k/m68k-devices.def: Remove multilibs that only differ
+ by MAC/EMAC.
+
+2008-07-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (execute): Fix -Wc++-compat warning.
+
+2008-07-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36720
+ * config/ia64/ia64.c (ia64_split_tmode): Fix typo in TImode
+ constant for little endian.
+
+2008-07-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Check
+ mips_base_mips16 instead of TARGET_MIPS16.
+ (mips_base_mips16): Declare.
+ * config/mips/mips.c (mips_base_mips16): Make global.
+ (was_mips16_p): Remove GTY marker.
+ (was_mips16_pch_p): New variable.
+ (mips_set_mips16_mode): Check both was_mips16_p and was_mips16_pch_p.
+ (mips_override_options): Force to non-MIPS16 mode initially.
+ Do not complain about MIPS16 PIC incompatibilities here.
+ Only allow -mgpopt if -mexplicit-relocs is in force for
+ non-MIPS16 code.
+
+2008-07-06 Andreas Tobler <a.tobler@schweiz.org>
+
+ * configure.ac: Check for caddr_t, define to char * if not defined.
+ * configure: Regenerate.
+ * ggc-common.c (mmap_gt_pch_get_address): Fix -Wc++-compat warnings.
+ (mmap_gt_pch_use_address): Likewise.
+ * config/host-solaris.c (sol_gt_pch_use_address): Likewise.
+
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (struct variable_info): Remove has_union.
+ (new_var_info): Deal with it.
+ (solution_set_add): Likewise.
+ (bitpos_of_field): Make signed, fix.
+ (struct fieldoff): Remove type and decl fields. Make size field
+ unsigned HOST_WIDE_INT. Add has_unknown_size and may_have_pointers
+ flags.
+ (fieldoff_compare): Deal with it.
+ (push_fields_onto_fieldstack): Remove has_union argument, glob
+ adjacent non-pointer fields together.
+ (create_function_info_for): Do not set has_union.
+ (create_variable_info_for): Simplify.
+
+2008-07-06 Kai Tietz <kai.tietz@onevision.com>
+
+ * config.gcc (extra_headers): Add cross-stdarg.h for target
+ x86_64-*-* and i?86-*-*.
+ * config/i386/cross-stdarg.h: New.
+ * builtins.c (std_fn_abi_va_list): New.
+ (std_canonical_va_list_type): New.
+ (stabilize_va_list): Replace va_list_type_node use by
+ mtarget.canonical_va_list_type.
+ (gimplify_va_arg_expr): Likewise.
+ (expand_builtin_va_copy): Replace va_list_type_node use by
+ mtarget.fn_abi_va_list.
+ * tree-sra.c (is_va_list_type): New helper.
+ (decl_can_be_decomposed_p): Replace
+ va_list_type_node use by is_va_list_type.
+ * tree-ssa-ccp.c (optimize_stdarg_builtin): Likewise.
+ * tree-stdarg.c (execute_optimize_stdarg): Likewise.
+ * c-common.c (c_common_nodes_and_builtins): Use TARGET_ENUM_VA_LIST.
+ * config/i386/i386-protos.h (ix86_get_valist_type): New.
+ (ix86_enum_va_list): New.
+ * config/i386/i386.c (sysv_va_list_type_node): New.
+ (ms_va_list_type_node): New.
+ (ix86_function_type_abi): Remove sorry.
+ (ix86_build_builtin_va_list_abi): New.
+ (ix86_build_builtin_va_list): Call ix86_build_builtin_va_list_abi
+ for 64-bit targets.
+ (ix86_va_start): Replace va_list_type_node by sysv_va_list_type_node.
+ (ix86_init_builtins_va_builtins_abi): New.
+ (ix86_init_builtins): Use ix86_init_builtins_va_builtins_abi
+ for 64-bit targets.
+ (ix86_handle_abi_attribute): New.
+ (attribute_spec): Add sysv_abi and ms_abi.
+ (ix86_fn_abi_va_list): New.
+ (ix86_canonical_va_list_type): New.
+ (ix86_enum_va_list): New.
+ (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ * config/i386/i386.h (TARGET_ENUM_VA_LIST): New.
+ * doc/tm.texi (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ (TARGET_ENUM_VA_LIST): New.
+ * expr.h (std_fn_abi_va_list): New.
+ (std_canonical_va_list_type): New.
+ * target-def.h (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ (TARGET_INITIALIZER): Add TARGET_FN_ABI_VA_LIST and
+ TARGET_CANONICAL_VA_LIST_TYPE.
+ * target.h (struct gcc_target): Add fn_abi_va_list hook
+ and canonical_va_list_type hook.
+
+2008-07-05 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * fold-const.c (fold_convert_const): Treat OFFSET_TYPE the same as
+ integral and pointer types.
+
+2008-07-04 Roger Sayle <roger@eyesopen.com>
+
+ * config/rs6000/host-darwin.c (darwin_rs6000_extra_siganls): Cast
+ the "void*" result of xmalloc to "char*" to fix bootstrap breakage.
+
+2008-07-04 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/36684
+ * config/sh/sh.h (OVERRIDE_OPTIONS): Disable -fschedule-insns
+ for PIC.
+
+2008-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-switch-conversion.c (build_one_array, gen_def_assigns): Use
+ build_gimple_modify_stmt.
+ (build_arrays, gen_inbound_check): Likewise. Force RHS to be
+ gimple operand. Use fold_build* instead of build*.
+
+2008-07-04 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (lookup_vi_for_tree): Declare.
+ (do_sd_constraint): Handle a dereference of ESCAPED and CALLUSED
+ properly to compute the reachability set if we do field-sensitive PTA.
+ * invoke.texi (max-fields-for-field-sensitive): Document default.
+ * opts.c (decode_options): Set max-fields-for-field-sensitive to
+ 100 for optimize >= 2.
+
+2008-07-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ggc-zone.c (lookup_page_table_if_allocated,
+ set_page_table_entry, zone_find_object_size, alloc_small_page,
+ alloc_large_page, ggc_free, gt_ggc_m_S, ggc_marked_p, init_ggc,
+ new_ggc_zone, init_ggc_pch, ggc_pch_this_base, ggc_pch_read): Fix
+ -Wc++-compat and/or -Wcast-qual warnings.
+
+2008-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/36634
+ * config/rs6000/rs6000.md (call, call_value): Don't arrange for
+ pic_offset_table_rtx to be marked as used here.
+ (call_nonlocal_sysv, call_value_nonlocal_sysv): Add split for
+ TARGET_SECURE_PLT to "use" pic_offset_table_rtx.
+ (call_nonlocal_sysv_secure, call_value_nonlocal_sysv_secure): New insn.
+ (sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv): Assert
+ !TARGET_SECURE_PLT.
+
+2008-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alloc-pool.c (hash_descriptor, eq_descriptor,
+ alloc_pool_descriptor): Fix -Wc++-compat warnings.
+ * bitmap.c (hash_descriptor, eq_descriptor, bitmap_descriptor):
+ Likewise.
+ * ggc-common.c (hash_descriptor, eq_descriptor, hash_ptr, eq_ptr,
+ loc_descriptor, ggc_prune_ptr, ggc_free_overhead,
+ final_cmp_statistic, cmp_statistic, dump_ggc_loc_statistics):
+ Likewise.
+ * varray.c (hash_descriptor, eq_descriptor, varray_descriptor):
+ Likewise.
+
+2008-07-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-flow.h (loop_only_exit_p): Declare.
+ * tree-ssa-loop-niter.c (loop_only_exit_p): Make public.
+ * tree-ssa-loop-ivopts.c (may_eliminate_iv): Reinstate direct check on
+ the number of iterations if it is constant. Otherwise, if this is the
+ only possible exit of the loop, use the conservative estimate on the
+ number of iterations of the entire loop if available.
+
+2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * Makefile.in (libgcc.mvars): Add LIBGCC_SYNC and LIBGCC_SYNC_CFLAGS.
+ * libgcc-std.ver (GCC_4.4.0): New version, inherited from GCC_4.3.0.
+ Add synchronization functions.
+ * config/sync.c: New file.
+ * config/mips/t-libgcc-mips16 (LIBGCC_SYNC): Define.
+ (LIBGCC_SYNC_CFLAGS): Likewise.
+
+2008-07-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/36710
+ * config/i386/i386.md (mode): Add TF to "mode" attribute.
+ (*pushtf_sse): New insn pattern.
+ (pushtf splitters): New splitters.
+
+2008-07-03 Michael Meissner <gnu@the-meissners.org>
+
+ PR middle-end/35736
+ * predict.c (build_predict_expr): Use void_type_node for the tree
+ type, instead of NULL_TREE.
+
+2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (contains_aligned_value_p): Return true
+ for TCmode.
+ (ix86_data_alignment): Align TCmode to 128bits.
+ (ix86_local_alignment): Likewise.
+
+2008-07-03 Andrew Haley <aph@redhat.com>
+
+ PR bootstrap/33304
+ * vec.h (VEC_TA): New.
+ (DEF_VEC_I, DEF_VEC_P, DEF_VEC_ALLOC_I, DEF_VEC_ALLOC_P,
+ DEF_VEC_O, DEF_VEC_ALLOC_O: Use VEC_TA.
+ * c-common.c (C_COMMON_FIXED_TYPES_SAT): New macro.
+ (C_COMMON_FIXED_MODE_TYPES_SAT): New macro.
+ (C_COMMON_FIXED_TYPES): Remove first arg.
+ (C_COMMON_FIXED_MODE_TYPES): Likewise.
+ * tree.c (MAKE_FIXED_TYPE_NODE): Break into two macros,
+ MAKE_FIXED_TYPE_NODE and MAKE_FIXED_TYPE_NODE_WIDTH in order
+ not to use empty macro arguments.
+
+2008-07-02 Joseph Myers <joseph@codesourcery.com>
+
+ * config/alpha/vms_tramp.asm, config/arm/crti.asm,
+ config/arm/crtn.asm, config/bfin/crti.s, config/bfin/crtlibid.s,
+ config/bfin/crtn.s, config/fr30/crti.asm, config/fr30/crtn.asm,
+ config/frv/lib1funcs.asm, config/i386/sol2-c1.asm,
+ config/i386/sol2-ci.asm, config/i386/sol2-cn.asm,
+ config/i386/sol2-gc1.asm, config/ia64/crti.asm,
+ config/ia64/crtn.asm, config/m68hc11/larith.asm,
+ config/m68hc11/m68hc11-crt0.S, config/m68k/crti.s,
+ config/m68k/crtn.s, config/mcore/crti.asm, config/mcore/crtn.asm,
+ config/rs6000/crtresfpr.asm, config/rs6000/crtresgpr.asm,
+ config/rs6000/crtresxfpr.asm, config/rs6000/crtresxgpr.asm,
+ config/rs6000/crtsavfpr.asm, config/rs6000/crtsavgpr.asm,
+ config/rs6000/crtsavres.asm, config/rs6000/e500crtres32gpr.asm,
+ config/rs6000/e500crtres64gpr.asm,
+ config/rs6000/e500crtres64gprctr.asm,
+ config/rs6000/e500crtrest32gpr.asm,
+ config/rs6000/e500crtrest64gpr.asm,
+ config/rs6000/e500crtresx32gpr.asm,
+ config/rs6000/e500crtresx64gpr.asm,
+ config/rs6000/e500crtsav32gpr.asm,
+ config/rs6000/e500crtsav64gpr.asm,
+ config/rs6000/e500crtsav64gprctr.asm,
+ config/rs6000/e500crtsavg32gpr.asm,
+ config/rs6000/e500crtsavg64gpr.asm,
+ config/rs6000/e500crtsavg64gprctr.asm, config/rs6000/eabi-ci.asm,
+ config/rs6000/eabi-cn.asm, config/rs6000/eabi.asm,
+ config/rs6000/sol-ci.asm, config/rs6000/sol-cn.asm,
+ config/rs6000/tramp.asm, config/sparc/sol2-ci.asm,
+ config/sparc/sol2-cn.asm: Remove .file directives.
+
+2008-07-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * resource.c (mark_referenced_resources): Look inside
+ UNSPEC_VOLATILEs and ASM_INPUTs.
+
+2008-07-02 Ian Lance Taylor <iant@google.com>
+
+ * rtlanal.c (add_reg_note): New function.
+ * rtl.h (add_reg_note): Declare.
+ * auto-inc-dec.c (attempt_change): Use add_reg_note.
+ * bb-reorder.c (add_reg_crossing_jump_notes): Likewise.
+ * builtins.c (expand_builtin_longjmp): Likewise.
+ (expand_builtin_nonlocal_goto): Likewise.
+ * calls.c (emit_call_1, expand_call): Likewise.
+ * cfgexpand.c (add_reg_br_prob_note): Likewise.
+ * cfglayout.c (fixup_reorder_chain): Likewise.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Likewise.
+ (commit_one_edge_insertion): Likewise.
+ * combine.c (move_deaths, distribute_notes): Likewise.
+ * df-problems.c (df_set_note): Likewise.
+ * emit-rtl.c (link_cc0_insns, try_split): Likewise.
+ (set_unique_reg_note): Likewise.
+ (emit_copy_of_insn_after): Likewise.
+ * expr.c (expand_expr_real): Likewise.
+ * gcse.c (add_label_notes): Likewise.
+ * haifa-sched.c (create_check_block_twin): Likewise.
+ * jump.c (mark_jump_label_1): Likewise.
+ * loop-doloop.c (add_test, doloop_modify): Likewise.
+ * loop-unswitch.c (compare_and_jump_seq): Likewise.
+ * lower-subreg.c (move_eh_region_note): Likewise.
+ * optabs.c (emit_libcall_block): Likewise.
+ * predict.c (predict_insn): Likewise.
+ (combine_predictions_for_insn): Likewise.
+ * recog.c (peephole2_optimize): Likewise.
+ * regmove.c (try_auto_increment): Likewise.
+ * reg-stack.c (emit_pop_insn, move_for_stack_reg): Likewise.
+ * reload.c (find_reloads): Likewise.
+ * reload1.c (fixup_eh_region_note): Likewise.
+ (reload_as_needed, add_auto_inc_notes, copy_eh_notes): Likewise.
+ * reorg.c (delete_prior_computation): Likewise.
+ (delete_computation, dbr_schedule): Likewise.
+ * config/pa/pa.c (legitimize_pic_address): Likewise.
+ * config/sh/sh.c (sh_reorg): Likewise.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36669
+ * config/libgcc-glibc.ver: Add %exclude.
+ * config/m32r/libgcc-glibc.ver: Likwise.
+ * config/s390/libgcc-glibc.ver: Likwise.
+ * config/sh/libgcc-glibc.ver: Likwise.
+ * config/sparc/libgcc-sparc-glibc.ver: Likwise.
+
+ * config/i386/libgcc-glibc.ver: New.
+
+ * config/i386/libgcc-x86_64-glibc.ver: Removed.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
+ from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
+ i[34567]86-*-linux*, x86_64-*-linux*. Add
+ i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
+ i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
+ x86_64-*-linux*. Add i386/t-linux to tmake_file for
+ i[34567]86-*-linux*, x86_64-*-linux*.
+
+ * libgcc-std.ver: Add empty GCC_4.4.0.
+
+ * mkmap-symver.awk: Support multiple versions per symbol.
+
+ * config/i386/i386.c (ix86_init_builtins): Always define
+ __builtin_fabsq and __builtin_copysignq with fallbacks.
+ (ix86_expand_builtin): Emit normal call for __builtin_fabsq
+ and __builtin_copysignq if SSE2 isn't available.
+
+ * config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
+ (LIBGCC2_TF_CEXT): Likwise.
+ (TF_SIZE): Likwise.
+
+ * config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.
+
+ * config/i386/sfp-machine.h: Moved to libgcc.
+
+ * config/i386/sfp-machine.h: New.
+ * config/i386/t-linux: Likwise.
+
+ * config/i386/t-darwin: Remove softfp_wrap_start and
+ softfp_wrap_end.
+ * config/i386/t-darwin64: Likewise.
+
+ * config/i386/t-fprules-softfp64: Renamed to ...
+ * config/i386/t-fprules-softfp: This.
+
+ * config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
+ and softfp_wrap_end.
+
+2008-07-02 Jason Merrill <jason@redhat.com>
+
+ * tree.c (ctor_to_list): Use FOR_EACH_CONSTRUCTOR_ELT.
+
+ * tree.c (ctor_to_list): New fn.
+ * tree.h: Declare it.
+ (CONSTRUCTOR_ELT): New macro.
+ (CONSTRUCTOR_NELTS): New macro.
+
2008-07-02 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (struct variable_info): Reorder
@@ -127,19 +679,19 @@
2008-07-01 Martin Jambor <mjambor@suse.cz>
- * Makefile.in (tree-switch-conversion.o): Add.
- (OBJS-common): Add tree-swtch-conversion.o.
- * passes.c (init_optimization_passes): Add pass_convert_switch.
- * tree-pass.h: (pass_convert_switch): Add.
- * tree-switch-conversion.c: New file.
- * gcc.dg/tree-ssa/cswtch.c: New testcase.
- * common.opt (ftree-cswtch): New option.
- * params.h (PARAM_SWITCH_CONVERSION_BRANCH_RATIO): New parameter.
- * params.def (PARAM_SWITCH_CONVERSION_BRANCH_RATIO): New parameter.
- * opts.c (decode_options): Set flag_tree_switch_conversion when
- optimization level is >= 2.
- * doc/invoke.texi (Optimize Options): Added description of
- -ftree-swtch-conversion and switch-conversion-max-branch-ratio.
+ * Makefile.in (tree-switch-conversion.o): Add.
+ (OBJS-common): Add tree-swtch-conversion.o.
+ * passes.c (init_optimization_passes): Add pass_convert_switch.
+ * tree-pass.h: (pass_convert_switch): Add.
+ * tree-switch-conversion.c: New file.
+ * gcc.dg/tree-ssa/cswtch.c: New testcase.
+ * common.opt (ftree-cswtch): New option.
+ * params.h (PARAM_SWITCH_CONVERSION_BRANCH_RATIO): New parameter.
+ * params.def (PARAM_SWITCH_CONVERSION_BRANCH_RATIO): New parameter.
+ * opts.c (decode_options): Set flag_tree_switch_conversion when
+ optimization level is >= 2.
+ * doc/invoke.texi (Optimize Options): Added description of
+ -ftree-swtch-conversion and switch-conversion-max-branch-ratio.
2008-06-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
@@ -159,7 +711,7 @@
PR rtl-optimization/34744
* df-scan.c (df_scan_free_ref_vec, df_scan_free_mws_vec): New macros.
- (df_scan_free_internal): Free data structures not
+ (df_scan_free_internal): Free data structures not
allocated in storage pools.
(df_mw_hardreg_chain_delete_eq_uses): Use df_scan_free_mws_vec.
(df_refs_add_to_chains): Use df_scan_free_ref_vec and
diff --git a/gcc/ChangeLog.melt b/gcc/ChangeLog.melt
index 9dffa5b07dc..f69ec5ba2a3 100644
--- a/gcc/ChangeLog.melt
+++ b/gcc/ChangeLog.melt
@@ -1,4 +1,7 @@
2008-07-08 Basile Starynkevitch <basile@starynkevitch.net>
+ MELT branch merged with trunk r137620
+
+2008-07-08 Basile Starynkevitch <basile@starynkevitch.net>
* melt/warmelt-macro.bysl: added mexpand_defciterator
expand_citeration and extended macroexpand_1
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index bc40ef40751..9c0637d2a77 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20080702
+20080708
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2688eed189b..4dff4b7b074 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -862,6 +862,7 @@ TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h
REAL_H = real.h $(MACHMODE_H)
DBGCNT_H = dbgcnt.h dbgcnt.def
EBIMAP_H = ebitmap.h sbitmap.h
+IPA_PROP_H = $(TREE_H) vec.h
#
# Now figure out from those variables how to compile and link.
@@ -1704,6 +1705,8 @@ libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
echo SHLIB_MAPFILES = '$(call srcdirify,$(SHLIB_MAPFILES))' >> tmp-libgcc.mvars
echo SHLIB_NM_FLAGS = '$(SHLIB_NM_FLAGS)' >> tmp-libgcc.mvars
echo LIBGCC2_CFLAGS = '$(LIBGCC2_CFLAGS)' >> tmp-libgcc.mvars
+ echo LIBGCC_SYNC = '$(LIBGCC_SYNC)' >> tmp-libgcc.mvars
+ echo LIBGCC_SYNC_CFLAGS = '$(LIBGCC_SYNC_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars
@@ -2045,7 +2048,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) intl.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
- ipa-prop.h value-prof.h $(TARGET_H) $(INTEGRATE_H)
+ $(IPA_PROP_H) value-prof.h $(TARGET_H) $(INTEGRATE_H)
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h $(TREE_FLOW_H)
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2582,7 +2585,7 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
$(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
- $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \
+ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
gt-cgraphunit.h
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(TREE_GIMPLE_H) \
@@ -2591,14 +2594,14 @@ varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
$(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
- $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \
+ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
gt-varpool.h
ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H)
ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) ipa-prop.h \
- $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H)
+ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) \
+ $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) tree-inline.h
ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h tree-inline.h tree-dump.h \
+ langhooks.h $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) tree-inline.h tree-dump.h \
$(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(DIAGNOSTIC_H)
matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TARGET_H) $(CGRAPH_H) $(TREE_FLOW_H) $(TM_H) tree-pass.h \
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index b22869fe787..7f0dc8ce7d2 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -81,13 +81,15 @@ static htab_t alloc_pool_hash;
static hashval_t
hash_descriptor (const void *p)
{
- const struct alloc_pool_descriptor *d = p;
+ const struct alloc_pool_descriptor *const d =
+ (const struct alloc_pool_descriptor * )p;
return htab_hash_pointer (d->name);
}
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct alloc_pool_descriptor *d = p1;
+ const struct alloc_pool_descriptor *const d =
+ (const struct alloc_pool_descriptor *) p1;
return d->name == p2;
}
@@ -106,7 +108,7 @@ alloc_pool_descriptor (const char *name)
1);
if (*slot)
return *slot;
- *slot = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct alloc_pool_descriptor);
(*slot)->name = name;
return *slot;
}
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 18c1b7107da..35d6c87a696 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -621,8 +621,7 @@ attempt_change (rtx new_addr, rtx inc_reg)
}
/* Record that this insn has an implicit side effect. */
- REG_NOTES (mem_insn.insn)
- = alloc_EXPR_LIST (REG_INC, inc_reg, REG_NOTES (mem_insn.insn));
+ add_reg_note (mem_insn.insn, REG_INC, inc_reg);
if (dump_file)
{
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index b36c6c24bb3..ae24c0c3245 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1785,10 +1785,7 @@ add_reg_crossing_jump_notes (void)
FOR_EACH_EDGE (e, ei, bb->succs)
if ((e->flags & EDGE_CROSSING)
&& JUMP_P (BB_END (e->src)))
- REG_NOTES (BB_END (e->src)) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP,
- NULL_RTX,
- REG_NOTES (BB_END
- (e->src)));
+ add_reg_note (BB_END (e->src), REG_CROSSING_JUMP, NULL_RTX);
}
/* Hot and cold basic blocks are partitioned and put in separate
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 4fabdc915d2..5e841e067a5 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -51,7 +51,8 @@ static htab_t bitmap_desc_hash;
static hashval_t
hash_descriptor (const void *p)
{
- const struct bitmap_descriptor *const d = p;
+ const struct bitmap_descriptor *const d =
+ (const struct bitmap_descriptor *) p;
return htab_hash_pointer (d->file) + d->line;
}
struct loc
@@ -63,8 +64,9 @@ struct loc
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct bitmap_descriptor *const d = p1;
- const struct loc *const l = p2;
+ const struct bitmap_descriptor *const d =
+ (const struct bitmap_descriptor *) p1;
+ const struct loc *const l = (const struct loc *) p2;
return d->file == l->file && d->function == l->function && d->line == l->line;
}
@@ -88,7 +90,7 @@ bitmap_descriptor (const char *file, const char *function, int line)
1);
if (*slot)
return *slot;
- *slot = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct bitmap_descriptor);
(*slot)->file = file;
(*slot)->function = function;
(*slot)->line = line;
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 10af34254aa..2d6ad2a1a34 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -845,8 +845,7 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
if (JUMP_P (insn))
{
- REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
- REG_NOTES (insn));
+ add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
break;
}
else if (CALL_P (insn))
@@ -929,8 +928,7 @@ expand_builtin_nonlocal_goto (tree exp)
{
if (JUMP_P (insn))
{
- REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
- const0_rtx, REG_NOTES (insn));
+ add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
break;
}
else if (CALL_P (insn))
@@ -4625,18 +4623,22 @@ expand_builtin_next_arg (void)
static tree
stabilize_va_list (tree valist, int needs_lvalue)
{
- if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
+ tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
+
+ gcc_assert (vatype != NULL_TREE);
+
+ if (TREE_CODE (vatype) == ARRAY_TYPE)
{
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
/* For this case, the backends will be expecting a pointer to
- TREE_TYPE (va_list_type_node), but it's possible we've
- actually been given an array (an actual va_list_type_node).
+ vatype, but it's possible we've actually been given an array
+ (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ tree p1 = build_pointer_type (TREE_TYPE (vatype));
valist = build_fold_addr_expr_with_type (valist, p1);
}
}
@@ -4649,7 +4651,7 @@ stabilize_va_list (tree valist, int needs_lvalue)
if (! TREE_SIDE_EFFECTS (valist))
return valist;
- pt = build_pointer_type (va_list_type_node);
+ pt = build_pointer_type (vatype);
valist = fold_build1 (ADDR_EXPR, pt, valist);
TREE_SIDE_EFFECTS (valist) = 1;
}
@@ -4670,6 +4672,47 @@ std_build_builtin_va_list (void)
return ptr_type_node;
}
+/* The "standard" abi va_list is va_list_type_node. */
+
+tree
+std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
+{
+ return va_list_type_node;
+}
+
+/* The "standard" type of va_list is va_list_type_node. */
+
+tree
+std_canonical_va_list_type (tree type)
+{
+ tree wtype, htype;
+
+ if (INDIRECT_REF_P (type))
+ type = TREE_TYPE (type);
+ else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
+ type = TREE_TYPE (type);
+
+ wtype = va_list_type_node;
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return va_list_type_node;
+
+ return NULL_TREE;
+}
+
/* The "standard" implementation of va_start: just assign `nextarg' to
the variable. */
@@ -4825,33 +4868,18 @@ dummy_object (tree type)
enum gimplify_status
gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
- tree promoted_type, want_va_type, have_va_type;
+ tree promoted_type, have_va_type;
tree valist = TREE_OPERAND (*expr_p, 0);
tree type = TREE_TYPE (*expr_p);
tree t;
/* Verify that valist is of the proper type. */
- want_va_type = va_list_type_node;
have_va_type = TREE_TYPE (valist);
-
if (have_va_type == error_mark_node)
return GS_ERROR;
+ have_va_type = targetm.canonical_va_list_type (have_va_type);
- if (TREE_CODE (want_va_type) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (have_va_type) == ARRAY_TYPE
- || POINTER_TYPE_P (have_va_type))
- {
- want_va_type = TREE_TYPE (want_va_type);
- have_va_type = TREE_TYPE (have_va_type);
- }
- }
-
- if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
+ if (have_va_type == NULL_TREE)
{
error ("first argument to %<va_arg%> not of type %<va_list%>");
return GS_ERROR;
@@ -4859,7 +4887,7 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Generate a diagnostic for requesting data of a type that cannot
be passed through `...' due to type promotion at the call site. */
- else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
+ if ((promoted_type = lang_hooks.types.type_promotes_to (type))
!= type)
{
static bool gave_help;
@@ -4891,15 +4919,15 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
/* Make it easier for the backends by protecting the valist argument
from multiple evaluations. */
- if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
+ if (TREE_CODE (have_va_type) == ARRAY_TYPE)
{
/* For this case, the backends will be expecting a pointer to
- TREE_TYPE (va_list_type_node), but it's possible we've
- actually been given an array (an actual va_list_type_node).
+ TREE_TYPE (abi), but it's possible we've
+ actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
valist = build_fold_addr_expr_with_type (valist, p1);
}
gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
@@ -4947,9 +4975,11 @@ expand_builtin_va_copy (tree exp)
dst = stabilize_va_list (dst, 1);
src = stabilize_va_list (src, 0);
- if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
+ gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
+
+ if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
{
- t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
+ t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -4960,8 +4990,8 @@ expand_builtin_va_copy (tree exp)
/* Evaluate to pointers. */
dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
- size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
- VOIDmode, EXPAND_NORMAL);
+ size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
+ NULL_RTX, VOIDmode, EXPAND_NORMAL);
dstb = convert_memory_address (Pmode, dstb);
srcb = convert_memory_address (Pmode, srcb);
@@ -4969,10 +4999,10 @@ expand_builtin_va_copy (tree exp)
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
- set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
+ set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
srcb = gen_rtx_MEM (BLKmode, srcb);
set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
- set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
+ set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
/* Copy. */
emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
diff --git a/gcc/c-common.c b/gcc/c-common.c
index dcae16529fb..9356b8e925e 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2291,53 +2291,77 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node)
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
-#define C_COMMON_FIXED_TYPES(SAT,NAME) \
- if (type1 == SAT ## short_ ## NAME ## _type_node \
- || type1 == SAT ## unsigned_short_ ## NAME ## _type_node) \
- return unsignedp ? SAT ## unsigned_short_ ## NAME ## _type_node \
- : SAT ## short_ ## NAME ## _type_node; \
- if (type1 == SAT ## NAME ## _type_node \
- || type1 == SAT ## unsigned_ ## NAME ## _type_node) \
- return unsignedp ? SAT ## unsigned_ ## NAME ## _type_node \
- : SAT ## NAME ## _type_node; \
- if (type1 == SAT ## long_ ## NAME ## _type_node \
- || type1 == SAT ## unsigned_long_ ## NAME ## _type_node) \
- return unsignedp ? SAT ## unsigned_long_ ## NAME ## _type_node \
- : SAT ## long_ ## NAME ## _type_node; \
- if (type1 == SAT ## long_long_ ## NAME ## _type_node \
- || type1 == SAT ## unsigned_long_long_ ## NAME ## _type_node) \
- return unsignedp ? SAT ## unsigned_long_long_ ## NAME ## _type_node \
- : SAT ## long_long_ ## NAME ## _type_node;
-
-#define C_COMMON_FIXED_MODE_TYPES(SAT,NAME) \
- if (type1 == SAT ## NAME ## _type_node \
- || type1 == SAT ## u ## NAME ## _type_node) \
- return unsignedp ? SAT ## u ## NAME ## _type_node \
- : SAT ## NAME ## _type_node;
-
- C_COMMON_FIXED_TYPES (, fract);
- C_COMMON_FIXED_TYPES (sat_, fract);
- C_COMMON_FIXED_TYPES (, accum);
- C_COMMON_FIXED_TYPES (sat_, accum);
-
- C_COMMON_FIXED_MODE_TYPES (, qq);
- C_COMMON_FIXED_MODE_TYPES (, hq);
- C_COMMON_FIXED_MODE_TYPES (, sq);
- C_COMMON_FIXED_MODE_TYPES (, dq);
- C_COMMON_FIXED_MODE_TYPES (, tq);
- C_COMMON_FIXED_MODE_TYPES (sat_, qq);
- C_COMMON_FIXED_MODE_TYPES (sat_, hq);
- C_COMMON_FIXED_MODE_TYPES (sat_, sq);
- C_COMMON_FIXED_MODE_TYPES (sat_, dq);
- C_COMMON_FIXED_MODE_TYPES (sat_, tq);
- C_COMMON_FIXED_MODE_TYPES (, ha);
- C_COMMON_FIXED_MODE_TYPES (, sa);
- C_COMMON_FIXED_MODE_TYPES (, da);
- C_COMMON_FIXED_MODE_TYPES (, ta);
- C_COMMON_FIXED_MODE_TYPES (sat_, ha);
- C_COMMON_FIXED_MODE_TYPES (sat_, sa);
- C_COMMON_FIXED_MODE_TYPES (sat_, da);
- C_COMMON_FIXED_MODE_TYPES (sat_, ta);
+#define C_COMMON_FIXED_TYPES(NAME) \
+ if (type1 == short_ ## NAME ## _type_node \
+ || type1 == unsigned_short_ ## NAME ## _type_node) \
+ return unsignedp ? unsigned_short_ ## NAME ## _type_node \
+ : short_ ## NAME ## _type_node; \
+ if (type1 == NAME ## _type_node \
+ || type1 == unsigned_ ## NAME ## _type_node) \
+ return unsignedp ? unsigned_ ## NAME ## _type_node \
+ : NAME ## _type_node; \
+ if (type1 == long_ ## NAME ## _type_node \
+ || type1 == unsigned_long_ ## NAME ## _type_node) \
+ return unsignedp ? unsigned_long_ ## NAME ## _type_node \
+ : long_ ## NAME ## _type_node; \
+ if (type1 == long_long_ ## NAME ## _type_node \
+ || type1 == unsigned_long_long_ ## NAME ## _type_node) \
+ return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \
+ : long_long_ ## NAME ## _type_node;
+
+#define C_COMMON_FIXED_MODE_TYPES(NAME) \
+ if (type1 == NAME ## _type_node \
+ || type1 == u ## NAME ## _type_node) \
+ return unsignedp ? u ## NAME ## _type_node \
+ : NAME ## _type_node;
+
+#define C_COMMON_FIXED_TYPES_SAT(NAME) \
+ if (type1 == sat_ ## short_ ## NAME ## _type_node \
+ || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \
+ return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \
+ : sat_ ## short_ ## NAME ## _type_node; \
+ if (type1 == sat_ ## NAME ## _type_node \
+ || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \
+ return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \
+ : sat_ ## NAME ## _type_node; \
+ if (type1 == sat_ ## long_ ## NAME ## _type_node \
+ || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \
+ return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \
+ : sat_ ## long_ ## NAME ## _type_node; \
+ if (type1 == sat_ ## long_long_ ## NAME ## _type_node \
+ || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \
+ return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \
+ : sat_ ## long_long_ ## NAME ## _type_node;
+
+#define C_COMMON_FIXED_MODE_TYPES_SAT(NAME) \
+ if (type1 == sat_ ## NAME ## _type_node \
+ || type1 == sat_ ## u ## NAME ## _type_node) \
+ return unsignedp ? sat_ ## u ## NAME ## _type_node \
+ : sat_ ## NAME ## _type_node;
+
+ C_COMMON_FIXED_TYPES (fract);
+ C_COMMON_FIXED_TYPES_SAT (fract);
+ C_COMMON_FIXED_TYPES (accum);
+ C_COMMON_FIXED_TYPES_SAT (accum);
+
+ C_COMMON_FIXED_MODE_TYPES (qq);
+ C_COMMON_FIXED_MODE_TYPES (hq);
+ C_COMMON_FIXED_MODE_TYPES (sq);
+ C_COMMON_FIXED_MODE_TYPES (dq);
+ C_COMMON_FIXED_MODE_TYPES (tq);
+ C_COMMON_FIXED_MODE_TYPES_SAT (qq);
+ C_COMMON_FIXED_MODE_TYPES_SAT (hq);
+ C_COMMON_FIXED_MODE_TYPES_SAT (sq);
+ C_COMMON_FIXED_MODE_TYPES_SAT (dq);
+ C_COMMON_FIXED_MODE_TYPES_SAT (tq);
+ C_COMMON_FIXED_MODE_TYPES (ha);
+ C_COMMON_FIXED_MODE_TYPES (sa);
+ C_COMMON_FIXED_MODE_TYPES (da);
+ C_COMMON_FIXED_MODE_TYPES (ta);
+ C_COMMON_FIXED_MODE_TYPES_SAT (ha);
+ C_COMMON_FIXED_MODE_TYPES_SAT (sa);
+ C_COMMON_FIXED_MODE_TYPES_SAT (da);
+ C_COMMON_FIXED_MODE_TYPES_SAT (ta);
/* For ENUMERAL_TYPEs in C++, must check the mode of the types, not
the precision; they have precision set to match their range, but
@@ -3988,6 +4012,20 @@ c_common_nodes_and_builtins (void)
lang_hooks.decls.pushdecl
(build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
va_list_type_node));
+#ifdef TARGET_ENUM_VA_LIST
+ {
+ int l;
+ const char *pname;
+ tree ptype;
+ for (l = 0; TARGET_ENUM_VA_LIST (l, &pname, &ptype); ++l)
+ {
+ lang_hooks.decls.pushdecl
+ (build_decl (TYPE_DECL, get_identifier (pname),
+ ptype));
+
+ }
+ }
+#endif
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
diff --git a/gcc/calls.c b/gcc/calls.c
index 79dc47b98fa..a4470fa1477 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -377,8 +377,7 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
/* If this call can't throw, attach a REG_EH_REGION reg note to that
effect. */
if (ecf_flags & ECF_NOTHROW)
- REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
- REG_NOTES (call_insn));
+ add_reg_note (call_insn, REG_EH_REGION, const0_rtx);
else
{
int rn = lookup_stmt_eh_region (fntree);
@@ -386,18 +385,15 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
/* If rn < 0, then either (1) tree-ssa not used or (2) doesn't
throw, which we already took care of. */
if (rn > 0)
- REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (rn),
- REG_NOTES (call_insn));
+ add_reg_note (call_insn, REG_EH_REGION, GEN_INT (rn));
}
if (ecf_flags & ECF_NORETURN)
- REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_NORETURN, const0_rtx,
- REG_NOTES (call_insn));
+ add_reg_note (call_insn, REG_NORETURN, const0_rtx);
if (ecf_flags & ECF_RETURNS_TWICE)
{
- REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_SETJMP, const0_rtx,
- REG_NOTES (call_insn));
+ add_reg_note (call_insn, REG_SETJMP, const0_rtx);
cfun->calls_setjmp = 1;
}
@@ -2814,8 +2810,7 @@ expand_call (tree exp, rtx target, int ignore)
/* The return value from a malloc-like function can not alias
anything else. */
last = get_last_insn ();
- REG_NOTES (last) =
- gen_rtx_EXPR_LIST (REG_NOALIAS, temp, REG_NOTES (last));
+ add_reg_note (last, REG_NOALIAS, temp);
/* Write out the sequence. */
insns = get_insns ();
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index afa3e123106..6a48e1632d7 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -67,18 +67,14 @@ add_reg_br_prob_note (rtx last, int probability)
|| NEXT_INSN (NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))))
goto failed;
gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
- REG_NOTES (last)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (REG_BR_PROB_BASE - probability),
- REG_NOTES (last));
+ add_reg_note (last, REG_BR_PROB,
+ GEN_INT (REG_BR_PROB_BASE - probability));
return;
}
if (!last || !JUMP_P (last) || !any_condjump_p (last))
goto failed;
gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
- REG_NOTES (last)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (probability), REG_NOTES (last));
+ add_reg_note (last, REG_BR_PROB, GEN_INT (probability));
return;
failed:
if (dump_file)
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 623e5bdd911..e4049d66465 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -855,8 +855,7 @@ fixup_reorder_chain (void)
&& JUMP_P (BB_END (bb))
&& !any_condjump_p (BB_END (bb))
&& (EDGE_SUCC (bb, 0)->flags & EDGE_CROSSING))
- REG_NOTES (BB_END (bb)) = gen_rtx_EXPR_LIST
- (REG_CROSSING_JUMP, NULL_RTX, REG_NOTES (BB_END (bb)));
+ add_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX);
}
}
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 8ce39006cf3..240455bca9d 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1111,11 +1111,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target)
&& JUMP_P (BB_END (jump_block))
&& !any_condjump_p (BB_END (jump_block))
&& (EDGE_SUCC (jump_block, 0)->flags & EDGE_CROSSING))
- REG_NOTES (BB_END (jump_block)) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP,
- NULL_RTX,
- REG_NOTES
- (BB_END
- (jump_block)));
+ add_reg_note (BB_END (jump_block), REG_CROSSING_JUMP, NULL_RTX);
/* Wire edge in. */
new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
@@ -1418,8 +1414,7 @@ commit_one_edge_insertion (edge e)
if (JUMP_P (BB_END (bb))
&& !any_condjump_p (BB_END (bb))
&& (single_succ_edge (bb)->flags & EDGE_CROSSING))
- REG_NOTES (BB_END (bb)) = gen_rtx_EXPR_LIST
- (REG_CROSSING_JUMP, NULL_RTX, REG_NOTES (BB_END (bb)));
+ add_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX);
}
}
}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 17ee8f0a63a..6a80bbed095 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -109,6 +109,9 @@ int cgraph_n_nodes;
/* Maximal uid used in cgraph nodes. */
int cgraph_max_uid;
+/* Maximal uid used in cgraph edges. */
+int cgraph_edge_max_uid;
+
/* Maximal pid used for profiling */
int cgraph_max_pid;
@@ -132,6 +135,206 @@ static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
them, to support -fno-toplevel-reorder. */
int cgraph_order;
+/* List of hooks trigerred on cgraph_edge events. */
+struct cgraph_edge_hook_list {
+ cgraph_edge_hook hook;
+ void *data;
+ struct cgraph_edge_hook_list *next;
+};
+
+/* List of hooks trigerred on cgraph_node events. */
+struct cgraph_node_hook_list {
+ cgraph_node_hook hook;
+ void *data;
+ struct cgraph_node_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_edges. */
+struct cgraph_2edge_hook_list {
+ cgraph_2edge_hook hook;
+ void *data;
+ struct cgraph_2edge_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_nodes. */
+struct cgraph_2node_hook_list {
+ cgraph_2node_hook hook;
+ void *data;
+ struct cgraph_2node_hook_list *next;
+};
+
+/* List of hooks triggered when an edge is removed. */
+struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook;
+/* List of hooks triggered when a node is removed. */
+struct cgraph_node_hook_list *first_cgraph_node_removal_hook;
+/* List of hooks triggered when an edge is duplicated. */
+struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook;
+/* List of hooks triggered when a node is duplicated. */
+struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook;
+
+
+/* Register HOOK to be called with DATA on each removed edge. */
+struct cgraph_edge_hook_list *
+cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
+{
+ struct cgraph_edge_hook_list *entry;
+ struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+ entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing edges. */
+void
+cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
+{
+ struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all edge removal hooks. */
+static void
+cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
+{
+ struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook;
+ while (entry)
+ {
+ entry->hook (e, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each removed node. */
+struct cgraph_node_hook_list *
+cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
+{
+ struct cgraph_node_hook_list *entry;
+ struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+ entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing nodes. */
+void
+cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
+{
+ struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all node removal hooks. */
+static void
+cgraph_call_node_removal_hooks (struct cgraph_node *node)
+{
+ struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook;
+ while (entry)
+ {
+ entry->hook (node, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each duplicated edge. */
+struct cgraph_2edge_hook_list *
+cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
+{
+ struct cgraph_2edge_hook_list *entry;
+ struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+ entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating edges. */
+void
+cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
+{
+ struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all edge duplication hooks. */
+static void
+cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
+ struct cgraph_edge *cs2)
+{
+ struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook;
+ while (entry)
+ {
+ entry->hook (cs1, cs2, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each duplicated node. */
+struct cgraph_2node_hook_list *
+cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
+{
+ struct cgraph_2node_hook_list *entry;
+ struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+ entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating nodes. */
+void
+cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
+{
+ struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all node duplication hooks. */
+static void
+cgraph_call_node_duplication_hooks (struct cgraph_node *node1,
+ struct cgraph_node *node2)
+{
+ struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook;
+ while (entry)
+ {
+ entry->hook (node1, node2, entry->data);
+ entry = entry->next;
+ }
+}
+
/* Returns a hash code for P. */
static hashval_t
@@ -365,6 +568,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (freq >= 0);
gcc_assert (freq <= CGRAPH_FREQ_MAX);
edge->loop_nest = nest;
+ edge->uid = cgraph_edge_max_uid++;
if (caller->call_site_hash)
{
void **slot;
@@ -414,6 +618,7 @@ cgraph_edge_remove_caller (struct cgraph_edge *e)
void
cgraph_remove_edge (struct cgraph_edge *e)
{
+ cgraph_call_edge_removal_hooks (e);
/* Remove from callers list of the callee. */
cgraph_edge_remove_callee (e);
@@ -495,7 +700,10 @@ cgraph_node_remove_callees (struct cgraph_node *node)
the callees. The callee list of the node can be zapped with one
assignment. */
for (e = node->callees; e; e = e->next_callee)
- cgraph_edge_remove_callee (e);
+ {
+ cgraph_call_edge_removal_hooks (e);
+ cgraph_edge_remove_callee (e);
+ }
node->callees = NULL;
if (node->call_site_hash)
{
@@ -515,7 +723,10 @@ cgraph_node_remove_callers (struct cgraph_node *node)
the callers. The caller list of the node can be zapped with one
assignment. */
for (e = node->callers; e; e = e->next_caller)
- cgraph_edge_remove_caller (e);
+ {
+ cgraph_call_edge_removal_hooks (e);
+ cgraph_edge_remove_caller (e);
+ }
node->callers = NULL;
}
@@ -549,6 +760,7 @@ cgraph_remove_node (struct cgraph_node *node)
void **slot;
bool kill_body = false;
+ cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node);
/* Incremental inlining access removed nodes stored in the postorder list.
@@ -891,6 +1103,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
if (e->count < 0)
e->count = 0;
}
+ cgraph_call_edge_duplication_hooks (e, new);
return new;
}
@@ -942,6 +1155,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_ne
if (new->next_clone)
new->next_clone->prev_clone = new;
+ cgraph_call_node_duplication_hooks (n, new);
return new;
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index dda2a1891f5..ee79c9200f1 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -209,6 +209,8 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call
int frequency;
/* Depth of loop nest, 1 means no loop nest. */
int loop_nest;
+ /* Unique id of the edge. */
+ int uid;
};
#define CGRAPH_FREQ_BASE 1000
@@ -266,6 +268,7 @@ struct cgraph_asm_node GTY(())
extern GTY(()) struct cgraph_node *cgraph_nodes;
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
+extern GTY(()) int cgraph_edge_max_uid;
extern GTY(()) int cgraph_max_pid;
extern bool cgraph_global_info_ready;
enum cgraph_state
@@ -351,6 +354,26 @@ struct cgraph_node *save_inline_function_body (struct cgraph_node *);
void record_references_in_initializer (tree);
bool cgraph_process_new_functions (void);
+typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
+typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
+typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
+ void *);
+typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *,
+ void *);
+struct cgraph_edge_hook_list;
+struct cgraph_node_hook_list;
+struct cgraph_2edge_hook_list;
+struct cgraph_2node_hook_list;
+struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
+void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
+struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
+ void *);
+void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *);
+struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
+void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
+struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
+void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
+
/* In cgraphbuild.c */
unsigned int rebuild_cgraph_edges (void);
diff --git a/gcc/combine.c b/gcc/combine.c
index 59586a8bf18..a6cff36480f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -12149,10 +12149,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx to_insn,
for (i = deadregno; i < deadend; i++)
if (i < regno || i >= ourend)
- REG_NOTES (where_dead)
- = gen_rtx_EXPR_LIST (REG_DEAD,
- regno_reg_rtx[i],
- REG_NOTES (where_dead));
+ add_reg_note (where_dead, REG_DEAD, regno_reg_rtx[i]);
}
/* If we didn't find any note, or if we found a REG_DEAD note that
@@ -12774,9 +12771,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
|| reg_bitfield_target_p (piece,
PATTERN (tem)))
{
- REG_NOTES (tem)
- = gen_rtx_EXPR_LIST (REG_UNUSED, piece,
- REG_NOTES (tem));
+ add_reg_note (tem, REG_UNUSED, piece);
break;
}
}
diff --git a/gcc/config.gcc b/gcc/config.gcc
index f4f171e0c02..e73223b9b32 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -281,14 +281,14 @@ i[34567]86-*-*)
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h"
+ wmmintrin.h cross-stdarg.h"
;;
x86_64-*-*)
cpu_type=i386
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h"
+ wmmintrin.h cross-stdarg.h"
need_64bit_hwint=yes
;;
ia64-*-*)
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
# then this file using that to set --with-cpu=i386 which has no -m64
# support.
with_cpu=${with_cpu:-generic}
- tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+ tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
;;
x86_64-*-darwin*)
with_cpu=${with_cpu:-generic}
- tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+ tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
tm_file="${tm_file} ${cpu_type}/darwin64.h"
;;
i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu)
if test x$enable_targets = xall; then
tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
tm_defines="${tm_defines} TARGET_BI_ARCH=1"
- tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+ tmake_file="${tmake_file} i386/t-linux64"
need_64bit_hwint=yes
case X"${with_cpu}" in
Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
esac
- tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+ tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
;;
i[34567]86-*-gnu*)
;;
@@ -1459,9 +1459,11 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
# aka the GNU/Linux C library 6.
default_m68k_cpu=68020
default_cf_cpu=5475
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h"
+ with_arch=${with_arch:-m68k}
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h ./sysroot-suffix.h"
extra_options="${extra_options} m68k/ieee.opt"
tm_defines="${tm_defines} MOTOROLA=1"
+ tmake_file="${tmake_file} m68k/t-floatlib m68k/t-linux m68k/t-mlibs"
# if not configured with --enable-sjlj-exceptions, bump the
# libgcc version number
if test x$sjlj != x1; then
@@ -2973,6 +2975,13 @@ case ${target} in
fi
;;
+ i[34567]86-*-darwin* | x86_64-*-darwin*)
+ tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+ ;;
+ i[34567]86-*-linux* | x86_64-*-linux*)
+ tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+ ;;
+
mips*-*-*)
if test x$gnu_ld = xyes
then
diff --git a/gcc/config.in b/gcc/config.in
index 5e584c11fd7..5cf01cc04d3 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -192,12 +192,6 @@
#endif
-/* Define to 1 if you have the `alphasort' function. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_ALPHASORT
-#endif
-
-
/* Define if your assembler supports cmpb. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_CMPB
@@ -1152,12 +1146,6 @@
#endif
-/* Define to 1 if you have the `scandir' function. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_SCANDIR
-#endif
-
-
/* Define to 1 if you have the `setlocale' function. */
#ifndef USED_FOR_TARGET
#undef HAVE_SETLOCALE
@@ -1548,6 +1536,12 @@
#endif
+/* Define to `char *' if <sys/types.h> does not define. */
+#ifndef USED_FOR_TARGET
+#undef caddr_t
+#endif
+
+
/* Define to `int' if <sys/types.h> doesn't define. */
#ifndef USED_FOR_TARGET
#undef gid_t
diff --git a/gcc/config/alpha/vms_tramp.asm b/gcc/config/alpha/vms_tramp.asm
index d197521a887..66ab2f0de59 100644
--- a/gcc/config/alpha/vms_tramp.asm
+++ b/gcc/config/alpha/vms_tramp.asm
@@ -33,7 +33,6 @@ Boston, MA 02110-1301, USA. */
.set noreorder
.set volatile
.set noat
- .file 1 "vms_tramp.asm"
.text
.align 3
.globl __tramp
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index cb46a8edc90..59c1bf70e5d 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -191,9 +191,6 @@
}
#endif
-/* Arm Assembler barfs on dollars. */
-#define DOLLARS_IN_IDENTIFIERS 0
-
#ifndef NO_DOLLAR_IN_LABEL
#define NO_DOLLAR_IN_LABEL 1
#endif
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index fa3d06dcd75..0ce531bb802 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -15094,6 +15094,24 @@ arm_init_neon_builtins (void)
TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE;
layout_type (neon_float_type_node);
+ /* Define typedefs which exactly correspond to the modes we are basing vector
+ types on. If you change these names you'll need to change
+ the table used by arm_mangle_type too. */
+ (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
+ "__builtin_neon_qi");
+ (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
+ "__builtin_neon_hi");
+ (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
+ "__builtin_neon_si");
+ (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
+ "__builtin_neon_sf");
+ (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
+ "__builtin_neon_di");
+ (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
+ "__builtin_neon_poly8");
+ (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
+ "__builtin_neon_poly16");
+
intQI_pointer_node = build_pointer_type (neon_intQI_type_node);
intHI_pointer_node = build_pointer_type (neon_intHI_type_node);
intSI_pointer_node = build_pointer_type (neon_intSI_type_node);
@@ -15146,12 +15164,32 @@ arm_init_neon_builtins (void)
intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode));
intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode));
+ (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
+ "__builtin_neon_uqi");
+ (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
+ "__builtin_neon_uhi");
+ (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
+ "__builtin_neon_usi");
+ (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
+ "__builtin_neon_udi");
+
/* Opaque integer types for structures of vectors. */
intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode));
intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode));
intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode));
intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode));
+ (*lang_hooks.types.register_builtin_type) (intTI_type_node,
+ "__builtin_neon_ti");
+ (*lang_hooks.types.register_builtin_type) (intEI_type_node,
+ "__builtin_neon_ei");
+ (*lang_hooks.types.register_builtin_type) (intOI_type_node,
+ "__builtin_neon_oi");
+ (*lang_hooks.types.register_builtin_type) (intCI_type_node,
+ "__builtin_neon_ci");
+ (*lang_hooks.types.register_builtin_type) (intXI_type_node,
+ "__builtin_neon_xi");
+
/* Pointers to vector types. */
V8QI_pointer_node = build_pointer_type (V8QI_type_node);
V4HI_pointer_node = build_pointer_type (V4HI_type_node);
@@ -15195,44 +15233,6 @@ arm_init_neon_builtins (void)
build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node,
V2DI_type_node, NULL);
- /* Define typedefs which exactly correspond to the modes we are basing vector
- types on. If you change these names you'll need to change
- the table used by arm_mangle_type too. */
- (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
- "__builtin_neon_qi");
- (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
- "__builtin_neon_hi");
- (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
- "__builtin_neon_si");
- (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
- "__builtin_neon_sf");
- (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
- "__builtin_neon_di");
-
- (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
- "__builtin_neon_poly8");
- (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
- "__builtin_neon_poly16");
- (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
- "__builtin_neon_uqi");
- (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
- "__builtin_neon_uhi");
- (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
- "__builtin_neon_usi");
- (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
- "__builtin_neon_udi");
-
- (*lang_hooks.types.register_builtin_type) (intTI_type_node,
- "__builtin_neon_ti");
- (*lang_hooks.types.register_builtin_type) (intEI_type_node,
- "__builtin_neon_ei");
- (*lang_hooks.types.register_builtin_type) (intOI_type_node,
- "__builtin_neon_oi");
- (*lang_hooks.types.register_builtin_type) (intCI_type_node,
- "__builtin_neon_ci");
- (*lang_hooks.types.register_builtin_type) (intXI_type_node,
- "__builtin_neon_xi");
-
dreg_types[0] = V8QI_type_node;
dreg_types[1] = V4HI_type_node;
dreg_types[2] = V2SI_type_node;
diff --git a/gcc/config/arm/crti.asm b/gcc/config/arm/crti.asm
index 6f0acd199e0..c77651a5191 100644
--- a/gcc/config/arm/crti.asm
+++ b/gcc/config/arm/crti.asm
@@ -64,8 +64,6 @@
#endif
.endm
- .file "crti.asm"
-
.section ".init"
.align 2
.global _init
diff --git a/gcc/config/arm/crtn.asm b/gcc/config/arm/crtn.asm
index 36c417d7dde..34b95d943d9 100644
--- a/gcc/config/arm/crtn.asm
+++ b/gcc/config/arm/crtn.asm
@@ -72,8 +72,6 @@
.endm
- .file "crtn.asm"
-
.section ".init"
;;
FUNC_END
diff --git a/gcc/config/bfin/crti.s b/gcc/config/bfin/crti.s
index c9753599986..8ddedcbfd18 100644
--- a/gcc/config/bfin/crti.s
+++ b/gcc/config/bfin/crti.s
@@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
* sections. It is linked in before crtbegin.o.
*/
- .file "crti.o"
.ident "GNU C crti.o"
.section .init
diff --git a/gcc/config/bfin/crtlibid.s b/gcc/config/bfin/crtlibid.s
index f80adfe7ec9..d4f7ee5e693 100644
--- a/gcc/config/bfin/crtlibid.s
+++ b/gcc/config/bfin/crtlibid.s
@@ -25,7 +25,6 @@ Boston, MA 02110-1301, USA. */
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
- .file "crtlibid.o"
.ident "GNU C crtlibid.o"
.weak _current_shared_library_p5_offset_
diff --git a/gcc/config/bfin/crtn.s b/gcc/config/bfin/crtn.s
index 06af2bea9e7..aff49b7984a 100644
--- a/gcc/config/bfin/crtn.s
+++ b/gcc/config/bfin/crtn.s
@@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
* It is linked in after all other files.
*/
- .file "crtn.o"
.ident "GNU C crtn.o"
.section .init
diff --git a/gcc/config/fr30/crti.asm b/gcc/config/fr30/crti.asm
index cd2bd82c0c3..acc8e07e7c4 100644
--- a/gcc/config/fr30/crti.asm
+++ b/gcc/config/fr30/crti.asm
@@ -37,8 +37,6 @@
# .init sections. Users may put any desired instructions in those
# sections.
- .file "crti.asm"
-
.section ".init"
.global _init
.type _init,#function
diff --git a/gcc/config/fr30/crtn.asm b/gcc/config/fr30/crtn.asm
index ad175b2eb75..e1b308f4da7 100644
--- a/gcc/config/fr30/crtn.asm
+++ b/gcc/config/fr30/crtn.asm
@@ -37,8 +37,6 @@
# fact return. Users may put any desired instructions in those sections.
# This file is the last thing linked into any executable.
- .file "crtn.s"
-
.section ".init"
.align 4
diff --git a/gcc/config/frv/lib1funcs.asm b/gcc/config/frv/lib1funcs.asm
index af02459d2aa..ddd3fe9d5ef 100644
--- a/gcc/config/frv/lib1funcs.asm
+++ b/gcc/config/frv/lib1funcs.asm
@@ -32,7 +32,6 @@
#ifdef L_cmpll
/* icc0 = __cmpll (long long a, long long b) */
- .file "_cmpll.s"
.globl EXT(__cmpll)
.type EXT(__cmpll),@function
.text
@@ -51,7 +50,6 @@ EXT(__cmpll):
/* Note, because this function returns the result in ICC0, it means it can't
handle NaNs. */
- .file "_cmpf.s"
.globl EXT(__cmpf)
.type EXT(__cmpf),@function
.text
@@ -91,7 +89,6 @@ EXT(__cmpf):
/* Note, because this function returns the result in ICC0, it means it can't
handle NaNs. */
- .file "_cmpd.s"
.globl EXT(__cmpd)
.type EXT(__cmpd),@function
.text
@@ -118,7 +115,6 @@ EXT(__cmpd):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_addll.s"
.globl EXT(__addll)
.type EXT(__addll),@function
.text
@@ -136,7 +132,6 @@ EXT(__addll):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_subll.s"
.globl EXT(__subll)
.type EXT(__subll),@function
.text
@@ -154,7 +149,6 @@ EXT(__subll):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_andll.s"
.globl EXT(__andll)
.type EXT(__andll),@function
.text
@@ -172,7 +166,6 @@ EXT(__andll):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_orll.s"
.globl EXT(__orll)
.type EXT(__orll),@function
.text
@@ -190,7 +183,6 @@ EXT(__orll):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_xorll.s"
.globl EXT(__xorll)
.type EXT(__xorll),@function
.text
@@ -208,7 +200,6 @@ EXT(__xorll):
/* Note, gcc will never call this function, but it is present in case an
ABI program calls it. */
- .file "_notll.s"
.globl EXT(__notll)
.type EXT(__notll),@function
.text
@@ -241,7 +232,6 @@ EXT(__notll):
* }
*/
- .file "_cmov.s"
.globl EXT(__cmov)
.type EXT(__cmov),@function
.text
diff --git a/gcc/config/host-solaris.c b/gcc/config/host-solaris.c
index 9a471b49f4c..bde01db9813 100644
--- a/gcc/config/host-solaris.c
+++ b/gcc/config/host-solaris.c
@@ -42,7 +42,7 @@ sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
if (size == 0)
return -1;
- addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
/* Solaris isn't good about honoring the mmap START parameter
@@ -55,18 +55,18 @@ sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
size_t i;
if (addr != (void *) MAP_FAILED)
- munmap (addr, size);
+ munmap ((caddr_t) addr, size);
errno = 0;
for (i = 0; i < size; i += page_size)
- if (mincore ((char *)base + i, page_size, (void *)&one_byte) == -1
+ if (mincore ((char *)base + i, page_size, (char *) &one_byte) == -1
&& errno == ENOMEM)
continue; /* The page is not mapped. */
else
break;
if (i >= size)
- addr = mmap (base, size,
+ addr = mmap ((caddr_t) base, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fd, offset);
}
diff --git a/gcc/config/i386/cross-stdarg.h b/gcc/config/i386/cross-stdarg.h
new file mode 100644
index 00000000000..98ac1ecd5cc
--- /dev/null
+++ b/gcc/config/i386/cross-stdarg.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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. */
+
+/* As a special exception, if you include this header file into source
+ files compiled by GCC, this header file does not by itself cause
+ the resulting executable to be covered by the GNU General Public
+ License. This exception does not however invalidate any other
+ reasons why the executable file might be covered by the GNU General
+ Public License. */
+
+#ifndef __CROSS_STDARG_H_INCLUDED
+#define __CROSS_STDARG_H_INCLUDED
+
+/* Make sure that for non x64 targets cross builtins are defined. */
+#ifndef __x86_64__
+/* Call abi ms_abi. */
+#define __builtin_ms_va_list __builtin_va_list
+#define __builtin_ms_va_copy __builtin_va_copy
+#define __builtin_ms_va_start __builtin_va_start
+#define __builtin_ms_va_end __builtin_va_end
+
+/* Call abi sysv_abi. */
+#define __builtin_sysv_va_list __builtin_va_list
+#define __builtin_sysv_va_copy __builtin_va_copy
+#define __builtin_sysv_va_start __builtin_va_start
+#define __builtin_sysv_va_end __builtin_va_end
+#endif
+
+#define __ms_va_copy(__d,__s) __builtin_ms_va_copy(__d,__s)
+#define __ms_va_start(__v,__l) __builtin_ms_va_start(__v,__l)
+#define __ms_va_arg(__v,__l) __builtin_va_arg(__v,__l)
+#define __ms_va_end(__v) __builtin_ms_va_end(__v)
+
+#define __sysv_va_copy(__d,__s) __builtin_sysv_va_copy(__d,__s)
+#define __sysv_va_start(__v,__l) __builtin_sysv_va_start(__v,__l)
+#define __sysv_va_arg(__v,__l) __builtin_va_arg(__v,__l)
+#define __sysv_va_end(__v) __builtin_sysv_va_end(__v)
+
+#ifndef __GNUC_SYSV_VA_LIST
+#define __GNUC_SYSV_VA_LIST
+ typedef __builtin_sysv_va_list __gnuc_sysv_va_list;
+#endif
+
+#ifndef _SYSV_VA_LIST_DEFINED
+#define _SYSV_VA_LIST_DEFINED
+ typedef __gnuc_sysv_va_list sysv_va_list;
+#endif
+
+#ifndef __GNUC_MS_VA_LIST
+#define __GNUC_MS_VA_LIST
+ typedef __builtin_ms_va_list __gnuc_ms_va_list;
+#endif
+
+#ifndef _MS_VA_LIST_DEFINED
+#define _MS_VA_LIST_DEFINED
+ typedef __gnuc_ms_va_list ms_va_list;
+#endif
+
+#endif /* __CROSS_STDARG_H_INCLUDED */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 8d0772dbe8b..9719ec2886f 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -141,6 +141,9 @@ extern int ix86_cfun_abi (void);
extern int ix86_function_abi (const_tree);
extern int ix86_function_type_abi (const_tree);
extern void ix86_call_abi_override (const_tree);
+extern tree ix86_fn_abi_va_list (tree);
+extern tree ix86_canonical_va_list_type (tree);
+extern int ix86_enum_va_list (int, const char **, tree *);
extern int ix86_reg_parm_stack_space (const_tree);
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5a2c0c870a7..26999e71d5b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1716,6 +1716,10 @@ unsigned int ix86_preferred_stack_boundary;
/* Values 1-5: see jump.c */
int ix86_branch_cost;
+/* Calling abi specific va_list type nodes. */
+static GTY(()) tree sysv_va_list_type_node;
+static GTY(()) tree ms_va_list_type_node;
+
/* Variables which are this size or smaller are put in the data/bss
or ldata/lbss sections. */
@@ -2774,9 +2778,8 @@ override_options (void)
set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
/* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
- can be optimized to ap = __builtin_next_arg (0).
- For abi switching it should be corrected. */
- if (!TARGET_64BIT || DEFAULT_ABI == MS_ABI)
+ can be optimized to ap = __builtin_next_arg (0). */
+ if (!TARGET_64BIT)
targetm.expand_builtin_va_start = NULL;
if (TARGET_64BIT)
@@ -3201,7 +3204,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
if (TARGET_64BIT)
{
/* Do not warn when emulating the MS ABI. */
- if (TREE_CODE (*node) != FUNCTION_TYPE || !ix86_function_type_abi (*node))
+ if (TREE_CODE (*node) != FUNCTION_TYPE || ix86_function_type_abi (*node)!=MS_ABI)
warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
@@ -3604,9 +3607,6 @@ ix86_function_type_abi (const_tree fntype)
else
abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
- if (DEFAULT_ABI == MS_ABI && abi == SYSV_ABI)
- sorry ("using sysv calling convention on target w64 is not supported");
-
return abi;
}
return DEFAULT_ABI;
@@ -4746,7 +4746,8 @@ contains_aligned_value_p (tree type)
enum machine_mode mode = TYPE_MODE (type);
if (((TARGET_SSE && SSE_REG_MODE_P (mode))
|| mode == TDmode
- || mode == TFmode)
+ || mode == TFmode
+ || mode == TCmode)
&& (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
return true;
if (TYPE_ALIGN (type) < 128)
@@ -5173,13 +5174,16 @@ ix86_struct_value_rtx (tree type, int incoming ATTRIBUTE_UNUSED)
/* Create the va_list data type. */
+/* Returns the calling convention specific va_list date type.
+ The argument ABI can be DEFAULT_ABI, MS_ABI, or SYSV_ABI. */
+
static tree
-ix86_build_builtin_va_list (void)
+ix86_build_builtin_va_list_abi (enum calling_abi abi)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
/* For i386 we use plain pointer to argument area. */
- if (!TARGET_64BIT || ix86_cfun_abi () == MS_ABI)
+ if (!TARGET_64BIT || abi == MS_ABI)
return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -5215,6 +5219,51 @@ ix86_build_builtin_va_list (void)
return build_array_type (record, build_index_type (size_zero_node));
}
+/* Setup the builtin va_list data type and for 64-bit the additional
+ calling convention specific va_list data types. */
+
+static tree
+ix86_build_builtin_va_list (void)
+{
+ tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
+
+ /* Initialize abi specific va_list builtin types. */
+ if (TARGET_64BIT)
+ {
+ tree t;
+ if (DEFAULT_ABI == MS_ABI)
+ {
+ t = ix86_build_builtin_va_list_abi (SYSV_ABI);
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ sysv_va_list_type_node = t;
+ }
+ else
+ {
+ t = ret;
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ sysv_va_list_type_node = t;
+ }
+ if (DEFAULT_ABI != MS_ABI)
+ {
+ t = ix86_build_builtin_va_list_abi (MS_ABI);
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ ms_va_list_type_node = t;
+ }
+ else
+ {
+ t = ret;
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ ms_va_list_type_node = t;
+ }
+ }
+
+ return ret;
+}
+
/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
static void
@@ -5359,6 +5408,21 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
setup_incoming_varargs_64 (&next_cum);
}
+/* Checks if TYPE is of kind va_list char *. */
+
+static bool
+is_va_list_char_pointer (tree type)
+{
+ tree canonic;
+
+ /* For 32-bit it is always true. */
+ if (!TARGET_64BIT)
+ return true;
+ canonic = ix86_canonical_va_list_type (type);
+ return (canonic == ms_va_list_type_node
+ || (DEFAULT_ABI == MS_ABI && canonic == va_list_type_node));
+}
+
/* Implement va_start. */
static void
@@ -5370,13 +5434,13 @@ ix86_va_start (tree valist, rtx nextarg)
tree type;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
+ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
{
std_expand_builtin_va_start (valist, nextarg);
return;
}
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
@@ -5449,10 +5513,10 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
enum machine_mode nat_mode;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
+ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
@@ -17103,7 +17167,8 @@ ix86_data_alignment (tree type, int align)
if (TYPE_MODE (type) == DCmode && align < 64)
return 64;
- if (TYPE_MODE (type) == XCmode && align < 128)
+ if ((TYPE_MODE (type) == XCmode
+ || TYPE_MODE (type) == TCmode) && align < 128)
return 128;
}
else if ((TREE_CODE (type) == RECORD_TYPE
@@ -17169,7 +17234,8 @@ ix86_local_alignment (tree type, enum machine_mode mode,
{
if (TYPE_MODE (type) == DCmode && align < 64)
return 64;
- if (TYPE_MODE (type) == XCmode && align < 128)
+ if ((TYPE_MODE (type) == XCmode
+ || TYPE_MODE (type) == TCmode) && align < 128)
return 128;
}
else if ((TREE_CODE (type) == RECORD_TYPE
@@ -20213,6 +20279,55 @@ ix86_init_mmx_sse_builtins (void)
}
}
+/* Internal method for ix86_init_builtins. */
+
+static void
+ix86_init_builtins_va_builtins_abi (void)
+{
+ tree ms_va_ref, sysv_va_ref;
+ tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
+ tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
+ tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
+ tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
+
+ if (!TARGET_64BIT)
+ return;
+ fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
+ fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
+ ms_va_ref = build_reference_type (ms_va_list_type_node);
+ sysv_va_ref =
+ build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
+
+ fnvoid_va_end_ms =
+ build_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
+ fnvoid_va_start_ms =
+ build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
+ fnvoid_va_end_sysv =
+ build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
+ fnvoid_va_start_sysv =
+ build_varargs_function_type_list (void_type_node, sysv_va_ref,
+ NULL_TREE);
+ fnvoid_va_copy_ms =
+ build_function_type_list (void_type_node, ms_va_ref, ms_va_list_type_node,
+ NULL_TREE);
+ fnvoid_va_copy_sysv =
+ build_function_type_list (void_type_node, sysv_va_ref,
+ sysv_va_ref, NULL_TREE);
+
+ add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
+ BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
+ BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
+ BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
+ BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+ add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
+ BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+ add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
+ BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+}
+
static void
ix86_init_builtins (void)
{
@@ -20247,19 +20362,31 @@ ix86_init_builtins (void)
NULL, NULL_TREE);
ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
+ /* We will expand them to normal call if SSE2 isn't available since
+ they are used by libgcc. */
ftype = build_function_type_list (float128_type_node,
float128_type_node,
NULL_TREE);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+ decl = add_builtin_function ("__builtin_fabsq", ftype,
+ IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+ "__fabstf2", NULL_TREE);
+ ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+ TREE_READONLY (decl) = 1;
ftype = build_function_type_list (float128_type_node,
float128_type_node,
float128_type_node,
NULL_TREE);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+ decl = add_builtin_function ("__builtin_copysignq", ftype,
+ IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+ "__copysigntf3", NULL_TREE);
+ ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+ TREE_READONLY (decl) = 1;
if (TARGET_MMX)
ix86_init_mmx_sse_builtins ();
+ if (TARGET_64BIT)
+ ix86_init_builtins_va_builtins_abi ();
}
/* Errors in the source file can cause expand_expr to return const0_rtx
@@ -21610,7 +21737,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
i < ARRAY_SIZE (bdesc_args);
i++, d++)
if (d->code == fcode)
- return ix86_expand_args_builtin (d, exp, target);
+ switch (fcode)
+ {
+ case IX86_BUILTIN_FABSQ:
+ case IX86_BUILTIN_COPYSIGNQ:
+ if (!TARGET_SSE2)
+ /* Emit a normal call if SSE2 isn't available. */
+ return expand_call (exp, target, ignore);
+ default:
+ return ix86_expand_args_builtin (d, exp, target);
+ }
for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
if (d->code == fcode)
@@ -23075,6 +23211,54 @@ x86_order_regs_for_local_alloc (void)
reg_alloc_order [pos++] = 0;
}
+/* Handle a "ms_abi" or "sysv" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+ix86_handle_abi_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_TYPE
+ && TREE_CODE (*node) != METHOD_TYPE
+ && TREE_CODE (*node) != FIELD_DECL
+ && TREE_CODE (*node) != TYPE_DECL)
+ {
+ warning (OPT_Wattributes, "%qs attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+ if (!TARGET_64BIT)
+ {
+ warning (OPT_Wattributes, "%qs attribute only available for 64-bit",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* Can combine regparm with all attributes but fastcall. */
+ if (is_attribute_p ("ms_abi", name))
+ {
+ if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("ms_abi and sysv_abi attributes are not compatible");
+ }
+
+ return NULL_TREE;
+ }
+ else if (is_attribute_p ("sysv_abi", name))
+ {
+ if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("ms_abi and sysv_abi attributes are not compatible");
+ }
+
+ return NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
struct attribute_spec.handler. */
static tree
@@ -25884,6 +26068,10 @@ static const struct attribute_spec ix86_attribute_table[] =
#ifdef SUBTARGET_ATTRIBUTE_TABLE
SUBTARGET_ATTRIBUTE_TABLE,
#endif
+ /* ms_abi and sysv_abi calling convention function attributes. */
+ { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+ { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+ /* End element. */
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -25911,6 +26099,128 @@ x86_builtin_vectorization_cost (bool runtime_test)
return 0;
}
+/* This function returns the calling abi specific va_list type node.
+ It returns the FNDECL specific va_list type. */
+
+tree
+ix86_fn_abi_va_list (tree fndecl)
+{
+ int abi;
+
+ if (!TARGET_64BIT)
+ return va_list_type_node;
+ gcc_assert (fndecl != NULL_TREE);
+ abi = ix86_function_abi ((const_tree) fndecl);
+
+ if (abi == MS_ABI)
+ return ms_va_list_type_node;
+ else
+ return sysv_va_list_type_node;
+}
+
+/* Returns the canonical va_list type specified by TYPE. If there
+ is no valid TYPE provided, it return NULL_TREE. */
+
+tree
+ix86_canonical_va_list_type (tree type)
+{
+ tree wtype, htype;
+
+ /* Resolve references and pointers to va_list type. */
+ if (INDIRECT_REF_P (type))
+ type = TREE_TYPE (type);
+ else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
+ type = TREE_TYPE (type);
+
+ if (TARGET_64BIT)
+ {
+ wtype = va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return va_list_type_node;
+ wtype = sysv_va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return sysv_va_list_type_node;
+ wtype = ms_va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return ms_va_list_type_node;
+ return NULL_TREE;
+ }
+ return std_canonical_va_list_type (type);
+}
+
+/* Iterate through the target-specific builtin types for va_list.
+ IDX denotes the iterator, *PTREE is set to the result type of
+ the va_list builtin, and *PNAME to its internal type.
+ Returns zero if there is no element for this index, otherwise
+ IDX should be increased upon the next call.
+ Note, do not iterate a base builtin's name like __builtin_va_list.
+ Used from c_common_nodes_and_builtins. */
+
+int
+ix86_enum_va_list (int idx, const char **pname, tree *ptree)
+{
+ if (!TARGET_64BIT)
+ return 0;
+ switch (idx) {
+ case 0:
+ *ptree = ms_va_list_type_node;
+ *pname = "__builtin_ms_va_list";
+ break;
+ case 1:
+ *ptree = sysv_va_list_type_node;
+ *pname = "__builtin_sysv_va_list";
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
@@ -26039,6 +26349,12 @@ x86_builtin_vectorization_cost (bool runtime_test)
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
+#undef TARGET_FN_ABI_VA_LIST
+#define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
+
+#undef TARGET_CANONICAL_VA_LIST_TYPE
+#define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
+
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b011885424a..d17e414eb5f 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -453,7 +453,7 @@ extern tree x86_mfence;
#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
/* Available call abi. */
-enum
+enum calling_abi
{
SYSV_ABI = 0,
MS_ABI = 1
@@ -2556,6 +2556,11 @@ struct machine_function GTY(())
#undef TARG_COND_BRANCH_COST
#define TARG_COND_BRANCH_COST ix86_cost->branch_cost
+/* Enum through the target specific extra va_list types. Please, do not
+ iterate the base va_list type name. */
+#define TARGET_ENUM_VA_LIST(IDX, PNAME, PTYPE) \
+ (!TARGET_64BIT ? 0 : ix86_enum_va_list (IDX, PNAME, PTYPE))
+
/* Cost of any scalar operation, excluding load and store. */
#undef TARG_SCALAR_STMT_COST
#define TARG_SCALAR_STMT_COST ix86_cost->scalar_stmt_cost
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c67cf467bc9..6c06184f879 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -289,7 +289,7 @@
;; Main data type used by the insn
(define_attr "mode"
- "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
+ "unknown,none,QI,HI,SI,DI,TI,SF,DF,XF,TF,V4SF,V2DF,V2SF,V1DF"
(const_string "unknown"))
;; The CPU unit operations uses.
@@ -3311,6 +3311,34 @@
(const_string "TI"))]
(const_string "DI")))])
+(define_insn "*pushtf_sse"
+ [(set (match_operand:TF 0 "push_operand" "=<,<,<")
+ (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
+ "TARGET_SSE2"
+{
+ /* This insn should be already split before reg-stack. */
+ gcc_unreachable ();
+}
+ [(set_attr "type" "multi")
+ (set_attr "unit" "sse,*,*")
+ (set_attr "mode" "TF,SI,SI")])
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_SSE2 && reload_completed
+ && !SSE_REG_P (operands[1])"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (match_operand:TF 1 "any_fp_register_operand" ""))]
+ "TARGET_SSE2"
+ [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
+ (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
+ "")
+
(define_split
[(set (match_operand 0 "nonimmediate_operand" "")
(match_operand 1 "general_operand" ""))]
diff --git a/gcc/config/i386/libgcc-x86_64-glibc.ver b/gcc/config/i386/libgcc-glibc.ver
index fa5d1a6dba2..be791745b43 100644
--- a/gcc/config/i386/libgcc-x86_64-glibc.ver
+++ b/gcc/config/i386/libgcc-glibc.ver
@@ -5,6 +5,20 @@
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
%ifndef __x86_64__
+%exclude {
+ __divdi3
+ __moddi3
+ __udivdi3
+ __umoddi3
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.0
GLIBC_2.0 {
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
@@ -24,16 +38,18 @@ GLIBC_2.0 {
}
%endif
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
+# 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+# and with GCC 4.4.0 to 32bit. These lines make the symbols to get
+# a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
-%ifdef __x86_64__
%exclude {
__addtf3
+ __divtc3
__divtf3
__eqtf2
__extenddftf2
__extendsftf2
+ __extendxftf2
__fixtfdi
__fixtfsi
__fixtfti
@@ -47,21 +63,45 @@ GLIBC_2.0 {
__floatunsitf
__floatuntitf
__getf2
+ __gttf2
__letf2
+ __lttf2
+ __multc3
__multf3
__negtf2
+ __netf2
+ __powitf2
__subtf3
__trunctfdf2
__trunctfsf2
+ __trunctfxf2
__unordtf2
}
+%ifdef __x86_64__
+# Those symbols had improper versions when they were added to gcc 4.3.0.
+# We corrected the default version to GCC_4.3.0. But we keep the old
+# version for backward binary compatibility.
+GCC_3.0 {
+ __gttf2
+ __lttf2
+ __netf2
+}
+
+GCC_4.0.0 {
+ __divtc3
+ __multc3
+ __powitf2
+}
+
GCC_4.3.0 {
__addtf3
+ __divtc3
__divtf3
__eqtf2
__extenddftf2
__extendsftf2
+ __extendxftf2
__fixtfdi
__fixtfsi
__fixtfti
@@ -75,12 +115,51 @@ GCC_4.3.0 {
__floatunsitf
__floatuntitf
__getf2
+ __gttf2
+ __letf2
+ __lttf2
+ __multc3
+ __multf3
+ __negtf2
+ __netf2
+ __powitf2
+ __subtf3
+ __trunctfdf2
+ __trunctfsf2
+ __trunctfxf2
+ __unordtf2
+}
+%else
+GCC_4.4.0 {
+ __addtf3
+ __copysigntf3
+ __divtc3
+ __divtf3
+ __eqtf2
+ __extenddftf2
+ __extendsftf2
+ __fabstf2
+ __fixtfdi
+ __fixtfsi
+ __fixunstfdi
+ __fixunstfsi
+ __floatditf
+ __floatsitf
+ __floatunditf
+ __floatunsitf
+ __getf2
+ __gttf2
__letf2
+ __lttf2
+ __multc3
__multf3
__negtf2
+ __netf2
+ __powitf2
__subtf3
__trunctfdf2
__trunctfsf2
+ __trunctfxf2
__unordtf2
}
%endif
diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
index ec5dc4e2230..78326b05ec0 100644
--- a/gcc/config/i386/linux.h
+++ b/gcc/config/i386/linux.h
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3. If not see
: "=d"(BASE))
#endif
+/* Put all *tf routines in libgcc. */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
#undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1
diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
index 37ede613e7d..04d12cadada 100644
--- a/gcc/config/i386/linux64.h
+++ b/gcc/config/i386/linux64.h
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3. If not see
/* Put all *tf routines in libgcc. */
#undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
#define LIBGCC2_TF_CEXT q
#define TF_SIZE 113
diff --git a/gcc/config/i386/sfp-machine.h b/gcc/config/i386/sfp-machine.h
index 190e3cb0e81..f2df869653f 100644
--- a/gcc/config/i386/sfp-machine.h
+++ b/gcc/config/i386/sfp-machine.h
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE 64
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison. This must
- match `__libgcc_cmp_return__' in GCC for the target. */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y) \
- _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S _FP_QNANBIT_S
-#define _FP_NANFRAC_D _FP_QNANBIT_D
-#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S 1
-#define _FP_NANSIGN_D 1
-#define _FP_NANSIGN_E 1
-#define _FP_NANSIGN_Q 1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
- the case where we have two NaNs with same mantissas, but
- different sign. Different operations pick up different NaNs. */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
- do { \
- if (_FP_FRAC_GT_##wc(X, Y) \
- || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
- { \
- R##_s = X##_s; \
- _FP_FRAC_COPY_##wc(R,X); \
- } \
- else \
- { \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R,Y); \
- } \
- R##_c = FP_CLS_NAN; \
- } while (0)
-
-#define FP_EX_INVALID 0x01
-#define FP_EX_DENORM 0x02
-#define FP_EX_DIVZERO 0x04
-#define FP_EX_OVERFLOW 0x08
-#define FP_EX_UNDERFLOW 0x10
-#define FP_EX_INEXACT 0x20
-
-struct fenv
-{
- unsigned short int __control_word;
- unsigned short int __unused1;
- unsigned short int __status_word;
- unsigned short int __unused2;
- unsigned short int __tags;
- unsigned short int __unused3;
- unsigned int __eip;
- unsigned short int __cs_selector;
- unsigned int __opcode:11;
- unsigned int __unused4:5;
- unsigned int __data_offset;
- unsigned short int __data_selector;
- unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS \
- do { \
- if (_fex & FP_EX_INVALID) \
- { \
- float f = 0.0; \
- __asm__ __volatile__ ("divss %0, %0 " : : "x" (f)); \
- } \
- if (_fex & FP_EX_DIVZERO) \
- { \
- float f = 1.0, g = 0.0; \
- __asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g)); \
- } \
- if (_fex & FP_EX_OVERFLOW) \
- { \
- struct fenv temp; \
- __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
- temp.__status_word |= FP_EX_OVERFLOW; \
- __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
- __asm__ __volatile__ ("fwait"); \
- } \
- if (_fex & FP_EX_UNDERFLOW) \
- { \
- struct fenv temp; \
- __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
- temp.__status_word |= FP_EX_UNDERFLOW; \
- __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
- __asm__ __volatile__ ("fwait"); \
- } \
- if (_fex & FP_EX_INEXACT) \
- { \
- struct fenv temp; \
- __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
- temp.__status_word |= FP_EX_INEXACT; \
- __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
- __asm__ __volatile__ ("fwait"); \
- } \
- } while (0)
-
-#define FP_RND_NEAREST 0
-#define FP_RND_ZERO 0xc00
-#define FP_RND_PINF 0x800
-#define FP_RND_MINF 0x400
-
-#define _FP_DECL_EX \
- unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE \
- do { \
- __asm__ ("fnstcw %0" : "=m" (_fcw)); \
- } while (0)
-
-#define FP_ROUNDMODE (_fcw & 0xc00)
-
-#define __LITTLE_ENDIAN 1234
-#define __BIG_ENDIAN 4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME. */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing. If these functions ever return
- anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
- CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
#else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
- extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
#endif
diff --git a/gcc/config/i386/sol2-c1.asm b/gcc/config/i386/sol2-c1.asm
index af1ab3141f0..4c30a16f4a7 100644
--- a/gcc/config/i386/sol2-c1.asm
+++ b/gcc/config/i386/sol2-c1.asm
@@ -41,7 +41,6 @@
! information obtained by single stepping executables on other i386 SVR4
! implementations. This file is the first thing linked into any executable.
- .file "crt1.s"
.ident "GNU C crt1.s"
.weak _cleanup
.weak _DYNAMIC
diff --git a/gcc/config/i386/sol2-ci.asm b/gcc/config/i386/sol2-ci.asm
index c7a17445fcc..1846a1eab89 100644
--- a/gcc/config/i386/sol2-ci.asm
+++ b/gcc/config/i386/sol2-ci.asm
@@ -37,7 +37,6 @@
! sections. It is linked in before the values-Xx.o files and also before
! crtbegin.o.
- .file "crti.s"
.ident "GNU C crti.s"
.section .init
diff --git a/gcc/config/i386/sol2-cn.asm b/gcc/config/i386/sol2-cn.asm
index acd266ac070..37f7362d5db 100644
--- a/gcc/config/i386/sol2-cn.asm
+++ b/gcc/config/i386/sol2-cn.asm
@@ -36,7 +36,6 @@
! This file just supplies returns for the .init and .fini sections. It is
! linked in after all other files.
- .file "crtn.o"
.ident "GNU C crtn.o"
.section .init
diff --git a/gcc/config/i386/sol2-gc1.asm b/gcc/config/i386/sol2-gc1.asm
index abe9ed6aae6..994326a6b00 100644
--- a/gcc/config/i386/sol2-gc1.asm
+++ b/gcc/config/i386/sol2-gc1.asm
@@ -45,7 +45,6 @@
! to allow program profiling, by calling monstartup on entry and _mcleanup
! on exit
- .file "gcrt1.s"
.ident "GNU C gcrt1.s"
.weak _DYNAMIC
.text
diff --git a/gcc/config/i386/t-darwin b/gcc/config/i386/t-darwin
index 6feb48a20a4..fb5bbe78c04 100644
--- a/gcc/config/i386/t-darwin
+++ b/gcc/config/i386/t-darwin
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
MULTILIB_DIRNAMES = x86_64
LIB2_SIDITI_CONV_FUNCS=yes
LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
diff --git a/gcc/config/i386/t-darwin64 b/gcc/config/i386/t-darwin64
index 2e55cb786d7..5143e3819dc 100644
--- a/gcc/config/i386/t-darwin64
+++ b/gcc/config/i386/t-darwin64
@@ -1,5 +1,2 @@
LIB2_SIDITI_CONV_FUNCS=yes
LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
diff --git a/gcc/config/i386/t-fprules-softfp64 b/gcc/config/i386/t-fprules-softfp
index 0b0068f9053..0b0068f9053 100644
--- a/gcc/config/i386/t-fprules-softfp64
+++ b/gcc/config/i386/t-fprules-softfp
diff --git a/gcc/config/i386/t-linux b/gcc/config/i386/t-linux
new file mode 100644
index 00000000000..4c6bb51e3b8
--- /dev/null
+++ b/gcc/config/i386/t-linux
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86. Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+ $(srcdir)/config/i386/libgcc-glibc.ver
diff --git a/gcc/config/i386/t-linux64 b/gcc/config/i386/t-linux64
index 0490d7812e1..36378d87e0b 100644
--- a/gcc/config/i386/t-linux64
+++ b/gcc/config/i386/t-linux64
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
- $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
# On Debian, Ubuntu and other derivative distributions, the 32bit libraries
# are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
# /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
diff --git a/gcc/config/ia64/crti.asm b/gcc/config/ia64/crti.asm
index a2d1e1221cc..773f154ad42 100644
--- a/gcc/config/ia64/crti.asm
+++ b/gcc/config/ia64/crti.asm
@@ -35,8 +35,6 @@
# .init sections. Users may put any desired instructions in those
# sections.
- .file "crti.asm"
-
.section ".init"
.align 16
.global _init
diff --git a/gcc/config/ia64/crtn.asm b/gcc/config/ia64/crtn.asm
index 52ec47c582e..c72bd696661 100644
--- a/gcc/config/ia64/crtn.asm
+++ b/gcc/config/ia64/crtn.asm
@@ -35,8 +35,6 @@
# fact return. Users may put any desired instructions in those sections.
# This file is the last thing linked into any executable.
- .file "crtn.asm"
-
.section ".init"
;;
mov ar.pfs = r34
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index de39ab12946..e93ae31b0bd 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -1119,8 +1119,8 @@ ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
}
else
{
- p[0] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
- p[1] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ p[0] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ p[1] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
}
out[0] = GEN_INT (p[0]);
out[1] = GEN_INT (p[1]);
diff --git a/gcc/config/libgcc-glibc.ver b/gcc/config/libgcc-glibc.ver
index 837c1a7ee56..264828b17c0 100644
--- a/gcc/config/libgcc-glibc.ver
+++ b/gcc/config/libgcc-glibc.ver
@@ -4,6 +4,20 @@
# maintain enough binary compatibility to allow future versions of glibc
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+%exclude {
+ __divdi3
+ __moddi3
+ __udivdi3
+ __umoddi3
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.0
GLIBC_2.0 {
# Sampling of DImode arithmetic used by (at least) i386 and m68k.
diff --git a/gcc/config/m32r/libgcc-glibc.ver b/gcc/config/m32r/libgcc-glibc.ver
index 450c4b60e92..977c3346604 100644
--- a/gcc/config/m32r/libgcc-glibc.ver
+++ b/gcc/config/m32r/libgcc-glibc.ver
@@ -8,6 +8,16 @@
# because GLIBC_2.0 does not exist on this architecture, as the first
# ever glibc release on the platform was GLIBC_2.3.
+%exclude {
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.3
GLIBC_2.3 {
__register_frame
diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm
index 7bb06915fca..c24a41c2646 100644
--- a/gcc/config/m68hc11/larith.asm
+++ b/gcc/config/m68hc11/larith.asm
@@ -33,8 +33,6 @@ Boston, MA 02110-1301, USA. */
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
- .file "larith.asm"
-
#ifdef __HAVE_SHORT_INT__
.mode mshort
#else
diff --git a/gcc/config/m68hc11/m68hc11-crt0.S b/gcc/config/m68hc11/m68hc11-crt0.S
index 5e92680b97d..c8644694918 100644
--- a/gcc/config/m68hc11/m68hc11-crt0.S
+++ b/gcc/config/m68hc11/m68hc11-crt0.S
@@ -34,7 +34,6 @@ Boston, MA 02110-1301, USA. */
;-----------------------------------------
; startup code
;-----------------------------------------
- .file "crt0.s"
#ifdef __HAVE_SHORT_INT__
.mode mshort
diff --git a/gcc/config/m68k/crti.s b/gcc/config/m68k/crti.s
index 760c2e85b0d..ac085419165 100644
--- a/gcc/config/m68k/crti.s
+++ b/gcc/config/m68k/crti.s
@@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
* sections. It is linked in before crtbegin.o.
*/
- .file "crti.o"
.ident "GNU C crti.o"
.section .init
diff --git a/gcc/config/m68k/crtn.s b/gcc/config/m68k/crtn.s
index 98c8bed3476..83f605347aa 100644
--- a/gcc/config/m68k/crtn.s
+++ b/gcc/config/m68k/crtn.s
@@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
* It is linked in after all other files.
*/
- .file "crtn.o"
.ident "GNU C crtn.o"
.section .init
diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm
index d09213fc033..e03b7b30d87 100644
--- a/gcc/config/m68k/lb1sf68.asm
+++ b/gcc/config/m68k/lb1sf68.asm
@@ -129,10 +129,11 @@ Boston, MA 02110-1301, USA. */
#else /* __PIC__ */
- /* Common for -mid-shared-libary and -msep-data */
+ /* Common for Linux and uClinux, the latter with either
+ -mid-shared-library or -msep-data. */
.macro PICCALL addr
-#if defined (__mcoldfire__) && !defined (__mcfisab__)
+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
lea \addr-.-8,a0
jsr pc@(a0)
#else
@@ -141,6 +142,9 @@ Boston, MA 02110-1301, USA. */
.endm
.macro PICJUMP addr
+ /* ISA C has no bra.l instruction, and since this assembly file
+ gets assembled into multiple object files, we avoid the
+ bra instruction entirely. */
#if defined (__mcoldfire__) && !defined (__mcfisab__)
lea \addr-.-8,a0
jmp pc@(a0)
@@ -149,7 +153,11 @@ Boston, MA 02110-1301, USA. */
#endif
.endm
-# if defined(__ID_SHARED_LIBRARY__)
+# if defined (__uClinux__)
+
+ /* Versions for uClinux */
+
+# if defined(__ID_SHARED_LIBRARY__)
/* -mid-shared-library versions */
@@ -163,7 +171,7 @@ Boston, MA 02110-1301, USA. */
movel \sym@GOT(\areg), sp@-
.endm
-# else /* !__ID_SHARED_LIBRARY__ */
+# else /* !__ID_SHARED_LIBRARY__ */
/* Versions for -msep-data */
@@ -175,7 +183,25 @@ Boston, MA 02110-1301, USA. */
movel \sym@GOT(a5), sp@-
.endm
-# endif /* !__ID_SHARED_LIBRARY__ */
+# endif
+
+# else /* !__uClinux__ */
+
+ /* Versions for Linux */
+
+ .macro PICLEA sym, reg
+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg
+ lea (-6, pc, \reg), \reg
+ movel \sym@GOT(\reg), \reg
+ .endm
+
+ .macro PICPEA sym, areg
+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg
+ lea (-6, pc, \areg), \areg
+ movel \sym@GOT(\areg), sp@-
+ .endm
+
+# endif
#endif /* __PIC__ */
diff --git a/gcc/config/m68k/m68k-devices.def b/gcc/config/m68k/m68k-devices.def
index 7b06e35b737..fb5cde3b451 100644
--- a/gcc/config/m68k/m68k-devices.def
+++ b/gcc/config/m68k/m68k-devices.def
@@ -63,7 +63,11 @@
There is a bit of duplication between devices in the same family,
but this approach makes scripting easier. We keep each entry on
- a single line for the same reason. */
+ a single line for the same reason.
+
+ As the compiler does not (currently) generate MAC or EMAC commands,
+ we do not need separate multilibs for cores that only differ in
+ their MAC functionality. */
/* 680x0 series processors. */
M68K_DEVICE ("68000", m68000, "68000", "68000", 68000, isa_00, 0)
@@ -86,31 +90,31 @@ M68K_DEVICE ("5206", mcf5206, "5206", "5206", cfv2, isa_a, 0)
M68K_DEVICE ("5206e", mcf5206e, "5206e", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5207", mcf5207, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5208", mcf5208, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5210a", mcf5210a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5211a", mcf5211a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5211", mcf5211, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5212", mcf5212, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5213", mcf5213, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5210a", mcf5210a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5211a", mcf5211a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5211", mcf5211, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5212", mcf5212, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5213", mcf5213, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5214", mcf5214, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5216", mcf5216, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("52221", mcf52221, "52223", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("52223", mcf52223, "52223", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("52221", mcf52221, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("52223", mcf52223, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("52230", mcf52230, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52231", mcf52231, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52232", mcf52232, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52233", mcf52233, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52234", mcf52234, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52235", mcf52235, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5224", mcf5224, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5225", mcf5225, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5224", mcf5224, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5225", mcf5225, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5232", mcf5232, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5233", mcf5233, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5234", mcf5234, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5235", mcf5235, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("523x", mcf523x, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5249", mcf5249, "5249", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5250", mcf5250, "5250", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5253", mcf5253, "5253", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5249", mcf5249, "5249", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5250", mcf5250, "5250", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5253", mcf5253, "5253", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5270", mcf5270, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5271", mcf5271, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV)
M68K_DEVICE ("5272", mcf5272, "5272", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC)
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 046132088bc..1853073af81 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -148,7 +148,7 @@ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
static bool m68k_ok_for_sibcall_p (tree, tree);
static bool m68k_rtx_costs (rtx, int, int, int *);
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
-static bool m68k_return_in_memory (tree, tree);
+static bool m68k_return_in_memory (const_tree, const_tree);
#endif
@@ -4627,7 +4627,7 @@ m68k_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
/* Worker function for TARGET_RETURN_IN_MEMORY. */
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
static bool
-m68k_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+m68k_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
enum machine_mode mode = TYPE_MODE (type);
diff --git a/gcc/config/m68k/t-cf b/gcc/config/m68k/t-cf
index 697946654af..7bf8e11ee82 100644
--- a/gcc/config/m68k/t-cf
+++ b/gcc/config/m68k/t-cf
@@ -2,3 +2,6 @@
M68K_MLIB_CPU += && (CPU ~ "^mcf")
M68K_ARCH := cf
+# Do not stamp the multilibs with a MAC type, as we never use those
+# instructions in compiler-generated code.
+MULTILIB_EXTRA_OPTS += Wa,-mno-mac
diff --git a/gcc/config/m68k/t-linux b/gcc/config/m68k/t-linux
new file mode 100644
index 00000000000..f46d3a873d5
--- /dev/null
+++ b/gcc/config/m68k/t-linux
@@ -0,0 +1,11 @@
+EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+
+# Only include multilibs for CPUs with an MMU.
+M68K_MLIB_CPU += && match(FLAGS, "FL_MMU")
+
+# This rule uses MULTILIB_MATCHES to generate a definition of
+# SYSROOT_SUFFIX_SPEC.
+sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
+ $(SHELL) $(srcdir)/config/m68k/print-sysroot-suffix.sh \
+ "$(SYSTEM_HEADER_DIR)/../.." "$(MULTILIB_MATCHES)" \
+ "$(MULTILIB_OPTIONS)" > $@
diff --git a/gcc/config/mcore/crti.asm b/gcc/config/mcore/crti.asm
index dac882d7ad8..281424f8e67 100644
--- a/gcc/config/mcore/crti.asm
+++ b/gcc/config/mcore/crti.asm
@@ -37,8 +37,6 @@
# .init sections. Users may put any desired instructions in those
# sections.
- .file "crti.asm"
-
.section ".init"
.global _init
.type _init,@function
diff --git a/gcc/config/mcore/crtn.asm b/gcc/config/mcore/crtn.asm
index 87f2455305b..dc46ca4e576 100644
--- a/gcc/config/mcore/crtn.asm
+++ b/gcc/config/mcore/crtn.asm
@@ -37,8 +37,6 @@
# fact return. Users may put any desired instructions in those sections.
# This file is the last thing linked into any executable.
- .file "crtn.asm"
-
.section ".init"
.align 4
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 48ba54b1cef..e8d51bcd40e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -442,7 +442,7 @@ const struct mips_rtx_cost_data *mips_cost;
static int mips_base_target_flags;
/* True if MIPS16 is the default mode. */
-static bool mips_base_mips16;
+bool mips_base_mips16;
/* The ambient values of other global variables. */
static int mips_base_delayed_branch; /* flag_delayed_branch */
@@ -12333,8 +12333,14 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
}
/* The last argument passed to mips_set_mips16_mode, or negative if the
- function hasn't been called yet. */
-static GTY(()) int was_mips16_p = -1;
+ function hasn't been called yet.
+
+ There are two copies of this information. One is saved and restored
+ by the PCH process while the other is specific to this compiler
+ invocation. The information calculated by mips_set_mips16_mode
+ is invalid unless the two variables are the same. */
+static int was_mips16_p = -1;
+static GTY(()) int was_mips16_pch_p = -1;
/* Set up the target-dependent global state so that it matches the
current function's ISA mode. */
@@ -12342,7 +12348,8 @@ static GTY(()) int was_mips16_p = -1;
static void
mips_set_mips16_mode (int mips16_p)
{
- if (mips16_p == was_mips16_p)
+ if (mips16_p == was_mips16_p
+ && mips16_p == was_mips16_pch_p)
return;
/* Restore base settings of various flags. */
@@ -12417,11 +12424,12 @@ mips_set_mips16_mode (int mips16_p)
/* (Re)initialize MIPS target internals for new ISA. */
mips_init_relocs ();
- if (was_mips16_p >= 0)
+ if (was_mips16_p >= 0 || was_mips16_pch_p >= 0)
/* Reinitialize target-dependent state. */
target_reinit ();
was_mips16_p = mips16_p;
+ was_mips16_pch_p = mips16_p;
}
/* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
@@ -12627,6 +12635,10 @@ mips_override_options (void)
{
int i, start, regno, mode;
+ /* Process flags as though we were generating non-MIPS16 code. */
+ mips_base_mips16 = TARGET_MIPS16;
+ target_flags &= ~MASK_MIPS16;
+
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
#endif
@@ -12772,14 +12784,6 @@ mips_override_options (void)
target_flags &= ~MASK_ABICALLS;
}
- /* MIPS16 cannot generate PIC yet. */
- if (TARGET_MIPS16 && (flag_pic || TARGET_ABICALLS))
- {
- sorry ("MIPS16 PIC");
- target_flags &= ~MASK_ABICALLS;
- flag_pic = flag_pie = flag_shlib = 0;
- }
-
if (TARGET_ABICALLS)
/* We need to set flag_pic for executables as well as DSOs
because we may reference symbols that are not defined in
@@ -12807,7 +12811,7 @@ mips_override_options (void)
{
if (!TARGET_GPOPT)
{
- if (!TARGET_MIPS16 && !TARGET_EXPLICIT_RELOCS)
+ if (!TARGET_EXPLICIT_RELOCS)
error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
TARGET_LOCAL_SDATA = false;
@@ -12911,7 +12915,6 @@ mips_override_options (void)
target_flags |= MASK_FIX_R4400;
/* Save base state of options. */
- mips_base_mips16 = TARGET_MIPS16;
mips_base_target_flags = target_flags;
mips_base_delayed_branch = flag_delayed_branch;
mips_base_schedule_insns = flag_schedule_insns;
@@ -12921,8 +12924,11 @@ mips_override_options (void)
mips_base_align_jumps = align_jumps;
mips_base_align_functions = align_functions;
- /* Now select the ISA mode. */
- mips_set_mips16_mode (mips_base_mips16);
+ /* Now select the ISA mode.
+
+ Do all CPP-sensitive stuff in non-MIPS16 mode; we'll switch to
+ MIPS16 mode afterwards if need be. */
+ mips_set_mips16_mode (false);
/* We call dbr_schedule from within mips_reorg. */
flag_delayed_branch = 0;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 781528d01ba..8518a86233b 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -390,7 +390,7 @@ enum mips_code_readable_setting {
else \
builtin_define ("__mips_fpr=32"); \
\
- if (TARGET_MIPS16) \
+ if (mips_base_mips16) \
builtin_define ("__mips16"); \
\
if (TARGET_MIPS3D) \
@@ -3232,6 +3232,7 @@ extern int mips_abi; /* which ABI to use */
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
extern const struct mips_rtx_cost_data *mips_cost;
+extern bool mips_base_mips16;
extern enum mips_code_readable_setting mips_code_readable;
#endif
diff --git a/gcc/config/mips/t-libgcc-mips16 b/gcc/config/mips/t-libgcc-mips16
index 819f5c6fc21..d37b6eef539 100644
--- a/gcc/config/mips/t-libgcc-mips16
+++ b/gcc/config/mips/t-libgcc-mips16
@@ -19,3 +19,6 @@ LIB1ASMFUNCS = _m16addsf3 _m16subsf3 _m16mulsf3 _m16divsf3 \
_m16stubsc9 _m16stubsc10 \
_m16stubdc0 _m16stubdc1 _m16stubdc2 _m16stubdc5 _m16stubdc6 \
_m16stubdc9 _m16stubdc10
+
+LIBGCC_SYNC = yes
+LIBGCC_SYNC_CFLAGS = -mno-mips16
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 0529a86a68c..238d35276e4 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -694,8 +694,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
orig = XEXP (XEXP (orig, 0), 0);
/* Extract CODE_LABEL. */
orig = XEXP (orig, 0);
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, orig,
- REG_NOTES (insn));
+ add_reg_note (insn, REG_LABEL_OPERAND, orig);
LABEL_NUSES (orig)++;
}
crtl->uses_pic_offset_table = 1;
diff --git a/gcc/config/rs6000/crtresfpr.asm b/gcc/config/rs6000/crtresfpr.asm
index aaa4b968049..fedff803bf8 100644
--- a/gcc/config/rs6000/crtresfpr.asm
+++ b/gcc/config/rs6000/crtresfpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtresfpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtresgpr.asm b/gcc/config/rs6000/crtresgpr.asm
index 928341d7624..7e73a1a8fe3 100644
--- a/gcc/config/rs6000/crtresgpr.asm
+++ b/gcc/config/rs6000/crtresgpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtresgpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtresxfpr.asm b/gcc/config/rs6000/crtresxfpr.asm
index 2a734866f07..a12683308f4 100644
--- a/gcc/config/rs6000/crtresxfpr.asm
+++ b/gcc/config/rs6000/crtresxfpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtresxfpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtresxgpr.asm b/gcc/config/rs6000/crtresxgpr.asm
index 1bab865c452..c4593ae5cd3 100644
--- a/gcc/config/rs6000/crtresxgpr.asm
+++ b/gcc/config/rs6000/crtresxgpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtresxgpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtsavfpr.asm b/gcc/config/rs6000/crtsavfpr.asm
index f3d708f6200..b6eaaab50bf 100644
--- a/gcc/config/rs6000/crtsavfpr.asm
+++ b/gcc/config/rs6000/crtsavfpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtsavfpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtsavgpr.asm b/gcc/config/rs6000/crtsavgpr.asm
index 0e244316fa6..0bf594d98e2 100644
--- a/gcc/config/rs6000/crtsavgpr.asm
+++ b/gcc/config/rs6000/crtsavgpr.asm
@@ -38,7 +38,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtsavgpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/crtsavres.asm b/gcc/config/rs6000/crtsavres.asm
index 498759d27d8..7fea5232885 100644
--- a/gcc/config/rs6000/crtsavres.asm
+++ b/gcc/config/rs6000/crtsavres.asm
@@ -37,7 +37,6 @@
/* Do any initializations needed for the eabi environment */
- .file "crtsavres.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtres32gpr.asm b/gcc/config/rs6000/e500crtres32gpr.asm
index bd5f825447f..31856feaf71 100644
--- a/gcc/config/rs6000/e500crtres32gpr.asm
+++ b/gcc/config/rs6000/e500crtres32gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtres32gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtres64gpr.asm b/gcc/config/rs6000/e500crtres64gpr.asm
index 73ab506710c..17660920fac 100644
--- a/gcc/config/rs6000/e500crtres64gpr.asm
+++ b/gcc/config/rs6000/e500crtres64gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtres64gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtres64gprctr.asm b/gcc/config/rs6000/e500crtres64gprctr.asm
index 93b5963321a..9dbc7ed9c3d 100644
--- a/gcc/config/rs6000/e500crtres64gprctr.asm
+++ b/gcc/config/rs6000/e500crtres64gprctr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtres64gprctr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtrest32gpr.asm b/gcc/config/rs6000/e500crtrest32gpr.asm
index 42f81d689f6..e2442c98be1 100644
--- a/gcc/config/rs6000/e500crtrest32gpr.asm
+++ b/gcc/config/rs6000/e500crtrest32gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtrest32gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtrest64gpr.asm b/gcc/config/rs6000/e500crtrest64gpr.asm
index cf7092c7a28..acc8349eebf 100644
--- a/gcc/config/rs6000/e500crtrest64gpr.asm
+++ b/gcc/config/rs6000/e500crtrest64gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtrest64gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtresx32gpr.asm b/gcc/config/rs6000/e500crtresx32gpr.asm
index 9fba08b5511..cab0d48d738 100644
--- a/gcc/config/rs6000/e500crtresx32gpr.asm
+++ b/gcc/config/rs6000/e500crtresx32gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtresx32gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtresx64gpr.asm b/gcc/config/rs6000/e500crtresx64gpr.asm
index e6a24e94b35..6a57ada0507 100644
--- a/gcc/config/rs6000/e500crtresx64gpr.asm
+++ b/gcc/config/rs6000/e500crtresx64gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtresx64gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsav32gpr.asm b/gcc/config/rs6000/e500crtsav32gpr.asm
index 6cf97956ccc..a606617b8ec 100644
--- a/gcc/config/rs6000/e500crtsav32gpr.asm
+++ b/gcc/config/rs6000/e500crtsav32gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsav32gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsav64gpr.asm b/gcc/config/rs6000/e500crtsav64gpr.asm
index 6a2b0fac82a..7d8c191cf4a 100644
--- a/gcc/config/rs6000/e500crtsav64gpr.asm
+++ b/gcc/config/rs6000/e500crtsav64gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsav64gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsav64gprctr.asm b/gcc/config/rs6000/e500crtsav64gprctr.asm
index 1261bb06ed8..99f72faea54 100644
--- a/gcc/config/rs6000/e500crtsav64gprctr.asm
+++ b/gcc/config/rs6000/e500crtsav64gprctr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsav64gprctr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsavg32gpr.asm b/gcc/config/rs6000/e500crtsavg32gpr.asm
index d648817a763..3c8d759dcd2 100644
--- a/gcc/config/rs6000/e500crtsavg32gpr.asm
+++ b/gcc/config/rs6000/e500crtsavg32gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsavg32gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsavg64gpr.asm b/gcc/config/rs6000/e500crtsavg64gpr.asm
index 7a60a84f2ec..a81faf87380 100644
--- a/gcc/config/rs6000/e500crtsavg64gpr.asm
+++ b/gcc/config/rs6000/e500crtsavg64gpr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsavg64gpr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/e500crtsavg64gprctr.asm b/gcc/config/rs6000/e500crtsavg64gprctr.asm
index 1d978ec2793..bdc598b0871 100644
--- a/gcc/config/rs6000/e500crtsavg64gprctr.asm
+++ b/gcc/config/rs6000/e500crtsavg64gprctr.asm
@@ -34,7 +34,6 @@
* the executable file might be covered by the GNU General Public License.
*/
- .file "e500crtsavg64gprctr.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/eabi-ci.asm b/gcc/config/rs6000/eabi-ci.asm
index d32120f13f1..6b332783766 100644
--- a/gcc/config/rs6000/eabi-ci.asm
+++ b/gcc/config/rs6000/eabi-ci.asm
@@ -36,7 +36,6 @@ Boston, MA 02110-1301, USA.
/* This file just supplies labeled starting points for the .got* and other
special sections. It is linked in first before other modules. */
- .file "crti.s"
.ident "GNU C crti.s"
#include <ppc-asm.h>
diff --git a/gcc/config/rs6000/eabi-cn.asm b/gcc/config/rs6000/eabi-cn.asm
index fcfea4d133e..df7baeb34f5 100644
--- a/gcc/config/rs6000/eabi-cn.asm
+++ b/gcc/config/rs6000/eabi-cn.asm
@@ -36,7 +36,6 @@ Boston, MA 02110-1301, USA.
/* This file just supplies labeled ending points for the .got* and other
special sections. It is linked in last after other modules. */
- .file "crtn.s"
.ident "GNU C crtn.s"
#ifndef __powerpc64__
diff --git a/gcc/config/rs6000/eabi.asm b/gcc/config/rs6000/eabi.asm
index b5d4505d9ed..347fd7b02e1 100644
--- a/gcc/config/rs6000/eabi.asm
+++ b/gcc/config/rs6000/eabi.asm
@@ -36,7 +36,6 @@
/* Do any initializations needed for the eabi environment */
- .file "eabi.asm"
.section ".text"
#include "ppc-asm.h"
diff --git a/gcc/config/rs6000/host-darwin.c b/gcc/config/rs6000/host-darwin.c
index bb50f0edfd3..333f4884e1b 100644
--- a/gcc/config/rs6000/host-darwin.c
+++ b/gcc/config/rs6000/host-darwin.c
@@ -1,5 +1,6 @@
/* Darwin/powerpc host-specific hook definitions.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -138,7 +139,7 @@ darwin_rs6000_extra_signals (void)
struct sigaction sact;
stack_t sigstk;
- sigstk.ss_sp = xmalloc (SIGSTKSZ);
+ sigstk.ss_sp = (char*)xmalloc (SIGSTKSZ);
sigstk.ss_size = SIGSTKSZ;
sigstk.ss_flags = 0;
if (sigaltstack (&sigstk, NULL) < 0)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5efde36de8d..8fe16464285 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10745,26 +10745,6 @@
operands[0] = XEXP (operands[0], 0);
- if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
- && flag_pic
- && GET_CODE (operands[0]) == SYMBOL_REF
- && !SYMBOL_REF_LOCAL_P (operands[0]))
- {
- rtx call;
- rtvec tmp;
-
- tmp = gen_rtvec (3,
- gen_rtx_CALL (VOIDmode,
- gen_rtx_MEM (SImode, operands[0]),
- operands[1]),
- gen_rtx_USE (VOIDmode, operands[2]),
- gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_REG (Pmode, LR_REGNO)));
- call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
- use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
- DONE;
- }
-
if (GET_CODE (operands[0]) != SYMBOL_REF
|| (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
@@ -10816,29 +10796,6 @@
operands[1] = XEXP (operands[1], 0);
- if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
- && flag_pic
- && GET_CODE (operands[1]) == SYMBOL_REF
- && !SYMBOL_REF_LOCAL_P (operands[1]))
- {
- rtx call;
- rtvec tmp;
-
- tmp = gen_rtvec (3,
- gen_rtx_SET (VOIDmode,
- operands[0],
- gen_rtx_CALL (VOIDmode,
- gen_rtx_MEM (SImode,
- operands[1]),
- operands[2])),
- gen_rtx_USE (VOIDmode, operands[3]),
- gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_REG (Pmode, LR_REGNO)));
- call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
- use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
- DONE;
- }
-
if (GET_CODE (operands[1]) != SYMBOL_REF
|| (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
@@ -11094,7 +11051,7 @@
[(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
(set_attr "length" "4,4,8,8")])
-(define_insn "*call_nonlocal_sysv<mode>"
+(define_insn_and_split "*call_nonlocal_sysv<mode>"
[(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
@@ -11114,18 +11071,51 @@
#else
if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
- if (TARGET_SECURE_PLT && flag_pic == 2)
- /* The magic 32768 offset here and in the other sysv call insns
- corresponds to the offset of r30 in .got2, as given by LCTOC1.
- See sysv4.h:toc_section. */
- return "bl %z0+32768@plt";
- else
- return "bl %z0@plt";
+ gcc_assert (!TARGET_SECURE_PLT);
+ return "bl %z0@plt";
}
else
return "bl %z0";
#endif
}
+ "DEFAULT_ABI == ABI_V4
+ && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
+ && (INTVAL (operands[2]) & CALL_LONG) == 0"
+ [(parallel [(call (mem:SI (match_dup 0))
+ (match_dup 1))
+ (use (match_dup 2))
+ (use (match_dup 3))
+ (clobber (reg:SI LR_REGNO))])]
+{
+ operands[3] = pic_offset_table_rtx;
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_nonlocal_sysv_secure<mode>"
+ [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
+ (match_operand 1 "" "g,g"))
+ (use (match_operand:SI 2 "immediate_operand" "O,n"))
+ (use (match_operand:SI 3 "register_operand" "r,r"))
+ (clobber (reg:SI LR_REGNO))]
+ "(DEFAULT_ABI == ABI_V4
+ && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
+ && (INTVAL (operands[2]) & CALL_LONG) == 0)"
+{
+ if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
+ output_asm_insn ("crxor 6,6,6", operands);
+
+ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
+ output_asm_insn ("creqv 6,6,6", operands);
+
+ if (flag_pic == 2)
+ /* The magic 32768 offset here and in the other sysv call insns
+ corresponds to the offset of r30 in .got2, as given by LCTOC1.
+ See sysv4.h:toc_section. */
+ return "bl %z0+32768@plt";
+ else
+ return "bl %z0@plt";
+}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -11149,7 +11139,7 @@
[(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
(set_attr "length" "4,4,8,8")])
-(define_insn "*call_value_nonlocal_sysv<mode>"
+(define_insn_and_split "*call_value_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "g,g")))
@@ -11170,15 +11160,50 @@
#else
if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
- if (TARGET_SECURE_PLT && flag_pic == 2)
- return "bl %z1+32768@plt";
- else
- return "bl %z1@plt";
+ gcc_assert (!TARGET_SECURE_PLT);
+ return "bl %z1@plt";
}
else
return "bl %z1";
#endif
}
+ "DEFAULT_ABI == ABI_V4
+ && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
+ && (INTVAL (operands[3]) & CALL_LONG) == 0"
+ [(parallel [(set (match_dup 0)
+ (call (mem:SI (match_dup 1))
+ (match_dup 2)))
+ (use (match_dup 3))
+ (use (match_dup 4))
+ (clobber (reg:SI LR_REGNO))])]
+{
+ operands[4] = pic_offset_table_rtx;
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_value_nonlocal_sysv_secure<mode>"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
+ (match_operand 2 "" "g,g")))
+ (use (match_operand:SI 3 "immediate_operand" "O,n"))
+ (use (match_operand:SI 4 "register_operand" "r,r"))
+ (clobber (reg:SI LR_REGNO))]
+ "(DEFAULT_ABI == ABI_V4
+ && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
+ && (INTVAL (operands[3]) & CALL_LONG) == 0)"
+{
+ if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
+ output_asm_insn ("crxor 6,6,6", operands);
+
+ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
+ output_asm_insn ("creqv 6,6,6", operands);
+
+ if (flag_pic == 2)
+ return "bl %z1+32768@plt";
+ else
+ return "bl %z1@plt";
+}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -11391,10 +11416,8 @@
if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
- if (TARGET_SECURE_PLT && flag_pic == 2)
- return \"b %z0+32768@plt\";
- else
- return \"b %z0@plt\";
+ gcc_assert (!TARGET_SECURE_PLT);
+ return \"b %z0@plt\";
}
else
return \"b %z0\";
@@ -11443,10 +11466,8 @@
if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
- if (TARGET_SECURE_PLT && flag_pic == 2)
- return \"b %z1+32768@plt\";
- else
- return \"b %z1@plt\";
+ gcc_assert (!TARGET_SECURE_PLT);
+ return \"b %z1@plt\";
}
else
return \"b %z1\";
diff --git a/gcc/config/rs6000/sol-ci.asm b/gcc/config/rs6000/sol-ci.asm
index 35e3b8e5c35..528a72d2d8d 100644
--- a/gcc/config/rs6000/sol-ci.asm
+++ b/gcc/config/rs6000/sol-ci.asm
@@ -36,7 +36,6 @@
# This file just supplies labeled starting points for the .got* and other
# special sections. It is linked in first before other modules.
- .file "scrti.s"
.ident "GNU C scrti.s"
#ifndef __powerpc64__
diff --git a/gcc/config/rs6000/sol-cn.asm b/gcc/config/rs6000/sol-cn.asm
index b9ef4443464..de144c07a79 100644
--- a/gcc/config/rs6000/sol-cn.asm
+++ b/gcc/config/rs6000/sol-cn.asm
@@ -36,7 +36,6 @@
# This file just supplies labeled ending points for the .got* and other
# special sections. It is linked in last after other modules.
- .file "scrtn.s"
.ident "GNU C scrtn.s"
#ifndef __powerpc64__
diff --git a/gcc/config/rs6000/tramp.asm b/gcc/config/rs6000/tramp.asm
index cd61f1d7efd..b620df32d00 100644
--- a/gcc/config/rs6000/tramp.asm
+++ b/gcc/config/rs6000/tramp.asm
@@ -35,7 +35,6 @@
/* Set up trampolines. */
- .file "tramp.asm"
.section ".text"
#include "ppc-asm.h"
#include "config.h"
diff --git a/gcc/config/s390/libgcc-glibc.ver b/gcc/config/s390/libgcc-glibc.ver
index e9413d0fff1..ab6eedcf683 100644
--- a/gcc/config/s390/libgcc-glibc.ver
+++ b/gcc/config/s390/libgcc-glibc.ver
@@ -9,6 +9,20 @@
# ever glibc release on the platform was GLIBC_2.2.
%ifndef __s390x__
+%exclude {
+ __divdi3
+ __moddi3
+ __udivdi3
+ __umoddi3
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.0
GLIBC_2.0 {
__divdi3
@@ -27,6 +41,16 @@ GLIBC_2.0 {
%endif
%ifdef __s390x__
+%exclude {
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.2
GLIBC_2.2 {
__register_frame
diff --git a/gcc/config/sh/libgcc-glibc.ver b/gcc/config/sh/libgcc-glibc.ver
index 734d3d6bfe1..11ef379effa 100644
--- a/gcc/config/sh/libgcc-glibc.ver
+++ b/gcc/config/sh/libgcc-glibc.ver
@@ -8,6 +8,16 @@
# because GLIBC_2.0 does not exist on this architecture, as the first
# ever glibc release on the platform was GLIBC_2.2.
+%exclude {
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%inherit GCC_3.0 GLIBC_2.2
GLIBC_2.2 {
__register_frame
@@ -18,4 +28,3 @@ GLIBC_2.2 {
__frame_state_for
__register_frame_info_table
}
-
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 71419ec61de..380705104ee 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -4983,10 +4983,8 @@ sh_reorg (void)
or pseudo-op. */
label = gen_label_rtx ();
- REG_NOTES (link) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, label,
- REG_NOTES (link));
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, label,
- REG_NOTES (insn));
+ add_reg_note (link, REG_LABEL_OPERAND, label);
+ add_reg_note (insn, REG_LABEL_OPERAND, label);
if (rescan)
{
scan = link;
@@ -5000,9 +4998,7 @@ sh_reorg (void)
&& reg_mentioned_p (reg, scan))
|| ((reg2 = sfunc_uses_reg (scan))
&& REGNO (reg2) == REGNO (reg))))
- REG_NOTES (scan)
- = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, label,
- REG_NOTES (scan));
+ add_reg_note (scan, REG_LABEL_OPERAND, label);
}
while (scan != dies);
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 2ff4a81f9b6..5204847abc5 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com).
Improved by Jim Wilson (wilson@cygnus.com).
@@ -712,8 +712,8 @@ do { \
to the pressure on R0. */ \
/* Enable sched1 for SH4; ready queue will be reordered by \
the target hooks when pressure is high. We can not do this for \
- SH3 and lower as they give spill failures for R0. */ \
- if (!TARGET_HARD_SH4) \
+ PIC, SH3 and lower as they give spill failures for R0. */ \
+ if (!TARGET_HARD_SH4 || flag_pic) \
flag_schedule_insns = 0; \
/* ??? Current exception handling places basic block boundaries \
after call_insns. It causes the high pressure on R0 and gives \
diff --git a/gcc/config/sparc/libgcc-sparc-glibc.ver b/gcc/config/sparc/libgcc-sparc-glibc.ver
index ed280fe05a7..8f50c0d5886 100644
--- a/gcc/config/sparc/libgcc-sparc-glibc.ver
+++ b/gcc/config/sparc/libgcc-sparc-glibc.ver
@@ -4,6 +4,20 @@
# maintain enough binary compatibility to allow future versions of glibc
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+%exclude {
+ __divdi3
+ __moddi3
+ __udivdi3
+ __umoddi3
+ __register_frame
+ __register_frame_table
+ __deregister_frame
+ __register_frame_info
+ __deregister_frame_info
+ __frame_state_for
+ __register_frame_info_table
+}
+
%ifdef __arch64__
%define GLIBC_VER GLIBC_2.2
%else
diff --git a/gcc/config/sparc/sol2-ci.asm b/gcc/config/sparc/sol2-ci.asm
index 5726d62d994..d1ddc8412ff 100644
--- a/gcc/config/sparc/sol2-ci.asm
+++ b/gcc/config/sparc/sol2-ci.asm
@@ -40,8 +40,6 @@
! This file is linked in before the Values-Xx.o files and also before
! crtbegin, with which perhaps it should be merged.
- .file "crti.s"
-
.section ".init"
.proc 022
.global _init
diff --git a/gcc/config/sparc/sol2-cn.asm b/gcc/config/sparc/sol2-cn.asm
index 6e2fb2c6e49..aad6f568058 100644
--- a/gcc/config/sparc/sol2-cn.asm
+++ b/gcc/config/sparc/sol2-cn.asm
@@ -37,8 +37,6 @@
! fact return. Users may put any desired instructions in those sections.
! This file is the last thing linked into any executable.
- .file "crtn.s"
-
.section ".init"
.align 4
diff --git a/gcc/config/sync.c b/gcc/config/sync.c
new file mode 100644
index 00000000000..ec60ef0a1a4
--- /dev/null
+++ b/gcc/config/sync.c
@@ -0,0 +1,185 @@
+/* Out-of-line libgcc versions of __sync_* builtins. */
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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. */
+
+/* This file is used by targets whose makefiles define LIBGCC_SYNC
+ to "yes". It is compiled with LIBGCC_SYNC_CFLAGS and provides
+ out-of-line versions of all relevant __sync_* primitives.
+
+ These routines are intended for targets like MIPS that have two
+ ISA encodings (the "normal" ISA and the MIPS16 ISA). The normal
+ ISA provides full synchronization capabilities but the MIPS16 ISA
+ has no encoding for them. MIPS16 code must therefore call external
+ non-MIPS16 implementations of the __sync_* routines.
+
+ The file is compiled once for each routine. The following __foo
+ routines are selected by defining a macro called L<foo>:
+
+ __sync_synchronize
+
+ The following __foo_N routines are selected by defining FN=foo
+ and SIZE=N:
+
+ __sync_fetch_and_add_N
+ __sync_fetch_and_sub_N
+ __sync_fetch_and_or_N
+ __sync_fetch_and_and_N
+ __sync_fetch_and_xor_N
+ __sync_fetch_and_nand_N
+ __sync_add_and_fetch_N
+ __sync_sub_and_fetch_N
+ __sync_or_and_fetch_N
+ __sync_and_and_fetch_N
+ __sync_xor_and_fetch_N
+ __sync_nand_and_fetch_N
+ __sync_bool_compare_and_swap_N
+ __sync_val_compare_and_swap_N
+ __sync_lock_test_and_set_N
+
+ SIZE can be 1, 2, 4, 8 or 16. __foo_N is omitted if the target does
+ not provide __sync_compare_and_swap_N.
+
+ Note that __sync_lock_release does not fall back on external
+ __sync_lock_release_N functions. The default implementation
+ of __sync_lock_release is a call to __sync_synchronize followed
+ by a store of zero, so we don't need separate library functions
+ for it. */
+
+#if defined FN
+
+/* Define macros for each __sync_* function type. Each macro defines a
+ local function called <NAME>_<UNITS> that acts like __<NAME>_<UNITS>.
+ TYPE is a type that has UNITS bytes. */
+
+#define DEFINE_V_PV(NAME, UNITS, TYPE) \
+ static TYPE \
+ NAME##_##UNITS (TYPE *ptr, TYPE value) \
+ { \
+ return __##NAME (ptr, value); \
+ }
+
+#define DEFINE_V_PVV(NAME, UNITS, TYPE) \
+ static TYPE \
+ NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
+ { \
+ return __##NAME (ptr, value1, value2); \
+ }
+
+#define DEFINE_BOOL_PVV(NAME, UNITS, TYPE) \
+ static _Bool \
+ NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
+ { \
+ return __##NAME (ptr, value1, value2); \
+ }
+
+/* Map function names to the appropriate DEFINE_* macro. */
+
+#define local_sync_fetch_and_add DEFINE_V_PV
+#define local_sync_fetch_and_sub DEFINE_V_PV
+#define local_sync_fetch_and_or DEFINE_V_PV
+#define local_sync_fetch_and_and DEFINE_V_PV
+#define local_sync_fetch_and_xor DEFINE_V_PV
+#define local_sync_fetch_and_nand DEFINE_V_PV
+
+#define local_sync_add_and_fetch DEFINE_V_PV
+#define local_sync_sub_and_fetch DEFINE_V_PV
+#define local_sync_or_and_fetch DEFINE_V_PV
+#define local_sync_and_and_fetch DEFINE_V_PV
+#define local_sync_xor_and_fetch DEFINE_V_PV
+#define local_sync_nand_and_fetch DEFINE_V_PV
+
+#define local_sync_bool_compare_and_swap DEFINE_BOOL_PVV
+#define local_sync_val_compare_and_swap DEFINE_V_PVV
+
+#define local_sync_lock_test_and_set DEFINE_V_PV
+
+/* Define the function __<NAME>_<UNITS>, given that TYPE is a type with
+ UNITS bytes. */
+#define DEFINE1(NAME, UNITS, TYPE) \
+ static int unused[sizeof (TYPE) == UNITS ? 1 : -1] \
+ __attribute__((unused)); \
+ local_##NAME (NAME, UNITS, TYPE); \
+ typeof (NAME##_##UNITS) __##NAME##_##UNITS \
+ __attribute__((alias (#NAME "_" #UNITS)));
+
+/* As above, but performing macro expansion on the arguments. */
+#define DEFINE(NAME, UNITS, TYPE) DEFINE1 (NAME, UNITS, TYPE)
+
+/* Find an appropriate type TYPE for SIZE and invoke DEFINE (FN, SIZE, TYPE).
+
+ The types chosen here may be incorrect for some targets.
+ For example, targets with 16-byte atomicity support might not
+ support OImode. We would need some kind of target-specific
+ override if that becomes a problem. */
+
+#if SIZE == 1 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+
+typedef unsigned int UQItype __attribute__((mode (QI)));
+DEFINE (FN, 1, UQItype)
+
+#elif SIZE == 2 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+
+typedef unsigned int UHItype __attribute__((mode (HI)));
+DEFINE (FN, 2, UHItype)
+
+#elif SIZE == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+
+typedef unsigned int USItype __attribute__((mode (SI)));
+DEFINE (FN, 4, USItype)
+
+#elif SIZE == 8 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+
+typedef unsigned int UDItype __attribute__((mode (DI)));
+DEFINE (FN, 8, UDItype)
+
+#elif SIZE == 16 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+
+typedef unsigned int UOItype __attribute__((mode (OI)));
+DEFINE (FN, 8, UOItype)
+
+#endif
+
+#elif __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 \
+ || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 \
+ || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 \
+ || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 \
+ || __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+
+#if defined Lsync_synchronize
+
+static void
+sync_synchronize (void)
+{
+ __sync_synchronize ();
+}
+typeof (sync_synchronize) __sync_synchronize \
+ __attribute__((alias ("sync_synchronize")));
+
+#endif
+
+#endif
diff --git a/gcc/configure b/gcc/configure
index 5c64f60cea3..4f9c86a0e53 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -10744,10 +10744,8 @@ fi
-
-
for ac_func in times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo scandir alphasort \
+ sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap mincore setlocale \
clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked
do
@@ -10973,6 +10971,72 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking for caddr_t" >&5
+echo $ECHO_N "checking for caddr_t... $ECHO_C" >&6
+if test "${ac_cv_type_caddr_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((caddr_t *) 0)
+ return 0;
+if (sizeof (caddr_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_caddr_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_caddr_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_caddr_t" >&5
+echo "${ECHO_T}$ac_cv_type_caddr_t" >&6
+if test $ac_cv_type_caddr_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define caddr_t char *
+_ACEOF
+
+fi
+
# Try to determine the array type of the second argument of getgroups
# for the target system (int or gid_t).
@@ -15306,13 +15370,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:15309: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:15373: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:15312: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:15376: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:15315: output\"" >&5)
+ (eval echo "\"\$as_me:15379: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -16367,7 +16431,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 16370 "configure"' > conftest.$ac_ext
+ echo '#line 16434 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -16987,11 +17051,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16990: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17054: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16994: \$? = $ac_status" >&5
+ echo "$as_me:17058: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -17309,11 +17373,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17312: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17376: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17316: \$? = $ac_status" >&5
+ echo "$as_me:17380: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -17414,11 +17478,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17417: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17481: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17421: \$? = $ac_status" >&5
+ echo "$as_me:17485: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -17469,11 +17533,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17472: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17536: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17476: \$? = $ac_status" >&5
+ echo "$as_me:17540: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -20266,7 +20330,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 20269 "configure"
+#line 20333 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20366,7 +20430,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 20369 "configure"
+#line 20433 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index c32af5ec3fe..9fc7d0b00f6 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1294,7 +1294,7 @@ define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl
fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo scandir alphasort \
+ sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap mincore setlocale \
gcc_UNLOCKED_FUNCS)
@@ -1317,6 +1317,7 @@ int main()
fi
AC_CHECK_TYPE(ssize_t, int)
+AC_CHECK_TYPE(caddr_t, char *)
# Try to determine the array type of the second argument of getgroups
# for the target system (int or gid_t).
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8aff706f9db..5ef7e2e1005 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,82 @@
+2008-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR c++/36128
+ * typeck.c (cp_build_function_call): Move code to verify
+ builtin function arguments ...
+ * call.c (build_cxx_call): ... here.
+
+2008-07-02 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (cp/typeck2.o): Add $(REAL_H) dependency.
+
+ Implement WG21 N2672, Initializer List proposed wording
+ * cp-tree.h (enum cp_tree_index): Add CPTI_INIT_LIST_TYPE.
+ (struct lang_type_class): Add has_list_ctor bitfield.
+ (TYPE_HAS_LIST_CTOR): New macro.
+ (BRACE_ENCLOSED_INITIALIZER_P): Expect init_list_type_node.
+ (CONSTRUCTOR_IS_DIRECT_INIT): New macro.
+ (LOOKUP_NO_NARROWING): New macro.
+ (LOOKUP_NO_COPY_CTOR_CONVERSION): New macro.
+ * parser.c (cp_parse_braced_list): Split out from...
+ (cp_parser_initializer_clause): ...here.
+ (cp_parser_postfix_expression): Build up CONSTRUCTOR for compound
+ literal here.
+ (cp_lexer_next_token_is_not_keyword): New fn.
+ (cp_parser_parenthesized_expression_list): Handle { }.
+ (cp_parser_new_expression, cp_parser_new_initializer): Likewise.
+ (cp_parser_assignment_expression, cp_parser_condition): Likewise.
+ (cp_parser_jump_statement, cp_parser_simple_declaration): Likewise.
+ (cp_parser_mem_initializer, cp_parser_init_declarator): Likewise.
+ (cp_parser_initializer, cp_parser_functional_cast): Likewise.
+ (cp_parser_omp_for_loop, cp_parser_cache_group): Likewise.
+ (cp_parser_save_member_function_body): Likewise.
+ * call.c (conversion_kind): Add ck_list, ck_aggr.
+ (struct conversion): Add check_narrowing bitfield, conversion list.
+ (build_list_conv): New fn.
+ (build_aggr_conv): New fn.
+ (implicit_conversion): Call them.
+ (standard_conversion): Set check_narrowing if appropriate.
+ (add_function_candidate): Handle LOOKUP_NO_COPY_CTOR_CONVERSION.
+ (build_user_type_conversion_1): When converting from an init list,
+ we allow additional conversions except when calling a copy ctor.
+ (convert_like_real): Calling an explicit ctor for an init list is
+ ill-formed. Handle ck_list and ck_addr. Check narrowing.
+ (build_new_method_call): If CONSTRUCTOR_IS_DIRECT_INIT is set and
+ class doesn't have a list ctor, break the {} into a TREE_LIST.
+ (compare_ics): ck_list is better than other UDCs.
+ (set_up_extended_ref_temp): Split out from initialize_reference.
+ (is_std_init_list): New fn.
+ (is_list_ctor): New fn.
+ * decl.c (cxx_init_decl_processing): Create init_list_type_node.
+ (reshape_init_array_1): Pass it to build_constructor.
+ (reshape_init_class): Ditto.
+ (initialize_artificial_var): Pass the appropriate type.
+ (build_aggr_init_full_exprs): Split out from...
+ (check_initializer): ...here. Handle new semantics.
+ (build_init_list_var_init): New subroutine of check_initializer.
+ (grokdeclarator): Converting constructors can have more than one parm.
+ (grok_special_member_properties): Set TYPE_HAS_LIST_CTOR.
+ * init.c (expand_default_init): Only do digest_init for aggregates.
+ * rtti.c (tinfo_base_init): Pass init_list_type_node to
+ build_constructor_from_list.
+ (generic_initializer, ptr_initializer): Ditto.
+ (ptm_initializer, class_initializer): Ditto.
+ (get_pseudo_ti_init): Ditto.
+ * error.c (dump_type): Handle init_list_type_node.
+ (maybe_warn_cpp0x): New fn.
+ (maybe_varn_variadic_templates): Call it.
+ * cvt.c (ocp_convert): Handle conversion from { }.
+ * tree.c (build_array_of_n_type): New fn.
+ * typeck2.c (store_init_value): Use init_list_type_node.
+ (digest_init): Likewise.
+ (check_narrowing): New fn.
+ * semantics.c: (finish_compound_literal): Take CONSTRUCTOR instead
+ of vector of constructor elts. Handle non-aggregate types. Make
+ constant literals static.
+ * pt.c: (tsubst_copy_and_build): Adjust.
+ (unify): Handle { }.
+ * name-lookup.c (arg_assoc_type): Handle init_list_type_node.
+
2008-07-01 Daniel Jacobowitz <dan@codesourcery.com>
* typeck.c (comp_ptr_ttypes_real): Use vector_targets_convertible_p.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 6fced350ec4..c7877205f25 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -245,7 +245,7 @@ cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
$(CXX_PRETTY_PRINT_H) cp/cp-objcp-common.h gt-cp-cp-objcp-common.h
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h output.h \
- $(TM_P_H) $(DIAGNOSTIC_H) gt-cp-typeck2.h
+ $(TM_P_H) $(DIAGNOSTIC_H) gt-cp-typeck2.h $(REAL_H)
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \
toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H)
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7f4c0168483..368d95a677f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -54,6 +54,8 @@ typedef enum conversion_kind {
ck_ref_bind,
ck_user,
ck_ambig,
+ ck_list,
+ ck_aggr,
ck_rvalue
} conversion_kind;
@@ -96,6 +98,7 @@ struct conversion {
being bound to an lvalue expression or an rvalue reference is
being bound to an rvalue expression. */
BOOL_BITFIELD rvaluedness_matches_p: 1;
+ BOOL_BITFIELD check_narrowing: 1;
/* The type of the expression resulting from the conversion. */
tree type;
union {
@@ -107,6 +110,8 @@ struct conversion {
/* The expression at the beginning of the conversion chain. This
variant is used only if KIND is ck_identity or ck_ambig. */
tree expr;
+ /* The array of conversions for an initializer_list. */
+ conversion **list;
} u;
/* The function candidate corresponding to this conversion
sequence. This field is only used if KIND is ck_user. */
@@ -174,6 +179,7 @@ static conversion *implicit_conversion (tree, tree, tree, bool, int);
static conversion *standard_conversion (tree, tree, tree, bool, int);
static conversion *reference_binding (tree, tree, tree, bool, int);
static conversion *build_conv (conversion_kind, tree, conversion *);
+static conversion *build_list_conv (tree, tree, int);
static bool is_subseq (conversion *, conversion *);
static conversion *maybe_handle_ref_bind (conversion **);
static void maybe_handle_implicit_object (conversion **);
@@ -529,9 +535,8 @@ build_conv (conversion_kind code, tree type, conversion *from)
conversion *t;
conversion_rank rank = CONVERSION_RANK (from);
- /* We can't use buildl1 here because CODE could be USER_CONV, which
- takes two arguments. In that case, the caller is responsible for
- filling in the second argument. */
+ /* Note that the caller is responsible for filling in t->cand for
+ user-defined conversions. */
t = alloc_conversion (code);
t->type = type;
t->u.next = from;
@@ -561,6 +566,83 @@ build_conv (conversion_kind code, tree type, conversion *from)
return t;
}
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+ specialization of std::initializer_list<T>, if such a conversion is
+ possible. */
+
+static conversion *
+build_list_conv (tree type, tree ctor, int flags)
+{
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
+ unsigned len = CONSTRUCTOR_NELTS (ctor);
+ conversion **subconvs = alloc_conversions (len);
+ conversion *t;
+ unsigned i;
+ tree val;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (val), val,
+ false, flags);
+ if (sub == NULL)
+ return NULL;
+
+ subconvs[i] = sub;
+ }
+
+ t = alloc_conversion (ck_list);
+ t->type = type;
+ t->u.list = subconvs;
+ t->rank = cr_exact;
+
+ for (i = 0; i < len; ++i)
+ {
+ conversion *sub = subconvs[i];
+ if (sub->rank > t->rank)
+ t->rank = sub->rank;
+ if (sub->user_conv_p)
+ t->user_conv_p = true;
+ if (sub->bad_p)
+ t->bad_p = true;
+ }
+
+ return t;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+ aggregate class, if such a conversion is possible. */
+
+static conversion *
+build_aggr_conv (tree type, tree ctor, int flags)
+{
+ unsigned HOST_WIDE_INT i = 0;
+ conversion *c;
+ tree field = TYPE_FIELDS (type);
+
+ for (; field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+ if (i < CONSTRUCTOR_NELTS (ctor))
+ {
+ constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
+ if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
+ ce->value, flags))
+ return NULL;
+ }
+ else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
+ return NULL;
+ }
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = cr_exact;
+ c->user_conv_p = true;
+ c->u.next = NULL;
+ return c;
+}
+
/* Build a representation of the identity conversion from EXPR to
itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */
@@ -865,6 +947,9 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
else
return NULL;
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+
return conv;
}
@@ -1296,6 +1381,10 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
if (conv)
return conv;
+ if (is_std_init_list (to) && expr
+ && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ return build_list_conv (to, expr, flags);
+
if (expr != NULL_TREE
&& (MAYBE_CLASS_TYPE_P (from)
|| MAYBE_CLASS_TYPE_P (to))
@@ -1305,6 +1394,11 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
int convflags = ((flags & LOOKUP_NO_TEMP_BIND)
|LOOKUP_ONLYCONVERTING);
+ if (CLASS_TYPE_P (to)
+ && !CLASSTYPE_NON_AGGREGATE (complete_type (to))
+ && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ return build_aggr_conv (to, expr, flags);
+
cand = build_user_type_conversion_1 (to, expr, convflags);
if (cand)
conv = cand->second_conv;
@@ -1431,6 +1525,7 @@ add_function_candidate (struct z_candidate **candidates,
if (parmnode)
{
tree parmtype = TREE_VALUE (parmnode);
+ int lflags = flags;
/* The type of the implicit object parameter ('this') for
overload resolution is not always the same as for the
@@ -1449,8 +1544,12 @@ add_function_candidate (struct z_candidate **candidates,
parmtype = build_pointer_type (parmtype);
}
+ if ((flags & LOOKUP_NO_COPY_CTOR_CONVERSION)
+ && ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+ lflags |= LOOKUP_NO_CONVERSION;
+
t = implicit_conversion (parmtype, argtype, arg,
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, lflags);
}
else
{
@@ -2607,7 +2706,18 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
ctors = BASELINK_FUNCTIONS (ctors);
t = build_int_cst (build_pointer_type (totype), 0);
- args = build_tree_list (NULL_TREE, expr);
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && !TYPE_HAS_LIST_CTOR (totype))
+ {
+ args = ctor_to_list (expr);
+ /* We still allow more conversions within an init-list. */
+ flags = ((flags & ~LOOKUP_NO_CONVERSION)
+ /* But not for the copy ctor. */
+ |LOOKUP_NO_COPY_CTOR_CONVERSION
+ |LOOKUP_NO_NARROWING);
+ }
+ else
+ args = build_tree_list (NULL_TREE, expr);
/* We should never try to call the abstract or base constructor
from here. */
gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
@@ -2617,7 +2727,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
for (; ctors; ctors = OVL_NEXT (ctors))
{
tree ctor = OVL_CURRENT (ctors);
- if (DECL_NONCONVERTING_P (ctor))
+ if (DECL_NONCONVERTING_P (ctor)
+ && !BRACE_ENCLOSED_INITIALIZER_P (expr))
continue;
if (TREE_CODE (ctor) == TEMPLATE_DECL)
@@ -4443,6 +4554,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree convfn = cand->fn;
unsigned i;
+ /* When converting from an init list we consider explicit
+ constructors, but actually trying to call one is an error. */
+ if (DECL_NONCONVERTING_P (convfn))
+ {
+ if (complain & tf_error)
+ error ("converting to %qT from initializer list would use "
+ "explicit constructor %qD", totype, convfn);
+ else
+ return error_mark_node;
+ }
+
/* Set user_conv_p on the argument conversions, so rvalue/base
handling knows not to allow any more UDCs. */
for (i = 0; i < cand->num_convs; ++i)
@@ -4478,6 +4600,44 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return build_user_type_conversion
(totype, convs->u.expr, LOOKUP_NORMAL);
+ case ck_list:
+ {
+ /* Conversion to std::initializer_list<T>. */
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
+ tree new_ctor = build_constructor (init_list_type_node, NULL);
+ unsigned len = CONSTRUCTOR_NELTS (expr);
+ tree array, parms, val;
+ unsigned ix;
+
+ /* Convert all the elements. */
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+ {
+ tree sub = convert_like_real (convs->u.list[ix], val, fn, argnum,
+ 1, false, false, complain);
+ if (sub == error_mark_node)
+ return sub;
+ check_narrowing (TREE_TYPE (sub), val);
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub);
+ }
+ /* Build up the array. */
+ elttype = cp_build_qualified_type
+ (elttype, TYPE_QUALS (elttype) | TYPE_QUAL_CONST);
+ array = build_array_of_n_type (elttype, len);
+ array = finish_compound_literal (array, new_ctor);
+
+ parms = build_tree_list (NULL_TREE, size_int (len));
+ parms = tree_cons (NULL_TREE, decay_conversion (array), parms);
+ /* Call the private constructor. */
+ push_deferring_access_checks (dk_no_check);
+ new_ctor = build_special_member_call
+ (NULL_TREE, complete_ctor_identifier, parms, totype, 0, complain);
+ pop_deferring_access_checks ();
+ return build_cplus_new (totype, new_ctor);
+ }
+
+ case ck_aggr:
+ return get_target_expr (digest_init (totype, expr));
+
default:
break;
};
@@ -4625,6 +4785,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
break;
}
+ if (convs->check_narrowing)
+ check_narrowing (totype, expr);
+
if (issue_conversion_warnings)
expr = convert_and_check (totype, expr);
else
@@ -5255,6 +5418,13 @@ build_cxx_call (tree fn, int nargs, tree *argarray)
&& cfun)
cp_function_chain->can_throw = 1;
+ /* Check that arguments to builtin functions match the expectations. */
+ if (fndecl
+ && DECL_BUILT_IN (fndecl)
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && !check_builtin_function_arguments (fndecl, nargs, argarray))
+ return error_mark_node;
+
/* Some built-in function calls will be evaluated at compile-time in
fold (). */
fn = fold_if_not_in_template (fn);
@@ -5626,6 +5796,18 @@ build_new_method_call (tree instance, tree fns, tree args,
if (DECL_DESTRUCTOR_P (fn))
name = complete_dtor_identifier;
+ /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
+ initializer, not T({ }). If the type doesn't have a list ctor,
+ break apart the list into separate ctor args. */
+ if (DECL_CONSTRUCTOR_P (fn) && args
+ && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (args))
+ && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (args))
+ && !TYPE_HAS_LIST_CTOR (basetype))
+ {
+ gcc_assert (TREE_CHAIN (args) == NULL_TREE);
+ args = ctor_to_list (TREE_VALUE (args));
+ }
+
class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
mem_args = tree_cons (NULL_TREE, instance_ptr, args);
@@ -5977,13 +6159,26 @@ compare_ics (conversion *ics1, conversion *ics2)
conversion *t1;
conversion *t2;
- for (t1 = ics1; t1->kind != ck_user; t1 = t1->u.next)
- if (t1->kind == ck_ambig)
+ for (t1 = ics1; t1->kind != ck_user && t1->kind != ck_list; t1 = t1->u.next)
+ if (t1->kind == ck_ambig || t1->kind == ck_aggr)
return 0;
- for (t2 = ics2; t2->kind != ck_user; t2 = t2->u.next)
- if (t2->kind == ck_ambig)
+ for (t2 = ics2; t2->kind != ck_user && t2->kind != ck_list; t2 = t2->u.next)
+ if (t2->kind == ck_ambig || t2->kind == ck_aggr)
return 0;
+ /* Conversion to std::initializer_list is better than other
+ user-defined conversions. */
+ if (t1->kind == ck_list
+ || t2->kind == ck_list)
+ {
+ if (t2->kind != ck_list)
+ return 1;
+ else if (t1->kind != ck_list)
+ return -1;
+ else
+ return 0;
+ }
+
if (t1->cand->fn != t2->cand->fn)
return 0;
@@ -6815,6 +7010,76 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
return var;
}
+/* EXPR is the initializer for a variable DECL of reference or
+ std::initializer_list type. Create, push and return a new VAR_DECL
+ for the initializer so that it will live as long as DECL. Any
+ cleanup for the new variable is returned through CLEANUP, and the
+ code to initialize the new variable is returned through INITP. */
+
+tree
+set_up_extended_ref_temp (tree decl, tree expr, tree *cleanup, tree *initp)
+{
+ tree init;
+ tree type;
+ tree var;
+
+ /* Create the temporary variable. */
+ type = TREE_TYPE (expr);
+ var = make_temporary_var_for_ref_to_temp (decl, type);
+ layout_decl (var, 0);
+ /* If the rvalue is the result of a function call it will be
+ a TARGET_EXPR. If it is some other construct (such as a
+ member access expression where the underlying object is
+ itself the result of a function call), turn it into a
+ TARGET_EXPR here. It is important that EXPR be a
+ TARGET_EXPR below since otherwise the INIT_EXPR will
+ attempt to make a bitwise copy of EXPR to initialize
+ VAR. */
+ if (TREE_CODE (expr) != TARGET_EXPR)
+ expr = get_target_expr (expr);
+ /* Create the INIT_EXPR that will initialize the temporary
+ variable. */
+ init = build2 (INIT_EXPR, type, var, expr);
+ if (at_function_scope_p ())
+ {
+ add_decl_expr (var);
+
+ if (TREE_STATIC (var))
+ init = add_stmt_to_compound (init, register_dtor_fn (var));
+ else
+ *cleanup = cxx_maybe_build_cleanup (var);
+
+ /* We must be careful to destroy the temporary only
+ after its initialization has taken place. If the
+ initialization throws an exception, then the
+ destructor should not be run. We cannot simply
+ transform INIT into something like:
+
+ (INIT, ({ CLEANUP_STMT; }))
+
+ because emit_local_var always treats the
+ initializer as a full-expression. Thus, the
+ destructor would run too early; it would run at the
+ end of initializing the reference variable, rather
+ than at the end of the block enclosing the
+ reference variable.
+
+ The solution is to pass back a cleanup expression
+ which the caller is responsible for attaching to
+ the statement tree. */
+ }
+ else
+ {
+ rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ static_aggregates = tree_cons (NULL_TREE, var,
+ static_aggregates);
+ }
+
+ *initp = init;
+ return var;
+}
+
/* Convert EXPR to the indicated reference TYPE, in a way suitable for
initializing a variable of that TYPE. If DECL is non-NULL, it is
the VAR_DECL being initialized with the EXPR. (In that case, the
@@ -6919,60 +7184,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
if (!real_lvalue_p (expr))
{
tree init;
- tree type;
-
- /* Create the temporary variable. */
- type = TREE_TYPE (expr);
- var = make_temporary_var_for_ref_to_temp (decl, type);
- layout_decl (var, 0);
- /* If the rvalue is the result of a function call it will be
- a TARGET_EXPR. If it is some other construct (such as a
- member access expression where the underlying object is
- itself the result of a function call), turn it into a
- TARGET_EXPR here. It is important that EXPR be a
- TARGET_EXPR below since otherwise the INIT_EXPR will
- attempt to make a bitwise copy of EXPR to initialize
- VAR. */
- if (TREE_CODE (expr) != TARGET_EXPR)
- expr = get_target_expr (expr);
- /* Create the INIT_EXPR that will initialize the temporary
- variable. */
- init = build2 (INIT_EXPR, type, var, expr);
- if (at_function_scope_p ())
- {
- add_decl_expr (var);
-
- if (TREE_STATIC (var))
- init = add_stmt_to_compound (init, register_dtor_fn (var));
- else
- *cleanup = cxx_maybe_build_cleanup (var);
-
- /* We must be careful to destroy the temporary only
- after its initialization has taken place. If the
- initialization throws an exception, then the
- destructor should not be run. We cannot simply
- transform INIT into something like:
-
- (INIT, ({ CLEANUP_STMT; }))
-
- because emit_local_var always treats the
- initializer as a full-expression. Thus, the
- destructor would run too early; it would run at the
- end of initializing the reference variable, rather
- than at the end of the block enclosing the
- reference variable.
-
- The solution is to pass back a cleanup expression
- which the caller is responsible for attaching to
- the statement tree. */
- }
- else
- {
- rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
- static_aggregates = tree_cons (NULL_TREE, var,
- static_aggregates);
- }
+ var = set_up_extended_ref_temp (decl, expr, cleanup, &init);
/* Use its address to initialize the reference variable. */
expr = build_address (var);
if (base_conv_type)
@@ -7003,4 +7215,39 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
return expr;
}
+/* Returns true iff TYPE is some variant of std::initializer_list. */
+
+bool
+is_std_init_list (tree type)
+{
+ return (CLASS_TYPE_P (type)
+ && CP_TYPE_CONTEXT (type) == std_node
+ && strcmp (TYPE_NAME_STRING (type), "initializer_list") == 0);
+}
+
+/* Returns true iff DECL is a list constructor: i.e. a constructor which
+ will accept an argument list of a single std::initializer_list<T>. */
+
+bool
+is_list_ctor (tree decl)
+{
+ tree args = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree arg;
+
+ if (!args || args == void_list_node)
+ return false;
+
+ arg = non_reference (TREE_VALUE (args));
+ if (!is_std_init_list (arg))
+ return false;
+
+ args = TREE_CHAIN (args);
+
+ if (args && args != void_list_node && !TREE_PURPOSE (args))
+ /* There are more non-defaulted parms. */
+ return false;
+
+ return true;
+}
+
#include "gt-cp-call.h"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d090d8ff0e2..ed6ae0e810a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -59,6 +59,7 @@ struct diagnostic_info;
TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
TYPE_REF_IS_RVALUE (in REFERENCE_TYPE)
ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute)
+ CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -572,6 +573,7 @@ enum cp_tree_index
CPTI_CLASS_TYPE,
CPTI_UNKNOWN_TYPE,
+ CPTI_INIT_LIST_TYPE,
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
CPTI_STD,
@@ -637,6 +639,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define class_type_node cp_global_trees[CPTI_CLASS_TYPE]
#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE]
+#define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE]
#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
#define std_node cp_global_trees[CPTI_STD]
@@ -1126,6 +1129,7 @@ struct lang_type_class GTY(())
unsigned has_complex_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned has_complex_dflt : 1;
+ unsigned has_list_ctor : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@@ -1134,7 +1138,7 @@ struct lang_type_class GTY(())
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
- unsigned dummy : 11;
+ unsigned dummy : 10;
tree primary_base;
VEC(tree_pair_s,gc) *vcall_indices;
@@ -1248,6 +1252,10 @@ struct lang_type GTY(())
#define TYPE_HAS_CONST_INIT_REF(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->has_const_init_ref)
+/* Nonzero if this class has an X(initializer_list<T>) constructor. */
+#define TYPE_HAS_LIST_CTOR(NODE) \
+ (LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor)
+
/* Nonzero if this class defines an overloaded operator new. (An
operator new [] doesn't count.) */
#define TYPE_HAS_NEW_OPERATOR(NODE) \
@@ -2713,7 +2721,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* True if NODE is a brace-enclosed initializer. */
#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \
- (TREE_CODE (NODE) == CONSTRUCTOR && !TREE_TYPE (NODE))
+ (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node)
/* True if NODE is a compound-literal, i.e., a brace-enclosed
initializer cast to a particular type. */
@@ -2725,6 +2733,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
CONSTRUCTOR_ELTS (NODE)) \
&& !TREE_HAS_CONSTRUCTOR (NODE))
+/* True if NODE is a init-list used as a direct-initializer, i.e.
+ B b{1,2}, not B b({1,2}) or B b = {1,2}. */
+#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+
/* Nonzero means that an object of this type can not be initialized using
an initializer list. */
#define CLASSTYPE_NON_AGGREGATE(NODE) \
@@ -3688,6 +3700,11 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define LOOKUP_HIDDEN (LOOKUP_PREFER_NAMESPACES << 1)
/* Prefer that the lvalue be treated as an rvalue. */
#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1)
+/* We're inside an init-list, so narrowing conversions are ill-formed. */
+#define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1)
+/* Avoid user-defined conversions for the first parameter of a copy
+ constructor. */
+#define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -4084,6 +4101,7 @@ extern tree cxx_type_promotes_to (tree);
extern tree type_passed_as (tree);
extern tree convert_for_arg_passing (tree, tree);
extern bool is_properly_derived_from (tree, tree);
+extern tree set_up_extended_ref_temp (tree, tree, tree *, tree *);
extern tree initialize_reference (tree, tree, tree, tree *);
extern tree make_temporary_var_for_ref_to_temp (tree, tree);
extern tree strip_top_quals (tree);
@@ -4092,6 +4110,8 @@ extern tree perform_direct_initialization_if_possible (tree, tree, bool,
tsubst_flags_t);
extern tree in_charge_arg_for_name (tree);
extern tree build_cxx_call (tree, int, tree *);
+extern bool is_std_init_list (tree);
+extern bool is_list_ctor (tree);
#ifdef ENABLE_CHECKING
extern void validate_conversion_obstack (void);
#endif /* ENABLE_CHECKING */
@@ -4311,6 +4331,7 @@ extern const char *language_to_string (enum languages);
extern const char *class_key_or_enum_as_string (tree);
extern void print_instantiation_context (void);
extern void maybe_warn_variadic_templates (void);
+extern void maybe_warn_cpp0x (const char *);
/* in except.c */
extern void init_exception_processing (void);
@@ -4622,7 +4643,7 @@ extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void);
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
extern tree finish_unary_op_expr (enum tree_code, tree);
-extern tree finish_compound_literal (tree, VEC(constructor_elt,gc) *);
+extern tree finish_compound_literal (tree, tree);
extern tree finish_fname (tree);
extern void finish_translation_unit (void);
extern tree finish_template_type_parm (tree, tree);
@@ -4707,6 +4728,7 @@ extern tree build_min_non_dep_call_list (tree, tree, tree);
extern tree build_cplus_new (tree, tree);
extern tree get_target_expr (tree);
extern tree build_cplus_array_type (tree, tree);
+extern tree build_array_of_n_type (tree, int);
extern tree hash_tree_cons (tree, tree, tree);
extern tree hash_tree_chain (tree, tree);
extern tree build_qualified_name (tree, tree, tree, bool);
@@ -4861,6 +4883,7 @@ extern void complete_type_check_abstract (tree);
extern int abstract_virtuals_error (tree, tree);
extern tree store_init_value (tree, tree);
+extern void check_narrowing (tree, tree);
extern tree digest_init (tree, tree);
extern tree build_scoped_ref (tree, tree, tree *);
extern tree build_x_arrow (tree);
@@ -4882,6 +4905,7 @@ extern tree mangle_thunk (tree, int, tree, tree);
extern tree mangle_conv_op_name_for_type (tree);
extern tree mangle_guard_variable (tree);
extern tree mangle_ref_init_variable (tree);
+extern tree mangle_compound_literal (void);
/* in dump.c */
extern bool cp_dump_tree (void *, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index b2c17c547db..70ef00a4fce 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -725,8 +725,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
if (abstract_virtuals_error (NULL_TREE, type))
return error_mark_node;
- if ((flags & LOOKUP_ONLYCONVERTING)
- && ! (MAYBE_CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
+ if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
+ ctor = perform_implicit_conversion (type, ctor, tf_warning_or_error);
+ else if ((flags & LOOKUP_ONLYCONVERTING)
+ && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
/* For copy-initialization, first we create a temp of the proper type
with a user-defined conversion sequence, then we direct-initialize
the target with the temp (see [dcl.init]). */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c6ae93e6104..a5a5574d7b4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3344,6 +3344,9 @@ cxx_init_decl_processing (void)
TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
+ init_list_type_node = make_node (UNKNOWN_TYPE);
+ record_unknown_type (init_list_type_node, "init list");
+
{
/* Make sure we get a unique function type, so we can give
its pointer type a name. (This wins for gdb.) */
@@ -4295,6 +4298,39 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
return NULL_TREE;
}
+/* Subroutine of check_initializer. We're initializing a DECL of
+ std::initializer_list<T> TYPE from a braced-init-list INIT, and need to
+ extend the lifetime of the underlying array to match that of the decl,
+ just like for reference initialization. CLEANUP is as for
+ grok_reference_init. */
+
+static tree
+build_init_list_var_init (tree decl, tree type, tree init, tree *cleanup)
+{
+ tree aggr_init, array, arrtype;
+ init = perform_implicit_conversion (type, init, tf_warning_or_error);
+ aggr_init = TARGET_EXPR_INITIAL (init);
+ init = build2 (INIT_EXPR, type, decl, init);
+
+ array = AGGR_INIT_EXPR_ARG (aggr_init, 1);
+ arrtype = TREE_TYPE (array);
+ STRIP_NOPS (array);
+ gcc_assert (TREE_CODE (array) == ADDR_EXPR);
+ array = TREE_OPERAND (array, 0);
+ /* If the array is constant, finish_compound_literal already made it a
+ static variable and we don't need to do anything here. */
+ if (decl && TREE_CODE (array) == TARGET_EXPR)
+ {
+ tree subinit;
+ tree var = set_up_extended_ref_temp (decl, array, cleanup, &subinit);
+ var = build_address (var);
+ var = convert (arrtype, var);
+ AGGR_INIT_EXPR_ARG (aggr_init, 1) = var;
+ init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init);
+ }
+ return init;
+}
+
/* Designated initializers in arrays are not supported in GNU C++.
The parser cannot detect this error since it does not know whether
a given brace-enclosed initializer is for a class type or for an
@@ -4573,7 +4609,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
unsigned HOST_WIDE_INT index;
/* The initializer for an array is always a CONSTRUCTOR. */
- new_init = build_constructor (NULL_TREE, NULL);
+ new_init = build_constructor (init_list_type_node, NULL);
if (sized_array_p)
{
@@ -4668,7 +4704,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
gcc_assert (CLASS_TYPE_P (type));
/* The initializer for a class is always a CONSTRUCTOR. */
- new_init = build_constructor (NULL_TREE, NULL);
+ new_init = build_constructor (init_list_type_node, NULL);
field = next_initializable_field (TYPE_FIELDS (type));
if (!field)
@@ -4926,6 +4962,26 @@ check_array_initializer (tree decl, tree type, tree init)
return false;
}
+/* Subroutine of check_initializer; args are passed down from that function.
+ Set stmts_are_full_exprs_p to 1 across a call to build_aggr_init. */
+
+static tree
+build_aggr_init_full_exprs (tree decl, tree init, int flags)
+
+{
+ int saved_stmts_are_full_exprs_p = 0;
+ if (building_stmt_tree ())
+ {
+ saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ }
+ init = build_aggr_init (decl, init, flags, tf_warning_or_error);
+ if (building_stmt_tree ())
+ current_stmt_tree ()->stmts_are_full_exprs_p =
+ saved_stmts_are_full_exprs_p;
+ return init;
+}
+
/* Verify INIT (the initializer for DECL), and record the
initialization in DECL_INITIAL, if appropriate. CLEANUP is as for
grok_reference_init.
@@ -4967,7 +5023,12 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
int init_len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init));
if (SCALAR_TYPE_P (type))
{
- if (init_len != 1)
+ if (init_len == 0)
+ {
+ maybe_warn_cpp0x ("extended initializer lists");
+ init = build_zero_init (type, NULL_TREE, false);
+ }
+ else if (init_len != 1)
{
error ("scalar object %qD requires one element in initializer",
decl);
@@ -4975,15 +5036,6 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
return NULL_TREE;
}
}
- else if ((cxx_dialect == cxx98) && !CP_AGGREGATE_TYPE_P (type))
- {
- /* A non-aggregate that is not a scalar cannot be initialized
- via an initializer-list in C++98. */
- error ("braces around initializer for non-aggregate type %qT",
- type);
- TREE_TYPE (decl) = error_mark_node;
- return NULL_TREE;
- }
}
if (TREE_CODE (decl) == CONST_DECL)
@@ -5001,17 +5053,26 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
{
/* Do not reshape constructors of vectors (they don't need to be
reshaped. */
- if (TREE_CODE (init) == CONSTRUCTOR
- && !COMPOUND_LITERAL_P (init)
- && !TREE_TYPE (init)) /* ptrmemfunc */
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
{
- init = reshape_init (type, init);
-
- if ((*targetm.vector_opaque_p) (type))
+ if (is_std_init_list (type))
+ return build_init_list_var_init (decl, type, init, cleanup);
+ else if (TYPE_NON_AGGREGATE_CLASS (type))
+ {
+ /* Don't reshape if the class has constructors. */
+ if (cxx_dialect == cxx98)
+ error ("in C++98 %qD must be initialized by constructor, "
+ "not by %<{...}%>",
+ decl);
+ init = build_tree_list (NULL_TREE, init);
+ }
+ else if ((*targetm.vector_opaque_p) (type))
{
error ("opaque vector types cannot be initialized");
init = error_mark_node;
}
+ else
+ init = reshape_init (type, init);
}
/* If DECL has an array type without a specific bound, deduce the
@@ -5021,60 +5082,26 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
if (type == error_mark_node)
return NULL_TREE;
- if (TREE_CODE (type) == ARRAY_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
- goto initialize_aggr;
- else if (CLASS_TYPE_P (type))
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ || (CLASS_TYPE_P (type)
+ && !BRACE_ENCLOSED_INITIALIZER_P (init)))
+ return build_aggr_init_full_exprs (decl, init, flags);
+ else if (TREE_CODE (init) != TREE_VEC)
{
- if (TREE_CODE (init) == CONSTRUCTOR)
- {
- if (TYPE_NON_AGGREGATE_CLASS (type))
- {
- error ("%qD must be initialized by constructor, "
- "not by %<{...}%>",
- decl);
- init = error_mark_node;
- }
- else
- goto dont_use_constructor;
- }
- else
- {
- int saved_stmts_are_full_exprs_p;
-
- initialize_aggr:
- saved_stmts_are_full_exprs_p = 0;
- if (building_stmt_tree ())
- {
- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
- current_stmt_tree ()->stmts_are_full_exprs_p = 1;
- }
- init = build_aggr_init (decl, init, flags, tf_warning_or_error);
- if (building_stmt_tree ())
- current_stmt_tree ()->stmts_are_full_exprs_p =
- saved_stmts_are_full_exprs_p;
- return init;
- }
- }
- else
- {
- dont_use_constructor:
- if (TREE_CODE (init) != TREE_VEC)
- {
- init_code = store_init_value (decl, init);
- if (pedantic && TREE_CODE (type) == ARRAY_TYPE
- && DECL_INITIAL (decl)
- && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
- && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl)))
- warning (0, "array %qD initialized by parenthesized string literal %qE",
- decl, DECL_INITIAL (decl));
- init = NULL;
- }
+ init_code = store_init_value (decl, init);
+ if (pedantic && TREE_CODE (type) == ARRAY_TYPE
+ && DECL_INITIAL (decl)
+ && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
+ && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl)))
+ warning (0, "array %qD initialized by parenthesized string literal %qE",
+ decl, DECL_INITIAL (decl));
+ init = NULL;
}
}
else if (DECL_EXTERNAL (decl))
;
else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))
- goto initialize_aggr;
+ return build_aggr_init_full_exprs (decl, init, flags);
else if (MAYBE_CLASS_TYPE_P (type))
{
tree core_type = strip_array_types (type);
@@ -5311,7 +5338,7 @@ initialize_artificial_var (tree decl, tree init)
{
gcc_assert (DECL_ARTIFICIAL (decl));
if (TREE_CODE (init) == TREE_LIST)
- init = build_constructor_from_list (NULL_TREE, init);
+ init = build_constructor_from_list (TREE_TYPE (decl), init);
gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
DECL_INITIAL (decl) = init;
DECL_INITIALIZED_P (decl) = 1;
@@ -8921,17 +8948,11 @@ grokdeclarator (const cp_declarator *declarator,
DECL_NONCONVERTING_P (decl) = 1;
else if (DECL_CONSTRUCTOR_P (decl))
{
- /* The constructor can be called with exactly one
- parameter if there is at least one parameter, and
- any subsequent parameters have default arguments.
+ /* A constructor with no parms is not a conversion.
Ignore any compiler-added parms. */
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
- if (arg_types == void_list_node
- || (arg_types
- && TREE_CHAIN (arg_types)
- && TREE_CHAIN (arg_types) != void_list_node
- && !TREE_PURPOSE (TREE_CHAIN (arg_types))))
+ if (arg_types == void_list_node)
DECL_NONCONVERTING_P (decl) = 1;
}
}
@@ -9646,6 +9667,8 @@ grok_special_member_properties (tree decl)
}
else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
+ else if (is_list_ctor (decl))
+ TYPE_HAS_LIST_CTOR (class_type) = 1;
}
else if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
{
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 55e620a6b54..80aa6e962d2 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -284,7 +284,10 @@ dump_type (tree t, int flags)
switch (TREE_CODE (t))
{
case UNKNOWN_TYPE:
- pp_identifier (cxx_pp, "<unresolved overloaded function type>");
+ if (t == init_list_type_node)
+ pp_identifier (cxx_pp, "<brace-enclosed initializer list>");
+ else
+ pp_identifier (cxx_pp, "<unresolved overloaded function type>");
break;
case TREE_LIST:
@@ -2674,13 +2677,20 @@ cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
report_diagnostic (&diagnostic);
}
-/* Warn about the use of variadic templates when appropriate. */
+/* Warn about the use of C++0x features when appropriate. */
void
-maybe_warn_variadic_templates (void)
+maybe_warn_cpp0x (const char* str)
{
if ((cxx_dialect == cxx98) && !in_system_header)
/* We really want to suppress this warning in system headers,
because libstdc++ uses variadic templates even when we aren't
in C++0x mode. */
- pedwarn ("ISO C++ does not include variadic templates");
+ pedwarn ("%s only available with -std=c++0x", str);
+}
+
+/* Warn about the use of variadic templates when appropriate. */
+void
+maybe_warn_variadic_templates (void)
+{
+ maybe_warn_cpp0x ("variadic templates");
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0c38a7fcb0c..3e9e612f2b4 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1334,10 +1334,10 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
to run a new constructor; and catching an exception, where we
have already built up the constructor call so we could wrap it
in an exception region. */;
- else if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ else if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CP_AGGREGATE_TYPE_P (type))
{
/* A brace-enclosed initializer for an aggregate. */
- gcc_assert (CP_AGGREGATE_TYPE_P (type));
init = digest_init (type, init);
}
else
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 290cb7030b5..e42f60afba7 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4639,7 +4639,8 @@ arg_assoc_type (struct arg_lookup *k, tree type)
case TYPENAME_TYPE:
return false;
case LANG_TYPE:
- gcc_assert (type == unknown_type_node);
+ gcc_assert (type == unknown_type_node
+ || type == init_list_type_node);
return false;
case TYPE_PACK_EXPANSION:
return arg_assoc_type (k, PACK_EXPANSION_PATTERN (type));
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7d530f50714..2323c672166 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -529,6 +529,14 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
return cp_lexer_peek_token (lexer)->keyword == keyword;
}
+/* Return true if the next token is not the indicated KEYWORD. */
+
+static inline bool
+cp_lexer_next_token_is_not_keyword (cp_lexer* lexer, enum rid keyword)
+{
+ return cp_lexer_peek_token (lexer)->keyword != keyword;
+}
+
/* Return true if the next token is a keyword for a decl-specifier. */
static bool
@@ -1743,6 +1751,8 @@ static tree cp_parser_initializer
(cp_parser *, bool *, bool *);
static tree cp_parser_initializer_clause
(cp_parser *, bool *);
+static tree cp_parser_braced_list
+ (cp_parser*, bool*);
static VEC(constructor_elt,gc) *cp_parser_initializer_list
(cp_parser *, bool *);
@@ -1965,7 +1975,7 @@ static bool cp_parser_optional_template_keyword
(cp_parser *);
static void cp_parser_pre_parsed_nested_name_specifier
(cp_parser *);
-static void cp_parser_cache_group
+static bool cp_parser_cache_group
(cp_parser *, enum cpp_ttype, unsigned);
static void cp_parser_parse_tentatively
(cp_parser *);
@@ -4534,7 +4544,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
/* Form the representation of the compound-literal. */
postfix_expression
- = finish_compound_literal (type, initializer_list);
+ = (finish_compound_literal
+ (type, build_constructor (init_list_type_node,
+ initializer_list)));
break;
}
}
@@ -5070,10 +5082,19 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
}
else
{
+ bool expr_non_constant_p;
+
/* Parse the next assignment-expression. */
- if (non_constant_p)
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* A braced-init-list. */
+ maybe_warn_cpp0x ("extended initializer lists");
+ expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+ if (non_constant_p && expr_non_constant_p)
+ *non_constant_p = true;
+ }
+ else if (non_constant_p)
{
- bool expr_non_constant_p;
expr = (cp_parser_constant_expression
(parser, /*allow_non_constant_p=*/true,
&expr_non_constant_p));
@@ -5535,8 +5556,9 @@ cp_parser_new_expression (cp_parser* parser)
else
type = cp_parser_new_type_id (parser, &nelts);
- /* If the next token is a `(', then we have a new-initializer. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ /* If the next token is a `(' or '{', then we have a new-initializer. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
+ || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
initializer = cp_parser_new_initializer (parser);
else
initializer = NULL_TREE;
@@ -5748,6 +5770,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
new-initializer:
( expression-list [opt] )
+ braced-init-list
Returns a representation of the expression-list. If there is no
expression-list, VOID_ZERO_NODE is returned. */
@@ -5757,9 +5780,18 @@ cp_parser_new_initializer (cp_parser* parser)
{
tree expression_list;
- expression_list = (cp_parser_parenthesized_expression_list
- (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
- /*non_constant_p=*/NULL));
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool expr_non_constant_p;
+ maybe_warn_cpp0x ("extended initializer lists");
+ expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
+ expression_list = build_tree_list (NULL_TREE, expression_list);
+ }
+ else
+ expression_list = (cp_parser_parenthesized_expression_list
+ (parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL));
if (!expression_list)
expression_list = void_zero_node;
@@ -6208,10 +6240,14 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
= cp_parser_assignment_operator_opt (parser);
if (assignment_operator != ERROR_MARK)
{
- tree rhs;
+ bool non_constant_p;
/* Parse the right-hand side of the assignment. */
- rhs = cp_parser_assignment_expression (parser, cast_p);
+ tree rhs = cp_parser_initializer_clause (parser, &non_constant_p);
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+ maybe_warn_cpp0x ("extended initializer lists");
+
/* An assignment may not appear in a
constant-expression. */
if (cp_parser_non_integral_constant_expression (parser,
@@ -7124,7 +7160,8 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
condition:
expression
- type-specifier-seq declarator = assignment-expression
+ type-specifier-seq declarator = initializer-clause
+ type-specifier-seq declarator braced-init-list
GNU Extension:
@@ -7170,31 +7207,47 @@ cp_parser_condition (cp_parser* parser)
attributes = cp_parser_attributes_opt (parser);
/* Parse the asm-specification. */
asm_specification = cp_parser_asm_specification_opt (parser);
- /* If the next token is not an `=', then we might still be
+ /* If the next token is not an `=' or '{', then we might still be
looking at an expression. For example:
if (A(a).x)
looks like a decl-specifier-seq and a declarator -- but then
there is no `=', so this is an expression. */
- cp_parser_require (parser, CPP_EQ, "%<=%>");
- /* If we did see an `=', then we are looking at a declaration
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ cp_parser_simulate_error (parser);
+
+ /* If we did see an `=' or '{', then we are looking at a declaration
for sure. */
if (cp_parser_parse_definitely (parser))
{
tree pushed_scope;
bool non_constant_p;
+ bool flags = LOOKUP_ONLYCONVERTING;
/* Create the declaration. */
decl = start_decl (declarator, &type_specifiers,
/*initialized_p=*/true,
attributes, /*prefix_attributes=*/NULL_TREE,
&pushed_scope);
- /* Parse the assignment-expression. */
- initializer
- = cp_parser_constant_expression (parser,
- /*allow_non_constant_p=*/true,
- &non_constant_p);
+
+ /* Parse the initializer. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ initializer = cp_parser_braced_list (parser, &non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
+ flags = 0;
+ }
+ else
+ {
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ initializer = cp_parser_initializer_clause (parser, &non_constant_p);
+ }
+ if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
+ maybe_warn_cpp0x ("extended initializer lists");
+
if (!non_constant_p)
initializer = fold_non_dependent_expr (initializer);
@@ -7202,7 +7255,7 @@ cp_parser_condition (cp_parser* parser)
cp_finish_decl (decl,
initializer, !non_constant_p,
asm_specification,
- LOOKUP_ONLYCONVERTING);
+ flags);
if (pushed_scope)
pop_scope (pushed_scope);
@@ -7426,6 +7479,7 @@ cp_parser_for_init_statement (cp_parser* parser)
break ;
continue ;
return expression [opt] ;
+ return braced-init-list ;
goto identifier ;
GNU extension:
@@ -7496,12 +7550,18 @@ cp_parser_jump_statement (cp_parser* parser)
case RID_RETURN:
{
tree expr;
+ bool expr_non_constant_p;
- /* If the next token is a `;', then there is no
- expression. */
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ maybe_warn_cpp0x ("extended initializer lists");
+ expr = cp_parser_braced_list (parser, &expr_non_constant_p);
+ }
+ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
expr = cp_parser_expression (parser, /*cast_p=*/false);
else
+ /* If the next token is a `;', then there is no
+ expression. */
expr = NULL_TREE;
/* Build the return-statement. */
statement = finish_return_stmt (expr);
@@ -7964,7 +8024,8 @@ cp_parser_simple_declaration (cp_parser* parser,
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.any_specifiers_p
- && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
cp_parser_commit_to_tentative_parse (parser);
/* Keep going until we hit the `;' at the end of the simple
@@ -8907,6 +8968,7 @@ cp_parser_mem_initializer_list (cp_parser* parser)
mem-initializer:
mem-initializer-id ( expression-list [opt] )
+ mem-initializer-id braced-init-list
GNU extension:
@@ -8937,11 +8999,20 @@ cp_parser_mem_initializer (cp_parser* parser)
if (member && !DECL_P (member))
in_base_initializer = 1;
- expression_list
- = cp_parser_parenthesized_expression_list (parser, false,
- /*cast_p=*/false,
- /*allow_expansion_p=*/true,
- /*non_constant_p=*/NULL);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ bool expr_non_constant_p;
+ maybe_warn_cpp0x ("extended initializer lists");
+ expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
+ expression_list = build_tree_list (NULL_TREE, expression_list);
+ }
+ else
+ expression_list
+ = cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
if (expression_list == error_mark_node)
return error_mark_node;
if (!expression_list)
@@ -12197,7 +12268,7 @@ cp_parser_init_declarator (cp_parser* parser,
initialized with "= ..", CPP_OPEN_PAREN if initialized with
"(...)". */
enum cpp_ttype initialization_kind;
- bool is_parenthesized_init = false;
+ bool is_direct_init = false;
bool is_non_constant_init;
int ctor_dtor_or_conv_p;
bool friend_p;
@@ -12263,7 +12334,8 @@ cp_parser_init_declarator (cp_parser* parser,
token = cp_lexer_peek_token (parser->lexer);
/* Check to see if the token indicates the start of a
function-definition. */
- if (cp_parser_token_starts_function_definition_p (token))
+ if (function_declarator_p (declarator)
+ && cp_parser_token_starts_function_definition_p (token))
{
if (!function_definition_allowed_p)
{
@@ -12314,9 +12386,10 @@ cp_parser_init_declarator (cp_parser* parser,
return error_mark_node;
}
- /* An `=' or an `(' indicates an initializer. */
+ /* An `=' or an `(', or an '{' in C++0x, indicates an initializer. */
if (token->type == CPP_EQ
- || token->type == CPP_OPEN_PAREN)
+ || token->type == CPP_OPEN_PAREN
+ || token->type == CPP_OPEN_BRACE)
{
is_initialized = true;
initialization_kind = token->type;
@@ -12399,7 +12472,7 @@ cp_parser_init_declarator (cp_parser* parser,
/* Parse the initializer. */
initializer = NULL_TREE;
- is_parenthesized_init = false;
+ is_direct_init = false;
is_non_constant_init = true;
if (is_initialized)
{
@@ -12422,7 +12495,7 @@ cp_parser_init_declarator (cp_parser* parser,
}
else
initializer = cp_parser_initializer (parser,
- &is_parenthesized_init,
+ &is_direct_init,
&is_non_constant_init);
}
@@ -12430,7 +12503,8 @@ cp_parser_init_declarator (cp_parser* parser,
initializer. Mark Mitchell proposed removing this functionality
on the GCC mailing lists on 2002-08-13. This parser accepts the
attributes -- but ignores them. */
- if (cp_parser_allow_gnu_extensions_p (parser) && is_parenthesized_init)
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && initialization_kind == CPP_OPEN_PAREN)
if (cp_parser_attributes_opt (parser))
warning (OPT_Wattributes,
"attributes after parenthesized initializer ignored");
@@ -12463,8 +12537,8 @@ cp_parser_init_declarator (cp_parser* parser,
a direct-initialization, which means that an
`explicit' constructor is OK. Otherwise, an
`explicit' constructor cannot be used. */
- ((is_parenthesized_init || !is_initialized)
- ? 0 : LOOKUP_ONLYCONVERTING));
+ ((is_direct_init || !is_initialized)
+ ? 0 : LOOKUP_ONLYCONVERTING));
}
else if ((cxx_dialect != cxx98) && friend_p
&& decl && TREE_CODE (decl) == FUNCTION_DECL)
@@ -13983,14 +14057,14 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser)
Returns an expression representing the initializer. If no
initializer is present, NULL_TREE is returned.
- *IS_PARENTHESIZED_INIT is set to TRUE if the `( expression-list )'
- production is used, and zero otherwise. *IS_PARENTHESIZED_INIT is
- set to FALSE if there is no initializer present. If there is an
+ *IS_DIRECT_INIT is set to FALSE if the `= initializer-clause'
+ production is used, and TRUE otherwise. *IS_DIRECT_INIT is
+ set to TRUE if there is no initializer present. If there is an
initializer, and it is not a constant-expression, *NON_CONSTANT_P
is set to true; otherwise it is set to false. */
static tree
-cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
+cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
bool* non_constant_p)
{
cp_token *token;
@@ -14001,7 +14075,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
/* Let our caller know whether or not this initializer was
parenthesized. */
- *is_parenthesized_init = (token->type == CPP_OPEN_PAREN);
+ *is_direct_init = (token->type != CPP_EQ);
/* Assume that the initializer is constant. */
*non_constant_p = false;
@@ -14017,6 +14091,12 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
/*cast_p=*/false,
/*allow_expansion_p=*/true,
non_constant_p);
+ else if (token->type == CPP_OPEN_BRACE)
+ {
+ maybe_warn_cpp0x ("extended initializer lists");
+ init = cp_parser_braced_list (parser, non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
+ }
else
{
/* Anything else is an error. */
@@ -14031,20 +14111,14 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
initializer-clause:
assignment-expression
- { initializer-list , [opt] }
- { }
+ braced-init-list
Returns an expression representing the initializer.
If the `assignment-expression' production is used the value
returned is simply a representation for the expression.
- Otherwise, a CONSTRUCTOR is returned. The CONSTRUCTOR_ELTS will be
- the elements of the initializer-list (or NULL, if the last
- production is used). The TREE_TYPE for the CONSTRUCTOR will be
- NULL_TREE. There is no way to detect whether or not the optional
- trailing `,' was provided. NON_CONSTANT_P is as for
- cp_parser_initializer. */
+ Otherwise, calls cp_parser_braced_list. */
static tree
cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
@@ -14066,25 +14140,46 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
initializer = fold_non_dependent_expr (initializer);
}
else
+ initializer = cp_parser_braced_list (parser, non_constant_p);
+
+ return initializer;
+}
+
+/* Parse a brace-enclosed initializer list.
+
+ braced-init-list:
+ { initializer-list , [opt] }
+ { }
+
+ Returns a CONSTRUCTOR. The CONSTRUCTOR_ELTS will be
+ the elements of the initializer-list (or NULL, if the last
+ production is used). The TREE_TYPE for the CONSTRUCTOR will be
+ NULL_TREE. There is no way to detect whether or not the optional
+ trailing `,' was provided. NON_CONSTANT_P is as for
+ cp_parser_initializer. */
+
+static tree
+cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
+{
+ tree initializer;
+
+ /* Consume the `{' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Create a CONSTRUCTOR to represent the braced-initializer. */
+ initializer = make_node (CONSTRUCTOR);
+ /* If it's not a `}', then there is a non-trivial initializer. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
{
- /* Consume the `{' token. */
- cp_lexer_consume_token (parser->lexer);
- /* Create a CONSTRUCTOR to represent the braced-initializer. */
- initializer = make_node (CONSTRUCTOR);
- /* If it's not a `}', then there is a non-trivial initializer. */
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
- {
- /* Parse the initializer list. */
- CONSTRUCTOR_ELTS (initializer)
- = cp_parser_initializer_list (parser, non_constant_p);
- /* A trailing `,' token is allowed. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
- cp_lexer_consume_token (parser->lexer);
- }
- /* Now, there should be a trailing `}'. */
- cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+ /* Parse the initializer list. */
+ CONSTRUCTOR_ELTS (initializer)
+ = cp_parser_initializer_list (parser, non_constant_p);
+ /* A trailing `,' token is allowed. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
}
-
+ /* Now, there should be a trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
+ TREE_TYPE (initializer) = init_list_type_node;
return initializer;
}
@@ -17297,11 +17392,22 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
{
tree expression_list;
tree cast;
+ bool nonconst_p;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ maybe_warn_cpp0x ("extended initializer lists");
+ expression_list = cp_parser_braced_list (parser, &nonconst_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+ return finish_compound_literal (type, expression_list);
+ }
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
/*cast_p=*/true,
- /*allow_expansion_p=*/true,
+ /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL);
cast = build_functional_cast (type, expression_list,
@@ -17352,6 +17458,22 @@ cp_parser_save_member_function_body (cp_parser* parser,
/* Save away the tokens that make up the body of the
function. */
first = parser->lexer->next_token;
+ /* We can have braced-init-list mem-initializers before the fn body. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
+ && cp_lexer_next_token_is_not_keyword (parser->lexer, RID_TRY))
+ {
+ /* cache_group will stop after an un-nested { } pair, too. */
+ if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
+ break;
+
+ /* variadic mem-inits have ... after the ')'. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
/* Handle function try blocks. */
while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
@@ -18210,41 +18332,54 @@ cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
parser->object_scope = NULL_TREE;
}
-/* Consume tokens up through a non-nested END token. */
+/* Consume tokens up through a non-nested END token. Returns TRUE if we
+ encounter the end of a block before what we were looking for. */
-static void
+static bool
cp_parser_cache_group (cp_parser *parser,
enum cpp_ttype end,
unsigned depth)
{
while (true)
{
- cp_token *token;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
- /* Abort a parenthesized expression if we encounter a brace. */
+ /* Abort a parenthesized expression if we encounter a semicolon. */
if ((end == CPP_CLOSE_PAREN || depth == 0)
- && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
- return;
+ && token->type == CPP_SEMICOLON)
+ return true;
/* If we've reached the end of the file, stop. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)
+ if (token->type == CPP_EOF
|| (end != CPP_PRAGMA_EOL
- && cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL)))
- return;
- /* Consume the next token. */
- token = cp_lexer_consume_token (parser->lexer);
+ && token->type == CPP_PRAGMA_EOL))
+ return true;
+ if (token->type == CPP_CLOSE_BRACE && depth == 0)
+ /* We've hit the end of an enclosing block, so there's been some
+ kind of syntax error. */
+ return true;
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
/* See if it starts a new group. */
if (token->type == CPP_OPEN_BRACE)
{
cp_parser_cache_group (parser, CPP_CLOSE_BRACE, depth + 1);
+ /* In theory this should probably check end == '}', but
+ cp_parser_save_member_function_body needs it to exit
+ after either '}' or ')' when called with ')'. */
if (depth == 0)
- return;
+ return false;
}
else if (token->type == CPP_OPEN_PAREN)
- cp_parser_cache_group (parser, CPP_CLOSE_PAREN, depth + 1);
+ {
+ cp_parser_cache_group (parser, CPP_CLOSE_PAREN, depth + 1);
+ if (depth == 0 && end == CPP_CLOSE_PAREN)
+ return false;
+ }
else if (token->type == CPP_PRAGMA)
cp_parser_cache_group (parser, CPP_PRAGMA_EOL, depth + 1);
else if (token->type == end)
- return;
+ return false;
}
}
@@ -20503,10 +20638,10 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
if (CLASS_TYPE_P (TREE_TYPE (decl))
|| type_dependent_expression_p (decl))
{
- bool is_parenthesized_init, is_non_constant_init;
+ bool is_direct_init, is_non_constant_init;
init = cp_parser_initializer (parser,
- &is_parenthesized_init,
+ &is_direct_init,
&is_non_constant_init);
cp_finish_decl (decl, init, !is_non_constant_init,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f24b6ff04b3..cce706f0705 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11507,6 +11507,7 @@ tsubst_copy_and_build (tree t,
bool process_index_p;
int newlen;
bool need_copy_p = false;
+ tree r;
if (type == error_mark_node)
return error_mark_node;
@@ -11571,10 +11572,12 @@ tsubst_copy_and_build (tree t,
}
}
+ r = build_constructor (init_list_type_node, n);
+
if (TREE_HAS_CONSTRUCTOR (t))
- return finish_compound_literal (type, n);
+ return finish_compound_literal (type, r);
- return build_constructor (NULL_TREE, n);
+ return r;
}
case TYPEID_EXPR:
@@ -12271,6 +12274,8 @@ type_unification_real (tree tparms,
arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg,
arg_expr);
+ if (arg == init_list_type_node && arg_expr)
+ arg = arg_expr;
if (unify (tparms, targs, parm, arg, arg_strict))
return 1;
}
@@ -13037,7 +13042,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
if (arg == error_mark_node)
return 1;
- if (arg == unknown_type_node)
+ if (arg == unknown_type_node
+ || arg == init_list_type_node)
/* We can't deduce anything from this, but we might get all the
template args from other function args. */
return 0;
@@ -13049,6 +13055,31 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
if (arg == parm && !uses_template_parms (parm))
return 0;
+ /* Handle init lists early, so the rest of the function can assume
+ we're dealing with a type. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (arg))
+ {
+ tree elt, elttype;
+ unsigned i;
+
+ if (!is_std_init_list (parm))
+ /* We can only deduce from an initializer list argument if the
+ parameter is std::initializer_list; otherwise this is a
+ non-deduced context. */
+ return 0;
+
+ elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (arg), i, elt)
+ {
+ if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
+ elt = TREE_TYPE (elt);
+ if (unify (tparms, targs, elttype, elt, UNIFY_ALLOW_NONE))
+ return 1;
+ }
+ return 0;
+ }
+
/* Immediately reject some pairs that won't unify because of
cv-qualification mismatches. */
if (TREE_CODE (arg) == TREE_CODE (parm)
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 1dcd785371a..8a36f0b77b7 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -900,7 +900,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
- init = build_constructor_from_list (NULL_TREE, nreverse (init));
+ init = build_constructor_from_list (init_list_type_node, nreverse (init));
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
init = tree_cons (NULL_TREE, init, NULL_TREE);
@@ -917,7 +917,7 @@ generic_initializer (tinfo_s *ti, tree target)
{
tree init = tinfo_base_init (ti, target);
- init = build_constructor_from_list (NULL_TREE, init);
+ init = build_constructor_from_list (init_list_type_node, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
return init;
@@ -942,7 +942,7 @@ ptr_initializer (tinfo_s *ti, tree target)
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
- init = build_constructor_from_list (NULL_TREE, nreverse (init));
+ init = build_constructor_from_list (init_list_type_node, nreverse (init));
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
return init;
@@ -974,7 +974,7 @@ ptm_initializer (tinfo_s *ti, tree target)
get_tinfo_ptr (klass),
init);
- init = build_constructor_from_list (NULL_TREE, nreverse (init));
+ init = build_constructor_from_list (init_list_type_node, nreverse (init));
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
return init;
@@ -990,7 +990,7 @@ class_initializer (tinfo_s *ti, tree target, tree trail)
tree init = tinfo_base_init (ti, target);
TREE_CHAIN (init) = trail;
- init = build_constructor_from_list (NULL_TREE, init);
+ init = build_constructor_from_list (init_list_type_node, init);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
return init;
@@ -1102,10 +1102,10 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
build_int_cst (offset_type, flags));
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
- base_init = build_constructor_from_list (NULL_TREE, base_init);
+ base_init = build_constructor_from_list (init_list_type_node, base_init);
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
- base_inits = build_constructor_from_list (NULL_TREE, base_inits);
+ base_inits = build_constructor_from_list (init_list_type_node, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2400aeb37da..fa65e9b2804 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2099,21 +2099,17 @@ finish_unary_op_expr (enum tree_code code, tree expr)
}
/* Finish a compound-literal expression. TYPE is the type to which
- the INITIALIZER_LIST is being cast. */
+ the CONSTRUCTOR in COMPOUND_LITERAL is being cast. */
tree
-finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
+finish_compound_literal (tree type, tree compound_literal)
{
- tree compound_literal;
-
if (!TYPE_OBJ_P (type))
{
error ("compound literal of non-object type %qT", type);
return error_mark_node;
}
- /* Build a CONSTRUCTOR for the INITIALIZER_LIST. */
- compound_literal = build_constructor (NULL_TREE, initializer_list);
if (processing_template_decl)
{
TREE_TYPE (compound_literal) = type;
@@ -2123,6 +2119,18 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
}
type = complete_type (type);
+
+ if (TYPE_NON_AGGREGATE_CLASS (type))
+ {
+ /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST
+ everywhere that deals with function arguments would be a pain, so
+ just wrap it in a TREE_LIST. The parser set a flag so we know
+ that it came from T{} rather than T({}). */
+ CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
+ compound_literal = build_tree_list (NULL_TREE, compound_literal);
+ return build_functional_cast (type, compound_literal, tf_error);
+ }
+
if (TREE_CODE (type) == ARRAY_TYPE
&& check_array_initializer (NULL_TREE, type, compound_literal))
return error_mark_node;
@@ -2130,7 +2138,19 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
if (TREE_CODE (type) == ARRAY_TYPE)
cp_complete_array_type (&type, compound_literal, false);
compound_literal = digest_init (type, compound_literal);
- return get_target_expr (compound_literal);
+ if ((!at_function_scope_p () || cp_type_readonly (type))
+ && initializer_constant_valid_p (compound_literal, type))
+ {
+ tree decl = create_temporary_var (type);
+ DECL_INITIAL (decl) = compound_literal;
+ TREE_STATIC (decl) = 1;
+ decl = pushdecl_top_level (decl);
+ DECL_NAME (decl) = make_anon_name ();
+ SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ return decl;
+ }
+ else
+ return get_target_expr (compound_literal);
}
/* Return the declaration for the function-name variable indicated by
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ff372206ee6..b7c0a8d33b8 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -616,6 +616,14 @@ build_cplus_array_type (tree elt_type, tree index_type)
return t;
}
+/* Return an ARRAY_TYPE with element type ELT and length N. */
+
+tree
+build_array_of_n_type (tree elt, int n)
+{
+ return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
+}
+
/* Return a reference type node referring to TO_TYPE. If RVAL is
true, return an rvalue reference type, otherwise return an lvalue
reference type. If a type node exists, reuse it, otherwise create
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 14cbd9d8dd2..409f34068d4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2887,13 +2887,6 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
if (nargs < 0)
return error_mark_node;
- /* Check that arguments to builtin functions match the expectations. */
- if (fndecl
- && DECL_BUILT_IN (fndecl)
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
- && !check_builtin_function_arguments (fndecl, nargs, argarray))
- return error_mark_node;
-
/* Check for errors in format strings and inappropriately
null parameters. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 05e88b9002e..4cf8021964f 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h"
#include "output.h"
#include "diagnostic.h"
+#include "real.h"
static tree
process_init_constructor (tree type, tree init);
@@ -592,7 +593,7 @@ store_init_value (tree decl, tree init)
{
error ("constructor syntax used, but no constructor declared "
"for type %qT", type);
- init = build_constructor_from_list (NULL_TREE, nreverse (init));
+ init = build_constructor_from_list (init_list_type_node, nreverse (init));
}
}
else if (TREE_CODE (init) == TREE_LIST
@@ -631,15 +632,70 @@ store_init_value (tree decl, tree init)
}
+/* Give errors about narrowing conversions within { }. */
+
+void
+check_narrowing (tree type, tree init)
+{
+ tree ftype = TREE_TYPE (init);
+ bool ok = true;
+ REAL_VALUE_TYPE d;
+
+ if (DECL_P (init))
+ init = decl_constant_value (init);
+
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_CODE (ftype) == REAL_TYPE)
+ ok = false;
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
+ && CP_INTEGRAL_TYPE_P (type))
+ {
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)
+ && (TREE_CODE (init) != INTEGER_CST
+ || !int_fits_type_p (init, type)))
+ ok = false;
+ }
+ else if (TREE_CODE (ftype) == REAL_TYPE
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))
+ {
+ ok = false;
+ if (TREE_CODE (init) == REAL_CST)
+ {
+ d = TREE_REAL_CST (init);
+ if (exact_real_truncate (TYPE_MODE (type), &d))
+ ok = true;
+ }
+ }
+ }
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ ok = false;
+ if (TREE_CODE (init) == INTEGER_CST)
+ {
+ d = real_value_from_int_cst (0, init);
+ if (exact_real_truncate (TYPE_MODE (type), &d))
+ ok = true;
+ }
+ }
+
+ if (!ok)
+ error ("narrowing conversion of %qE to %qT inside { }", init, type);
+}
+
/* Process the initializer INIT for a variable of type TYPE, emitting
diagnostics for invalid initializers and converting the initializer as
appropriate.
For aggregate types, it assumes that reshape_init has already run, thus the
- initializer will have the right shape (brace elision has been undone). */
+ initializer will have the right shape (brace elision has been undone).
-tree
-digest_init (tree type, tree init)
+ NESTED is true iff we are being called for an element of a CONSTRUCTOR. */
+
+static tree
+digest_init_r (tree type, tree init, bool nested)
{
enum tree_code code = TREE_CODE (type);
@@ -706,6 +762,8 @@ digest_init (tree type, tree init)
{
tree *exp;
+ if (cxx_dialect != cxx98 && nested)
+ check_narrowing (type, init);
init = convert_for_initialization (0, type, init, LOOKUP_NORMAL,
"initialization", NULL_TREE, 0,
tf_warning_or_error);
@@ -731,7 +789,7 @@ digest_init (tree type, tree init)
|| TREE_CODE (type) == COMPLEX_TYPE);
if (BRACE_ENCLOSED_INITIALIZER_P (init))
- return process_init_constructor (type, init);
+ return process_init_constructor (type, init);
else
{
if (COMPOUND_LITERAL_P (init) && TREE_CODE (type) == ARRAY_TYPE)
@@ -757,6 +815,11 @@ digest_init (tree type, tree init)
}
}
+tree
+digest_init (tree type, tree init)
+{
+ return digest_init_r (type, init, false);
+}
/* Set of flags used within process_init_constructor to describe the
initializers. */
@@ -828,7 +891,7 @@ process_init_constructor_array (tree type, tree init)
else
ce->index = size_int (i);
gcc_assert (ce->value);
- ce->value = digest_init (TREE_TYPE (type), ce->value);
+ ce->value = digest_init_r (TREE_TYPE (type), ce->value, true);
if (ce->value != error_mark_node)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
@@ -854,7 +917,7 @@ process_init_constructor_array (tree type, tree init)
next = build_functional_cast (TREE_TYPE (type), NULL_TREE,
tf_warning_or_error);
else
- next = build_constructor (NULL_TREE, NULL);
+ next = build_constructor (init_list_type_node, NULL);
next = digest_init (TREE_TYPE (type), next);
}
else if (!zero_init_p (TREE_TYPE (type)))
@@ -929,7 +992,7 @@ process_init_constructor_record (tree type, tree init)
}
gcc_assert (ce->value);
- next = digest_init (TREE_TYPE (field), ce->value);
+ next = digest_init_r (TREE_TYPE (field), ce->value, true);
++idx;
}
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
@@ -942,9 +1005,9 @@ process_init_constructor_record (tree type, tree init)
next = build_functional_cast (TREE_TYPE (field), NULL_TREE,
tf_warning_or_error);
else
- next = build_constructor (NULL_TREE, NULL);
+ next = build_constructor (init_list_type_node, NULL);
- next = digest_init (TREE_TYPE (field), next);
+ next = digest_init_r (TREE_TYPE (field), next, true);
/* Warn when some struct elements are implicitly initialized. */
warning (OPT_Wmissing_field_initializers,
@@ -1037,7 +1100,7 @@ process_init_constructor_union (tree type, tree init)
}
if (ce->value && ce->value != error_mark_node)
- ce->value = digest_init (TREE_TYPE (ce->index), ce->value);
+ ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true);
return picflag_from_initializer (ce->value);
}
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index 28c99638ec3..0c46bdaa496 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -3191,7 +3191,7 @@ df_set_note (enum reg_note note_type, rtx insn, rtx old, rtx reg)
}
/* Did not find the note. */
- REG_NOTES (insn) = alloc_EXPR_LIST (note_type, reg, REG_NOTES (insn));
+ add_reg_note (insn, note_type, reg);
return old;
}
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 86c2f46a49e..8913ec0c923 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -3427,15 +3427,17 @@ applications. There are no standard Unix configurations.
@end html
@heading @anchor{m68k-x-x}m68k-*-*
By default, @samp{m68k-*-aout}, @samp{m68k-*-coff*},
-@samp{m68k-*-elf*}, @samp{m68k-*-rtems} and @samp{m68k-*-uclinux}
+@samp{m68k-*-elf*}, @samp{m68k-*-rtems}, @samp{m68k-*-uclinux} and
+@samp{m68k-*-linux}
build libraries for both M680x0 and ColdFire processors. If you only
need the M680x0 libraries, you can omit the ColdFire ones by passing
@option{--with-arch=m68k} to @command{configure}. Alternatively, you
can omit the M680x0 libraries by passing @option{--with-arch=cf} to
-@command{configure}. These targets default to 5206 code when
+@command{configure}. These targets default to 5206 or 5475 code as
+appropriate for the target system when
configured with @option{--with-arch=cf} and 68020 code otherwise.
-The @samp{m68k-*-linux-gnu}, @samp{m68k-*-netbsd} and
+The @samp{m68k-*-netbsd} and
@samp{m68k-*-openbsd} targets also support the @option{--with-arch}
option. They will generate ColdFire CFV4e code when configured with
@option{--with-arch=cf} and 68020 code otherwise.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ed73610a7dc..a87d89e9d84 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -310,7 +310,7 @@ Objective-C and Objective-C++ Dialects}.
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
-print-multi-directory -print-multi-lib @gol
-print-prog-name=@var{program} -print-search-dirs -Q @gol
--print-sysroot-headers-suffix @gol
+-print-sysroot -print-sysroot-headers-suffix @gol
-save-temps -time}
@item Optimization Options
@@ -5064,6 +5064,14 @@ variable @env{GCC_EXEC_PREFIX} to the directory where you installed them.
Don't forget the trailing @samp{/}.
@xref{Environment Variables}.
+@item -print-sysroot
+@opindex print-sysroot
+Print the target sysroot directory that will be used during
+compilation. This is the target sysroot specified either at configure
+time or or using the @option{--sysroot} option, possibly with an extra
+suffix that depends on compilation options. If no target sysroot is
+specified, the option prints nothing.
+
@item -print-sysroot-headers-suffix
@opindex print-sysroot-headers-suffix
Print the suffix added to the target sysroot when searching for
@@ -7328,7 +7336,8 @@ duplicated when threading jumps.
@item max-fields-for-field-sensitive
Maximum number of fields in a structure we will treat in
-a field sensitive manner during pointer analysis.
+a field sensitive manner during pointer analysis. The default is zero
+for -O0, and -O1 and 100 for -Os, -O2, and -O3.
@item prefetch-latency
Estimate on average number of instructions that are executed before
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d4ba0e20814..b5418a3f465 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4187,6 +4187,18 @@ This hook returns a type node for @code{va_list} for the target.
The default version of the hook returns @code{void*}.
@end deftypefn
+@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST (tree @var{fndecl})
+This hook returns the va_list type of the calling convention specified by
+@var{fndecl}.
+The default version of this hook returns @code{va_list_type_node}.
+@end deftypefn
+
+@deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type})
+This hook returns the va_list type of the calling convention specified by the
+type of @var{type}. If @var{type} is not a valid va_list type, it returns
+@code{NULL_TREE}.
+@end deftypefn
+
@deftypefn {Target Hook} tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree @var{valist}, tree @var{type}, tree *@var{pre_p}, tree *@var{post_p})
This hook performs target-specific gimplification of
@code{VA_ARG_EXPR}. The first two parameters correspond to the
@@ -4317,6 +4329,20 @@ function use different registers for the return value, this macro
should recognize only the caller's register numbers.
@end defmac
+@defmac TARGET_ENUM_VA_LIST (@var{idx}, @var{pname}, @var{ptype})
+This target macro is used in function @code{c_common_nodes_and_builtins}
+to iterate through the target specific builtin types for va_list. The
+variable @var{idx} is used as iterator. @var{pname} has to be a pointer
+to a @code{const char *} and @var{ptype} a pointer to a @code{tree} typed
+variable.
+The arguments @var{pname} and @var{ptype} are used to store the result of
+this macro and are set to the name of the va_list builtin type and its
+internal type.
+If the return value of this macro is zero, then there is no more element.
+Otherwise the @var{IDX} should be increased for the next call of this
+macro to iterate through all types.
+@end defmac
+
@defmac APPLY_RESULT_SIZE
Define this macro if @samp{untyped_call} and @samp{untyped_return}
need more space than is implied by @code{FUNCTION_VALUE_REGNO_P} for
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 418da241b66..22c7979a773 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3044,9 +3044,8 @@ link_cc0_insns (rtx insn)
if (NONJUMP_INSN_P (user) && GET_CODE (PATTERN (user)) == SEQUENCE)
user = XVECEXP (PATTERN (user), 0, 0);
- REG_NOTES (user) = gen_rtx_INSN_LIST (REG_CC_SETTER, insn,
- REG_NOTES (user));
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_CC_USER, user, REG_NOTES (insn));
+ add_reg_note (user, REG_CC_SETTER, insn);
+ add_reg_note (insn, REG_CC_USER, user);
}
/* Return the next insn that uses CC0 after INSN, which is assumed to
@@ -3223,10 +3222,7 @@ try_split (rtx pat, rtx trial, int last)
is responsible for this step using
split_branch_probability variable. */
gcc_assert (njumps == 1);
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (probability),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_BR_PROB, GEN_INT (probability));
}
}
}
@@ -3257,10 +3253,7 @@ try_split (rtx pat, rtx trial, int last)
if (CALL_P (insn)
|| (flag_non_call_exceptions && INSN_P (insn)
&& may_trap_p (PATTERN (insn))))
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_EH_REGION,
- XEXP (note, 0),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_EH_REGION, XEXP (note, 0));
}
break;
@@ -3269,10 +3262,7 @@ try_split (rtx pat, rtx trial, int last)
for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
{
if (CALL_P (insn))
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
}
break;
@@ -3280,10 +3270,7 @@ try_split (rtx pat, rtx trial, int last)
for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
{
if (JUMP_P (insn))
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
}
break;
@@ -3294,8 +3281,7 @@ try_split (rtx pat, rtx trial, int last)
rtx reg = XEXP (note, 0);
if (!FIND_REG_INC_NOTE (insn, reg)
&& for_each_rtx (&PATTERN (insn), find_auto_inc, reg) > 0)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, reg,
- REG_NOTES (insn));
+ add_reg_note (insn, REG_INC, reg);
}
break;
#endif
@@ -4600,7 +4586,6 @@ rtx
set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
{
rtx note = find_reg_note (insn, kind, NULL_RTX);
- rtx new_note = NULL;
switch (kind)
{
@@ -4638,8 +4623,7 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
break;
}
- new_note = gen_rtx_EXPR_LIST (kind, datum, REG_NOTES (insn));
- REG_NOTES (insn) = new_note;
+ add_reg_note (insn, kind, datum);
switch (kind)
{
@@ -5525,13 +5509,10 @@ emit_copy_of_insn_after (rtx insn, rtx after)
if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
{
if (GET_CODE (link) == EXPR_LIST)
- REG_NOTES (new)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
- copy_insn_1 (XEXP (link, 0)), REG_NOTES (new));
+ add_reg_note (new, REG_NOTE_KIND (link),
+ copy_insn_1 (XEXP (link, 0)));
else
- REG_NOTES (new)
- = gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
- XEXP (link, 0), REG_NOTES (new));
+ add_reg_note (new, REG_NOTE_KIND (link), XEXP (link, 0));
}
INSN_CODE (new) = INSN_CODE (insn);
diff --git a/gcc/expr.c b/gcc/expr.c
index 6d6278a7bc7..33616d6900e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7102,10 +7102,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
&& GET_CODE (PATTERN (insn)) != CLOBBER
&& GET_CODE (PATTERN (insn)) != USE
&& (CALL_P (insn) || may_trap_p (PATTERN (insn))))
- {
- REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (rn),
- REG_NOTES (insn));
- }
+ add_reg_note (insn, REG_EH_REGION, GEN_INT (rn));
}
}
diff --git a/gcc/expr.h b/gcc/expr.h
index beb44bd80b7..39a51fcfe13 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -342,6 +342,9 @@ extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
/* Functions from builtins.c: */
extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern tree std_build_builtin_va_list (void);
+extern tree std_fn_abi_va_list (tree);
+extern tree std_canonical_va_list_type (tree);
+
extern void std_expand_builtin_va_start (tree, rtx);
extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern void expand_builtin_setjmp_setup (rtx, rtx);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index fc72b9b38a2..e1e04bb625d 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2396,7 +2396,8 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
if (TREE_TYPE (arg1) == type)
return arg1;
- if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
+ if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE)
{
if (TREE_CODE (arg1) == INTEGER_CST)
return fold_convert_const_int_from_int (type, arg1);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 82c2392d14d..44f61fa2458 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,39 @@
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36670
+ * iresolve.c (gfc_resolve_product): Set shape of return
+ value from array.
+ (gfc_resolve_sum): Likewise.
+
+2008-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36726
+ * f95-lang.c (poplevel): Don't ever add subblocks to
+ global_binding_level.
+
+2008-07-02 Janus Weil <janus@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+ Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/32580
+ * gfortran.h (struct gfc_symbol): New member "proc_pointer".
+ * check.c (gfc_check_associated,gfc_check_null): Implement
+ procedure pointers.
+ * decl.c (match_procedure_decl): Ditto.
+ * expr.c (gfc_check_pointer_assign,gfc_check_assign_symbol): Ditto.
+ * interface.c (compare_actual_formal): Ditto.
+ * match.h: Ditto.
+ * match.c (gfc_match_pointer_assignment): Ditto.
+ * parse.c (parse_interface): Ditto.
+ * primary.c (gfc_match_rvalue,match_variable): Ditto.
+ * resolve.c (resolve_fl_procedure): Ditto.
+ * symbol.c (check_conflict,gfc_add_external,gfc_add_pointer,
+ gfc_copy_attr,gen_fptr_param,build_formal_args): Ditto.
+ * trans-decl.c (get_proc_pointer_decl,gfc_get_extern_function_decl,
+ create_function_arglist): Ditto.
+ * trans-expr.c (gfc_conv_variable,gfc_conv_function_val,
+ gfc_conv_function_call,gfc_trans_pointer_assignment): Ditto.
+
2008-07-02 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/36590
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 87d962e50a7..c0f9891bd98 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -584,7 +584,7 @@ gfc_check_x_yd (gfc_expr *x, gfc_expr *y)
try
gfc_check_associated (gfc_expr *pointer, gfc_expr *target)
{
- symbol_attribute attr;
+ symbol_attribute attr1, attr2;
int i;
try t;
locus *where;
@@ -592,15 +592,15 @@ gfc_check_associated (gfc_expr *pointer, gfc_expr *target)
where = &pointer->where;
if (pointer->expr_type == EXPR_VARIABLE)
- attr = gfc_variable_attr (pointer, NULL);
+ attr1 = gfc_variable_attr (pointer, NULL);
else if (pointer->expr_type == EXPR_FUNCTION)
- attr = pointer->symtree->n.sym->attr;
+ attr1 = pointer->symtree->n.sym->attr;
else if (pointer->expr_type == EXPR_NULL)
goto null_arg;
else
gcc_assert (0); /* Pointer must be a variable or a function. */
- if (!attr.pointer)
+ if (!attr1.pointer && !attr1.proc_pointer)
{
gfc_error ("'%s' argument of '%s' intrinsic at %L must be a POINTER",
gfc_current_intrinsic_arg[0], gfc_current_intrinsic,
@@ -617,9 +617,9 @@ gfc_check_associated (gfc_expr *pointer, gfc_expr *target)
goto null_arg;
if (target->expr_type == EXPR_VARIABLE)
- attr = gfc_variable_attr (target, NULL);
+ attr2 = gfc_variable_attr (target, NULL);
else if (target->expr_type == EXPR_FUNCTION)
- attr = target->symtree->n.sym->attr;
+ attr2 = target->symtree->n.sym->attr;
else
{
gfc_error ("'%s' argument of '%s' intrinsic at %L must be a pointer "
@@ -628,7 +628,7 @@ gfc_check_associated (gfc_expr *pointer, gfc_expr *target)
return FAILURE;
}
- if (!attr.pointer && !attr.target)
+ if (attr1.pointer && !attr2.pointer && !attr2.target)
{
gfc_error ("'%s' argument of '%s' intrinsic at %L must be a POINTER "
"or a TARGET", gfc_current_intrinsic_arg[1],
@@ -2071,7 +2071,7 @@ gfc_check_null (gfc_expr *mold)
attr = gfc_variable_attr (mold, NULL);
- if (!attr.pointer)
+ if (!attr.pointer && !attr.proc_pointer)
{
gfc_error ("'%s' argument of '%s' intrinsic at %L must be a POINTER",
gfc_current_intrinsic_arg[0],
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 869ece6c3f6..d23a32946ef 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -4065,6 +4065,7 @@ match_procedure_decl (void)
locus old_loc, entry_loc;
gfc_symbol *sym, *proc_if = NULL;
int num;
+ gfc_expr *initializer = NULL;
old_loc = entry_loc = gfc_current_locus;
@@ -4183,7 +4184,7 @@ got_ts:
return MATCH_ERROR;
}
- if (!sym->attr.pointer && gfc_add_external (&sym->attr, NULL) == FAILURE)
+ if (gfc_add_external (&sym->attr, NULL) == FAILURE)
return MATCH_ERROR;
if (gfc_add_proc (&sym->attr, sym->name, NULL) == FAILURE)
return MATCH_ERROR;
@@ -4203,6 +4204,40 @@ got_ts:
sym->attr.function = sym->ts.interface->attr.function;
}
+ if (gfc_match (" =>") == MATCH_YES)
+ {
+ if (!current_attr.pointer)
+ {
+ gfc_error ("Initialization at %C isn't for a pointer variable");
+ m = MATCH_ERROR;
+ goto cleanup;
+ }
+
+ m = gfc_match_null (&initializer);
+ if (m == MATCH_NO)
+ {
+ gfc_error ("Pointer initialization requires a NULL() at %C");
+ m = MATCH_ERROR;
+ }
+
+ if (gfc_pure (NULL))
+ {
+ gfc_error ("Initialization of pointer at %C is not allowed in "
+ "a PURE procedure");
+ m = MATCH_ERROR;
+ }
+
+ if (m != MATCH_YES)
+ goto cleanup;
+
+ if (add_init_expr_to_sym (sym->name, &initializer, &gfc_current_locus)
+ != SUCCESS)
+ goto cleanup;
+
+ }
+
+ gfc_set_sym_referenced (sym);
+
if (gfc_match_eos () == MATCH_YES)
return MATCH_YES;
if (gfc_match_char (',') != MATCH_YES)
@@ -4212,6 +4247,11 @@ got_ts:
syntax:
gfc_error ("Syntax error in PROCEDURE statement at %C");
return MATCH_ERROR;
+
+cleanup:
+ /* Free stuff up and return. */
+ gfc_free_expr (initializer);
+ return m;
}
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 2f7030ed833..12987e6b748 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -2874,7 +2874,8 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
int is_pure;
int pointer, check_intent_in;
- if (lvalue->symtree->n.sym->ts.type == BT_UNKNOWN)
+ if (lvalue->symtree->n.sym->ts.type == BT_UNKNOWN
+ && !lvalue->symtree->n.sym->attr.proc_pointer)
{
gfc_error ("Pointer assignment target is not a POINTER at %L",
&lvalue->where);
@@ -2894,7 +2895,8 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
/* Check INTENT(IN), unless the object itself is the component or
sub-component of a pointer. */
check_intent_in = 1;
- pointer = lvalue->symtree->n.sym->attr.pointer;
+ pointer = lvalue->symtree->n.sym->attr.pointer
+ | lvalue->symtree->n.sym->attr.proc_pointer;
for (ref = lvalue->ref; ref; ref = ref->next)
{
@@ -2933,6 +2935,10 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
if (rvalue->expr_type == EXPR_NULL && rvalue->ts.type == BT_UNKNOWN)
return SUCCESS;
+ /* TODO checks on rvalue for a procedure pointer assignment. */
+ if (lvalue->symtree->n.sym->attr.proc_pointer)
+ return SUCCESS;
+
if (!gfc_compare_types (&lvalue->ts, &rvalue->ts))
{
gfc_error ("Different types in pointer assignment at %L; attempted "
@@ -3024,7 +3030,7 @@ gfc_check_assign_symbol (gfc_symbol *sym, gfc_expr *rvalue)
lvalue.symtree->n.sym = sym;
lvalue.where = sym->declared_at;
- if (sym->attr.pointer)
+ if (sym->attr.pointer || sym->attr.proc_pointer)
r = gfc_check_pointer_assign (&lvalue, rvalue);
else
r = gfc_check_assign (&lvalue, rvalue, 1);
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 794cc41a2d0..9dfb4233210 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -435,6 +435,10 @@ poplevel (int keep, int reverse, int functionbody)
DECL_INITIAL (current_function_decl) = block_node;
BLOCK_VARS (block_node) = 0;
}
+ else if (current_binding_level == global_binding_level)
+ /* When using gfc_start_block/gfc_finish_block from middle-end hooks,
+ don't add newly created BLOCKs as sublocks of global_binding_level. */
+ ;
else if (block_node)
{
current_binding_level->blocks
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 5d025db869b..aa2296c72a5 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -620,7 +620,7 @@ typedef struct
unsigned allocatable:1, dimension:1, external:1, intrinsic:1,
optional:1, pointer:1, target:1, value:1, volatile_:1,
dummy:1, result:1, assign:1, threadprivate:1, not_always_present:1,
- implied_index:1, subref_array_pointer:1;
+ implied_index:1, subref_array_pointer:1, proc_pointer:1;
ENUM_BITFIELD (save_state) save:2;
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 26b4591166a..a20319976bb 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1959,6 +1959,17 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
return 0;
}
+ /* Satisfy 12.4.1.3 by ensuring that a procedure pointer actual argument
+ is provided for a procedure pointer formal argument. */
+ if (f->sym->attr.proc_pointer
+ && !a->expr->symtree->n.sym->attr.proc_pointer)
+ {
+ if (where)
+ gfc_error ("Expected a procedure pointer for argument '%s' at %L",
+ f->sym->name, &a->expr->where);
+ return 0;
+ }
+
/* Satisfy 12.4.1.2 by ensuring that a procedure actual argument is
provided for a procedure formal argument. */
if (a->expr->ts.type != BT_PROCEDURE
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 64a24e80007..2c804143ba9 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -1788,6 +1788,7 @@ gfc_resolve_product (gfc_expr *f, gfc_expr *array, gfc_expr *dim,
if (dim != NULL)
{
f->rank = array->rank - 1;
+ f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
gfc_resolve_dim_arg (dim);
}
@@ -2271,6 +2272,7 @@ gfc_resolve_sum (gfc_expr *f, gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
if (dim != NULL)
{
f->rank = array->rank - 1;
+ f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
gfc_resolve_dim_arg (dim);
}
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 6f5765f1784..d501d682475 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "match.h"
#include "parse.h"
+int gfc_matching_procptr_assignment = 0;
/* For debugging and diagnostic purposes. Return the textual representation
of the intrinsic operator OP. */
@@ -1329,6 +1330,7 @@ gfc_match_pointer_assignment (void)
old_loc = gfc_current_locus;
lvalue = rvalue = NULL;
+ gfc_matching_procptr_assignment = 0;
m = gfc_match (" %v =>", &lvalue);
if (m != MATCH_YES)
@@ -1337,7 +1339,11 @@ gfc_match_pointer_assignment (void)
goto cleanup;
}
+ if (lvalue->symtree->n.sym->attr.proc_pointer)
+ gfc_matching_procptr_assignment = 1;
+
m = gfc_match (" %e%t", &rvalue);
+ gfc_matching_procptr_assignment = 0;
if (m != MATCH_YES)
goto cleanup;
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index cf30b2730dc..21a24795664 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -33,6 +33,8 @@ extern gfc_symbol *gfc_new_block;
separate. */
extern gfc_st_label *gfc_statement_label;
+extern int gfc_matching_procptr_assignment;
+
/****************** All gfc_match* routines *****************/
/* match.c. */
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index c35db2d9cf6..781efbc205d 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1992,6 +1992,11 @@ loop:
new_state = COMP_SUBROUTINE;
else if (st == ST_FUNCTION)
new_state = COMP_FUNCTION;
+ if (gfc_new_block->attr.pointer)
+ {
+ gfc_new_block->attr.pointer = 0;
+ gfc_new_block->attr.proc_pointer = 1;
+ }
if (gfc_add_explicit_interface (gfc_new_block, IFSRC_IFBODY,
gfc_new_block->formal, NULL) == FAILURE)
{
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index d7236e1be01..c67f2bd1873 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2323,6 +2323,9 @@ gfc_match_rvalue (gfc_expr **result)
}
}
+ if (gfc_matching_procptr_assignment)
+ goto procptr0;
+
if (sym->attr.function || sym->attr.external || sym->attr.intrinsic)
goto function0;
@@ -2399,6 +2402,27 @@ gfc_match_rvalue (gfc_expr **result)
/* If we're here, then the name is known to be the name of a
procedure, yet it is not sure to be the name of a function. */
case FL_PROCEDURE:
+
+ /* Procedure Pointer Assignments. */
+ procptr0:
+ if (gfc_matching_procptr_assignment)
+ {
+ gfc_gobble_whitespace ();
+ if (sym->attr.function && gfc_peek_ascii_char () == '(')
+ /* Parse functions returning a procptr. */
+ goto function0;
+
+ if (sym->attr.flavor == FL_UNKNOWN) sym->attr.flavor = FL_PROCEDURE;
+ if (gfc_intrinsic_name (sym->name, 0)
+ || gfc_intrinsic_name (sym->name, 1))
+ sym->attr.intrinsic = 1;
+ e = gfc_get_expr ();
+ e->expr_type = EXPR_VARIABLE;
+ e->symtree = symtree;
+ m = match_varspec (e, 0);
+ break;
+ }
+
if (sym->attr.subroutine)
{
gfc_error ("Unexpected use of subroutine name '%s' at %C",
@@ -2780,6 +2804,9 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
break;
}
+ if (sym->attr.proc_pointer)
+ break;
+
/* Fall through to error */
default:
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 3b798d8643c..c0ec7847747 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7330,7 +7330,8 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
}
}
- if (sym->attr.function && sym->value && sym->attr.proc != PROC_ST_FUNCTION)
+ if (sym->attr.function && sym->value && sym->attr.proc != PROC_ST_FUNCTION
+ && !sym->attr.proc_pointer)
{
gfc_error ("Function '%s' at %L cannot have an initializer",
sym->name, &sym->declared_at);
@@ -7338,8 +7339,8 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
}
/* An external symbol may not have an initializer because it is taken to be
- a procedure. */
- if (sym->attr.external && sym->value)
+ a procedure. Exception: Procedure Pointers. */
+ if (sym->attr.external && sym->value && !sym->attr.proc_pointer)
{
gfc_error ("External object '%s' at %L may not have an initializer",
sym->name, &sym->declared_at);
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index cd181d4f0f1..f91ef9157c0 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -410,13 +410,19 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
case FL_BLOCK_DATA:
case FL_MODULE:
case FL_LABEL:
- case FL_PROCEDURE:
case FL_DERIVED:
case FL_PARAMETER:
a1 = gfc_code2string (flavors, attr->flavor);
a2 = save;
goto conflict;
+ case FL_PROCEDURE:
+ if (attr->proc_pointer)
+ break;
+ a1 = gfc_code2string (flavors, attr->flavor);
+ a2 = save;
+ goto conflict;
+
case FL_VARIABLE:
case FL_NAMELIST:
default:
@@ -557,13 +563,6 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf (procedure, value)
conf (procedure, volatile_)
conf (procedure, entry)
- /* TODO: Implement procedure pointers. */
- if (attr->procedure && attr->pointer)
- {
- gfc_error ("Fortran 2003: Procedure pointers at %L are "
- "not yet implemented in gfortran", where);
- return FAILURE;
- }
a1 = gfc_code2string (flavors, attr->flavor);
@@ -619,11 +618,11 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
break;
case FL_PROCEDURE:
- conf2 (intent);
+ if (!attr->proc_pointer)
+ conf2 (intent);
if (attr->subroutine)
{
- conf2 (pointer);
conf2 (target);
conf2 (allocatable);
conf2 (result);
@@ -866,6 +865,12 @@ gfc_add_external (symbol_attribute *attr, locus *where)
return FAILURE;
}
+ if (attr->pointer && attr->if_source != IFSRC_IFBODY)
+ {
+ attr->pointer = 0;
+ attr->proc_pointer = 1;
+ }
+
attr->external = 1;
return check_conflict (attr, NULL, where);
@@ -916,7 +921,20 @@ gfc_add_pointer (symbol_attribute *attr, locus *where)
if (check_used (attr, NULL, where))
return FAILURE;
- attr->pointer = 1;
+ if (attr->pointer && !(attr->if_source == IFSRC_IFBODY
+ && gfc_find_state (COMP_INTERFACE) == FAILURE))
+ {
+ duplicate_attr ("POINTER", where);
+ return FAILURE;
+ }
+
+ if (attr->procedure || (attr->external && attr->if_source != IFSRC_IFBODY)
+ || (attr->if_source == IFSRC_IFBODY
+ && gfc_find_state (COMP_INTERFACE) == FAILURE))
+ attr->proc_pointer = 1;
+ else
+ attr->pointer = 1;
+
return check_conflict (attr, NULL, where);
}
@@ -1641,6 +1659,8 @@ gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where)
goto fail;
if (src->intrinsic && gfc_add_intrinsic (dest, where) == FAILURE)
goto fail;
+ if (src->proc_pointer)
+ dest->proc_pointer = 1;
return SUCCESS;
@@ -3574,7 +3594,7 @@ static void
gen_fptr_param (gfc_formal_arglist **head,
gfc_formal_arglist **tail,
const char *module_name,
- gfc_namespace *ns, const char *f_ptr_name)
+ gfc_namespace *ns, const char *f_ptr_name, int proc)
{
gfc_symbol *param_sym = NULL;
gfc_symtree *param_symtree = NULL;
@@ -3593,7 +3613,10 @@ gen_fptr_param (gfc_formal_arglist **head,
/* Set up the necessary fields for the fptr output param sym. */
param_sym->refs++;
- param_sym->attr.pointer = 1;
+ if (proc)
+ param_sym->attr.proc_pointer = 1;
+ else
+ param_sym->attr.pointer = 1;
param_sym->attr.dummy = 1;
param_sym->attr.use_assoc = 1;
@@ -3773,21 +3796,23 @@ build_formal_args (gfc_symbol *new_proc_sym,
gfc_current_ns->proc_name = new_proc_sym;
/* Generate the params. */
- if ((old_sym->intmod_sym_id == ISOCBINDING_F_POINTER) ||
- (old_sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER))
+ if (old_sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)
{
gen_cptr_param (&head, &tail, (const char *) new_proc_sym->module,
gfc_current_ns, "cptr", old_sym->intmod_sym_id);
gen_fptr_param (&head, &tail, (const char *) new_proc_sym->module,
- gfc_current_ns, "fptr");
-
+ gfc_current_ns, "fptr", 1);
+ }
+ else if (old_sym->intmod_sym_id == ISOCBINDING_F_POINTER)
+ {
+ gen_cptr_param (&head, &tail, (const char *) new_proc_sym->module,
+ gfc_current_ns, "cptr", old_sym->intmod_sym_id);
+ gen_fptr_param (&head, &tail, (const char *) new_proc_sym->module,
+ gfc_current_ns, "fptr", 0);
/* If we're dealing with c_f_pointer, it has an optional third arg. */
- if (old_sym->intmod_sym_id == ISOCBINDING_F_POINTER)
- {
- gen_shape_param (&head, &tail,
- (const char *) new_proc_sym->module,
- gfc_current_ns, "shape");
- }
+ gen_shape_param (&head, &tail,(const char *) new_proc_sym->module,
+ gfc_current_ns, "shape");
+
}
else if (old_sym->intmod_sym_id == ISOCBINDING_ASSOCIATED)
{
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 686e059ec4e..e960fa026b1 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1104,6 +1104,44 @@ gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
}
+/* Declare a procedure pointer. */
+
+static tree
+get_proc_pointer_decl (gfc_symbol *sym)
+{
+ tree decl;
+
+ decl = sym->backend_decl;
+ if (decl)
+ return decl;
+
+ decl = build_decl (VAR_DECL, get_identifier (sym->name),
+ build_pointer_type (gfc_get_function_type (sym)));
+
+ if (sym->ns->proc_name->backend_decl == current_function_decl
+ || sym->attr.contained)
+ gfc_add_decl_to_function (decl);
+ else
+ gfc_add_decl_to_parent_function (decl);
+
+ sym->backend_decl = decl;
+
+ if (!sym->attr.use_assoc
+ && (sym->attr.save != SAVE_NONE || sym->attr.data
+ || (sym->value && sym->ns->proc_name->attr.is_main_program)))
+ TREE_STATIC (decl) = 1;
+
+ if (TREE_STATIC (decl) && sym->value)
+ {
+ /* Add static initializer. */
+ DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
+ TREE_TYPE (decl), sym->attr.dimension, sym->attr.proc_pointer);
+ }
+
+ return decl;
+}
+
+
/* Get a basic decl for an external function. */
tree
@@ -1126,6 +1164,9 @@ gfc_get_extern_function_decl (gfc_symbol * sym)
to know that. */
gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
+ if (sym->attr.proc_pointer)
+ return get_proc_pointer_decl (sym);
+
if (sym->attr.intrinsic)
{
/* Call the resolution function to get the actual name. This is
@@ -1540,6 +1581,9 @@ create_function_arglist (gfc_symbol * sym)
type = gfc_sym_type (f->sym);
}
+ if (f->sym->attr.proc_pointer)
+ type = build_pointer_type (type);
+
/* Build a the argument declaration. */
parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 59a0a2d8eb7..570e07b5a06 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -480,8 +480,7 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
else if (sym->attr.flavor == FL_PROCEDURE
&& se->expr != current_function_decl)
{
- gcc_assert (se->want_pointer);
- if (!sym->attr.dummy)
+ if (!sym->attr.dummy && !sym->attr.proc_pointer)
{
gcc_assert (TREE_CODE (se->expr) == FUNCTION_DECL);
se->expr = build_fold_addr_expr (se->expr);
@@ -1372,6 +1371,8 @@ gfc_conv_function_val (gfc_se * se, gfc_symbol * sym)
if (sym->attr.dummy)
{
tmp = gfc_get_symbol_decl (sym);
+ if (sym->attr.proc_pointer)
+ tmp = build_fold_indirect_ref (tmp);
gcc_assert (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) == FUNCTION_TYPE);
}
@@ -2498,9 +2499,10 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
else
{
gfc_conv_expr_reference (&parmse, e);
- if (fsym && fsym->attr.pointer
- && fsym->attr.flavor != FL_PROCEDURE
- && e->expr_type != EXPR_NULL)
+ if (fsym && e->expr_type != EXPR_NULL
+ && ((fsym->attr.pointer
+ && fsym->attr.flavor != FL_PROCEDURE)
+ || fsym->attr.proc_pointer))
{
/* Scalar pointer dummy args require an extra level of
indirection. The null pointer already contains
@@ -3867,6 +3869,11 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
gfc_init_se (&rse, NULL);
rse.want_pointer = 1;
gfc_conv_expr (&rse, expr2);
+
+ if (expr1->symtree->n.sym->attr.proc_pointer
+ && expr1->symtree->n.sym->attr.dummy)
+ lse.expr = build_fold_indirect_ref (lse.expr);
+
gfc_add_block_to_block (&block, &lse.pre);
gfc_add_block_to_block (&block, &rse.pre);
gfc_add_modify_expr (&block, lse.expr,
diff --git a/gcc/function.c b/gcc/function.c
index d8234da3877..69c2f68a4f9 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2364,8 +2364,7 @@ assign_parm_remove_parallels (struct assign_parm_data_one *data)
This can be done with register operations rather than on the
stack, even if we will store the reconstituted parameter on the
stack later. */
- if (GET_CODE (entry_parm) == PARALLEL
- && data->passed_mode != BLKmode)
+ if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode)
{
rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
emit_group_store (parmreg, entry_parm, NULL_TREE,
@@ -2421,6 +2420,8 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
{
if (data->nominal_mode == BLKmode)
return true;
+ if (GET_MODE (data->entry_parm) == BLKmode)
+ return true;
#ifdef BLOCK_REG_PADDING
/* Only assign_parm_setup_block knows how to deal with register arguments
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 3da40a8c2a7..7914e4b6f35 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -155,6 +155,8 @@ static const char *print_prog_name = NULL;
static int print_multi_directory;
+static int print_sysroot;
+
/* Flag saying to print the relative path we'd use to
find OS libraries given the current compiler flags. */
@@ -1162,6 +1164,7 @@ static const struct option_map option_map[] =
{"--print-multi-directory", "-print-multi-directory", 0},
{"--print-multi-os-directory", "-print-multi-os-directory", 0},
{"--print-prog-name", "-print-prog-name=", "aj"},
+ {"--print-sysroot", "-print-sysroot", 0},
{"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0},
{"--profile", "-p", 0},
{"--profile-blocks", "-a", 0},
@@ -2973,7 +2976,7 @@ execute (void)
for (argc = 0; commands[i].argv[argc] != NULL; argc++)
;
- argv = alloca ((argc + 3) * sizeof (char *));
+ argv = XALLOCAVEC (const char *, argc + 3);
argv[0] = VALGRIND_PATH;
argv[1] = "-q";
@@ -3244,6 +3247,7 @@ display_help (void)
-print-multi-lib Display the mapping between command line options and\n\
multiple library search directories\n"), stdout);
fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
+ fputs (_(" -print-sysroot Display the target libraries directory\n"), stdout);
fputs (_(" -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout);
fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
@@ -3686,6 +3690,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
print_multi_lib = 1;
else if (! strcmp (argv[i], "-print-multi-directory"))
print_multi_directory = 1;
+ else if (! strcmp (argv[i], "-print-sysroot"))
+ print_sysroot = 1;
else if (! strcmp (argv[i], "-print-multi-os-directory"))
print_multi_os_directory = 1;
else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
@@ -4126,6 +4132,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
;
else if (! strcmp (argv[i], "-print-multi-directory"))
;
+ else if (! strcmp (argv[i], "-print-sysroot"))
+ ;
else if (! strcmp (argv[i], "-print-multi-os-directory"))
;
else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
@@ -6529,6 +6537,18 @@ main (int argc, char **argv)
return (0);
}
+ if (print_sysroot)
+ {
+ if (target_system_root)
+ {
+ if (target_sysroot_suffix)
+ printf ("%s%s\n", target_system_root, target_sysroot_suffix);
+ else
+ printf ("%s\n", target_system_root);
+ }
+ return (0);
+ }
+
if (print_multi_os_directory)
{
if (multilib_os_dir == NULL)
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 771df43a321..0955744855c 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -4562,9 +4562,8 @@ add_label_notes (rtx x, rtx insn)
such a LABEL_REF, so we don't have to handle REG_LABEL_TARGET
notes. */
gcc_assert (!JUMP_P (insn));
- REG_NOTES (insn)
- = gen_rtx_INSN_LIST (REG_LABEL_OPERAND, XEXP (x, 0),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_LABEL_OPERAND, XEXP (x, 0));
+
if (LABEL_P (XEXP (x, 0)))
LABEL_NUSES (XEXP (x, 0))++;
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index a01fa3f0b01..8c0e459fe38 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -638,7 +638,7 @@ mmap_gt_pch_get_address (size_t size, int fd)
if (ret == (void *) MAP_FAILED)
ret = NULL;
else
- munmap (ret, size);
+ munmap ((caddr_t) ret, size);
return ret;
}
@@ -662,7 +662,7 @@ mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
if (size == 0)
return -1;
- addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
return addr == base ? 1 : -1;
@@ -791,7 +791,7 @@ static htab_t loc_hash;
static hashval_t
hash_descriptor (const void *p)
{
- const struct loc_descriptor *const d = p;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p;
return htab_hash_pointer (d->function) | d->line;
}
@@ -799,8 +799,8 @@ hash_descriptor (const void *p)
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct loc_descriptor *const d = p1;
- const struct loc_descriptor *const d2 = p2;
+ const struct loc_descriptor *const d = (const struct loc_descriptor *) p1;
+ const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2;
return (d->file == d2->file && d->line == d2->line
&& d->function == d2->function);
@@ -819,7 +819,7 @@ struct ptr_hash_entry
static hashval_t
hash_ptr (const void *p)
{
- const struct ptr_hash_entry *const d = p;
+ const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p;
return htab_hash_pointer (d->ptr);
}
@@ -827,7 +827,7 @@ hash_ptr (const void *p)
static int
eq_ptr (const void *p1, const void *p2)
{
- const struct ptr_hash_entry *const p = p1;
+ const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1;
return (p->ptr == p2);
}
@@ -848,7 +848,7 @@ loc_descriptor (const char *name, int line, const char *function)
slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
if (*slot)
return *slot;
- *slot = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct loc_descriptor);
(*slot)->file = name;
(*slot)->line = line;
(*slot)->function = function;
@@ -883,7 +883,7 @@ ggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
static int
ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
{
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
if (!ggc_marked_p (p->ptr))
{
p->loc->collected += p->size;
@@ -907,7 +907,7 @@ ggc_free_overhead (void *ptr)
{
PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
NO_INSERT);
- struct ptr_hash_entry *p = *slot;
+ struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot;
p->loc->freed += p->size;
htab_clear_slot (ptr_hash, slot);
free (p);
@@ -917,8 +917,10 @@ ggc_free_overhead (void *ptr)
static int
final_cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed) -
(l2->allocated + l2->overhead - l2->freed));
@@ -929,8 +931,10 @@ final_cmp_statistic (const void *loc1, const void *loc2)
static int
cmp_statistic (const void *loc1, const void *loc2)
{
- struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
- struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
+ const struct loc_descriptor *const l1 =
+ *(const struct loc_descriptor *const *) loc1;
+ const struct loc_descriptor *const l2 =
+ *(const struct loc_descriptor *const *) loc2;
long diff;
diff = ((long)(l1->allocated + l1->overhead - l1->freed - l1->collected) -
@@ -967,7 +971,7 @@ dump_ggc_loc_statistics (bool final ATTRIBUTE_UNUSED)
ggc_force_collect = true;
ggc_collect ();
- loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
+ loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements);
fprintf (stderr, "-------------------------------------------------------\n");
fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n",
"source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index a80a6a0e979..5031a01b404 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -541,7 +541,7 @@ lookup_page_table_if_allocated (const void *p)
return NULL;
/* We might have a page entry which does not correspond exactly to a
system page. */
- if (base[L1][L2] && (char *) p < base[L1][L2]->page)
+ if (base[L1][L2] && (const char *) p < base[L1][L2]->page)
return NULL;
return base[L1][L2];
@@ -566,7 +566,7 @@ set_page_table_entry (void *p, page_entry *entry)
goto found;
/* Not found -- allocate a new table. */
- table = xcalloc (1, sizeof(*table));
+ table = XCNEW (struct page_table_chain);
table->next = G.lookup;
table->high_bits = high_bits;
G.lookup = table;
@@ -579,7 +579,7 @@ found:
L2 = LOOKUP_L2 (p);
if (base[L1] == NULL)
- base[L1] = xcalloc (PAGE_L2_SIZE, sizeof (page_entry *));
+ base[L1] = XCNEWVEC (page_entry *, PAGE_L2_SIZE);
base[L1][L2] = entry;
}
@@ -715,7 +715,7 @@ zone_find_object_size (struct small_page_entry *page,
unsigned int start_word = zone_get_object_alloc_word (object_midptr);
unsigned int start_bit = zone_get_object_alloc_bit (object_midptr);
size_t max_size = (page->common.page + SMALL_PAGE_SIZE
- - (char *) object);
+ - (const char *) object);
return zone_object_size_1 (page->alloc_bits, start_word, start_bit,
max_size);
@@ -898,7 +898,7 @@ alloc_small_page (struct alloc_zone *zone)
memory order. */
for (i = G.quire_size - 1; i >= 1; i--)
{
- e = xcalloc (1, G.small_page_overhead);
+ e = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
e->common.page = page + (i << GGC_PAGE_SHIFT);
e->common.zone = zone;
e->next = f;
@@ -908,7 +908,7 @@ alloc_small_page (struct alloc_zone *zone)
zone->free_pages = f;
- entry = xcalloc (1, G.small_page_overhead);
+ entry = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
entry->common.page = page;
entry->common.zone = zone;
set_page_table_entry (page, &entry->common);
@@ -935,7 +935,7 @@ alloc_large_page (size_t size, struct alloc_zone *zone)
size_t needed_size;
needed_size = size + sizeof (struct large_page_entry);
- page = xmalloc (needed_size);
+ page = XNEWVAR (char, needed_size);
entry = (struct large_page_entry *) page;
@@ -1439,7 +1439,7 @@ ggc_free (void *p)
/* Add the chunk to the free list. We don't bother with coalescing,
since we are likely to want a chunk of this size again. */
- free_chunk (p, size, page->zone);
+ free_chunk ((char *)p, size, page->zone);
}
}
@@ -1494,7 +1494,7 @@ gt_ggc_m_S (const void *p)
a STRING_CST. */
gcc_assert (offset == offsetof (struct tree_string, str));
p = ((const char *) p) - offset;
- gt_ggc_mx_lang_tree_node ((void *) p);
+ gt_ggc_mx_lang_tree_node (CONST_CAST(void *, p));
return;
}
@@ -1560,7 +1560,7 @@ int
ggc_marked_p (const void *p)
{
struct page_entry *page;
- const char *ptr = p;
+ const char *ptr = (const char *) p;
page = zone_get_object_page (p);
@@ -1686,7 +1686,7 @@ init_ggc (void)
if (GGC_PAGE_SIZE == G.pagesize)
{
/* We have a good page, might as well hold onto it... */
- e = xcalloc (1, G.small_page_overhead);
+ e = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
e->common.page = p;
e->common.zone = &main_zone;
e->next = main_zone.free_pages;
@@ -1714,7 +1714,7 @@ new_ggc_zone_1 (struct alloc_zone *new_zone, const char * name)
struct alloc_zone *
new_ggc_zone (const char * name)
{
- struct alloc_zone *new_zone = xcalloc (1, sizeof (struct alloc_zone));
+ struct alloc_zone *new_zone = XCNEW (struct alloc_zone);
new_ggc_zone_1 (new_zone, name);
return new_zone;
}
@@ -2301,7 +2301,7 @@ struct ggc_pch_data
struct ggc_pch_data *
init_ggc_pch (void)
{
- return xcalloc (sizeof (struct ggc_pch_data), 1);
+ return XCNEW (struct ggc_pch_data);
}
/* Return which of the page-aligned buckets the object at X, with type
@@ -2380,7 +2380,7 @@ ggc_pch_this_base (struct ggc_pch_data *d, void *base_)
}
if (d->alloc_bits == NULL)
- d->alloc_bits = xcalloc (1, d->alloc_size);
+ d->alloc_bits = XCNEWVAR (alloc_type, d->alloc_size);
}
/* Allocate a place for object X of size SIZE in the PCH file. */
@@ -2516,7 +2516,7 @@ ggc_pch_read (FILE *f, void *addr)
/* Allocate the dummy page entry for the PCH, and set all pages
mapped into the PCH to reference it. */
- pch_page = xcalloc (1, sizeof (struct page_entry));
+ pch_page = XCNEW (struct page_entry);
pch_page->page = pch_zone.page;
pch_page->pch_p = true;
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 8d5b38bbf32..d614986b49c 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -3773,11 +3773,7 @@ create_check_block_twin (rtx insn, bool mutate_p)
/* any_condjump_p (jump) == false.
We don't need the same note for the check because
any_condjump_p (check) == true. */
- {
- REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_CROSSING_JUMP,
- NULL_RTX,
- REG_NOTES (jump));
- }
+ add_reg_note (jump, REG_CROSSING_JUMP, NULL_RTX);
edge_flags = EDGE_CROSSING;
}
else
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 9e2153141d3..bda0fc261d6 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -153,7 +153,7 @@ static void
ipcp_init_cloned_node (struct cgraph_node *orig_node,
struct cgraph_node *new_node)
{
- ipa_create_node_params (new_node);
+ ipa_check_create_node_params ();
IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node;
ipa_count_formal_params (new_node);
ipa_create_param_decls_array (new_node);
@@ -998,8 +998,9 @@ ipcp_driver (void)
{
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation start:\n");
- ipa_create_all_node_params ();
- ipa_create_all_edge_args ();
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+ ipa_register_cgraph_hooks ();
/* 1. Call the init stage to initialize
the ipa_node_params and ipa_edge_args structures. */
ipcp_init_stage ();
@@ -1025,8 +1026,7 @@ ipcp_driver (void)
ipcp_print_profile_data (dump_file);
}
/* Free all IPCP structures. */
- ipa_free_all_node_params ();
- ipa_free_all_edge_args ();
+ free_all_ipa_structures_after_ipa_cp ();
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation end\n");
cgraph_remove_unreachable_nodes (true, NULL);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c5b4c9a80c8..f67d6579e10 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -28,8 +28,21 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-prop.h"
#include "tree-flow.h"
#include "tree-pass.h"
+#include "tree-inline.h"
#include "flags.h"
#include "timevar.h"
+#include "flags.h"
+
+/* Vector where the parameter infos are actually stored. */
+VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
+/* Vector where the parameter infos are actually stored. */
+VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+
+/* Holders of ipa cgraph hooks: */
+struct cgraph_edge_hook_list *edge_removal_hook_holder;
+struct cgraph_node_hook_list *node_removal_hook_holder;
+struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
+struct cgraph_2node_hook_list *node_duplication_hook_holder;
/* Initialize worklist to contain all functions. */
struct ipa_func_list *
@@ -176,7 +189,7 @@ ipa_detect_param_modifications (struct cgraph_node *mt)
tree stmt, parm_tree;
struct ipa_node_params *info = IPA_NODE_REF (mt);
- if (ipa_get_param_count (info) == 0)
+ if (ipa_get_param_count (info) == 0 || info->modified_flags)
return;
count = ipa_get_param_count (info);
@@ -244,7 +257,7 @@ ipa_compute_jump_functions (struct cgraph_edge *cs)
call_expr_arg_iterator iter;
struct ipa_edge_args *args = IPA_EDGE_REF (cs);
- if (ipa_get_cs_argument_count (args) == 0)
+ if (ipa_get_cs_argument_count (args) == 0 || args->jump_functions)
return;
args->jump_functions = XCNEWVEC (struct ipa_jump_func,
ipa_get_cs_argument_count (args));
@@ -316,74 +329,184 @@ ipa_compute_jump_functions (struct cgraph_edge *cs)
}
}
-/* Allocate and initialize ipa_node_params structure for the given cgraph
- node. */
+/* Frees all dynamically allocated structures that the argument info points
+ to. */
void
-ipa_create_node_params (struct cgraph_node *node)
+ipa_free_edge_args_substructures (struct ipa_edge_args *args)
{
- node->aux = xcalloc (1, sizeof (struct ipa_node_params));
+ if (args->jump_functions)
+ free (args->jump_functions);
+
+ memset (args, 0, sizeof (*args));
}
-/* Allocate and initialize ipa_node_params structure for all
- nodes in callgraph. */
+/* Free all ipa_edge structures. */
void
-ipa_create_all_node_params (void)
+ipa_free_all_edge_args (void)
{
- struct cgraph_node *node;
+ int i;
+ struct ipa_edge_args *args;
- for (node = cgraph_nodes; node; node = node->next)
- ipa_create_node_params (node);
+ for (i = 0;
+ VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args);
+ i++)
+ ipa_free_edge_args_substructures (args);
+
+ VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
+ ipa_edge_args_vector = NULL;
}
-/* Allocate and initialize ipa_edge structure. */
+/* Frees all dynamically allocated structures that the param info points
+ to. */
void
-ipa_create_all_edge_args (void)
+ipa_free_node_params_substructures (struct ipa_node_params *info)
{
- struct cgraph_node *node;
- struct cgraph_edge *cs;
-
- for (node = cgraph_nodes; node; node = node->next)
- for (cs = node->callees; cs; cs = cs->next_callee)
- cs->aux = xcalloc (1, sizeof (struct ipa_edge_args));
+ if (info->ipcp_lattices)
+ free (info->ipcp_lattices);
+ if (info->param_decls)
+ free (info->param_decls);
+ if (info->modified_flags)
+ free (info->modified_flags);
+
+ memset (info, 0, sizeof (*info));
}
-/* Free ipa_edge structure. */
+/* Free all ipa_node_params structures. */
void
-ipa_free_all_edge_args (void)
+ipa_free_all_node_params (void)
{
- struct cgraph_node *node;
- struct cgraph_edge *cs;
+ int i;
+ struct ipa_node_params *info;
- for (node = cgraph_nodes; node; node = node->next)
- for (cs = node->callees; cs; cs = cs->next_callee)
- if (cs->aux)
- {
- if (IPA_EDGE_REF (cs)->jump_functions)
- free (IPA_EDGE_REF (cs)->jump_functions);
- free (cs->aux);
- cs->aux = NULL;
- }
+ for (i = 0;
+ VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info);
+ i++)
+ ipa_free_node_params_substructures (info);
+
+ VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
+ ipa_node_params_vector = NULL;
+}
+
+/* Hook that is called by cgraph.c when an edge is removed. */
+static void
+ipa_edge_removal_hook (struct cgraph_edge *cs,
+ void *data __attribute__ ((unused)))
+{
+ ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
}
-/* Free ipa data structures of ipa_node_params and ipa_edge_args. */
+/* Hook that is called by cgraph.c when a node is removed. */
+static void
+ipa_node_removal_hook (struct cgraph_node *node,
+ void *data __attribute__ ((unused)))
+{
+ ipa_free_node_params_substructures (IPA_NODE_REF (node));
+}
+
+/* Helper function to duplicate an array of size N that is at SRC and store a
+ pointer to it to DST. Nothing is done if SRC is NULL. */
+static void *
+duplicate_array (void *src, size_t n)
+{
+ void *p;
+
+ if (!src)
+ return NULL;
+
+ p = xcalloc (1, n);
+ memcpy (p, src, n);
+ return p;
+}
+
+/* Hook that is called by cgraph.c when a node is duplicated. */
+static void
+ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
+ void *data)
+{
+ struct ipa_edge_args *old_args, *new_args;
+ int arg_count;
+
+ ipa_check_create_edge_args ();
+
+ old_args = IPA_EDGE_REF (src);
+ new_args = IPA_EDGE_REF (dst);
+
+ arg_count = ipa_get_cs_argument_count (old_args);
+ ipa_set_cs_argument_count (new_args, arg_count);
+ new_args->jump_functions = (struct ipa_jump_func *)
+ duplicate_array (old_args->jump_functions,
+ sizeof (struct ipa_jump_func) * arg_count);
+ data = data; /* Suppressing compiler warning. */
+}
+
+/* Hook that is called by cgraph.c when a node is duplicated. */
+static void
+ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
+ void *data)
+{
+ struct ipa_node_params *old_info, *new_info;
+ int param_count;
+
+ ipa_check_create_node_params ();
+ old_info = IPA_NODE_REF (src);
+ new_info = IPA_NODE_REF (dst);
+ param_count = ipa_get_param_count (old_info);
+
+ ipa_set_param_count (new_info, param_count);
+ new_info->ipcp_lattices = (struct ipcp_lattice *)
+ duplicate_array (old_info->ipcp_lattices,
+ sizeof (struct ipcp_lattice) * param_count);
+ new_info->param_decls = (tree *)
+ duplicate_array (old_info->param_decls, sizeof (tree) * param_count);
+ new_info->modified_flags = (bool *)
+ duplicate_array (old_info->modified_flags, sizeof (bool) * param_count);
+
+ new_info->ipcp_orig_node = old_info->ipcp_orig_node;
+ new_info->count_scale = old_info->count_scale;
+
+ data = data; /* Suppressing compiler warning. */
+}
+
+/* Register our cgraph hooks if they are not already there. */
void
-ipa_free_all_node_params (void)
+ipa_register_cgraph_hooks (void)
{
- struct cgraph_node *node;
+ if (!edge_removal_hook_holder)
+ edge_removal_hook_holder =
+ cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
+ if (!node_removal_hook_holder)
+ node_removal_hook_holder =
+ cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
+ if (!edge_duplication_hook_holder)
+ edge_duplication_hook_holder =
+ cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
+ if (!node_duplication_hook_holder)
+ node_duplication_hook_holder =
+ cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
+}
- for (node = cgraph_nodes; node; node = node->next)
- {
- if (node->aux == NULL)
- continue;
- if (IPA_NODE_REF (node)->ipcp_lattices)
- free (IPA_NODE_REF (node)->ipcp_lattices);
- if (IPA_NODE_REF (node)->param_decls)
- free (IPA_NODE_REF (node)->param_decls);
- if (IPA_NODE_REF (node)->modified_flags)
- free (IPA_NODE_REF (node)->modified_flags);
- free (node->aux);
- node->aux = NULL;
- }
+/* Unregister our cgraph hooks if they are not already there. */
+static void
+ipa_unregister_cgraph_hooks (void)
+{
+ cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
+ edge_removal_hook_holder = NULL;
+ cgraph_remove_node_removal_hook (node_removal_hook_holder);
+ node_removal_hook_holder = NULL;
+ cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
+ edge_duplication_hook_holder = NULL;
+ cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
+ node_duplication_hook_holder = NULL;
+}
+
+/* Free all ipa_node_params and all ipa_edge_args structures if they are no
+ longer needed after ipa-cp. */
+void
+free_all_ipa_structures_after_ipa_cp (void)
+{
+ ipa_free_all_edge_args ();
+ ipa_free_all_node_params ();
+ ipa_unregister_cgraph_hooks ();
}
/* Print ipa_tree_map data structures of all functions in the
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index a81418d7f47..e442698bd3a 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define IPA_PROP_H
#include "tree.h"
+#include "vec.h"
/* The following definitions and interfaces are used by
interprocedural analyses. */
@@ -100,14 +101,6 @@ struct ipa_replace_map
bool ref_p;
};
-/* Return the field in cgraph_node/cgraph_edge struct that points
- to ipa_node_params/ipa_edge_args struct. */
-#define IPA_NODE_REF(MT) ((struct ipa_node_params *)(MT)->aux)
-#define IPA_EDGE_REF(EDGE) ((struct ipa_edge_args *)(EDGE)->aux)
-/* This macro checks validity of index returned by
- ipa_get_param_decl_index function. */
-#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
-
/* ipa_node_params stores information related to formal parameters of functions
and some other information for interprocedural passes that operate on
parameters (such as ipa-cp). */
@@ -229,6 +222,71 @@ ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
return &args->jump_functions[i];
}
+/* Vectors need to have typedefs of structures. */
+typedef struct ipa_node_params ipa_node_params_t;
+typedef struct ipa_edge_args ipa_edge_args_t;
+
+/* Types of vectors hodling the infos. */
+DEF_VEC_O (ipa_node_params_t);
+DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
+DEF_VEC_O (ipa_edge_args_t);
+DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);
+
+/* Vector where the parameter infos are actually stored. */
+extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
+/* Vector where the parameter infos are actually stored. */
+extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+
+/* Return the associated parameter/argument info corresponding to the given
+ node/edge. */
+#define IPA_NODE_REF(NODE) (VEC_index (ipa_node_params_t, \
+ ipa_node_params_vector, (NODE)->uid))
+#define IPA_EDGE_REF(EDGE) (VEC_index (ipa_edge_args_t, \
+ ipa_edge_args_vector, (EDGE)->uid))
+/* This macro checks validity of index returned by
+ ipa_get_param_decl_index function. */
+#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
+
+/* Creating and freeing ipa_node_params and ipa_edge_args. */
+void ipa_create_all_node_params (void);
+void ipa_create_all_edge_args (void);
+void ipa_free_edge_args_substructures (struct ipa_edge_args *);
+void ipa_free_node_params_substructures (struct ipa_node_params *);
+void ipa_free_all_node_params (void);
+void ipa_free_all_edge_args (void);
+void free_all_ipa_structures_after_ipa_cp (void);
+void ipa_register_cgraph_hooks (void);
+
+/* This function ensures the array of node param infos is big enough to
+ accomdate a structure for all nodes and realloacates it if not. */
+static inline void
+ipa_check_create_node_params (void)
+{
+ if (!ipa_node_params_vector)
+ ipa_node_params_vector = VEC_alloc (ipa_node_params_t, heap,
+ cgraph_max_uid);
+
+ if (VEC_length (ipa_node_params_t, ipa_node_params_vector)
+ <= (unsigned) cgraph_max_uid)
+ VEC_safe_grow_cleared (ipa_node_params_t, heap,
+ ipa_node_params_vector, cgraph_max_uid + 1);
+}
+
+/* This function ensures the array of adge arguments infos is big enough to
+ accomdate a structure for all edges and realloacates it if not. */
+static inline void
+ipa_check_create_edge_args (void)
+{
+ if (!ipa_edge_args_vector)
+ ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
+ cgraph_edge_max_uid);
+
+ if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
+ <= (unsigned) cgraph_edge_max_uid)
+ VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
+ cgraph_edge_max_uid + 1);
+}
+
/* A function list element. It is used to create a temporary worklist used in
the propagation stage of IPCP. (can be used for more IPA optimizations) */
struct ipa_func_list
@@ -251,13 +309,6 @@ void ipa_count_formal_params (struct cgraph_node *);
void ipa_create_param_decls_array (struct cgraph_node *);
void ipa_detect_param_modifications (struct cgraph_node *);
-/* Creating and freeing ipa_node_params and ipa_edge_args. */
-void ipa_create_node_params (struct cgraph_node *);
-void ipa_free_all_node_params (void);
-void ipa_create_all_node_params (void);
-void ipa_create_all_edge_args (void);
-void ipa_free_all_edge_args (void);
-
/* Debugging interface. */
void ipa_print_all_tree_maps (FILE *);
void ipa_print_all_params_modified (FILE *);
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 33ac01f7a7c..f0f57e76390 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,21 @@
+2008-07-06 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (java/parse.o-warn): Remove.
+ (java/jcf-io.o-warn): Remove.
+
+2008-07-05 Tom Tromey <tromey@redhat.com>
+
+ * jcf-io.c: Don't include fnmatch.h. Don't use JCF_USE_SCANDIR.
+ (compare_path): Remove.
+ (java_or_class_file): Likewise.
+ (memoized_dirlist_entry): Likewise.
+ (memoized_dirlist_hash): Likewise.
+ (memoized_dirlist_lookup_eq): Likewise.
+ (memoized_dirlists): Likewise.
+ (caching_stat): Likewise.
+ (find_class): Use stat.
+ * jcf.h (JCF_USE_SCANDIR): Remove.
+
2008-06-30 Joshua Sumali <jsumali@redhat.com>
* Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index cab40afb959..6f0c4179f97 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -98,12 +98,6 @@ java-warn = $(STRICT_WARN)
# String length warnings
jvspec.o-warn = -Wno-error
-# Bison-1.75 output often yields (harmless) -Wtraditional warnings
-java/parse.o-warn = -Wno-error
-
-# java/jcf-io.c contains a -Wc++compat warning.
-java/jcf-io.o-warn = -Wno-error
-
jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o
rm -f $@
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index 52120971fa2..b968214e509 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -34,10 +34,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
#include "java-tree.h"
#include "hashtab.h"
-#if JCF_USE_SCANDIR
#include <dirent.h>
-#include <fnmatch.h>
-#endif
#include "zlib.h"
@@ -283,145 +280,6 @@ find_classfile (char *filename, JCF *jcf, const char *dep_name)
return open_class (filename, jcf, fd, dep_name);
}
-#if JCF_USE_SCANDIR
-
-/* A comparison function (as for qsort) that compares KEY (a char *
- giving the basename of a file) with the name stored in ENTRY (a
- dirent **). */
-
-static int
-compare_path (const void *key, const void *entry)
-{
- return strcmp ((const char *) key,
- (*((const struct dirent *const*) entry))->d_name);
-}
-
-/* Returns nonzero if ENTRY names a .java or .class file. */
-
-static int
-java_or_class_file (const struct dirent *entry)
-{
- const char *base = lbasename (entry->d_name);
- return (fnmatch ("*.java", base, 0) == 0 ||
- fnmatch ("*.class", base, 0) == 0);
-}
-
-/* Information about the files present in a particular directory. */
-typedef struct memoized_dirlist_entry
-{
- /* The name of the directory. */
- const char *dir;
- /* The number of .java and .class files present, or -1 if we could
- not, for some reason, obtain the list. */
- int num_files;
- /* The .java and .class files in the directory, in alphabetical
- order. */
- struct dirent **files;
-} memoized_dirlist_entry;
-
-/* A hash function for a memoized_dirlist_entry. */
-static hashval_t
-memoized_dirlist_hash (const void *entry)
-{
- const memoized_dirlist_entry *mde = (const memoized_dirlist_entry *) entry;
- return htab_hash_string (mde->dir);
-}
-
-/* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
- the directory given by KEY (a char *) giving the directory
- name. */
-
-static int
-memoized_dirlist_lookup_eq (const void *entry, const void *key)
-{
- return strcmp ((const char *) key,
- ((const memoized_dirlist_entry *) entry)->dir) == 0;
-}
-
-/* A hash table mapping directory names to the lists of .java and
- .class files in that directory. */
-
-static htab_t memoized_dirlists;
-
-#endif
-
-/* Like stat, but avoids actually making the stat system call if we
- know that it cannot succeed. FILENAME and BUF are as for stat. */
-
-static int
-caching_stat (char *filename, struct stat *buf)
-{
-#if JCF_USE_SCANDIR
- char *sep;
- char origsep = 0;
- char *base;
- memoized_dirlist_entry *dent;
- void **slot;
- struct memoized_dirlist_entry temp;
-
- /* If the hashtable has not already been created, create it now. */
- if (!memoized_dirlists)
- memoized_dirlists = htab_create (37,
- memoized_dirlist_hash,
- memoized_dirlist_lookup_eq,
- NULL);
-
- /* Get the name of the directory. */
- sep = strrchr (filename, DIR_SEPARATOR);
-#ifdef DIR_SEPARATOR_2
- if (! sep)
- sep = strrchr (filename, DIR_SEPARATOR_2);
-#endif
- if (sep)
- {
- origsep = *sep;
- *sep = '\0';
- base = sep + 1;
- }
- else
- base = filename;
-
- /* Obtain the entry for this directory from the hash table. This
- approach is ok since we know that the hash function only looks at
- the directory name. */
- temp.dir = filename;
- temp.num_files = 0;
- temp.files = NULL;
- slot = htab_find_slot (memoized_dirlists, &temp, INSERT);
- if (!*slot)
- {
- /* We have not already scanned this directory; scan it now. */
- dent = XNEW (memoized_dirlist_entry);
- dent->dir = xstrdup (filename);
- /* Unfortunately, scandir is not fully standardized. In
- particular, the type of the function pointer passed as the
- third argument sometimes takes a "const struct dirent *"
- parameter, and sometimes just a "struct dirent *". We cast
- to (void *) and use __extension__ so that either way it is
- quietly accepted. FIXME: scandir is not in POSIX. */
- dent->num_files = __extension__ scandir (filename, &dent->files,
- (void *) java_or_class_file,
- alphasort);
- *slot = dent;
- }
- else
- dent = *((memoized_dirlist_entry **) slot);
-
- /* Put the separator back. */
- if (sep)
- *sep = origsep;
-
- /* If the file is not in the list, there is no need to stat it; it
- does not exist. */
- if (dent->num_files != -1
- && !bsearch (base, dent->files, dent->num_files,
- sizeof (struct dirent *), compare_path))
- return -1;
-#endif
-
- return stat (filename, buf);
-}
-
/* Returns 1 if the CLASSNAME (really a char *) matches the name
stored in TABLE_ENTRY (also a char *). */
@@ -521,7 +379,7 @@ find_class (const char *classname, int classname_length, JCF *jcf)
else
continue;
}
- klass = caching_stat(buffer, &class_buf);
+ klass = stat (buffer, &class_buf);
}
}
diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h
index d4de2c57d54..40bbd725d45 100644
--- a/gcc/java/jcf.h
+++ b/gcc/java/jcf.h
@@ -1,6 +1,6 @@
/* Utility macros to read Java(TM) .class files and byte codes.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -45,14 +45,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define JCF_word JCF_u4
#endif
-/* If we have both "scandir" and "alphasort", we can cache directory
- listings to reduce the time taken to search the classpath. */
-#if defined(HAVE_SCANDIR) && defined(HAVE_ALPHASORT)
-#define JCF_USE_SCANDIR 1
-#else
-#define JCF_USE_SCANDIR 0
-#endif
-
/* On case-insensitive file systems, we need to ensure that a request
to open a .java or .class file is honored only if the file to be
opened is of the exact case we are asking for. In other words, we
diff --git a/gcc/jump.c b/gcc/jump.c
index 23d183e932c..595363b1adb 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -1068,8 +1068,7 @@ mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
a label, except for the primary target of a jump,
must have such a note. */
if (! find_reg_note (insn, kind, label))
- REG_NOTES (insn)
- = gen_rtx_INSN_LIST (kind, label, REG_NOTES (insn));
+ add_reg_note (insn, kind, label);
}
}
return;
diff --git a/gcc/libgcc-std.ver b/gcc/libgcc-std.ver
index 89be00cf3be..2df39f63e37 100644
--- a/gcc/libgcc-std.ver
+++ b/gcc/libgcc-std.ver
@@ -1800,3 +1800,88 @@ GCC_4.3.0 {
__satfractunstiuda
__satfractunstiuta
}
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+ __sync_fetch_and_add_1
+ __sync_fetch_and_sub_1
+ __sync_fetch_and_or_1
+ __sync_fetch_and_and_1
+ __sync_fetch_and_xor_1
+ __sync_fetch_and_nand_1
+ __sync_add_and_fetch_1
+ __sync_sub_and_fetch_1
+ __sync_or_and_fetch_1
+ __sync_and_and_fetch_1
+ __sync_xor_and_fetch_1
+ __sync_nand_and_fetch_1
+ __sync_bool_compare_and_swap_1
+ __sync_val_compare_and_swap_1
+ __sync_lock_test_and_set_1
+
+ __sync_fetch_and_add_2
+ __sync_fetch_and_sub_2
+ __sync_fetch_and_or_2
+ __sync_fetch_and_and_2
+ __sync_fetch_and_xor_2
+ __sync_fetch_and_nand_2
+ __sync_add_and_fetch_2
+ __sync_sub_and_fetch_2
+ __sync_or_and_fetch_2
+ __sync_and_and_fetch_2
+ __sync_xor_and_fetch_2
+ __sync_nand_and_fetch_2
+ __sync_bool_compare_and_swap_2
+ __sync_val_compare_and_swap_2
+ __sync_lock_test_and_set_2
+
+ __sync_fetch_and_add_4
+ __sync_fetch_and_sub_4
+ __sync_fetch_and_or_4
+ __sync_fetch_and_and_4
+ __sync_fetch_and_xor_4
+ __sync_fetch_and_nand_4
+ __sync_add_and_fetch_4
+ __sync_sub_and_fetch_4
+ __sync_or_and_fetch_4
+ __sync_and_and_fetch_4
+ __sync_xor_and_fetch_4
+ __sync_nand_and_fetch_4
+ __sync_bool_compare_and_swap_4
+ __sync_val_compare_and_swap_4
+ __sync_lock_test_and_set_4
+
+ __sync_fetch_and_add_8
+ __sync_fetch_and_sub_8
+ __sync_fetch_and_or_8
+ __sync_fetch_and_and_8
+ __sync_fetch_and_xor_8
+ __sync_fetch_and_nand_8
+ __sync_add_and_fetch_8
+ __sync_sub_and_fetch_8
+ __sync_or_and_fetch_8
+ __sync_and_and_fetch_8
+ __sync_xor_and_fetch_8
+ __sync_nand_and_fetch_8
+ __sync_bool_compare_and_swap_8
+ __sync_val_compare_and_swap_8
+ __sync_lock_test_and_set_8
+
+ __sync_fetch_and_add_16
+ __sync_fetch_and_sub_16
+ __sync_fetch_and_or_16
+ __sync_fetch_and_and_16
+ __sync_fetch_and_xor_16
+ __sync_fetch_and_nand_16
+ __sync_add_and_fetch_16
+ __sync_sub_and_fetch_16
+ __sync_or_and_fetch_16
+ __sync_and_and_fetch_16
+ __sync_xor_and_fetch_16
+ __sync_nand_and_fetch_16
+ __sync_bool_compare_and_swap_16
+ __sync_val_compare_and_swap_16
+ __sync_lock_test_and_set_16
+
+ __sync_synchronize
+}
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index c6e0540d15f..293b3ae3776 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -321,9 +321,8 @@ add_test (rtx cond, edge *e, basic_block dest)
JUMP_LABEL (jump) = label;
/* The jump is supposed to handle an unlikely special case. */
- REG_NOTES (jump)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- const0_rtx, REG_NOTES (jump));
+ add_reg_note (jump, REG_BR_PROB, const0_rtx);
+
LABEL_NUSES (label)++;
make_edge (bb, dest, (*e)->flags & ~EDGE_FALLTHRU);
@@ -518,18 +517,14 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
/* Add a REG_NONNEG note if the actual or estimated maximum number
of iterations is non-negative. */
if (nonneg)
- {
- REG_NOTES (jump_insn)
- = gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn));
- }
+ add_reg_note (jump_insn, REG_NONNEG, NULL_RTX);
+
/* Update the REG_BR_PROB note. */
if (true_prob_val)
{
/* Seems safer to use the branch probability. */
- REG_NOTES (jump_insn) =
- gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (desc->in_edge->probability),
- REG_NOTES (jump_insn));
+ add_reg_note (jump_insn, REG_BR_PROB,
+ GEN_INT (desc->in_edge->probability));
}
}
diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c
index 54c39a5698a..9d66d41db6e 100644
--- a/gcc/loop-unswitch.c
+++ b/gcc/loop-unswitch.c
@@ -125,8 +125,8 @@ compare_and_jump_seq (rtx op0, rtx op1, enum rtx_code comp, rtx label, int prob,
JUMP_LABEL (jump) = label;
LABEL_NUSES (label)++;
}
- REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (jump));
+ add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
+
seq = get_insns ();
end_sequence ();
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 67a95984fab..57205b51e61 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -551,8 +551,7 @@ move_eh_region_note (rtx insn, rtx insns)
|| (flag_non_call_exceptions
&& INSN_P (p)
&& may_trap_p (PATTERN (p))))
- REG_NOTES (p) = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0),
- REG_NOTES (p));
+ add_reg_note (p, REG_EH_REGION, XEXP (note, 0));
}
}
diff --git a/gcc/mkmap-symver.awk b/gcc/mkmap-symver.awk
index 855043f7e6c..4877e905147 100644
--- a/gcc/mkmap-symver.awk
+++ b/gcc/mkmap-symver.awk
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U") {
}
state == "nm" && NF == 3 {
- def[$3] = 1;
+ split ($3, s, "@")
+ def[s[1]] = 1;
sawsymbol = 1;
next;
}
@@ -82,10 +83,13 @@ $1 == "}" {
{
sym = prefix $1;
+ symbols[sym] = 1
if (thislib != "%exclude")
- ver[sym] = thislib;
- else
- delete ver[sym];
+ ver[sym, thislib] = 1;
+ else {
+ for (l in libs)
+ ver[sym, l] = 0;
+ }
next;
}
@@ -107,8 +111,8 @@ function output(lib) {
output(inherit[lib]);
empty=1
- for (sym in ver)
- if ((ver[sym] == lib) && (sym in def))
+ for (sym in symbols)
+ if ((ver[sym, lib] != 0) && (sym in def))
{
if (empty)
{
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 32a6396bd70..6e8c6cf3d21 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3879,8 +3879,7 @@ emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
if (note != 0)
XEXP (note, 0) = constm1_rtx;
else
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
- REG_NOTES (insn));
+ add_reg_note (insn, REG_EH_REGION, constm1_rtx);
}
/* First emit all insns that set pseudos. Remove them from the list as
diff --git a/gcc/opts.c b/gcc/opts.c
index 0bea9e4e94b..c26260acdd7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -903,6 +903,9 @@ decode_options (unsigned int argc, const char **argv)
/* Allow more virtual operators to increase alias precision. */
set_param_value ("max-aliased-vops", 500);
+
+ /* Track fields in field-sensitive alias analysis. */
+ set_param_value ("max-fields-for-field-sensitive", 100);
}
if (optimize >= 3)
diff --git a/gcc/predict.c b/gcc/predict.c
index ca7f9448d01..f85786e1a1d 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -263,12 +263,10 @@ predict_insn (rtx insn, enum br_predictor predictor, int probability)
if (!flag_guess_branch_prob)
return;
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PRED,
- gen_rtx_CONCAT (VOIDmode,
- GEN_INT ((int) predictor),
- GEN_INT ((int) probability)),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_BR_PRED,
+ gen_rtx_CONCAT (VOIDmode,
+ GEN_INT ((int) predictor),
+ GEN_INT ((int) probability)));
}
/* Predict insn by given predictor. */
@@ -561,9 +559,7 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
if (!prob_note)
{
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_BR_PROB,
- GEN_INT (combined_probability), REG_NOTES (insn));
+ add_reg_note (insn, REG_BR_PROB, GEN_INT (combined_probability));
/* Save the prediction into CFG in case we are seeing non-degenerated
conditional jump. */
@@ -1948,7 +1944,8 @@ gate_estimate_probability (void)
tree
build_predict_expr (enum br_predictor predictor, enum prediction taken)
{
- tree t = build1 (PREDICT_EXPR, NULL_TREE, build_int_cst (NULL, predictor));
+ tree t = build1 (PREDICT_EXPR, void_type_node,
+ build_int_cst (NULL, predictor));
PREDICT_EXPR_OUTCOME (t) = taken;
return t;
}
diff --git a/gcc/recog.c b/gcc/recog.c
index a176ed30af6..3ddfd86c635 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3045,10 +3045,9 @@ peephole2_optimize (void)
{
case REG_NORETURN:
case REG_SETJMP:
- REG_NOTES (new_insn)
- = gen_rtx_EXPR_LIST (REG_NOTE_KIND (note),
- XEXP (note, 0),
- REG_NOTES (new_insn));
+ add_reg_note (new_insn, REG_NOTE_KIND (note),
+ XEXP (note, 0));
+ break;
default:
/* Discard all other reg notes. */
break;
@@ -3096,10 +3095,7 @@ peephole2_optimize (void)
&& !find_reg_note (x, REG_EH_REGION, NULL)))
{
if (note)
- REG_NOTES (x)
- = gen_rtx_EXPR_LIST (REG_EH_REGION,
- XEXP (note, 0),
- REG_NOTES (x));
+ add_reg_note (x, REG_EH_REGION, XEXP (note, 0));
if (x != BB_END (bb) && eh_edge)
{
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index ffa06fd5752..4b5e422e207 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -788,9 +788,7 @@ emit_pop_insn (rtx insn, stack regstack, rtx reg, enum emit_where where)
else
pop_insn = emit_insn_before (pop_rtx, insn);
- REG_NOTES (pop_insn)
- = gen_rtx_EXPR_LIST (REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode),
- REG_NOTES (pop_insn));
+ add_reg_note (pop_insn, REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode));
regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
= regstack->reg[regstack->top];
@@ -1064,8 +1062,7 @@ move_for_stack_reg (rtx insn, stack regstack, rtx pat)
push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
emit_insn_before (push_rtx, insn);
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg,
- REG_NOTES (insn));
+ add_reg_note (insn, REG_DEAD, top_stack_reg);
}
replace_reg (psrc, FIRST_STACK_REG);
diff --git a/gcc/regmove.c b/gcc/regmove.c
index 4a53defed24..7de8d0d5b98 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -200,9 +200,8 @@ try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
if (note)
PUT_MODE (note, REG_UNUSED);
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_INC,
- reg, REG_NOTES (insn));
+ add_reg_note (insn, REG_INC, reg);
+
if (! inc_insn_set)
delete_insn (inc_insn);
return 1;
diff --git a/gcc/reload.c b/gcc/reload.c
index 9ab01375a91..e426d3634f6 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4145,9 +4145,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& (!JUMP_P (insn)
|| !label_is_jump_target_p (XEXP (substitution, 0),
insn)))
- REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL_OPERAND,
- XEXP (substitution, 0),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_LABEL_OPERAND, XEXP (substitution, 0));
}
else
retval |= (substed_operand[i] != *recog_data.operand_loc[i]);
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 297acbf8aa5..f449ffa9c32 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4000,8 +4000,7 @@ fixup_eh_region_note (rtx insn, rtx prev, rtx next)
if (INSN_P (i) && i != insn && may_trap_p (PATTERN (i)))
{
trap_count++;
- REG_NOTES (i)
- = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0), REG_NOTES (i));
+ add_reg_note (i, REG_EH_REGION, XEXP (note, 0));
}
}
@@ -4235,9 +4234,7 @@ reload_as_needed (int live_known)
}
if (n == 1)
{
- REG_NOTES (p)
- = gen_rtx_EXPR_LIST (REG_INC, reload_reg,
- REG_NOTES (p));
+ add_reg_note (p, REG_INC, reload_reg);
/* Mark this as having an output reload so that the
REG_INC processing code below won't invalidate
the reload for inheritance. */
@@ -8535,8 +8532,7 @@ add_auto_inc_notes (rtx insn, rtx x)
if (code == MEM && auto_inc_p (XEXP (x, 0)))
{
- REG_NOTES (insn)
- = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
+ add_reg_note (insn, REG_INC, XEXP (XEXP (x, 0), 0));
return;
}
@@ -8563,9 +8559,7 @@ copy_eh_notes (rtx insn, rtx x)
for (; x != 0; x = NEXT_INSN (x))
{
if (may_trap_p (PATTERN (x)))
- REG_NOTES (x)
- = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (eh_note, 0),
- REG_NOTES (x));
+ add_reg_note (x, REG_EH_REGION, XEXP (eh_note, 0));
}
}
}
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 7135a188574..25f410aad2d 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -3217,9 +3217,7 @@ delete_prior_computation (rtx note, rtx insn)
{
int i;
- REG_NOTES (our_prev)
- = gen_rtx_EXPR_LIST (REG_UNUSED, reg,
- REG_NOTES (our_prev));
+ add_reg_note (our_prev, REG_UNUSED, reg);
for (i = dest_regno; i < dest_endregno; i++)
if (! find_regno_note (our_prev, REG_UNUSED, i))
@@ -3281,8 +3279,7 @@ delete_computation (rtx insn)
delete_computation (prev);
else
/* Otherwise, show that cc0 won't be used. */
- REG_NOTES (prev) = gen_rtx_EXPR_LIST (REG_UNUSED,
- cc0_rtx, REG_NOTES (prev));
+ add_reg_note (prev, REG_UNUSED, cc0_rtx);
}
}
#endif
@@ -4024,9 +4021,7 @@ dbr_schedule (rtx first)
continue;
pred_flags = get_jump_flags (insn, JUMP_LABEL (insn));
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_BR_PRED,
- GEN_INT (pred_flags),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_BR_PRED, GEN_INT (pred_flags));
}
free_resource_info ();
free (uid_to_ruid);
diff --git a/gcc/resource.c b/gcc/resource.c
index 05308491f61..009fb6e609b 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -266,13 +266,10 @@ mark_referenced_resources (rtx x, struct resources *res,
return;
case UNSPEC_VOLATILE:
+ case TRAP_IF:
case ASM_INPUT:
/* Traditional asm's are always volatile. */
res->volatil = 1;
- return;
-
- case TRAP_IF:
- res->volatil = 1;
break;
case ASM_OPERANDS:
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 2e0884f8f56..b2b561c3421 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1755,6 +1755,7 @@ extern rtx find_reg_equal_equiv_note (const_rtx);
extern rtx find_constant_src (const_rtx);
extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
+extern void add_reg_note (rtx, enum reg_note, rtx);
extern void remove_note (rtx, const_rtx);
extern void remove_reg_equal_equiv_notes (rtx);
extern int side_effects_p (const_rtx);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index dec7daf0e3d..d569ff04b2b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1842,6 +1842,34 @@ find_regno_fusage (const_rtx insn, enum rtx_code code, unsigned int regno)
}
+/* Add register note with kind KIND and datum DATUM to INSN. */
+
+void
+add_reg_note (rtx insn, enum reg_note kind, rtx datum)
+{
+ rtx note;
+
+ switch (kind)
+ {
+ case REG_CC_SETTER:
+ case REG_CC_USER:
+ case REG_LABEL_TARGET:
+ case REG_LABEL_OPERAND:
+ /* These types of register notes use an INSN_LIST rather than an
+ EXPR_LIST, so that copying is done right and dumps look
+ better. */
+ note = alloc_INSN_LIST (datum, REG_NOTES (insn));
+ PUT_REG_NOTE_KIND (note, kind);
+ break;
+
+ default:
+ note = alloc_EXPR_LIST (kind, datum, REG_NOTES (insn));
+ break;
+ }
+
+ REG_NOTES (insn) = note;
+}
+
/* Remove register note NOTE from the REG_NOTES of INSN. */
void
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 2692e94aabc..7ffb1346021 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -520,6 +520,8 @@
#define TARGET_MACHINE_DEPENDENT_REORG 0
#define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
+#define TARGET_FN_ABI_VA_LIST std_fn_abi_va_list
+#define TARGET_CANONICAL_VA_LIST_TYPE std_canonical_va_list_type
#define TARGET_EXPAND_BUILTIN_VA_START 0
#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
@@ -820,6 +822,8 @@
TARGET_CC_MODES_COMPATIBLE, \
TARGET_MACHINE_DEPENDENT_REORG, \
TARGET_BUILD_BUILTIN_VA_LIST, \
+ TARGET_FN_ABI_VA_LIST, \
+ TARGET_CANONICAL_VA_LIST_TYPE, \
TARGET_EXPAND_BUILTIN_VA_START, \
TARGET_GIMPLIFY_VA_ARG_EXPR, \
TARGET_GET_PCH_VALIDITY, \
diff --git a/gcc/target.h b/gcc/target.h
index 012d1c0099b..11852430c8d 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -697,6 +697,12 @@ struct gcc_target
/* Create the __builtin_va_list type. */
tree (* build_builtin_va_list) (void);
+ /* Get the cfun/fndecl calling abi __builtin_va_list type. */
+ tree (* fn_abi_va_list) (tree);
+
+ /* Get the __builtin_va_list type dependent on input type. */
+ tree (* canonical_va_list_type) (tree);
+
/* Expand the __builtin_va_start builtin. */
void (* expand_builtin_va_start) (tree valist, rtx nextarg);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e8175a12083..f73e0443f8a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,264 @@
+2008-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.dg/compat/struct-layout-1_generate.c (vector_types): Add
+ v32qi, v16hi, v8si, v4di, v8sf, v4df, u32qi, u16hi, u8si, u4di,
+ u8sf and u4df.
+
+ * gcc.dg/compat/union-m128-1_main.c: Run only on x86. Remove
+ __x86_64__ check. Include "cpuid.h".
+ (main): Check SSE2 at runtime.
+
+ * gcc.dg/compat/union-m128-1_x.c: Compile with -msse2. Remove
+ __x86_64__ check.
+ * gcc.dg/compat/union-m128-1_y.c: Likewise.
+
+ * gcc.dg/compat/vector-1_x.c: Add 32byte vector tests.
+ * gcc.dg/compat/vector-1_y.c: Likewise.
+ * gcc.dg/compat/vector-2_x.c: Likewise.
+ * gcc.dg/compat/vector-2_y.c: Likewise.
+
+ * gcc.dg/compat/vector-1a_main.c: New.
+ * gcc.dg/compat/vector-1a_x.c: Likewise.
+ * gcc.dg/compat/vector-1a_y.c: Likewise.
+ * gcc.dg/compat/vector-2a_main.c: Likewise.
+ * gcc.dg/compat/vector-2a_x.c: Likewise.
+ * gcc.dg/compat/vector-2a_y.c: Likewise.
+
+ * gcc.dg/compat/vector-defs.h (v32qi): New.
+ (v16hi): Likewise.
+ (v8si): Likewise.
+ (v4di): Likewise.
+ (v8sf): Likewise.
+ (v4df): Likewise.
+ (u32qi): Likewise.
+ (u16hi): Likewise.
+ (u8si): Likewise.
+ (u4di): Likewise.
+ (u8sf): Likewise.
+ (u4df): Likewise.
+
+ * lib/compat.exp (compat-get-options-main): Support dg-skip-if.
+
+2008-07-07 Andy Hutchinson <hutchinsonandy@aim.com>
+
+ * gcc.c-torture/compile/20080625-1.c: Skip for AVR target.
+ * gcc.dg/torture/pr36373-10.c: Correct test where target pointer
+ is not same size as unsigned long.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36670
+ * gfortran.dg/product_sum_bounds_1.f90: New test case.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36341
+ PR fortran/34670
+ * gfortran.dg/matmul_bounds_2.f90: New test.
+ * gfortran.dg/matmul_bounds_3.f90: New test.
+ * gfortran.dg/matmul_bounds_4.f90: New test.
+ * gfortran.dg/matmul_bounds_5.f90: New test.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/torture/pta-ptrarith-1.c: New testcase.
+ * gcc.dg/torture/pta-ptrarith-2.c: Likewise.
+ * gcc.dg/torture/ipa-pta-1.c: Likewise.
+
+2008-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36726
+ * gfortran.dg/gomp/pr36726.f90: New test.
+
+2008-07-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-1.c: Expect the
+ macros to be defined for MIPS16 too.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-2.c: Likewise.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-3.c: New test.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-4.c: Likewise.
+
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-callused.c: Adjust testcase.
+
+2008-07-06 Kai Tietz <kai.tietz@onevision.com>
+
+ * gcc.dg/callabi/callabi.h: New.
+ * gcc.dg/callabi/vaarg-1.c: New.
+ * gcc.dg/callabi/vaarg-2.c: New.
+ * gcc.dg/callabi/vaarg-3.c: New.
+ * gcc.dg/callabi/func-1.c: New.
+
+2008-07-05 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * g++.dg/tree-ssa/ptrmemfield.C: New testcase.
+
+2008-07-05 Joseph Myers <joseph@codesourcery.com>
+
+ * lib/gcc-dg.exp (remove-build-file): Remove files on remote host
+ as well as on build.
+
+2008-07-04 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-callused.c: New testcase.
+
+2008-07-04 Richard Sandiford <richard@codesourcery.com>
+
+ * gcc.target/m68k/interrupt-2.c: New file.
+ * gcc.dg/tree-ssa/20040204-1.c: Don't XFAIL for m68k*-*-*.
+
+2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.dg/compat/struct-by-value-17a_x.c: Remove duplicated code.
+ * gcc.dg/compat/struct-by-value-17a_y.c: Likewise.
+
+2008-07-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization3.adb: New test.
+ * gnat.dg/loop_optimization3_pkg.ad[sb]: New helper.
+
+2008-07-03 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/36710
+ * gcc.target/i386/float128-2.c: New test.
+
+2008-07-03 Michael Meissner <gnu@the-meissners.org>
+
+ PR middle-end/35736
+ * gcc.dg/pr35736.c: New file.
+
+2008-07-03 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * gcc.dg/pr28243.c: Skip on SPU.
+ * gcc.dg/torture/pr25947-1.c: Likewise.
+ * gcc.dg/20030702-1.c: Likewise.
+ * g++.old-deja/g++.other/comdat5.C: Likewise.
+ * g++.old-deja/g++.other/local-alloc1.C: Likewise.
+ * g++.dg/opt/vt1.C: Likewise.
+
+2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.dg/compat/struct-by-value-17a_main.c: Remove duplicated code.
+
+2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/float128-1.c: New.
+
+2008-07-03 Andrew Haley <aph@redhat.com>
+
+ PR preprocessor/33305
+ * gcc.dg/cpp/avoidpaste1.c: Use dg-options "-ansi" to avoid
+ "-pedantic".
+ * gcc.dg/cpp/avoidpaste2.c: Likewise
+ * gcc.dg/cpp/20000519-1.c: Likewise.
+ * g++.dg/ext/gnu-inline-global-reject.C: Likewise.
+ * gcc.dg/cpp/c99-empty-macro-args.c: New test.
+ * gcc.dg/cpp/c90-empty-macro-args.c: New test.
+
+2008-07-03 Richard Guenther <rguenther@suse.de>
+
+ PR c++/36128
+ * g++.dg/other/builtin1.C: New testcase.
+
+2008-07-02 Joseph Myers <joseph@codesourcery.com>
+
+ * g++.dg/compat/struct-layout-1.exp: Compile generator on build system.
+ * gcc.dg/compat/struct-layout-1.exp: Likewise.
+ * objc.dg/gnu-encoding/gnu-encoding.exp: Likewise.
+
+2008-07-02 Andy Hutchinson <hutchinsonandy@aim.com>
+
+ PR testsuite/36285
+ * gcc.dg/compat/struct-by-value-16_x.c: Move some tests to new file
+ to reduce code size.
+ * gcc.dg/compat/struct-by-value-16_y.c: Ditto.
+ * gcc.dg/compat/struct-by-value-16a_main.c: New file.
+ * gcc.dg/compat/struct-by-value-16a_x.c: Ditto.
+ * gcc.dg/compat/struct-by-value-16a_y.c: Ditto.
+ * gcc.dg/compat/struct-by-value-17_x.c: Move some tests to new file
+ to reduce code size.
+ * gcc.dg/compat/struct-by-value-17_y.c: Ditto.
+ * gcc.dg/compat/struct-by-value-17a_main.c: New file.
+ * gcc.dg/compat/struct-by-value-17a_x.c: Ditto.
+ * gcc.dg/compat/struct-by-value-17a_y.c: Ditto.
+ * gcc.dg/compat/struct-by-value-18_x.c: Move some tests to new file
+ to reduce code size.
+ * gcc.dg/compat/struct-by-value-18_y.c: Ditto.
+ * gcc.dg/compat/struct-by-value-18a_main.c: New file.
+ * gcc.dg/compat/struct-by-value-18a_x.c: Ditto.
+ * gcc.dg/compat/struct-by-value-18a_y.c: Ditto.
+
+
+2008-07-02 Andy Hutchinson <hutchinsonandy@aim.com>
+
+ * gcc.dg/pr36227.c: Correct test for targets where long is
+ not the same size as pointer.
+
+2008-07-02 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * g++.dg/cdce3.C: Test long double math functions for
+ large_long_double target only. Skip pow10 and exp10
+ functions for *-*-darwin*.
+
+2008-07-02 Janus Weil <janus@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/32580
+ * gfortran.dg/c_f_pointer_tests_3.f90: Updated.
+ * gfortran.dg/proc_decl_1.f90: Updated.
+ * gfortran.dg/proc_ptr_1.f90: New.
+ * gfortran.dg/proc_ptr_2.f90: New.
+ * gfortran.dg/proc_ptr_3.f90: New.
+ * gfortran.dg/proc_ptr_4.f90: New.
+ * gfortran.dg/proc_ptr_5.f90: New.
+ * gfortran.dg/proc_ptr_6.f90: New.
+ * gfortran.dg/proc_ptr_7.f90: New.
+ * gfortran.dg/proc_ptr_8.f90: New.
+
+2008-07-02 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.target/arm/neon/polytypes.c: Use dg-message separately from
+ dg-error to match separate messages.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * g++.dg/abi/mangle24.C: Remove -mmmx.
+ * gcc.dg/const-float80-ped.c: Likewise.
+ * gcc.dg/const-float80.c: Likewise.
+ * gcc.dg/torture/fp-int-convert-float80.c: Likewise.
+
+ * g++.dg/abi/mangle25.C: Enable x86.
+ * gcc.dg/const-float128-ped.c: Likewise.
+ * gcc.dg/const-float128.c: Likewise.
+ * gcc.dg/torture/fp-int-convert-float128.c: Likewise.
+ * gcc.target/i386/pr32191.c: Likewise.
+ * gcc.target/i386/pr32268.c: Likewise.
+
+2008-07-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ PR target/36698
+ * gcc.c-torture/compile/20001226-1.c: XFAIL -O0 case on SPU.
+
+ * gcc.dg/pr27095.c: Provide target-specific regexp for SPU.
+
+2008-07-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * lib/compat.exp (compat-execute): Add -ffunction-sections
+ and -Wl,--auto-overlay when building for spu-*-elf*.
+
+2008-07-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * gcc.dg/nrv3.c (S): Increase size of padding for SPU.
+ * g++.dg/opt/temp1.C (struct T): Likewise.
+
+2008-07-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * gcc.c-torture/execute/20030222-1.x: New file.
+ * gcc.dg/tree-ssa/ssa-fre-3.c: Disable test on SPU.
+ * gcc.dg/lower-subreg-1.c: Likewise.
+
2008-07-02 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
SPU single-precision FP does not support subnormals:
diff --git a/gcc/testsuite/g++.dg/abi/mangle24.C b/gcc/testsuite/g++.dg/abi/mangle24.C
index 16aa2ea8e59..3a9f629d5bf 100644
--- a/gcc/testsuite/g++.dg/abi/mangle24.C
+++ b/gcc/testsuite/g++.dg/abi/mangle24.C
@@ -5,7 +5,6 @@
// Origin: Joseph Myers <joseph@codesourcery.com>
// { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
// { dg-options "" } */
-// { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
// { dg-final { scan-assembler "_Z1fe" { target i?86-*-* x86_64-*-* } } } */
// { dg-final { scan-assembler "_Z1fe" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
// { dg-final { scan-assembler "_Z1fu9__float80" { target ia64-*-hpux* } } } */
diff --git a/gcc/testsuite/g++.dg/abi/mangle25.C b/gcc/testsuite/g++.dg/abi/mangle25.C
index 75819a7bfaf..e00ba5c692d 100644
--- a/gcc/testsuite/g++.dg/abi/mangle25.C
+++ b/gcc/testsuite/g++.dg/abi/mangle25.C
@@ -4,7 +4,7 @@
// ia64-hpux where "long double" is "e" and __float128 is synonymous with
// "long double".
// Origin: Joseph Myers <joseph@codesourcery.com>
-// { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } }
+// { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } }
// { dg-options "" } */
// { dg-final { scan-assembler "_Z1fg" { target i?86-*-* x86_64-*-* } } } */
// { dg-final { scan-assembler "_Z1fg" { target { ia64-*-* && { ! "ia64-*-hpux*" } } } } } */
diff --git a/gcc/testsuite/g++.dg/cdce3.C b/gcc/testsuite/g++.dg/cdce3.C
index 6c6afc89027..19f7f0b295a 100644
--- a/gcc/testsuite/g++.dg/cdce3.C
+++ b/gcc/testsuite/g++.dg/cdce3.C
@@ -1,21 +1,23 @@
-/* { dg-do run { target { ! "*-*-darwin*" } } } */
-/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -lm" } */
-/* { dg-final { scan-tree-dump "cdce3.C:68: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:69: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:70: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:71: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:72: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:73: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:74: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:75: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:76: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:77: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:78: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:79: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:80: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:81: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:82: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
-/* { dg-final { scan-tree-dump "cdce3.C:83: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-do run } */
+/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -DNO_GNU_EXTENSION -lm" { target "*-*-darwin*" } } */
+/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -lm" { target { {! "*-*-darwin*" } && large_long_double } } }*/
+/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -DNO_LONG_DOUBLE -lm" { target {! large_long_double } } } */
+/* { dg-final { scan-tree-dump "cdce3.C:89: note: function call is shrink-wrapped into error conditions\." "cdce" { target {! "*-*-darwin*" } } } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:90: note: function call is shrink-wrapped into error conditions\." "cdce" { target {! "*-*-darwin*" } } } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:92: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:93: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:94: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:95: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:96: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:97: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:98: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:99: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:100: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:101: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:102: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:103: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:104: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
+/* { dg-final { scan-tree-dump "cdce3.C:105: note: function call is shrink-wrapped into error conditions\." "cdce" } }*/
/* { dg-final { cleanup-tree-dump "cdce" } } */
#include <stdlib.h>
#include <math.h>
@@ -23,9 +25,24 @@
#include <stdio.h>
#endif
#include <errno.h>
-typedef long double ldouble;
typedef void (*FP) (int xp);
#define NI __attribute__((noinline))
+
+#if defined(NO_LONG_DOUBLE)
+double result;
+
+#define DEF_MATH_FUNC(prefix, name) NI void prefix##name##f (int x) \
+{ \
+ float yy = name##f ((float) x); \
+ STORE_RESULT; \
+} \
+NI void prefix##name (int x) \
+{ \
+ double yy = name ((double)x); \
+ STORE_RESULT; \
+}
+#else
+typedef long double ldouble;
ldouble result;
#define DEF_MATH_FUNC(prefix, name) NI void prefix##name##f (int x) \
@@ -42,12 +59,15 @@ NI void prefix##name##l (int x) \
{ \
ldouble yy = name##l ((ldouble)x); \
STORE_RESULT; \
-}
+}
+#endif
#undef STORE_RESULT
#define STORE_RESULT result = yy
+#if !defined(NO_GNU_EXTENSION)
DEF_MATH_FUNC (m,pow10)
DEF_MATH_FUNC (m,exp10)
+#endif
DEF_MATH_FUNC (m,exp2)
DEF_MATH_FUNC (m,exp)
DEF_MATH_FUNC (m,expm1)
@@ -65,8 +85,10 @@ DEF_MATH_FUNC (m,sqrt)
#undef STORE_RESULT
#define STORE_RESULT
+#if !defined(NO_GNU_EXTENSION)
DEF_MATH_FUNC (o,pow10)
DEF_MATH_FUNC (o,exp10)
+#endif
DEF_MATH_FUNC (o,exp2)
DEF_MATH_FUNC (o,exp)
DEF_MATH_FUNC (o,expm1)
@@ -82,9 +104,14 @@ DEF_MATH_FUNC (o,log10)
DEF_MATH_FUNC (o,log1p)
DEF_MATH_FUNC (o,sqrt)
+#if defined(NO_LONG_DOUBLE)
+#define INIT_MATH_FUNC(prefix, name, lb, ub) { prefix##name##f, #name "f", 0, 0, lb, ub }, \
+{ prefix##name, #name, 0, 0, lb, ub },
+#else
#define INIT_MATH_FUNC(prefix, name, lb, ub) { prefix##name##f, #name "f", 0, 0, lb, ub }, \
{ prefix##name, #name, 0, 0, lb, ub }, \
{ prefix##name##l, #name "l" , 0, 0, lb, ub },
+#endif
struct MathFuncInfo
{
@@ -95,8 +122,10 @@ struct MathFuncInfo
bool has_lb;
bool has_ub;
} math_func_arr[] = {
+#if !defined(NO_GNU_EXTENSION)
INIT_MATH_FUNC (m,pow10, false, true)
INIT_MATH_FUNC (m,exp10, false, true)
+#endif
INIT_MATH_FUNC (m,exp2, false, true)
INIT_MATH_FUNC (m,expm1, false, true)
INIT_MATH_FUNC (m,exp, false, true)
@@ -114,8 +143,11 @@ struct MathFuncInfo
{ 0, 0, 0, 0, 0, 0} };
MathFuncInfo opt_math_func_arr[] =
-{ INIT_MATH_FUNC (o,pow10, false, true)
+{
+#if !defined(NO_GNU_EXTENSION)
+ INIT_MATH_FUNC (o,pow10, false, true)
INIT_MATH_FUNC (o,exp10, false, true)
+#endif
INIT_MATH_FUNC (o,exp2, false, true)
INIT_MATH_FUNC (o,expm1, false, true)
INIT_MATH_FUNC (o,exp, false, true)
diff --git a/gcc/testsuite/g++.dg/compat/struct-layout-1.exp b/gcc/testsuite/g++.dg/compat/struct-layout-1.exp
index 14473486aeb..cd58e7302a2 100644
--- a/gcc/testsuite/g++.dg/compat/struct-layout-1.exp
+++ b/gcc/testsuite/g++.dg/compat/struct-layout-1.exp
@@ -136,7 +136,7 @@ if [info exists env(GCC_EXEC_PREFIX)] {
set orig_gcc_exec_prefix_saved 1
unsetenv GCC_EXEC_PREFIX
}
-set status [remote_exec host "$HOSTCC $HOSTCFLAGS $generator_cmd"]
+set status [remote_exec build "$HOSTCC $HOSTCFLAGS $generator_cmd"]
set status [lindex $status 0]
if { $orig_gcc_exec_prefix_saved } {
set orig_gcc_exec_prefix_saved 0
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist1.C b/gcc/testsuite/g++.dg/cpp0x/initlist1.C
new file mode 100644
index 00000000000..b7583da7829
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist1.C
@@ -0,0 +1,69 @@
+// Basic uses of initializer lists
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+#include <initializer_list>
+
+extern "C" void abort();
+
+using namespace std;
+
+struct A { int i,j; A(int _i,int _j): i(_i), j(_j) {} };
+struct B { A a; B(A _a): a(_a) {} };
+struct C { B b; C(B _b): b(_b) {} };
+
+struct D
+{
+ int ia[3];
+ D (initializer_list<int> l)
+ {
+ const int *p = l.begin();
+ for (int i = 0; i < 3; ++i)
+ ia[i] = *p++;
+ }
+};
+
+void f(C c)
+{
+ if (c.b.a.i != 1) abort();
+ if (c.b.a.j != 2) abort();
+}
+void f(int);
+
+void g(D d)
+{
+ if (d.ia[0] != 1 || d.ia[1] != 2 || d.ia[2] != 3)
+ abort();
+}
+
+struct E
+{
+ int i, j, k;
+};
+
+void h(E e)
+{
+ if (e.i != 1 || e.j != 2 || e.k != 3)
+ abort();
+}
+
+void i(initializer_list<int> l)
+{
+ const int *p = l.begin();
+ if (*p++ != 1) abort();
+ if (*p++ != 2) abort();
+ if (*p++ != 3) abort();
+ if (p != l.end()) abort();
+}
+
+int main()
+{
+ g({1,2,3});
+
+ h({1,2,3});
+
+ f({{{1,2}}});
+ f({{A{1,2}}});
+
+ i({1,2,3});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist2.C b/gcc/testsuite/g++.dg/cpp0x/initlist2.C
new file mode 100644
index 00000000000..2fe4770560d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist2.C
@@ -0,0 +1,32 @@
+// Test that conversion to std::initializer_list takes priority over other
+// user-defined conversions.
+
+// { dg-do link }
+// { dg-options "-std=c++0x" }
+
+#include <initializer_list>
+
+struct string
+{
+ string (const char *) {}
+ template <class Iter> string (Iter, Iter);
+};
+
+template <class T, class U>
+struct pair
+{
+ pair (T t, U u) {}
+};
+
+template<class T, class U>
+struct map
+{
+ void insert (pair<T,U>);
+ void insert (std::initializer_list<pair<T,U> >) {}
+};
+
+int main()
+{
+ map<string,string> m;
+ m.insert({ {"this","that"}, {"me","you"} });
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist3.C b/gcc/testsuite/g++.dg/cpp0x/initlist3.C
new file mode 100644
index 00000000000..412deb51129
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist3.C
@@ -0,0 +1,11 @@
+// { dg-options "-std=c++0x" }
+
+#include <initializer_list>
+
+template <class T> void f(std::initializer_list<T>);
+
+void g()
+{
+ f({1,2,3});
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist4.C b/gcc/testsuite/g++.dg/cpp0x/initlist4.C
new file mode 100644
index 00000000000..d1ffab8546c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist4.C
@@ -0,0 +1,32 @@
+// Test for initializer-list 'explicit' rule
+// { dg-options "-std=c++0x" }
+
+struct A
+{
+ explicit A(int,int);
+ operator bool();
+};
+
+A f(A)
+{
+ A{1,2};
+ A a1{1,2};
+ new A{1,2};
+ if (A a5{1,2});
+
+ A({1,2}); // { dg-error "explicit" }
+ A a2({1,2}); // { dg-error "explicit" }
+ A a3 = {1,2}; // { dg-error "explicit" }
+ new A({1,2}); // { dg-error "explicit" }
+ f({1,2}); // { dg-error "explicit" }
+ a1 = {1,2}; // { dg-error "explicit" }
+ if (A a4 = {1,2}); // { dg-error "explicit" }
+ return {1,2}; // { dg-error "explicit" }
+}
+
+struct B
+{
+ A a;
+ B(): a{1,2} {}
+ B(const B&): a({1,2}) {} // { dg-error "explicit" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist5.C b/gcc/testsuite/g++.dg/cpp0x/initlist5.C
new file mode 100644
index 00000000000..0d02fd42d7f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist5.C
@@ -0,0 +1,21 @@
+// Test for narrowing diagnostics
+// { dg-options "-std=c++0x" }
+
+#include <initializer_list>
+
+struct A { int i; int j; };
+A a2 { 1.2 }; // { dg-error "narrowing" }
+A a1 { 1, 2 }; // aggregate initialization
+struct B {
+ B(std::initializer_list<int>);
+};
+B b1 { 1, 2 }; // creates initializer_list<int> and calls constructor
+B b2 { 1, 2.0 }; // { dg-error "narrowing" }
+struct C {
+ C(int i, double j);
+};
+C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2)
+C c2 = { 1.1, 2 }; // { dg-error "narrowing" }
+
+int j { 1 }; // initialize to 1
+int k {}; // initialize to 0
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist6.C b/gcc/testsuite/g++.dg/cpp0x/initlist6.C
new file mode 100644
index 00000000000..523570315eb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist6.C
@@ -0,0 +1,30 @@
+// Test for initlist lifetime
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+#include <initializer_list>
+
+int c;
+
+struct A
+{
+ A(int,int) { ++c; }
+ ~A() { --c; }
+};
+
+void f (std::initializer_list<A> l) { }
+
+int main()
+{
+ f({ {1,2}, {3,4} });
+ if (c != 0)
+ return 1;
+
+ {
+ std::initializer_list<A> l { {1,2}, {3,4} };
+ if (c != 2)
+ return 2;
+ }
+ if (c != 0)
+ return 3;
+}
diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
index 2f2b8f29a08..d9e26609550 100644
--- a/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
+++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
@@ -4,6 +4,7 @@
*/
/* { dg-do compile } */
+/* { dg-options " -ansi -Wno-long-long" } */
#include "gnu-inline-common.h"
diff --git a/gcc/testsuite/g++.dg/inherit/error4.C b/gcc/testsuite/g++.dg/inherit/error4.C
index 77fa75d1994..d56d67f7556 100644
--- a/gcc/testsuite/g++.dg/inherit/error4.C
+++ b/gcc/testsuite/g++.dg/inherit/error4.C
@@ -2,9 +2,9 @@
struct A { virtual ~A(); };
-struct B : A A {}; // { dg-error "'A'|function definition|extra" }
+struct B : A A {}; // { dg-error "" }
-A foo(const B &b)
+A foo(const B &b) // { dg-error "" }
{
- return b; // { dg-error "conversion" }
+ return b;
}
diff --git a/gcc/testsuite/g++.dg/init/brace2.C b/gcc/testsuite/g++.dg/init/brace2.C
index 2af063d5f56..619a20f3c70 100644
--- a/gcc/testsuite/g++.dg/init/brace2.C
+++ b/gcc/testsuite/g++.dg/init/brace2.C
@@ -5,4 +5,4 @@ const char * y = { "hello" };
int a = 2;
int b = { 2,3 }; // { dg-error "requires one element in initializer" }
int c = { { 2 } } ; // { dg-error "braces around scalar initializer" }
-int d = {}; // { dg-error "requires one element in initializer" }
+int d = {}; // { dg-error "initializer" }
diff --git a/gcc/testsuite/g++.dg/init/brace6.C b/gcc/testsuite/g++.dg/init/brace6.C
index ffb70118f9e..066d1ba65ff 100644
--- a/gcc/testsuite/g++.dg/init/brace6.C
+++ b/gcc/testsuite/g++.dg/init/brace6.C
@@ -6,7 +6,7 @@ struct A {
};
struct B {
- B(const B&);
+ B(const B&); // { dg-error "candidate" }
int b;
};
@@ -18,8 +18,8 @@ int main()
{
int i = { 1 };
int j = { 1, 2 }; /* { dg-error "requires one element" } */
- A a = { 6 }; /* { dg-error "initializer for non" } */
- B b = { 6 }; /* { dg-error "initializer for non" } */
+ A a = { 6 }; /* { dg-error "initialize" } */
+ B b = { 6 }; /* { dg-error "initialize" } */
C c = { 6 }; /* { dg-error "too many initializers" } */
D d = { 6 };
}
diff --git a/gcc/testsuite/g++.dg/opt/temp1.C b/gcc/testsuite/g++.dg/opt/temp1.C
index b822dc464fe..dc13f516246 100644
--- a/gcc/testsuite/g++.dg/opt/temp1.C
+++ b/gcc/testsuite/g++.dg/opt/temp1.C
@@ -24,7 +24,12 @@ void *memcpy (void *dest, const void *src, __SIZE_TYPE__ n)
}
struct T {
+#ifdef __SPU__
+ /* SPU returns aggregates up to 1172 bytes in registers. */
+ int a[300];
+#else
int a[128];
+#endif
T &operator+=(T const &v) __attribute__((noinline));
T operator+(T const &v) const { T t = *this; t += v; return t; }
};
diff --git a/gcc/testsuite/g++.dg/opt/vt1.C b/gcc/testsuite/g++.dg/opt/vt1.C
index b3abb5d57a2..ea74f52126f 100644
--- a/gcc/testsuite/g++.dg/opt/vt1.C
+++ b/gcc/testsuite/g++.dg/opt/vt1.C
@@ -1,6 +1,7 @@
// Test whether vtable for S is not put into read-only section.
// { dg-do compile { target fpic } }
// { dg-options "-O2 -fpic -fno-rtti" }
+// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } }
// Origin: Jakub Jelinek <jakub@redhat.com>
struct S
diff --git a/gcc/testsuite/g++.dg/other/builtin1.C b/gcc/testsuite/g++.dg/other/builtin1.C
new file mode 100644
index 00000000000..88665819987
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/builtin1.C
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+void foo()
+{
+ __builtin_isless (foo, 0); /* { dg-error "non-floating-point arguments" } */
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash36.C b/gcc/testsuite/g++.dg/parse/crash36.C
index bcd96e4ec1f..1397e87d256 100644
--- a/gcc/testsuite/g++.dg/parse/crash36.C
+++ b/gcc/testsuite/g++.dg/parse/crash36.C
@@ -2,7 +2,7 @@
// { dg-do compile }
// { dg-options "-std=c++98" }
-template <typename... T> struct A // { dg-error "does not include variadic templates" }
+template <typename... T> struct A // { dg-error "variadic templates" }
{
static T &t; // { dg-error "not expanded with|T" }
static const int i = sizeof (++t); // { dg-error "was not declared in this scope" }
diff --git a/gcc/testsuite/g++.dg/parse/ctor3.C b/gcc/testsuite/g++.dg/parse/ctor3.C
index 193ffae24fe..e597d926f40 100644
--- a/gcc/testsuite/g++.dg/parse/ctor3.C
+++ b/gcc/testsuite/g++.dg/parse/ctor3.C
@@ -4,5 +4,5 @@ struct A {};
struct B : A
{
- B() : A {} // { dg-error "expected" }
+ B() : A {} // { dg-error "initializer|expected" }
};
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C
new file mode 100644
index 00000000000..38189eb43af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+// { dg-options "-O2 -fdump-tree-final_cleanup" }
+
+
+struct f
+{
+ char m;
+ char m1;
+};
+
+static inline char f:: *g(int a)
+{
+ return a?0:&f::m;
+}
+
+int h(void)
+{
+ char f:: *a = g(0);
+ return a == 0;
+}
+
+/* We should have no cast to offset_type. */
+/* { dg-final { scan-tree-dump-times "offset_type" 0 "final_cleanup"} } */
+// And we should optimized this code to just return 0
+/* { dg-final { scan-tree-dump-times "return 0" 1 "final_cleanup"} } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/comdat5.C b/gcc/testsuite/g++.old-deja/g++.other/comdat5.C
index 5c2baa389e2..ad707f57247 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/comdat5.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/comdat5.C
@@ -2,5 +2,6 @@
// { dg-do link { target fpic } }
// { dg-additional-sources " comdat5-aux.cc" }
// { dg-options "-O2 -fPIC" }
+// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } }
#include "comdat4.C"
diff --git a/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C b/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C
index fe9d24fccf7..7488f1971c4 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/local-alloc1.C
@@ -1,5 +1,6 @@
// { dg-do assemble { target fpic } }
// { dg-options "-O0 -fpic" }
+// { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } }
// Origin: Jakub Jelinek <jakub@redhat.com>
struct bar {
diff --git a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
index cfcf546e157..19701ab3877 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20001226-1.c
@@ -4,6 +4,7 @@
/* { dg-xfail-if "function larger than 64K" { m6811-*-* } { "*" } { "" } } */
/* { dg-skip-if "too much code for avr" { "avr-*-*" } { "*" } { "" } } */
/* { dg-xfail-if "jump beyond 128K not supported" { xtensa-*-* } { "-O0" } { "" } } */
+/* { dg-xfail-if "PR36698" { spu-*-* } { "-O0" } { "" } } */
/* { dg-skip-if "" { m32c-*-* } { "*" } { "" } } */
/* This testcase exposed two branch shortening bugs on powerpc. */
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
index f0900fd9693..226bea1ffae 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
@@ -1,3 +1,4 @@
+/* { dg-skip-if "too much data" { "avr-*-*" } { "*" } { "" } } */
struct peakbufStruct {
unsigned int lnum [5000];
int lscan [5000][4000];
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030222-1.x b/gcc/testsuite/gcc.c-torture/execute/20030222-1.x
new file mode 100644
index 00000000000..e195563ddd0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030222-1.x
@@ -0,0 +1,6 @@
+if [istarget "spu-*-*"] {
+ # Using inline assembly to convert long long to int is not working quite
+ # right # on the SPU. An extra shift-left-4-byte is needed.
+ return 1
+}
+return 0
diff --git a/gcc/testsuite/gcc.dg/20030702-1.c b/gcc/testsuite/gcc.dg/20030702-1.c
index 892f7d50539..4dbb4c50fc5 100644
--- a/gcc/testsuite/gcc.dg/20030702-1.c
+++ b/gcc/testsuite/gcc.dg/20030702-1.c
@@ -2,6 +2,7 @@
correctly in combine. */
/* { dg-do compile { target fpic } } */
/* { dg-options "-O2 -fpic -fprofile-arcs" } */
+/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } } */
void test (void)
{
diff --git a/gcc/testsuite/gcc.dg/callabi/callabi.h b/gcc/testsuite/gcc.dg/callabi/callabi.h
new file mode 100644
index 00000000000..d008ad659cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/callabi.h
@@ -0,0 +1,50 @@
+/* First the default target definition. */
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+ typedef __builtin_va_list __gnuc_va_list;
+#endif
+
+#ifndef _VA_LIST_DEFINED
+#define _VA_LIST_DEFINED
+ typedef __gnuc_va_list va_list;
+#endif
+
+#define __va_copy(d,s) __builtin_va_copy(d,s)
+#define __va_start(v,l) __builtin_va_start(v,l)
+#define __va_arg(v,l) __builtin_va_arg(v,l)
+#define __va_end(v) __builtin_va_end(v)
+
+#define __ms_va_copy(d,s) __builtin_ms_va_copy(d,s)
+#define __ms_va_start(v,l) __builtin_ms_va_start(v,l)
+#define __ms_va_arg(v,l) __builtin_va_arg(v,l)
+#define __ms_va_end(v) __builtin_ms_va_end(v)
+
+#define __sysv_va_copy(d,s) __builtin_sysv_va_copy(d,s)
+#define __sysv_va_start(v,l) __builtin_sysv_va_start(v,l)
+#define __sysv_va_arg(v,l) __builtin_va_arg(v,l)
+#define __sysv_va_end(v) __builtin_sysv_va_end(v)
+
+#define CALLABI_NATIVE
+
+#ifdef _WIN64
+#define CALLABI_CROSS __attribute__ ((sysv_abi))
+
+#define CROSS_VA_LIST __builtin_sysv_va_list
+
+#define CROSS_VA_COPY(d,s) __sysv_va_copy(d,s)
+#define CROSS_VA_START(v,l) __sysv_va_start(v,l)
+#define CROSS_VA_ARG(v,l) __sysv_va_arg(v,l)
+#define CROSS_VA_END(v) __sysv_va_end(v)
+
+#else
+
+#define CALLABI_CROSS __attribute__ ((ms_abi))
+
+#define CROSS_VA_LIST __builtin_ms_va_list
+
+#define CROSS_VA_COPY(d,s) __ms_va_copy(d,s)
+#define CROSS_VA_START(v,l) __ms_va_start(v,l)
+#define CROSS_VA_ARG(v,l) __ms_va_arg(v,l)
+#define CROSS_VA_END(v) __ms_va_end(v)
+
+#endif \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/callabi/func-1.c b/gcc/testsuite/gcc.dg/callabi/func-1.c
new file mode 100644
index 00000000000..c727dbe6e53
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/func-1.c
@@ -0,0 +1,40 @@
+/* Test for cross x86_64<->w64 abi standard calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99 -ffast-math" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+long double
+CALLABI_CROSS func_cross (long double a, double b, float c, long d, int e,
+ char f)
+{
+ long double ret;
+ ret = a + (long double) b + (long double) c;
+ ret *= (long double) (d + (long) e);
+ if (f>0)
+ ret += func_cross (a,b,c,d,e,-f);
+ return ret;
+}
+
+long double
+CALLABI_NATIVE func_native (long double a, double b, float c, long d, int e,
+ char f)
+{
+ long double ret;
+ ret = a + (long double) b + (long double) c;
+ ret *= (long double) (d + (long) e);
+ if (f>0)
+ ret += func_native (a,b,c,d,e,-f);
+ return ret;
+}
+
+int main ()
+{
+ if (func_cross (1.0,2.0,3.0,1,2,3)
+ != func_native (1.0,2.0,3.0,1,2,3))
+ abort ();
+ return 0;
+} \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-1.c b/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
new file mode 100644
index 00000000000..1e745e56085
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern __SIZE_TYPE__ strlen (const char *);
+extern int sprintf (char *,const char *, ...);
+extern void abort (void);
+
+static
+void CALLABI_CROSS vdo_cpy (char *s, CROSS_VA_LIST argp)
+{
+ __SIZE_TYPE__ len;
+ char *r = s;
+ char *e;
+ *r = 0;
+ for (;;) {
+ e = CROSS_VA_ARG (argp,char *);
+ if (*e == 0) break;
+ sprintf (r,"%s", e);
+ r += strlen (r);
+ }
+}
+
+static
+void CALLABI_CROSS do_cpy (char *s, ...)
+{
+ CROSS_VA_LIST argp;
+ CROSS_VA_START (argp, s);
+ vdo_cpy (s, argp);
+ CROSS_VA_END (argp);
+}
+
+int main ()
+{
+ char s[256];
+
+ do_cpy (s, "1","2","3","4", "5", "6", "7", "");
+
+ if (s[0] != '1' || s[1] !='2' || s[2] != '3' || s[3] != '4'
+ || s[4] != '5' || s[5] != '6' || s[6] != '7' || s[7] != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-2.c b/gcc/testsuite/gcc.dg/callabi/vaarg-2.c
new file mode 100644
index 00000000000..c9b716194a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-2.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+static
+int CALLABI_CROSS fct1 (va_list argp, ...)
+{
+ long long p1,p2;
+ int ret = 1;
+ CROSS_VA_LIST argp_2;
+ CROSS_VA_START (argp_2,argp);
+
+ do {
+ p1 = CROSS_VA_ARG (argp_2, long long);
+ p2 = __va_arg (argp, long long);
+ if (p1 != p2)
+ ret = 0;
+ } while (ret && p1 != 0);
+ CROSS_VA_END (argp_2);
+ return ret;
+}
+
+static
+int fct2 (int dummy, ...)
+{
+ va_list argp;
+ int ret = dummy;
+
+ __va_start (argp, dummy);
+ ret += fct1 (argp, SZ_ARGS);
+ __va_end (argp);
+ return ret;
+}
+
+int main()
+{
+ if (fct2 (-1, SZ_ARGS) != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-3.c b/gcc/testsuite/gcc.dg/callabi/vaarg-3.c
new file mode 100644
index 00000000000..d0d068754e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-3.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+static
+int fct1 (CROSS_VA_LIST argp, ...)
+{
+ long long p1,p2;
+ int ret = 1;
+ va_list argp_2;
+
+ __va_start (argp_2,argp);
+ do {
+ p1 = __va_arg (argp_2, long long);
+ p2 = CROSS_VA_ARG (argp, long long);
+ if (p1 != p2)
+ ret = 0;
+ } while (ret && p1 != 0);
+ __va_end (argp_2);
+ return ret;
+}
+
+static
+int CALLABI_CROSS fct2 (int dummy, ...)
+{
+ CROSS_VA_LIST argp;
+ int ret = dummy;
+
+ CROSS_VA_START (argp, dummy);
+ ret += fct1 (argp, SZ_ARGS);
+ CROSS_VA_END (argp);
+ return ret;
+}
+
+int main()
+{
+ if (fct2 (-1, SZ_ARGS) != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-16_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-16_x.c
index 6b7331833ae..eb995921467 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-16_x.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-16_x.c
@@ -19,10 +19,7 @@ TEST(Scf9, _Complex float)
TEST(Scf10, _Complex float)
TEST(Scf11, _Complex float)
TEST(Scf12, _Complex float)
-TEST(Scf13, _Complex float)
-TEST(Scf14, _Complex float)
-TEST(Scf15, _Complex float)
-TEST(Scf16, _Complex float)
+
#undef T
@@ -45,10 +42,7 @@ T(Scf9, _Complex float)
T(Scf10, _Complex float)
T(Scf11, _Complex float)
T(Scf12, _Complex float)
-T(Scf13, _Complex float)
-T(Scf14, _Complex float)
-T(Scf15, _Complex float)
-T(Scf16, _Complex float)
+
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-16_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-16_y.c
index 273d7cc4f3e..9450815e74c 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-16_y.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-16_y.c
@@ -27,7 +27,4 @@ TEST(Scf9, _Complex float)
TEST(Scf10, _Complex float)
TEST(Scf11, _Complex float)
TEST(Scf12, _Complex float)
-TEST(Scf13, _Complex float)
-TEST(Scf14, _Complex float)
-TEST(Scf15, _Complex float)
-TEST(Scf16, _Complex float)
+
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_main.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_main.c
new file mode 100644
index 00000000000..6a71d15b8ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_main.c
@@ -0,0 +1,14 @@
+/* Test structures passed by value, including to a function with a
+ variable-length argument lists. All struct members are of type
+ _Complex float. */
+
+extern void struct_by_value_16_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ struct_by_value_16a_x ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_x.c
new file mode 100644
index 00000000000..0aa45249590
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_x.c
@@ -0,0 +1,37 @@
+#include "compat-common.h"
+
+#include "fp-struct-defs.h"
+#include "fp-struct-check.h"
+#include "fp-struct-test-by-value-x.h"
+
+DEFS(cf, _Complex float)
+CHECKS(cf, _Complex float)
+
+
+TEST(Scf13, _Complex float)
+TEST(Scf14, _Complex float)
+TEST(Scf15, _Complex float)
+TEST(Scf16, _Complex float)
+
+#undef T
+
+void
+struct_by_value_16a_x ()
+{
+DEBUG_INIT
+
+#define T(TYPE, MTYPE) testit##TYPE ();
+
+
+T(Scf13, _Complex float)
+T(Scf14, _Complex float)
+T(Scf15, _Complex float)
+T(Scf16, _Complex float)
+
+DEBUG_FINI
+
+if (fails != 0)
+ abort ();
+
+#undef T
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_y.c
new file mode 100644
index 00000000000..2fd561ef044
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-16a_y.c
@@ -0,0 +1,22 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#include "fp-struct-defs.h"
+#include "fp-struct-init.h"
+#include "fp-struct-test-by-value-y.h"
+
+DEFS(cf,_Complex float)
+INITS(cf, _Complex float)
+
+
+TEST(Scf13, _Complex float)
+TEST(Scf14, _Complex float)
+TEST(Scf15, _Complex float)
+TEST(Scf16, _Complex float)
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-17_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-17_x.c
index cba628bcb5b..93fd788ea45 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-17_x.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-17_x.c
@@ -19,10 +19,7 @@ TEST(Scd9, _Complex double)
TEST(Scd10, _Complex double)
TEST(Scd11, _Complex double)
TEST(Scd12, _Complex double)
-TEST(Scd13, _Complex double)
-TEST(Scd14, _Complex double)
-TEST(Scd15, _Complex double)
-TEST(Scd16, _Complex double)
+
#undef T
@@ -45,10 +42,7 @@ T(Scd9, _Complex double)
T(Scd10, _Complex double)
T(Scd11, _Complex double)
T(Scd12, _Complex double)
-T(Scd13, _Complex double)
-T(Scd14, _Complex double)
-T(Scd15, _Complex double)
-T(Scd16, _Complex double)
+
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-17_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-17_y.c
index a0342a37c0c..f8ac0a7c15e 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-17_y.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-17_y.c
@@ -27,7 +27,4 @@ TEST(Scd9, _Complex double)
TEST(Scd10, _Complex double)
TEST(Scd11, _Complex double)
TEST(Scd12, _Complex double)
-TEST(Scd13, _Complex double)
-TEST(Scd14, _Complex double)
-TEST(Scd15, _Complex double)
-TEST(Scd16, _Complex double)
+
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_main.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_main.c
new file mode 100644
index 00000000000..1db00215f2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_main.c
@@ -0,0 +1,14 @@
+/* Test structures passed by value, including to a function with a
+ variable-length argument lists. All struct members are of type
+ _Complex double. */
+
+extern void struct_by_value_17_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ struct_by_value_17a_x ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_x.c
new file mode 100644
index 00000000000..5b2f1d1d920
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_x.c
@@ -0,0 +1,37 @@
+#include "compat-common.h"
+
+#include "fp-struct-defs.h"
+#include "fp-struct-check.h"
+#include "fp-struct-test-by-value-x.h"
+
+DEFS(cd, _Complex double)
+CHECKS(cd, _Complex double)
+
+
+TEST(Scd13, _Complex double)
+TEST(Scd14, _Complex double)
+TEST(Scd15, _Complex double)
+TEST(Scd16, _Complex double)
+
+#undef T
+
+void
+struct_by_value_17a_x ()
+{
+DEBUG_INIT
+
+#define T(TYPE, MTYPE) testit##TYPE ();
+
+
+T(Scd13, _Complex double)
+T(Scd14, _Complex double)
+T(Scd15, _Complex double)
+T(Scd16, _Complex double)
+
+DEBUG_FINI
+
+if (fails != 0)
+ abort ();
+
+#undef T
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_y.c
new file mode 100644
index 00000000000..d785a999d58
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-17a_y.c
@@ -0,0 +1,22 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#include "fp-struct-defs.h"
+#include "fp-struct-init.h"
+#include "fp-struct-test-by-value-y.h"
+
+DEFS(cd,_Complex double)
+INITS(cd, _Complex double)
+
+
+TEST(Scd13, _Complex double)
+TEST(Scd14, _Complex double)
+TEST(Scd15, _Complex double)
+TEST(Scd16, _Complex double)
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-18_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-18_x.c
index e040ecc79a7..f9dd6aa0b72 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-18_x.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-18_x.c
@@ -19,10 +19,7 @@ TEST(Scld9, _Complex long double)
TEST(Scld10, _Complex long double)
TEST(Scld11, _Complex long double)
TEST(Scld12, _Complex long double)
-TEST(Scld13, _Complex long double)
-TEST(Scld14, _Complex long double)
-TEST(Scld15, _Complex long double)
-TEST(Scld16, _Complex long double)
+
#undef T
@@ -45,10 +42,7 @@ T(Scld9, _Complex long double)
T(Scld10, _Complex long double)
T(Scld11, _Complex long double)
T(Scld12, _Complex long double)
-T(Scld13, _Complex long double)
-T(Scld14, _Complex long double)
-T(Scld15, _Complex long double)
-T(Scld16, _Complex long double)
+
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-18_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-18_y.c
index b69425a5f4e..8c732d58273 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-by-value-18_y.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-18_y.c
@@ -27,7 +27,4 @@ TEST(Scld9, _Complex long double)
TEST(Scld10, _Complex long double)
TEST(Scld11, _Complex long double)
TEST(Scld12, _Complex long double)
-TEST(Scld13, _Complex long double)
-TEST(Scld14, _Complex long double)
-TEST(Scld15, _Complex long double)
-TEST(Scld16, _Complex long double)
+
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_main.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_main.c
new file mode 100644
index 00000000000..5b9dfd983b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_main.c
@@ -0,0 +1,14 @@
+/* Test structures passed by value, including to a function with a
+ variable-length argument lists. All struct members are of type
+ _Complex long double. */
+
+extern void struct_by_value_18_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ struct_by_value_18a_x ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_x.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_x.c
new file mode 100644
index 00000000000..72f5bbf5d44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_x.c
@@ -0,0 +1,37 @@
+#include "compat-common.h"
+
+#include "fp-struct-defs.h"
+#include "fp-struct-check.h"
+#include "fp-struct-test-by-value-x.h"
+
+DEFS(cld, _Complex long double)
+CHECKS(cld, _Complex long double)
+
+
+TEST(Scld13, _Complex long double)
+TEST(Scld14, _Complex long double)
+TEST(Scld15, _Complex long double)
+TEST(Scld16, _Complex long double)
+
+#undef T
+
+void
+struct_by_value_18a_x ()
+{
+DEBUG_INIT
+
+#define T(TYPE, MTYPE) testit##TYPE ();
+
+
+T(Scld13, _Complex long double)
+T(Scld14, _Complex long double)
+T(Scld15, _Complex long double)
+T(Scld16, _Complex long double)
+
+DEBUG_FINI
+
+if (fails != 0)
+ abort ();
+
+#undef T
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_y.c b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_y.c
new file mode 100644
index 00000000000..545dcf8970f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/struct-by-value-18a_y.c
@@ -0,0 +1,22 @@
+#include <stdarg.h>
+
+#include "compat-common.h"
+
+#ifdef SKIP_VA
+const int test_va = 0;
+#else
+const int test_va = 1;
+#endif
+
+#include "fp-struct-defs.h"
+#include "fp-struct-init.h"
+#include "fp-struct-test-by-value-y.h"
+
+DEFS(cld,_Complex long double)
+INITS(cld, _Complex long double)
+
+
+TEST(Scld13, _Complex long double)
+TEST(Scld14, _Complex long double)
+TEST(Scld15, _Complex long double)
+TEST(Scld16, _Complex long double)
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp b/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp
index 5de2c1e2618..992b62cdc09 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp
@@ -98,7 +98,7 @@ if [info exists env(GCC_EXEC_PREFIX)] {
set orig_gcc_exec_prefix_saved 1
unsetenv GCC_EXEC_PREFIX
}
-set status [remote_exec host "$HOSTCC $HOSTCFLAGS $generator_cmd"]
+set status [remote_exec build "$HOSTCC $HOSTCFLAGS $generator_cmd"]
set status [lindex $status 0]
if { $orig_gcc_exec_prefix_saved } {
set orig_gcc_exec_prefix_saved 0
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
index c53c3e8c2bd..f6a217e6f56 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
@@ -186,30 +186,42 @@ struct types vector_types[] = {
/* vector-defs.h typedefs */
{ "v8qi", TYPE_OTHER, 0, 0 },
{ "v16qi", TYPE_OTHER, 0, 0 },
+{ "v32qi", TYPE_OTHER, 0, 0 },
{ "v2hi", TYPE_OTHER, 0, 0 },
{ "v4hi", TYPE_OTHER, 0, 0 },
{ "v8hi", TYPE_OTHER, 0, 0 },
+{ "v16hi", TYPE_OTHER, 0, 0 },
{ "v2si", TYPE_OTHER, 0, 0 },
{ "v4si", TYPE_OTHER, 0, 0 },
+{ "v8si", TYPE_OTHER, 0, 0 },
{ "v1di", TYPE_OTHER, 0, 0 },
{ "v2di", TYPE_OTHER, 0, 0 },
+{ "v4di", TYPE_OTHER, 0, 0 },
{ "v2sf", TYPE_OTHER, 0, 0 },
{ "v4sf", TYPE_OTHER, 0, 0 },
+{ "v8sf", TYPE_OTHER, 0, 0 },
{ "v16sf", TYPE_OTHER, 0, 0 },
{ "v2df", TYPE_OTHER, 0, 0 },
+{ "v4df", TYPE_OTHER, 0, 0 },
{ "u8qi", TYPE_OTHER, 0, 0 },
{ "u16qi", TYPE_OTHER, 0, 0 },
+{ "u32qi", TYPE_OTHER, 0, 0 },
{ "u2hi", TYPE_OTHER, 0, 0 },
{ "u4hi", TYPE_OTHER, 0, 0 },
{ "u8hi", TYPE_OTHER, 0, 0 },
+{ "u16hi", TYPE_OTHER, 0, 0 },
{ "u2si", TYPE_OTHER, 0, 0 },
{ "u4si", TYPE_OTHER, 0, 0 },
+{ "u8si", TYPE_OTHER, 0, 0 },
{ "u1di", TYPE_OTHER, 0, 0 },
{ "u2di", TYPE_OTHER, 0, 0 },
+{ "u4di", TYPE_OTHER, 0, 0 },
{ "u2sf", TYPE_OTHER, 0, 0 },
{ "u4sf", TYPE_OTHER, 0, 0 },
+{ "u8sf", TYPE_OTHER, 0, 0 },
{ "u16sf", TYPE_OTHER, 0, 0 },
{ "u2df", TYPE_OTHER, 0, 0 },
+{ "u4df", TYPE_OTHER, 0, 0 },
{ "__m64", TYPE_OTHER, 0, 0 },
{ "__m128", TYPE_OTHER, 0, 0 }
#define NVTYPES2 (sizeof (vector_types) / sizeof (vector_types[0]))
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
index 69dd34dce57..11f872154eb 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
@@ -1,6 +1,8 @@
+/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-O" } */
-#ifdef __x86_64__
+#include "cpuid.h"
+
/* Test function argument passing. PR target/15301. */
extern void union_m128_1_x (void);
@@ -9,13 +11,14 @@ extern void exit (int);
int
main ()
{
- union_m128_1_x ();
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ union_m128_1_x ();
+
exit (0);
}
-#else
-int
-main ()
-{
- return 0;
-}
-#endif
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
index 06a4ef5ffdb..1f92303d95b 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
@@ -1,6 +1,5 @@
-/* { dg-options "-O" } */
+/* { dg-options "-O -msse2" } */
-#ifdef __x86_64__
#include "union-m128-1.h"
SS_union_mi128 un;
@@ -23,7 +22,3 @@ union_m128_1_x ()
foo(un);
foo(st);
}
-#else
-int dummy_x;
-#endif
-
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
index 2b6eb0a6ee8..be9d6e8f3d5 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
@@ -1,6 +1,5 @@
-/* { dg-options "-O" } */
+/* { dg-options "-O -msse2" } */
-#ifdef __x86_64__
#include <stdlib.h>
#include "union-m128-1.h"
@@ -26,7 +25,3 @@ foo (SS_struct_mi128 st)
|| x.u [1] != 0xfedcba9876543210LL)
abort ();
}
-#else
-int dummy_y;
-#endif
-
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_x.c b/gcc/testsuite/gcc.dg/compat/vector-1_x.c
index 11995b496e5..ab4f88bf48b 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-1_x.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-1_x.c
@@ -8,13 +8,17 @@
SETUP (8, qi);
SETUP (16, qi);
+SETUP (32, qi);
SETUP (2, hi);
SETUP (4, hi);
SETUP (8, hi);
+SETUP (16, hi);
SETUP (2, si);
SETUP (4, si);
+SETUP (8, si);
SETUP (1, di);
SETUP (2, di);
+SETUP (4, di);
#endif
@@ -26,13 +30,17 @@ vector_1_x (void)
CHECK (8, qi);
CHECK (16, qi);
+ CHECK (32, qi);
CHECK (2, hi);
CHECK (4, hi);
CHECK (8, hi);
+ CHECK (16, hi);
CHECK (2, si);
CHECK (4, si);
+ CHECK (8, si);
CHECK (1, di);
CHECK (2, di);
+ CHECK (4, di);
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_y.c b/gcc/testsuite/gcc.dg/compat/vector-1_y.c
index 1cec61734b4..5a09c0eadb6 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-1_y.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-1_y.c
@@ -8,12 +8,16 @@
TEST (8, qi, 101)
TEST (16, qi, 101)
+TEST (32, qi, 90)
TEST (2, hi, 201)
TEST (4, hi, 202)
TEST (8, hi, 203)
+TEST (16, hi, 203)
TEST (2, si, 301)
TEST (4, si, 302)
+TEST (8, si, 303)
TEST (1, di, 401)
TEST (2, di, 402)
+TEST (4, di, 403)
#endif
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_main.c b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c
new file mode 100644
index 00000000000..76fb2915e1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c
@@ -0,0 +1,26 @@
+/* { dg-skip-if "test SSE2 vector" { ! { i?86-*-* x86_64-*-* } } } */
+
+/* Test compatibility of vector types: layout between separately-compiled
+ modules, parameter passing, and function return. This test uses
+ vectors of integer values. */
+
+#include "cpuid.h"
+
+extern void vector_1_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ vector_1_x ();
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_x.c b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c
new file mode 100644
index 00000000000..aa0fa7f208c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-1_x.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_y.c b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c
new file mode 100644
index 00000000000..2c88e198845
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-1_y.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_x.c b/gcc/testsuite/gcc.dg/compat/vector-2_x.c
index de5f29c2688..d08c77fe3a0 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-2_x.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-2_x.c
@@ -10,7 +10,9 @@
SETUP (2, sf);
SETUP (4, sf);
SETUP (16, sf);
+SETUP (8, sf);
SETUP (2, df);
+SETUP (4, df);
#endif
@@ -22,7 +24,9 @@ vector_2_x (void)
CHECK (2, sf);
CHECK (4, sf);
+ CHECK (8, sf);
CHECK (16, sf);
+ CHECK (4, df);
CHECK (2, df);
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_y.c b/gcc/testsuite/gcc.dg/compat/vector-2_y.c
index 10d7a064532..fd5830c35b3 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-2_y.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-2_y.c
@@ -9,7 +9,9 @@
TEST (2, sf, 301.0)
TEST (4, sf, 302.0)
+TEST (8, sf, 303.0)
TEST (16, sf, 304.0)
TEST (2, df, 402.0)
+TEST (4, df, 402.0)
#endif
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_main.c b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c
new file mode 100644
index 00000000000..96c1111fddc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c
@@ -0,0 +1,26 @@
+/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
+
+/* Test compatibility of vector types: layout between separately-compiled
+ modules, parameter passing, and function return. This test uses
+ vectors of floating points values. */
+
+#include "cpuid.h"
+
+extern void vector_2_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ vector_2_x ();
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_x.c b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c
new file mode 100644
index 00000000000..fcfacec04e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-2_x.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_y.c b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c
new file mode 100644
index 00000000000..3797acb6a57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-2_y.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-defs.h b/gcc/testsuite/gcc.dg/compat/vector-defs.h
index 7574e28c53d..f2f050527ec 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-defs.h
+++ b/gcc/testsuite/gcc.dg/compat/vector-defs.h
@@ -56,6 +56,20 @@ typedef float __attribute__((mode(V2DF))) v2df;
#endif
+typedef qi __attribute__((vector_size (32))) v32qi;
+typedef hi __attribute__((vector_size (32))) v16hi;
+typedef si __attribute__((vector_size (32))) v8si;
+typedef di __attribute__((vector_size (32))) v4di;
+typedef sf __attribute__((vector_size (32))) v8sf;
+typedef df __attribute__((vector_size (32))) v4df;
+
+typedef union U32QI { v32qi v; qi a[32]; } u32qi;
+typedef union U16HI { v16hi v; hi a[16]; } u16hi;
+typedef union U8SI { v8si v; si a[8]; } u8si;
+typedef union U4DI { v4di v; di a[4]; } u4di;
+typedef union U8SF { v8sf v; sf a[8]; } u8sf;
+typedef union U4DF { v4df v; df a[4]; } u4df;
+
typedef union U8QI { v8qi v; qi a[8]; } u8qi;
typedef union U16QI { v16qi v; qi a[16]; } u16qi;
diff --git a/gcc/testsuite/gcc.dg/const-float128-ped.c b/gcc/testsuite/gcc.dg/const-float128-ped.c
index 86a630cf951..6a6b6223ce2 100644
--- a/gcc/testsuite/gcc.dg/const-float128-ped.c
+++ b/gcc/testsuite/gcc.dg/const-float128-ped.c
@@ -1,5 +1,5 @@
/* Test 'q' suffix with -pedantic on __float128 type constants. */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
/* { dg-options "-pedantic" } */
__float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */
diff --git a/gcc/testsuite/gcc.dg/const-float128.c b/gcc/testsuite/gcc.dg/const-float128.c
index 146e0c9c986..116e4597b44 100644
--- a/gcc/testsuite/gcc.dg/const-float128.c
+++ b/gcc/testsuite/gcc.dg/const-float128.c
@@ -1,5 +1,5 @@
/* Test 'q' and 'Q' suffixes on __float128 type constants. */
-/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-* } && lp64 } } } } */
+/* { dg-do compile { target ia64-*-* i?86-*-* x86_64-*-* } } */
/* { dg-options "" } */
__float128 a = 123.456789q;
diff --git a/gcc/testsuite/gcc.dg/const-float80-ped.c b/gcc/testsuite/gcc.dg/const-float80-ped.c
index 9cf047804a4..d1cf316dcad 100644
--- a/gcc/testsuite/gcc.dg/const-float80-ped.c
+++ b/gcc/testsuite/gcc.dg/const-float80-ped.c
@@ -1,6 +1,5 @@
/* Test 'w' suffix with -pedantic on __float80 type constants. */
/* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "-pedantic" } */
-/* { dg-options "-mmmx -pedantic" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
__float80 a = 123.456789w; /* { dg-warning "non-standard suffix on floating constant" } */
diff --git a/gcc/testsuite/gcc.dg/const-float80.c b/gcc/testsuite/gcc.dg/const-float80.c
index f2a836d3e64..8ec771f8f9c 100644
--- a/gcc/testsuite/gcc.dg/const-float80.c
+++ b/gcc/testsuite/gcc.dg/const-float80.c
@@ -1,7 +1,6 @@
/* Test 'w' and 'W' suffixes on __float80 type constants. */
/* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
__float80 a = 123.456789W;
__float80 b = 123.456789w;
diff --git a/gcc/testsuite/gcc.dg/cpp/20000519-1.c b/gcc/testsuite/gcc.dg/cpp/20000519-1.c
index 82ab3a26861..7cd7daa3ad2 100644
--- a/gcc/testsuite/gcc.dg/cpp/20000519-1.c
+++ b/gcc/testsuite/gcc.dg/cpp/20000519-1.c
@@ -1,6 +1,7 @@
/* Regression test for preprocessor crash.
Reported by Mathias Froehlich <frohlich@na.uni-tuebingen.de>. */
/* { dg-do preprocess } */
+/* { dg-options "-ansi" } */
#define foo
#define __CAT__(a,b,c,d) a##b##c##d
diff --git a/gcc/testsuite/gcc.dg/cpp/avoidpaste1.c b/gcc/testsuite/gcc.dg/cpp/avoidpaste1.c
index d304a744155..3591f9c08ae 100644
--- a/gcc/testsuite/gcc.dg/cpp/avoidpaste1.c
+++ b/gcc/testsuite/gcc.dg/cpp/avoidpaste1.c
@@ -1,6 +1,7 @@
/* Copyright (C) 2001, 2003 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
+/* { dg-options "-ansi" } */
/* This tests that we avoid accidental pasting only before and after
macros and arguments, and not when the tokens are already pasted
diff --git a/gcc/testsuite/gcc.dg/cpp/avoidpaste2.c b/gcc/testsuite/gcc.dg/cpp/avoidpaste2.c
index 42b549c8d6c..dc5bbc7f270 100644
--- a/gcc/testsuite/gcc.dg/cpp/avoidpaste2.c
+++ b/gcc/testsuite/gcc.dg/cpp/avoidpaste2.c
@@ -1,6 +1,7 @@
/* Copyright (C) 2001, 2003 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
+/* { dg-options "-ansi" } */
/* This tests that we avoid accidental pasting, as well as gratuitous
space insertion, in various nasty places _inside_ a macro's
diff --git a/gcc/testsuite/gcc.dg/cpp/c90-empty-macro-args.c b/gcc/testsuite/gcc.dg/cpp/c90-empty-macro-args.c
new file mode 100644
index 00000000000..e90f8e6cb69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/c90-empty-macro-args.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c89 -pedantic" } */
+
+#define f(a,b) f2(a,,b)
+#define f2(a,b,c) a; b; c;
+#define f3(a) a
+
+#define g() p()
+
+void p(void) {}
+
+
+void foo(void)
+{
+ f(p(),p()); /* { dg-warning "macro f2 argument 2: empty macro arguments are undefined" } */
+ f2(p(),,p()); /* { dg-warning "macro f2 argument 2: empty macro arguments are undefined" } */
+ f3(); /* { dg-warning "macro f3 argument 1: empty macro arguments are undefined" } */
+ g();
+}
diff --git a/gcc/testsuite/gcc.dg/cpp/c99-empty-macro-args.c b/gcc/testsuite/gcc.dg/cpp/c99-empty-macro-args.c
new file mode 100644
index 00000000000..e1e0c61ec29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/c99-empty-macro-args.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+#define f(a,b) f2(a,,b)
+#define f2(a,b,c) a; b; c;
+#define f3(a) a
+
+#define g() p()
+
+void p(void) {}
+
+
+void foo(void)
+{
+ f(p(),p());
+ f2(p(),,p());
+ f3();
+ g();
+}
diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c
index 01851268c11..bb35d21bb50 100644
--- a/gcc/testsuite/gcc.dg/lower-subreg-1.c
+++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { { ! mips64 } && { ! ia64-*-* } } } } */
+/* { dg-do compile { target { { { ! mips64 } && { ! ia64-*-* } } && { ! spu-*-* } } } } */
/* { dg-options "-O -fdump-rtl-subreg" } */
/* { dg-require-effective-target ilp32 } */
diff --git a/gcc/testsuite/gcc.dg/nrv3.c b/gcc/testsuite/gcc.dg/nrv3.c
index 2b582c3ebe8..c28b8ec570d 100644
--- a/gcc/testsuite/gcc.dg/nrv3.c
+++ b/gcc/testsuite/gcc.dg/nrv3.c
@@ -3,7 +3,12 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-optimized" } */
+#ifdef __SPU__
+/* SPU returns aggregates up to 1172 bytes in registers. */
+typedef struct { int x[300]; void *y; } S;
+#else
typedef struct { int x[20]; void *y; } S;
+#endif
typedef struct { int a; S b; } T;
S nrv_candidate (void);
void use_result (S, int);
diff --git a/gcc/testsuite/gcc.dg/pr27095.c b/gcc/testsuite/gcc.dg/pr27095.c
index 5ec39687a06..d274f4e8445 100644
--- a/gcc/testsuite/gcc.dg/pr27095.c
+++ b/gcc/testsuite/gcc.dg/pr27095.c
@@ -11,7 +11,7 @@ main (int argc, char **argv)
memset (x, argc, strlen (x));
return 0;
}
-/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen" { target { ! { powerpc*-*-darwin* hppa*-*-hpux* ia64-*-hpux* alpha*-*-* } } } } } */
+/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen" { target { ! { powerpc*-*-darwin* hppa*-*-hpux* ia64-*-hpux* alpha*-*-* spu-*-* } } } } } */
/* hppa*-*-hpux* has an IMPORT statement for strlen (plus the branch). */
/* *-*-darwin* has something similar. */
/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen\(.*\n\)+.*strlen" { target hppa*-*-hpux* } } } */
@@ -20,3 +20,5 @@ main (int argc, char **argv)
/* { dg-final { scan-assembler-not "(?n)strlen\(.*\n\)+.*strlen\(.*\n\)+.*strlen\(.*\n\)+.*strlen" { target ia64-*-hpux* } } } */
/* alpha-*-* has a GOT load and the call. */
/* { dg-final { scan-assembler-not "(?n)jsr .*,strlen\(.*\n\)+.*jsr .*,strlen" { target alpha*-*-* } } } */
+/* spu-*-* has a branch hint and the call. */
+/* { dg-final { scan-assembler-not "(?n)brsl.*,strlen\(.*\n\)+.*brsl.*,strlen" { target spu-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/pr28243.c b/gcc/testsuite/gcc.dg/pr28243.c
index c2797c0fb3f..12447a1c3d3 100644
--- a/gcc/testsuite/gcc.dg/pr28243.c
+++ b/gcc/testsuite/gcc.dg/pr28243.c
@@ -4,6 +4,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target fpic } */
/* { dg-options "-O2 -ftracer -fPIC" } */
+/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "*" } { "" } } */
struct displayfuncs {
void (*init) ();
diff --git a/gcc/testsuite/gcc.dg/pr35736.c b/gcc/testsuite/gcc.dg/pr35736.c
new file mode 100644
index 00000000000..f411bb8a92f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr35736.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wall" } */
+
+void foo()
+{
+ while (1)
+ for (;;({ continue; }))
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr36227.c b/gcc/testsuite/gcc.dg/pr36227.c
index d6657632b91..27fe0015505 100644
--- a/gcc/testsuite/gcc.dg/pr36227.c
+++ b/gcc/testsuite/gcc.dg/pr36227.c
@@ -1,12 +1,22 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Wstrict-overflow=3" } */
+#if (__SIZEOF_LONG_LONG__ == __SIZEOF_POINTER__)
+typedef unsigned long long ptrcast;
+#elif (__SIZEOF_LONG__ == __SIZEOF_POINTER__)
+typedef unsigned long ptrcast;
+#elif (__SIZEOF_INT__ == __SIZEOF_POINTER__)
+typedef unsigned int ptrcast;
+#else
+#error Add target support here
+#endif
volatile unsigned long *
sat_add(volatile unsigned long *ptr, unsigned long i, volatile unsigned long *end)
{
- if ((unsigned long)ptr + i * sizeof(*ptr) > (unsigned long)ptr) /* { dg-bogus "pointer wraparound" } */
+ if ((ptrcast)ptr + i * sizeof(*ptr) > (ptrcast)ptr) /* { dg-bogus "pointer wraparound" } */
return ptr + i;
else
return end;
}
+
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
index 24decb86fdf..a4b73e9cf5d 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128.c
@@ -1,6 +1,6 @@
/* Test floating-point conversions. __float128 type. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
-/* { dg-do run { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */
+/* { dg-do run { target ia64-*-* i?86-*-* x86_64-*-* } } */
/* { dg-options "" } */
#include "fp-int-convert.h"
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
index e2b587c0cba..3e25f904dbe 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float80.c
@@ -2,7 +2,6 @@
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */
/* { dg-options "" } */
-/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
#include "fp-int-convert.h"
diff --git a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
new file mode 100644
index 00000000000..c5adb259d26
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fipa-pta -fdump-ipa-pta" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct X { char x; char y; };
+
+void bar (char *p);
+
+void test1 (char a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a;
+ p++;
+ bar (p);
+}
+
+void test2 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a.x;
+ p++;
+ bar (p);
+}
+
+void test3 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a.y;
+ bar (p);
+}
+
+void test4 (int a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = (char *)&a;
+ p++;
+ p++;
+ p++;
+ p++;
+ bar (p);
+}
+
+/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr25947-1.c b/gcc/testsuite/gcc.dg/torture/pr25947-1.c
index d52ef8c8e3f..8af6f8d4624 100644
--- a/gcc/testsuite/gcc.dg/torture/pr25947-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pr25947-1.c
@@ -1,5 +1,6 @@
/* PR target/25947: define_split in cris.md caused unrecognized insn. */
/* { dg-options "-fpic" { target fpic } } */
+/* { dg-skip-if "requires unsupported run-time relocation" { spu-*-* } { "-O0" } { "" } } */
extern char *rl_line_buffer;
extern int rl_point;
diff --git a/gcc/testsuite/gcc.dg/torture/pr35842.c b/gcc/testsuite/gcc.dg/torture/pr35842.c
index 05b26d84c11..05b26d84c11 100755..100644
--- a/gcc/testsuite/gcc.dg/torture/pr35842.c
+++ b/gcc/testsuite/gcc.dg/torture/pr35842.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-10.c b/gcc/testsuite/gcc.dg/torture/pr36373-10.c
index b84e2544152..ed701772828 100644
--- a/gcc/testsuite/gcc.dg/torture/pr36373-10.c
+++ b/gcc/testsuite/gcc.dg/torture/pr36373-10.c
@@ -1,6 +1,14 @@
/* { dg-do run } */
+#if (__SIZEOF_LONG_LONG__ == __SIZEOF_POINTER__)
+typedef unsigned long long uintptr_t;
+#elif (__SIZEOF_LONG__ == __SIZEOF_POINTER__)
typedef unsigned long uintptr_t;
+#elif (__SIZEOF_INT__ == __SIZEOF_POINTER__)
+typedef unsigned int uintptr_t;
+#else
+#error Add target support here
+#endif
void __attribute__((noinline))
foo(uintptr_t l)
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
new file mode 100644
index 00000000000..2a8dc9e3037
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-alias" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct Foo {
+ int *p;
+};
+
+void __attribute__((noinline))
+foo (void *p)
+{
+ struct Foo *f = (struct Foo *)p - 1;
+ *f->p = 0;
+}
+
+int bar (void)
+{
+ struct Foo f;
+ int i = 1;
+ f.p = &i;
+ foo (&f + 1);
+ return i;
+}
+extern void abort (void);
+int main()
+{
+ if (bar () != 0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL f .* i }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c
new file mode 100644
index 00000000000..fb5b2e15ede
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-alias" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct Foo {
+ int **p;
+ int **q;
+};
+
+int __attribute__((noinline))
+bar (void)
+{
+ struct Foo f;
+ int j, i = 1;
+ char *p;
+ int *x = &i;
+ int *y = &j;
+ f.p = &y;
+ f.q = &x;
+ p = (char *)&f;
+ for (j = 0; j < sizeof (int *); ++j)
+ p++;
+ return ***(int ***)p;
+}
+extern void abort (void);
+int main()
+{
+ if (bar () != 1)
+ abort ();
+ return 0;
+}
+
+/* In theory = { i } is the correct solution. But it's not easy to scan
+ for that reliably, so just use what we create now. */
+/* { dg-final { scan-tree-dump "= { i j }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
index 28cdfd23181..d7aea1b8430 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
@@ -33,5 +33,5 @@ void test55 (int x, int y)
that the && should be emitted (based on BRANCH_COST). Fix this
by teaching dom to look through && and register all components
as true. */
-/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "powerpc*-*-* cris-*-* crisv32-*-* mmix-*-* mips*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "powerpc*-*-* cris-*-* crisv32-*-* mmix-*-* mips*-*-* m68k*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
new file mode 100644
index 00000000000..c2b512a12e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --param max-fields-for-field-sensitive=2 -fdump-tree-alias" } */
+
+struct Foo {
+ int *p, *q;
+};
+
+int foo (int ***x) __attribute__((pure));
+
+int bar (int b)
+{
+ int i;
+ struct Foo f;
+ int *p, **q;
+ p = &i;
+ f.p = &i;
+ f.q = f.p;
+ if (b)
+ q = &f.p;
+ else
+ q = &f.q;
+ return foo (&q);
+}
+
+/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
index 3b7a547a6e7..85e444886d0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
@@ -5,7 +5,7 @@
When the condition is true, we distribute "(int) (a + b)" as
"(int) a + (int) b", otherwise we keep the original. */
-/* { dg-do compile { target { ! mips64 } } } */
+/* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */
/* { dg-options "-O -fwrapv -fdump-tree-fre-details" } */
/* From PR14844. */
diff --git a/gcc/testsuite/gcc.target/arm/neon/polytypes.c b/gcc/testsuite/gcc.target/arm/neon/polytypes.c
index 9aca6671ae0..12e9b0a7f6a 100644
--- a/gcc/testsuite/gcc.target/arm/neon/polytypes.c
+++ b/gcc/testsuite/gcc.target/arm/neon/polytypes.c
@@ -28,7 +28,8 @@ void foo ()
poly8x16_t v128_8;
poly16x8_t v128_16;
- s64_8 (v64_8); /* { dg-error "use -flax-vector-conversions.*incompatible type for argument 1 of 's64_8'" } */
+ s64_8 (v64_8); /* { dg-message "use -flax-vector-conversions" } */
+ /* { dg-error "incompatible type for argument 1 of 's64_8'" "" { target *-*-* } 31 } */
u64_8 (v64_8); /* { dg-error "incompatible type for argument 1 of 'u64_8'" } */
p64_8 (v64_8);
diff --git a/gcc/testsuite/gcc.target/i386/float128-1.c b/gcc/testsuite/gcc.target/i386/float128-1.c
new file mode 100644
index 00000000000..9c6d22745f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/float128-1.c
@@ -0,0 +1,24 @@
+/* { dg-do run { target *-*-linux* } } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "sse2-check.h"
+
+extern void abort (void);
+
+typedef _Complex float __attribute__((mode(TC))) _Complex128;
+
+_Complex128 __attribute__ ((noinline))
+foo (_Complex128 x, _Complex128 y)
+{
+ return x * y;
+}
+
+static void
+sse2_test (void)
+{
+ _Complex128 a = 1.3q + 3.4qi, b = 5.6q + 7.8qi, c;
+
+ c = foo (a, b);
+ if (__real__(c) == 0.0q || __imag__ (c) == 0.0q)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/float128-2.c b/gcc/testsuite/gcc.target/i386/float128-2.c
new file mode 100644
index 00000000000..94408d2ef35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/float128-2.c
@@ -0,0 +1,17 @@
+/* PR target/36710 */
+
+/* { dg-do run { target *-*-linux* *-*-darwin* } } */
+/* { dg-options "-Os -msse2" } */
+
+#include "sse2-check.h"
+
+extern void abort (void);
+
+static void
+sse2_test (void)
+{
+ static volatile __float128 a = 123.0q;
+
+ if ((int) a != 123)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr32191.c b/gcc/testsuite/gcc.target/i386/pr32191.c
index 0da5d5c5aae..f5238b01dee 100644
--- a/gcc/testsuite/gcc.target/i386/pr32191.c
+++ b/gcc/testsuite/gcc.target/i386/pr32191.c
@@ -1,5 +1,4 @@
/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
/* { dg-options "-std=c99" } */
typedef _Complex float __attribute__((mode(TC))) _Complex128;
diff --git a/gcc/testsuite/gcc.target/i386/pr32268.c b/gcc/testsuite/gcc.target/i386/pr32268.c
index 472259c1eba..a5d673ad94f 100644
--- a/gcc/testsuite/gcc.target/i386/pr32268.c
+++ b/gcc/testsuite/gcc.target/i386/pr32268.c
@@ -1,5 +1,4 @@
/* { dg-do run { target *-*-linux* } } */
-/* { dg-require-effective-target lp64 } */
/* { dg-options "-O2" } */
extern void abort(void);
diff --git a/gcc/testsuite/gcc.target/m68k/interrupt-2.c b/gcc/testsuite/gcc.target/m68k/interrupt-2.c
new file mode 100644
index 00000000000..7d4cb68c121
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/interrupt-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+int x;
+volatile unsigned int y;
+
+#define REPEAT10(X, Y) \
+ X(Y##0); X(Y##1); X(Y##2); X(Y##3); X(Y##4); \
+ X(Y##5); X(Y##6); X(Y##7); X(Y##8); X(Y##9)
+
+#define REPEAT30(X) REPEAT10 (X, 0); REPEAT10 (X, 1); REPEAT10 (X, 2)
+#define IN(X) unsigned int x##X = y
+#define OUT(X) y = x##X
+
+void __attribute__ ((interrupt_handler)) f1 (void)
+{
+ x = y + 11;
+}
+
+void __attribute__ ((interrupt_handler)) f2 (void)
+{
+ REPEAT30 (IN);
+ REPEAT30 (OUT);
+}
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
index 4c642258f7b..c12d08e0521 100644
--- a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
@@ -1,15 +1,15 @@
/* { dg-do preprocess } */
/* { dg-mips-options "-mips2" } */
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
#error nonono
#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
index 4265e4167ba..eaae7801754 100644
--- a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
@@ -1,19 +1,19 @@
/* { dg-do preprocess } */
/* { dg-mips-options "-mgp64" } */
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#error nonono
#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c
new file mode 100644
index 00000000000..faf50fc69ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c
@@ -0,0 +1,23 @@
+/* { dg-do preprocess { target mips16_attribute } } */
+/* { dg-mips-options "-mips2 -mips16" } */
+/* { dg-add-options mips16_attribute } */
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+#error nonono
+#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c
new file mode 100644
index 00000000000..b53f4b05b61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c
@@ -0,0 +1,23 @@
+/* { dg-do preprocess { target mips16_attribute } } */
+/* { dg-mips-options "-mgp64 -mips16" } */
+/* { dg-add-options mips16_attribute } */
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+#error nonono
+#endif
diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_tests_3.f90 b/gcc/testsuite/gfortran.dg/c_f_pointer_tests_3.f90
index 525af506428..3b28f52b4e7 100644
--- a/gcc/testsuite/gfortran.dg/c_f_pointer_tests_3.f90
+++ b/gcc/testsuite/gfortran.dg/c_f_pointer_tests_3.f90
@@ -14,11 +14,11 @@ program test
type(c_funptr) :: cfunptr
integer(4), pointer :: fptr
integer(4), pointer :: fptr_array(:)
-! procedure(integer(4)), pointer :: fprocptr ! TODO
+ procedure(integer(4)), pointer :: fprocptr
call c_f_pointer(cptr, fptr)
call c_f_pointer(cptr, fptr_array, [ 1 ])
-! call c_f_procpointer(cfunptr, fprocptr) ! TODO
+ call c_f_procpointer(cfunptr, fprocptr)
end program test
! Make sure there is only a single function call:
@@ -30,6 +30,6 @@ end program test
! { dg-final { scan-tree-dump-times " fptr = .integer.kind=4. .. cptr" 1 "original" } }
!
! Check c_f_procpointer
-! TODO { scan-tree-dump-times " fprocptr = .integer.kind=4. .\\*<.*>. .void.. cfunptr;" 1 "original" } } TODO
+! { dg-final { scan-tree-dump-times " fprocptr = .integer.kind=4. .\\*<.*>. .void.. cfunptr;" 1 "original" } }
!
! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr36726.f90 b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90
new file mode 100644
index 00000000000..99e170ad798
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90
@@ -0,0 +1,20 @@
+! PR middle-end/36726
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+subroutine foo
+ integer, allocatable :: vs(:)
+ !$omp parallel private (vs)
+ allocate (vs(10))
+ vs = 2
+ deallocate (vs)
+ !$omp end parallel
+end subroutine foo
+subroutine bar
+ integer, allocatable :: vs(:)
+ !$omp parallel private (vs)
+ allocate (vs(10))
+ vs = 2
+ deallocate (vs)
+ !$omp end parallel
+end subroutine bar
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90
new file mode 100644
index 00000000000..429b28c3016
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" }
+program main
+ real, dimension(3,2) :: a
+ real, dimension(2,3) :: b
+ real, dimension(:,:), allocatable :: ret
+ allocate (ret(2,2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(b,a) ! This is OK
+ deallocate(ret)
+ allocate(ret(3,2))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90
new file mode 100644
index 00000000000..c5830ded729
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" }
+program main
+ real, dimension(3,2) :: a
+ real, dimension(2,3) :: b
+ real, dimension(:,:), allocatable :: ret
+ allocate (ret(3,3))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(2,3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90
new file mode 100644
index 00000000000..a61bacc1d2b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
+program main
+ real, dimension(3) :: a
+ real, dimension(3,2) :: b
+ real, dimension(:), allocatable :: ret
+ allocate (ret(2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90
new file mode 100644
index 00000000000..4b20098f50f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
+program main
+ real, dimension(2,3) :: a
+ real, dimension(3) :: b
+ real, dimension(:), allocatable :: ret
+ allocate (ret(2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_1.f90 b/gcc/testsuite/gfortran.dg/proc_decl_1.f90
index c01f7c6101e..3e7a3d18fb7 100644
--- a/gcc/testsuite/gfortran.dg/proc_decl_1.f90
+++ b/gcc/testsuite/gfortran.dg/proc_decl_1.f90
@@ -40,8 +40,6 @@ program prog
procedure(dcos) :: my1
procedure(amax0) :: my2 ! { dg-error "not allowed in PROCEDURE statement" }
- procedure(),pointer:: ptr ! { dg-error "not yet implemented" }
-
type t
procedure(),pointer:: p ! { dg-error "not yet implemented" }
end type
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_1.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_1.f90
new file mode 100644
index 00000000000..fe8e201000e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_1.f90
@@ -0,0 +1,73 @@
+! { dg-do run }
+!
+! basic tests of PROCEDURE POINTERS
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+contains
+ subroutine proc1(arg)
+ character (5) :: arg
+ arg = "proc1"
+ end subroutine
+ integer function proc2(arg)
+ integer, intent(in) :: arg
+ proc2 = arg**2
+ end function
+ complex function proc3(re, im)
+ real, intent(in) :: re, im
+ proc3 = complex (re, im)
+ end function
+end module
+
+subroutine foo1
+end subroutine
+
+real function foo2()
+ foo2=6.3
+end function
+
+program procPtrTest
+ use m, only: proc1, proc2, proc3
+ character (5) :: str
+ PROCEDURE(proc1), POINTER :: ptr1
+ PROCEDURE(proc2), POINTER :: ptr2
+ PROCEDURE(proc3), POINTER :: ptr3 => NULL()
+ PROCEDURE(REAL), SAVE, POINTER :: ptr4
+ PROCEDURE(), POINTER :: ptr5,ptr6
+
+ EXTERNAL :: foo1,foo2
+ real :: foo2
+
+ if(ASSOCIATED(ptr3)) call abort()
+
+ NULLIFY(ptr1)
+ if (ASSOCIATED(ptr1)) call abort()
+ ptr1 => proc1
+ if (.not. ASSOCIATED(ptr1)) call abort()
+ call ptr1 (str)
+ if (str .ne. "proc1") call abort ()
+
+ ptr2 => NULL()
+ if (ASSOCIATED(ptr2)) call abort()
+ ptr2 => proc2
+ if (.not. ASSOCIATED(ptr2,proc2)) call abort()
+ if (10*ptr2 (10) .ne. 1000) call abort ()
+
+ ptr3 => NULL (ptr3)
+ if (ASSOCIATED(ptr3)) call abort()
+ ptr3 => proc3
+ if (ptr3 (1.0, 2.0) .ne. (1.0, 2.0)) call abort ()
+
+ ptr4 => cos
+ if (ptr4(0.0)/=1.0) call abort()
+
+ ptr5 => foo1
+ call ptr5()
+
+ ptr6 => foo2
+ if (ptr6()/=6.3) call abort()
+
+end program
+
+! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_2.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_2.f90
new file mode 100644
index 00000000000..d19b81d6e47
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_2.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+!
+! checking invalid code for PROCEDURE POINTERS
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+PROCEDURE(REAL), POINTER :: ptr
+PROCEDURE(REAL), SAVE :: noptr ! { dg-error "attribute conflicts with" }
+
+ptr => cos(4.0) ! { dg-error "Invalid character" }
+
+ALLOCATE(ptr) ! { dg-error "must be ALLOCATABLE" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_3.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_3.f90
new file mode 100644
index 00000000000..34d4f1625fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_3.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+!
+! PROCEDURE POINTERS without the PROCEDURE statement
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+real function e1(x)
+ real :: x
+ print *,'e1!',x
+ e1 = x * 3.0
+end function
+
+subroutine e2(a,b)
+ real, intent(inout) :: a
+ real, intent(in) :: b
+ print *,'e2!',a,b
+ a = a + b
+end subroutine
+
+program proc_ptr_3
+
+real, external, pointer :: fp
+
+pointer :: sp
+interface
+ subroutine sp(a,b)
+ real, intent(inout) :: a
+ real, intent(in) :: b
+ end subroutine sp
+end interface
+
+external :: e1,e2
+real :: c = 1.2
+
+fp => e1
+
+if (abs(fp(2.5)-7.5)>0.01) call abort()
+
+sp => e2
+
+call sp(c,3.4)
+
+if (abs(c-4.6)>0.01) call abort()
+
+end
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_4.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_4.f90
new file mode 100644
index 00000000000..60b9e73af82
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_4.f90
@@ -0,0 +1,57 @@
+! { dg-do compile }
+!
+! PROCEDURE POINTERS & pointer-valued functions
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+interface
+ integer function f1()
+ end function
+end interface
+
+interface
+ function f2()
+ integer, pointer :: f2
+ end function
+end interface
+
+interface
+ function pp1()
+ integer :: pp1
+ end function
+end interface
+pointer :: pp1
+
+pointer :: pp2
+interface
+ function pp2()
+ integer :: pp2
+ end function
+end interface
+
+pointer :: pp3
+interface
+ function pp3()
+ integer, pointer :: pp3
+ end function
+end interface
+
+interface
+ function pp4()
+ integer, pointer :: pp4
+ end function
+end interface
+pointer :: pp4
+
+
+pp1 => f1
+
+pp2 => pp1
+
+f2 => f1 ! { dg-error "is not a variable" }
+
+pp3 => f2
+
+pp4 => pp3
+
+end \ No newline at end of file
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_5.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_5.f90
new file mode 100644
index 00000000000..61cf8a35d10
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_5.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+!
+! NULL() initialization for PROCEDURE POINTERS
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+program main
+implicit none
+call test(.true.)
+call test(.false.)
+
+contains
+
+integer function hello()
+ hello = 42
+end function hello
+
+subroutine test(first)
+ logical :: first
+ integer :: i
+ procedure(integer), pointer :: x => null()
+
+ if(first) then
+ if(associated(x)) call abort()
+ x => hello
+ else
+ if(.not. associated(x)) call abort()
+ i = x()
+ if(i /= 42) call abort()
+ end if
+ end subroutine test
+
+end program main
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_6.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_6.f90
new file mode 100644
index 00000000000..6a5c7e5f462
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_6.f90
@@ -0,0 +1,39 @@
+! { dg-do run }
+!
+! PROCEDURE POINTERS as actual/formal arguments
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+subroutine foo(j)
+ INTEGER, INTENT(OUT) :: j
+ j = 6
+end subroutine
+
+program proc_ptr_6
+
+PROCEDURE(),POINTER :: ptr1
+PROCEDURE(REAL),POINTER :: ptr2
+EXTERNAL foo
+INTEGER :: k = 0
+
+ptr1 => foo
+call s_in(ptr1,k)
+if (k /= 6) call abort()
+
+call s_out(ptr2)
+if (ptr2(-3.0) /= 3.0) call abort()
+
+contains
+
+subroutine s_in(p,i)
+ PROCEDURE(),POINTER,INTENT(IN) :: p
+ INTEGER, INTENT(OUT) :: i
+ call p(i)
+end subroutine
+
+subroutine s_out(p)
+ PROCEDURE(REAL),POINTER,INTENT(OUT) :: p
+ p => abs
+end subroutine
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_7.c b/gcc/testsuite/gfortran.dg/proc_ptr_7.c
new file mode 100644
index 00000000000..7e9542fd86e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_7.c
@@ -0,0 +1,10 @@
+/* Procedure pointer test. Used by proc_ptr_7.f90.
+ PR fortran/32580. */
+
+int f(void) {
+ return 42;
+}
+
+void assignf_(int(**ptr)(void)) {
+ *ptr = f;
+}
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_7.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_7.f90
new file mode 100644
index 00000000000..8b1ea0a44b3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_7.f90
@@ -0,0 +1,47 @@
+! { dg-do run }
+! { dg-additional-sources proc_ptr_7.c }
+!
+! PR fortran/32580
+! Procedure pointer test
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+program proc_pointer_test
+ use iso_c_binding, only: c_int
+ implicit none
+
+ interface
+ subroutine assignF(f)
+ import c_int
+ procedure(Integer(c_int)), pointer :: f
+ end subroutine
+ end interface
+
+ procedure(Integer(c_int)), pointer :: ptr
+
+ call assignF(ptr)
+ if(ptr() /= 42) call abort()
+
+ ptr => f55
+ if(ptr() /= 55) call abort()
+
+ call foo(ptr)
+ if(ptr() /= 65) call abort()
+
+contains
+
+ subroutine foo(a)
+ procedure(integer(c_int)), pointer :: a
+ if(a() /= 55) call abort()
+ a => f65
+ if(a() /= 65) call abort()
+ end subroutine foo
+
+ integer(c_int) function f55()
+ f55 = 55
+ end function f55
+
+ integer(c_int) function f65()
+ f65 = 65
+ end function f65
+end program proc_pointer_test
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_8.c b/gcc/testsuite/gfortran.dg/proc_ptr_8.c
new file mode 100644
index 00000000000..c732ff6667c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_8.c
@@ -0,0 +1,14 @@
+/* Used by proc_ptr_8.f90.
+ PR fortran/32580. */
+
+int (*funpointer)(int);
+
+int f(int t)
+{
+ return t*3;
+}
+
+void init()
+{
+ funpointer=f;
+}
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_8.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_8.f90
new file mode 100644
index 00000000000..80d26619bc0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_8.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+! { dg-additional-sources proc_ptr_8.c }
+!
+! PR fortran/32580
+! Original test case
+!
+! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
+
+MODULE X
+
+ USE ISO_C_BINDING
+ INTERFACE
+ INTEGER(KIND=C_INT) FUNCTION mytype( a ) BIND(C)
+ USE ISO_C_BINDING
+ INTEGER(KIND=C_INT), VALUE :: a
+ END FUNCTION
+ SUBROUTINE init() BIND(C,name="init")
+ END SUBROUTINE
+ END INTERFACE
+
+ TYPE(C_FUNPTR), BIND(C,name="funpointer") :: funpointer
+
+END MODULE X
+
+USE X
+PROCEDURE(mytype), POINTER :: ptype
+
+CALL init()
+CALL C_F_PROCPOINTER(funpointer,ptype)
+if (ptype(3) /= 9) call abort()
+
+END
+
+! { dg-final { cleanup-modules "X" } }
diff --git a/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90 b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90
new file mode 100644
index 00000000000..c6390896c17
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+program main
+ real, dimension(4,3) :: a
+ real, dimension(2) :: b
+ a = 21.
+ b = product(a,dim=1) ! { dg-error "Different shape" }
+ b = sum(a,dim=2) ! { dg-error "Different shape" }
+end program main
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3.adb b/gcc/testsuite/gnat.dg/loop_optimization3.adb
new file mode 100644
index 00000000000..e69f535fb05
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+with Loop_Optimization3_Pkg; use Loop_Optimization3_Pkg;
+
+procedure Loop_Optimization3 is
+
+ type Arr is array (Integer range -3 .. 3) of Integer;
+ C : constant Arr := (1, others => F(2));
+
+begin
+ if C /= (1, 2, 2, 2, 2, 2, 2) then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb
new file mode 100644
index 00000000000..7a64815033d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.adb
@@ -0,0 +1,8 @@
+package body Loop_Optimization3_Pkg is
+
+ function F (n : Integer) return Integer is
+ begin
+ return n;
+ end;
+
+end Loop_Optimization3_Pkg;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads
new file mode 100644
index 00000000000..90f4fc32bad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization3_pkg.ads
@@ -0,0 +1,5 @@
+package Loop_Optimization3_Pkg is
+
+ function F (n : Integer) return Integer;
+
+end Loop_Optimization3_Pkg;
diff --git a/gcc/testsuite/lib/compat.exp b/gcc/testsuite/lib/compat.exp
index 474af620d16..ee7cff56fbe 100644
--- a/gcc/testsuite/lib/compat.exp
+++ b/gcc/testsuite/lib/compat.exp
@@ -156,6 +156,8 @@ proc compat-run { testname objlist dest optall optfile optstr } {
proc compat-get-options-main { src } {
# dg-options sets a variable called dg-extra-tool-flags.
set dg-extra-tool-flags ""
+ # dg-options sets a variable called tool_flags.
+ set tool_flags ""
# dg-require-* sets dg-do-what.
upvar dg-do-what dg-do-what
@@ -164,6 +166,7 @@ proc compat-get-options-main { src } {
foreach op $tmp {
set cmd [lindex $op 0]
if { ![string compare "dg-options" $cmd] \
+ || [string match "dg-skip-if" $cmd] \
|| [string match "dg-require-*" $cmd] } {
set status [catch "$op" errmsg]
if { $status != 0 } {
@@ -275,6 +278,15 @@ proc compat-execute { src1 sid use_alt } {
set extra_flags_3 [compat-get-options $src3]
set compile_xfail_3 $compiler_conditional_xfail_data
+ # On the SPU, most of the compat test cases exceed local store size.
+ # Use automatic overlay support to make them fit.
+ if { [istarget spu-*-elf*] } {
+ set extra_flags_1 "$extra_flags_1 -Wl,--auto-overlay"
+ set extra_flags_1 "$extra_flags_1 -ffunction-sections"
+ set extra_flags_2 "$extra_flags_2 -ffunction-sections"
+ set extra_flags_3 "$extra_flags_3 -ffunction-sections"
+ }
+
# Define the names of the object files.
regsub "sid" "sid_main_tst.o" $sid obj1
regsub "sid" "sid_x_tst.o" $sid obj2_tst
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 9a3f12b5131..8d308d42461 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -354,6 +354,11 @@ proc remove-build-file { pat } {
set file_list "[glob -nocomplain $pat]"
verbose "remove-build-file `$file_list'" 2
foreach output_file $file_list {
+ if [is_remote host] {
+ # Ensure the host knows the file is gone by deleting there
+ # first.
+ remote_file host delete $output_file
+ }
remote_file build delete $output_file
}
}
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
index 7a0bdf3196c..dc4d9245a32 100644
--- a/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
+++ b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
@@ -37,7 +37,7 @@ set generator_src "$srcdir/$subdir/struct-layout-encoding-1_generate.c"
set generator_src "$generator_src $srcdir/$subdir/generate-random.c"
set generator_src "$generator_src $srcdir/$subdir/generate-random_r.c"
set generator_cmd "-o $generator $generator_src"
-set status [remote_exec host "$HOSTCC $HOSTCFLAGS $generator_cmd"]
+set status [remote_exec build "$HOSTCC $HOSTCFLAGS $generator_cmd"]
set status [lindex $status 0]
if { $status == 0 } then {
file delete -force $tstobjdir
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index b7363c377c0..7cc0285ff48 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -814,6 +814,7 @@ static const struct dump_option_value_info dump_options[] =
{"address", TDF_ADDRESS},
{"slim", TDF_SLIM},
{"raw", TDF_RAW},
+ {"graph", TDF_GRAPH},
{"details", TDF_DETAILS},
{"stats", TDF_STATS},
{"blocks", TDF_BLOCKS},
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index f700ab8347c..480ca41b417 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -881,7 +881,15 @@ factoring_name_p (const_tree name)
return TREE_CODE (SSA_NAME_VAR (name)) == MEMORY_PARTITION_TAG;
}
-/* Return true if VAR is a clobbered by function calls. */
+/* Return true if VAR is used by function calls. */
+static inline bool
+is_call_used (const_tree var)
+{
+ return (var_ann (var)->call_clobbered
+ || bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (var)));
+}
+
+/* Return true if VAR is clobbered by function calls. */
static inline bool
is_call_clobbered (const_tree var)
{
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 961054703db..5479c3342c7 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -1039,6 +1039,7 @@ void tree_ssa_iv_optimize (void);
unsigned tree_predictive_commoning (void);
bool parallelize_loops (void);
+bool loop_only_exit_p (const struct loop *, const_edge);
bool number_of_iterations_exit (struct loop *, edge,
struct tree_niter_desc *niter, bool);
tree find_loop_niter (struct loop *, edge *);
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index 13febcaf79b..cdf6c3fd9e6 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -265,7 +265,7 @@ dest_safe_for_nrv_p (tree dest)
if (TREE_CODE (dest) == SSA_NAME)
dest = SSA_NAME_VAR (dest);
- if (is_call_clobbered (dest))
+ if (is_call_used (dest))
return false;
return true;
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 40c1d3f9c3b..21f362b9059 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -128,6 +128,8 @@ create_temp (tree t)
set_symbol_mem_tag (tmp, symbol_mem_tag (t));
if (is_call_clobbered (t))
mark_call_clobbered (tmp, var_ann (t)->escape_mask);
+ if (bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (t)))
+ bitmap_set_bit (gimple_call_used_vars (cfun), DECL_UID (tmp));
return tmp;
}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 391511f56a7..c50c6cd225b 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -308,6 +308,26 @@ sra_type_can_be_decomposed_p (tree type)
return false;
}
+/* Returns true if the TYPE is one of the available va_list types.
+ Otherwise it returns false.
+ Note, that for multiple calling conventions there can be more
+ than just one va_list type present. */
+
+static bool
+is_va_list_type (tree type)
+{
+ tree h;
+
+ if (type == NULL_TREE)
+ return false;
+ h = targetm.canonical_va_list_type (type);
+ if (h == NULL_TREE)
+ return false;
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (h))
+ return true;
+ return false;
+}
+
/* Return true if DECL can be decomposed into a set of independent
(though not necessarily scalar) variables. */
@@ -360,9 +380,7 @@ decl_can_be_decomposed_p (tree var)
tree-stdarg.c, as the decomposition is truly a win. This could also
be fixed if the stdarg pass ran early, but this can't be done until
we've aliasing information early too. See PR 30791. */
- if (early_sra
- && TYPE_MAIN_VARIANT (TREE_TYPE (var))
- == TYPE_MAIN_VARIANT (va_list_type_node))
+ if (early_sra && is_va_list_type (TREE_TYPE (var)))
return false;
return true;
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ee0f4a7316a..d4a1e219a0c 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2316,7 +2316,6 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
tree ptr;
timevar_push (TV_FLOW_SENSITIVE);
- set_used_smts ();
for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++)
{
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d4dfadbced0..da6b7855a81 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2748,17 +2748,19 @@ optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i)
static tree
optimize_stdarg_builtin (tree call)
{
- tree callee, lhs, rhs;
+ tree callee, lhs, rhs, cfun_va_list;
bool va_list_simple_ptr;
if (TREE_CODE (call) != CALL_EXPR)
return NULL_TREE;
- va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
- && (TREE_TYPE (va_list_type_node) == void_type_node
- || TREE_TYPE (va_list_type_node) == char_type_node);
-
callee = get_callee_fndecl (call);
+
+ cfun_va_list = targetm.fn_abi_va_list (callee);
+ va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
+ && (TREE_TYPE (cfun_va_list) == void_type_node
+ || TREE_TYPE (cfun_va_list) == char_type_node);
+
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_VA_START:
@@ -2773,7 +2775,7 @@ optimize_stdarg_builtin (tree call)
lhs = CALL_EXPR_ARG (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
lhs = build_fold_indirect_ref (lhs);
@@ -2792,13 +2794,13 @@ optimize_stdarg_builtin (tree call)
lhs = CALL_EXPR_ARG (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
lhs = build_fold_indirect_ref (lhs);
rhs = CALL_EXPR_ARG (call, 1);
if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
rhs = fold_convert (TREE_TYPE (lhs), rhs);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 41c37943656..ce5c05cd88f 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -3745,13 +3745,12 @@ may_eliminate_iv (struct ivopts_data *data,
tree nit, period;
struct loop *loop = data->current_loop;
aff_tree bnd;
- double_int period_value, max_niter;
if (TREE_CODE (cand->iv->step) != INTEGER_CST)
return false;
- /* For now works only for exits that dominate the loop latch. TODO -- extend
- for other conditions inside loop body. */
+ /* For now works only for exits that dominate the loop latch.
+ TODO: extend to other conditions inside loop body. */
ex_bb = bb_for_stmt (use->stmt);
if (use->stmt != last_stmt (ex_bb)
|| TREE_CODE (use->stmt) != COND_EXPR)
@@ -3769,19 +3768,33 @@ may_eliminate_iv (struct ivopts_data *data,
if (!nit)
return false;
- /* Determine whether we may use the variable to test whether niter iterations
- elapsed. This is the case iff the period of the induction variable is
- greater than the number of iterations. */
+ /* Determine whether we can use the variable to test the exit condition.
+ This is the case iff the period of the induction variable is greater
+ than the number of iterations for which the exit condition is true. */
period = iv_period (cand->iv);
- if (!period)
- return false;
- /* Compare the period with the estimate on the number of iterations of the
- loop. */
- if (!estimated_loop_iterations (loop, true, &max_niter))
- return false;
- period_value = tree_to_double_int (period);
- if (double_int_ucmp (period_value, max_niter) <= 0)
+ /* If the number of iterations is constant, compare against it directly. */
+ if (TREE_CODE (nit) == INTEGER_CST)
+ {
+ if (!tree_int_cst_lt (nit, period))
+ return false;
+ }
+
+ /* If not, and if this is the only possible exit of the loop, see whether
+ we can get a conservative estimate on the number of iterations of the
+ entire loop and compare against that instead. */
+ else if (loop_only_exit_p (loop, exit))
+ {
+ double_int period_value, max_niter;
+ if (!estimated_loop_iterations (loop, true, &max_niter))
+ return false;
+ period_value = tree_to_double_int (period);
+ if (double_int_ucmp (max_niter, period_value) >= 0)
+ return false;
+ }
+
+ /* Otherwise, punt. */
+ else
return false;
cand_value_at (loop, cand, use->stmt, nit, &bnd);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 74153fd294d..80b45c298b7 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1672,7 +1672,7 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
/* Returns true if EXIT is the only possible exit from LOOP. */
-static bool
+bool
loop_only_exit_p (const struct loop *loop, const_edge exit)
{
basic_block *body;
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 553125641ce..6121437b245 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -220,8 +220,8 @@ struct variable_info
/* True for variables whose size is not known or variable. */
unsigned int is_unknown_size_var:1;
- /* True for variables that have unions somewhere in them. */
- unsigned int has_union:1;
+ /* True for (sub-)fields that represent a whole variable. */
+ unsigned int is_full_var : 1;
/* True if this is a heap variable. */
unsigned int is_heap_var:1;
@@ -262,6 +262,7 @@ struct variable_info
typedef struct variable_info *varinfo_t;
static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
+static varinfo_t lookup_vi_for_tree (tree);
/* Pool of variable info structures. */
static alloc_pool variable_info_pool;
@@ -375,7 +376,7 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->is_heap_var = false;
ret->is_special_var = false;
ret->is_unknown_size_var = false;
- ret->has_union = false;
+ ret->is_full_var = false;
var = t;
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
@@ -623,6 +624,96 @@ debug_constraints (void)
dump_constraints (stderr);
}
+/* Print out to FILE the edge in the constraint graph that is created by
+ constraint c. The edge may have a label, depending on the type of
+ constraint that it represents. If complex1, e.g: a = *b, then the label
+ is "=*", if complex2, e.g: *a = b, then the label is "*=", if
+ complex with an offset, e.g: a = b + 8, then the label is "+".
+ Otherwise the edge has no label. */
+
+void
+dump_constraint_edge (FILE *file, constraint_t c)
+{
+ if (c->rhs.type != ADDRESSOF)
+ {
+ const char *src = get_varinfo_fc (c->rhs.var)->name;
+ const char *dst = get_varinfo_fc (c->lhs.var)->name;
+ fprintf (file, " \"%s\" -> \"%s\" ", src, dst);
+ /* Due to preprocessing of constraints, instructions like *a = *b are
+ illegal; thus, we do not have to handle such cases. */
+ if (c->lhs.type == DEREF)
+ fprintf (file, " [ label=\"*=\" ] ;\n");
+ else if (c->rhs.type == DEREF)
+ fprintf (file, " [ label=\"=*\" ] ;\n");
+ else
+ {
+ /* We must check the case where the constraint is an offset.
+ In this case, it is treated as a complex constraint. */
+ if (c->rhs.offset != c->lhs.offset)
+ fprintf (file, " [ label=\"+\" ] ;\n");
+ else
+ fprintf (file, " ;\n");
+ }
+ }
+}
+
+/* Print the constraint graph in dot format. */
+
+void
+dump_constraint_graph (FILE *file)
+{
+ unsigned int i=0, size;
+ constraint_t c;
+
+ /* Only print the graph if it has already been initialized: */
+ if (!graph)
+ return;
+
+ /* Print the constraints used to produce the constraint graph. The
+ constraints will be printed as comments in the dot file: */
+ fprintf (file, "\n\n/* Constraints used in the constraint graph:\n");
+ dump_constraints (file);
+ fprintf (file, "*/\n");
+
+ /* Prints the header of the dot file: */
+ fprintf (file, "\n\n// The constraint graph in dot format:\n");
+ fprintf (file, "strict digraph {\n");
+ fprintf (file, " node [\n shape = box\n ]\n");
+ fprintf (file, " edge [\n fontsize = \"12\"\n ]\n");
+ fprintf (file, "\n // List of nodes in the constraint graph:\n");
+
+ /* The next lines print the nodes in the graph. In order to get the
+ number of nodes in the graph, we must choose the minimum between the
+ vector VEC (varinfo_t, varmap) and graph->size. If the graph has not
+ yet been initialized, then graph->size == 0, otherwise we must only
+ read nodes that have an entry in VEC (varinfo_t, varmap). */
+ size = VEC_length (varinfo_t, varmap);
+ size = size < graph->size ? size : graph->size;
+ for (i = 0; i < size; i++)
+ {
+ const char *name = get_varinfo_fc (graph->rep[i])->name;
+ fprintf (file, " \"%s\" ;\n", name);
+ }
+
+ /* Go over the list of constraints printing the edges in the constraint
+ graph. */
+ fprintf (file, "\n // The constraint edges:\n");
+ for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
+ if (c)
+ dump_constraint_edge (file, c);
+
+ /* Prints the tail of the dot file. By now, only the closing bracket. */
+ fprintf (file, "}\n\n\n");
+}
+
+/* Print out the constraint graph to stderr. */
+
+void
+debug_constraint_graph (void)
+{
+ dump_constraint_graph (stderr);
+}
+
/* SOLVER FUNCTIONS
The solver is a simple worklist solver, that works on the following
@@ -755,23 +846,32 @@ solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
{
- /* If this is a properly sized variable, only add offset if it's
- less than end. Otherwise, it is globbed to a single
- variable. */
+ varinfo_t vi = get_varinfo (i);
- if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize)
+ /* If this is a variable with just one field just set its bit
+ in the result. */
+ if (vi->is_artificial_var
+ || vi->is_unknown_size_var
+ || vi->is_full_var)
+ bitmap_set_bit (result, i);
+ else
{
- unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
- varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset);
+ unsigned HOST_WIDE_INT fieldoffset = vi->offset + offset;
+ varinfo_t v = first_vi_for_offset (vi, fieldoffset);
+ /* If the result is outside of the variable use the last field. */
if (!v)
- continue;
+ {
+ v = vi;
+ while (v->next != NULL)
+ v = v->next;
+ }
bitmap_set_bit (result, v->id);
- }
- else if (get_varinfo (i)->is_artificial_var
- || get_varinfo (i)->has_union
- || get_varinfo (i)->is_unknown_size_var)
- {
- bitmap_set_bit (result, i);
+ /* If the result is not exactly at fieldoffset include the next
+ field as well. See get_constraint_for_ptr_offset for more
+ rationale. */
+ if (v->offset != fieldoffset
+ && v->next != NULL)
+ bitmap_set_bit (result, v->next->id);
}
}
@@ -1379,7 +1479,8 @@ type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
0. */
if (ninfo->is_special_var
|| ninfo->is_artificial_var
- || ninfo->is_unknown_size_var)
+ || ninfo->is_unknown_size_var
+ || ninfo->is_full_var)
{
*offset = 0;
return true;
@@ -1406,6 +1507,51 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
goto done;
}
+ /* For x = *ESCAPED and x = *CALLUSED we want to compute the
+ reachability set of the rhs var. As a pointer to a sub-field
+ of a variable can also reach all other fields of the variable
+ we simply have to expand the solution to contain all sub-fields
+ if one sub-field is contained. */
+ if (c->rhs.var == escaped_id
+ || c->rhs.var == callused_id)
+ {
+ bitmap vars = NULL;
+ /* In a first pass record all variables we need to add all
+ sub-fields off. This avoids quadratic behavior. */
+ EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
+ {
+ varinfo_t v = get_varinfo (j);
+ if (v->is_full_var)
+ continue;
+
+ v = lookup_vi_for_tree (v->decl);
+ if (v->next != NULL)
+ {
+ if (vars == NULL)
+ vars = BITMAP_ALLOC (NULL);
+ bitmap_set_bit (vars, v->id);
+ }
+ }
+ /* In the second pass now do the addition to the solution and
+ to speed up solving add it to the delta as well. */
+ if (vars != NULL)
+ {
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, j, bi)
+ {
+ varinfo_t v = get_varinfo (j);
+ for (; v != NULL; v = v->next)
+ {
+ if (bitmap_set_bit (sol, v->id))
+ {
+ flag = true;
+ bitmap_set_bit (delta, v->id);
+ }
+ }
+ }
+ BITMAP_FREE (vars);
+ }
+ }
+
/* For each variable j in delta (Sol(y)), add
an edge in the graph from j to x, and union Sol(j) into Sol(x). */
EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
@@ -1418,6 +1564,7 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
unsigned int t;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
if (!v)
continue;
t = find (v->id);
@@ -1470,9 +1617,14 @@ do_ds_constraint (constraint_t c, bitmap delta)
unsigned HOST_WIDE_INT fieldoffset = jvi->offset + loff;
varinfo_t v;
- v = first_vi_for_offset (get_varinfo (j), fieldoffset);
- if (!v)
- continue;
+ v = get_varinfo (j);
+ if (!v->is_full_var)
+ {
+ v = first_vi_for_offset (v, fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
+ if (!v)
+ continue;
+ }
t = find (v->id);
if (bitmap_set_bit (get_varinfo (t)->solution, anything_id)
@@ -1498,6 +1650,7 @@ do_ds_constraint (constraint_t c, bitmap delta)
bitmap tmp;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
if (!v)
continue;
t = find (v->id);
@@ -2560,12 +2713,6 @@ process_constraint (constraint_t t)
gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
- if (!use_field_sensitive)
- {
- t->rhs.offset = 0;
- t->lhs.offset = 0;
- }
-
/* ANYTHING == ANYTHING is pointless. */
if (lhs.var == anything_id && rhs.var == anything_id)
return;
@@ -2628,16 +2775,129 @@ could_have_pointers (tree t)
/* Return the position, in bits, of FIELD_DECL from the beginning of its
structure. */
-static unsigned HOST_WIDE_INT
+static HOST_WIDE_INT
bitpos_of_field (const tree fdecl)
{
- if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
- || TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
+ if (!host_integerp (DECL_FIELD_OFFSET (fdecl), 0)
+ || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0))
return -1;
- return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
+ return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * 8
+ + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl)));
+}
+
+
+/* Get constraint expressions for offsetting PTR by OFFSET. Stores the
+ resulting constraint expressions in *RESULTS. */
+
+static void
+get_constraint_for_ptr_offset (tree ptr, tree offset,
+ VEC (ce_s, heap) **results)
+{
+ struct constraint_expr *c;
+ unsigned int j, n;
+ unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset;
+
+ /* If we do not do field-sensitive PTA adding offsets to pointers
+ does not change the points-to solution. */
+ if (!use_field_sensitive)
+ {
+ get_constraint_for (ptr, results);
+ return;
+ }
+
+ /* If the offset is not a non-negative integer constant that fits
+ in a HOST_WIDE_INT, we have to fall back to a conservative
+ solution which includes all sub-fields of all pointed-to
+ variables of ptr.
+ ??? As we do not have the ability to express this, fall back
+ to anything. */
+ if (!host_integerp (offset, 1))
+ {
+ struct constraint_expr temp;
+ temp.var = anything_id;
+ temp.type = SCALAR;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
+ return;
+ }
+
+ /* Make sure the bit-offset also fits. */
+ rhsunitoffset = TREE_INT_CST_LOW (offset);
+ rhsoffset = rhsunitoffset * BITS_PER_UNIT;
+ if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ {
+ struct constraint_expr temp;
+ temp.var = anything_id;
+ temp.type = SCALAR;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
+ return;
+ }
+
+ get_constraint_for (ptr, results);
+ if (rhsoffset == 0)
+ return;
+
+ /* As we are eventually appending to the solution do not use
+ VEC_iterate here. */
+ n = VEC_length (ce_s, *results);
+ for (j = 0; j < n; j++)
+ {
+ varinfo_t curr;
+ c = VEC_index (ce_s, *results, j);
+ curr = get_varinfo (c->var);
+
+ if (c->type == ADDRESSOF
+ && !curr->is_full_var)
+ {
+ varinfo_t temp, curr = get_varinfo (c->var);
+
+ /* Search the sub-field which overlaps with the
+ pointed-to offset. As we deal with positive offsets
+ only, we can start the search from the current variable. */
+ temp = first_vi_for_offset (curr, curr->offset + rhsoffset);
+
+ /* If the result is outside of the variable we have to provide
+ a conservative result, as the variable is still reachable
+ from the resulting pointer (even though it technically
+ cannot point to anything). The last sub-field is such
+ a conservative result.
+ ??? If we always had a sub-field for &object + 1 then
+ we could represent this in a more precise way. */
+ if (temp == NULL)
+ {
+ temp = curr;
+ while (temp->next != NULL)
+ temp = temp->next;
+ continue;
+ }
+
+ /* If the found variable is not exactly at the pointed to
+ result, we have to include the next variable in the
+ solution as well. Otherwise two increments by offset / 2
+ do not result in the same or a conservative superset
+ solution. */
+ if (temp->offset != curr->offset + rhsoffset
+ && temp->next != NULL)
+ {
+ struct constraint_expr c2;
+ c2.var = temp->next->id;
+ c2.type = ADDRESSOF;
+ c2.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &c2);
+ }
+ c->var = temp->id;
+ c->offset = 0;
+ }
+ else if (c->type == ADDRESSOF
+ /* If this varinfo represents a full variable just use it. */
+ && curr->is_full_var)
+ c->offset = 0;
+ else
+ c->offset = rhsoffset;
+ }
}
@@ -2677,15 +2937,18 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
/* Pretend to take the address of the base, we'll take care of
adding the required subset of sub-fields below. */
get_constraint_for_1 (t, results, true);
- result = VEC_last (ce_s, *results);
-
gcc_assert (VEC_length (ce_s, *results) == 1);
+ result = VEC_last (ce_s, *results);
/* This can also happen due to weird offsetof type macros. */
if (TREE_CODE (t) != ADDR_EXPR && result->type == ADDRESSOF)
result->type = SCALAR;
- if (result->type == SCALAR)
+ if (result->type == SCALAR
+ && get_varinfo (result->var)->is_full_var)
+ /* For single-field vars do not bother about the offset. */
+ result->offset = 0;
+ else if (result->type == SCALAR)
{
/* In languages like C, you can access one past the end of an
array. You aren't allowed to dereference it, so we can
@@ -2714,12 +2977,25 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
break;
}
}
- /* assert that we found *some* field there. The user couldn't be
- accessing *only* padding. */
- /* Still the user could access one past the end of an array
- embedded in a struct resulting in accessing *only* padding. */
- gcc_assert (VEC_length (ce_s, *results) >= 1
- || ref_contains_array_ref (orig_t));
+ /* If we are going to take the address of this field then
+ to be able to compute reachability correctly add at least
+ the last field of the variable. */
+ if (address_p
+ && VEC_length (ce_s, *results) == 0)
+ {
+ curr = get_varinfo (cexpr.var);
+ while (curr->next != NULL)
+ curr = curr->next;
+ cexpr.var = curr->id;
+ VEC_safe_push (ce_s, heap, *results, &cexpr);
+ }
+ else
+ /* Assert that we found *some* field there. The user couldn't be
+ accessing *only* padding. */
+ /* Still the user could access one past the end of an array
+ embedded in a struct resulting in accessing *only* padding. */
+ gcc_assert (VEC_length (ce_s, *results) >= 1
+ || ref_contains_array_ref (orig_t));
}
else if (bitmaxsize == 0)
{
@@ -2863,24 +3139,10 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
VEC_safe_push (ce_s, heap, *results, &temp);
return;
}
- else
- {
- temp.var = anything_id;
- temp.type = SCALAR;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
break;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_reference:
{
@@ -2897,15 +3159,9 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
case COMPONENT_REF:
get_constraint_for_component_ref (t, results, address_p);
return;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_unary:
{
@@ -2926,15 +3182,19 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
/* FALLTHRU */
}
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
+ }
+ case tcc_binary:
+ {
+ if (TREE_CODE (t) == POINTER_PLUS_EXPR)
+ {
+ get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
+ TREE_OPERAND (t, 1), results);
+ return;
+ }
+ break;
}
case tcc_exceptional:
{
@@ -2945,37 +3205,28 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
get_constraint_for_1 (PHI_RESULT (t), results, address_p);
return;
}
- break;
case SSA_NAME:
{
get_constraint_for_ssa_var (t, results, address_p);
return;
}
- break;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_declaration:
{
get_constraint_for_ssa_var (t, results, address_p);
return;
}
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+
+ /* The default fallback is a constraint from anything. */
+ temp.type = ADDRESSOF;
+ temp.var = anything_id;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
}
/* Given a gimple tree T, return the constraint expression vector for it. */
@@ -3261,80 +3512,6 @@ do_structure_copy (tree lhsop, tree rhsop)
}
}
-
-/* Handle pointer arithmetic EXPR when creating aliasing constraints.
- Expressions of the type PTR + CST can be handled in two ways:
-
- 1- If the constraint for PTR is ADDRESSOF for a non-structure
- variable, then we can use it directly because adding or
- subtracting a constant may not alter the original ADDRESSOF
- constraint (i.e., pointer arithmetic may not legally go outside
- an object's boundaries).
-
- 2- If the constraint for PTR is ADDRESSOF for a structure variable,
- then if CST is a compile-time constant that can be used as an
- offset, we can determine which sub-variable will be pointed-to
- by the expression.
-
- Return true if the expression is handled. For any other kind of
- expression, return false so that each operand can be added as a
- separate constraint by the caller. */
-
-static bool
-handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
-{
- tree op0, op1;
- struct constraint_expr *c, *c2;
- unsigned int i = 0;
- unsigned int j = 0;
- VEC (ce_s, heap) *temp = NULL;
- unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset;
-
- if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
- return false;
-
- op0 = TREE_OPERAND (expr, 0);
- op1 = TREE_OPERAND (expr, 1);
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0)));
-
- /* If the offset is not a non-negative integer constant that fits
- in a HOST_WIDE_INT, we cannot handle it here. */
- if (!host_integerp (op1, 1))
- return false;
-
- /* Make sure the bit-offset also fits. */
- rhsunitoffset = TREE_INT_CST_LOW (op1);
- rhsoffset = rhsunitoffset * BITS_PER_UNIT;
- if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
- return false;
-
- get_constraint_for (op0, &temp);
-
- for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
- for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
- {
- if (c2->type == ADDRESSOF && rhsoffset != 0)
- {
- varinfo_t temp = get_varinfo (c2->var);
-
- /* An access one after the end of an array is valid,
- so simply punt on accesses we cannot resolve. */
- temp = first_vi_for_offset (temp, rhsoffset);
- if (temp == NULL)
- continue;
- c2->var = temp->id;
- c2->offset = 0;
- }
- else
- c2->offset = rhsoffset;
- process_constraint (new_constraint (*c, *c2));
- }
-
- VEC_free (ce_s, heap, temp);
-
- return true;
-}
-
/* Create a constraint ID = OP. */
static void
@@ -3734,89 +3911,29 @@ find_func_aliases (tree origt)
}
}
}
- /* Otherwise, just a regular assignment statement. */
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+ /* Otherwise, just a regular assignment statement. Only care about
+ operations with pointer result, others are dealt with as escape
+ points if they have pointer operands. */
+ else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
+ && could_have_pointers (GIMPLE_STMT_OPERAND (t, 0)))
{
tree lhsop = GIMPLE_STMT_OPERAND (t, 0);
tree rhsop = GIMPLE_STMT_OPERAND (t, 1);
- int i;
- if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
- && AGGREGATE_TYPE_P (TREE_TYPE (rhsop)))
- {
- do_structure_copy (lhsop, rhsop);
- }
+ if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
+ do_structure_copy (lhsop, rhsop);
else
{
- /* Only care about operations with pointers, structures
- containing pointers, dereferences, and call expressions. */
- if (could_have_pointers (lhsop)
- || TREE_CODE (rhsop) == CALL_EXPR)
+ unsigned int j;
+ get_constraint_for (lhsop, &lhsc);
+ get_constraint_for (rhsop, &rhsc);
+ for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
{
- get_constraint_for (lhsop, &lhsc);
- switch (TREE_CODE_CLASS (TREE_CODE (rhsop)))
- {
- /* RHS that consist of unary operations,
- exceptional types, or bare decls/constants, get
- handled directly by get_constraint_for. */
- case tcc_reference:
- case tcc_declaration:
- case tcc_constant:
- case tcc_exceptional:
- case tcc_expression:
- case tcc_vl_exp:
- case tcc_unary:
- {
- unsigned int j;
-
- get_constraint_for (rhsop, &rhsc);
- for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
- {
- struct constraint_expr *c2;
- unsigned int k;
-
- for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++)
- process_constraint (new_constraint (*c, *c2));
- }
-
- }
- break;
+ struct constraint_expr *c2;
+ unsigned int k;
- case tcc_binary:
- {
- /* For pointer arithmetic of the form
- PTR + CST, we can simply use PTR's
- constraint because pointer arithmetic is
- not allowed to go out of bounds. */
- if (handle_ptr_arith (lhsc, rhsop))
- break;
- }
- /* FALLTHRU */
-
- /* Otherwise, walk each operand. Notice that we
- can't use the operand interface because we need
- to process expressions other than simple operands
- (e.g. INDIRECT_REF, ADDR_EXPR, CALL_EXPR). */
- default:
- for (i = 0; i < TREE_OPERAND_LENGTH (rhsop); i++)
- {
- tree op = TREE_OPERAND (rhsop, i);
- unsigned int j;
-
- gcc_assert (VEC_length (ce_s, rhsc) == 0);
- get_constraint_for (op, &rhsc);
- for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
- {
- struct constraint_expr *c2;
- while (VEC_length (ce_s, rhsc) > 0)
- {
- c2 = VEC_last (ce_s, rhsc);
- process_constraint (new_constraint (*c, *c2));
- VEC_pop (ce_s, rhsc);
- }
- }
- }
- }
+ for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++)
+ process_constraint (new_constraint (*c, *c2));
}
}
}
@@ -3963,17 +4080,15 @@ insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
struct fieldoff
{
- /* Type of the field. */
- tree type;
+ /* Offset from the base of the base containing object to this field. */
+ HOST_WIDE_INT offset;
/* Size, in bits, of the field. */
- tree size;
+ unsigned HOST_WIDE_INT size;
- /* Field. */
- tree decl;
+ unsigned has_unknown_size : 1;
- /* Offset from the base of the base containing object to this field. */
- HOST_WIDE_INT offset;
+ unsigned may_have_pointers : 1;
};
typedef struct fieldoff fieldoff_s;
@@ -3994,10 +4109,10 @@ fieldoff_compare (const void *pa, const void *pb)
else if (foa->offset > fob->offset)
return 1;
- foasize = TREE_INT_CST_LOW (foa->size);
- fobsize = TREE_INT_CST_LOW (fob->size);
+ foasize = foa->size;
+ fobsize = fob->size;
if (foasize < fobsize)
- return - 1;
+ return -1;
else if (foasize > fobsize)
return 1;
return 0;
@@ -4041,14 +4156,11 @@ var_can_have_subvars (const_tree v)
OFFSET is used to keep track of the offset in this entire
structure, rather than just the immediately containing structure.
- Returns the number of fields pushed.
-
- HAS_UNION is set to true if we find a union type as a field of
- TYPE. */
+ Returns the number of fields pushed. */
static int
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
- HOST_WIDE_INT offset, bool *has_union)
+ HOST_WIDE_INT offset)
{
tree field;
int count = 0;
@@ -4067,19 +4179,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
{
bool push = false;
int pushed = 0;
+ HOST_WIDE_INT foff = bitpos_of_field (field);
- if (has_union
- && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
- *has_union = true;
-
- if (!var_can_have_subvars (field))
+ if (!var_can_have_subvars (field)
+ || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
+ || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
push = true;
else if (!(pushed = push_fields_onto_fieldstack
- (TREE_TYPE (field),
- fieldstack,
- offset + bitpos_of_field (field),
- has_union))
+ (TREE_TYPE (field), fieldstack, offset + foff))
&& (DECL_SIZE (field)
&& !integer_zerop (DECL_SIZE (field))))
/* Empty structures may have actual size, like in C++. So
@@ -4089,14 +4196,39 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
if (push)
{
- fieldoff_s *pair;
-
- pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
- pair->type = TREE_TYPE (field);
- pair->size = DECL_SIZE (field);
- pair->decl = field;
- pair->offset = offset + bitpos_of_field (field);
- count++;
+ fieldoff_s *pair = NULL;
+ bool has_unknown_size = false;
+
+ if (!VEC_empty (fieldoff_s, *fieldstack))
+ pair = VEC_last (fieldoff_s, *fieldstack);
+
+ if (!DECL_SIZE (field)
+ || !host_integerp (DECL_SIZE (field), 1))
+ has_unknown_size = true;
+
+ /* If adjacent fields do not contain pointers merge them. */
+ if (pair
+ && !pair->may_have_pointers
+ && !could_have_pointers (field)
+ && !pair->has_unknown_size
+ && !has_unknown_size
+ && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
+ {
+ pair = VEC_last (fieldoff_s, *fieldstack);
+ pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
+ }
+ else
+ {
+ pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ pair->offset = offset + foff;
+ pair->has_unknown_size = has_unknown_size;
+ if (!has_unknown_size)
+ pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
+ else
+ pair->size = -1;
+ pair->may_have_pointers = could_have_pointers (field);
+ count++;
+ }
}
else
count += pushed;
@@ -4162,7 +4294,6 @@ create_function_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = 0;
vi->size = 1;
vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
insert_vi_for_tree (vi->decl, vi);
@@ -4171,8 +4302,7 @@ create_function_info_for (tree decl, const char *name)
stats.total_vars++;
/* If it's varargs, we don't know how many arguments it has, so we
- can't do much.
- */
+ can't do much. */
if (is_varargs)
{
vi->fullsize = ~0;
@@ -4206,8 +4336,8 @@ create_function_info_for (tree decl, const char *name)
VEC_safe_push (varinfo_t, heap, varmap, argvi);
argvi->offset = i;
argvi->size = 1;
+ argvi->is_full_var = true;
argvi->fullsize = vi->fullsize;
- argvi->has_union = false;
insert_into_field_list_sorted (vi, argvi);
stats.total_vars ++;
if (arg)
@@ -4243,7 +4373,7 @@ create_function_info_for (tree decl, const char *name)
resultvi->offset = i;
resultvi->size = 1;
resultvi->fullsize = vi->fullsize;
- resultvi->has_union = false;
+ resultvi->is_full_var = true;
insert_into_field_list_sorted (vi, resultvi);
stats.total_vars ++;
if (DECL_RESULT (decl))
@@ -4283,25 +4413,14 @@ create_variable_info_for (tree decl, const char *name)
varinfo_t vi;
tree decltype = TREE_TYPE (decl);
tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decltype);
- bool notokay = false;
- bool hasunion;
bool is_global = DECL_P (decl) ? is_global_var (decl) : false;
VEC (fieldoff_s,heap) *fieldstack = NULL;
if (TREE_CODE (decl) == FUNCTION_DECL && in_ipa_mode)
return create_function_info_for (decl, name);
- hasunion = TREE_CODE (decltype) == UNION_TYPE
- || TREE_CODE (decltype) == QUAL_UNION_TYPE;
- if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
- {
- push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
- if (hasunion)
- {
- VEC_free (fieldoff_s, heap, fieldstack);
- notokay = true;
- }
- }
+ if (var_can_have_subvars (decl) && use_field_sensitive)
+ push_fields_onto_fieldstack (decltype, &fieldstack, 0);
/* If the variable doesn't have subvars, we may end up needing to
sort the field list and create fake variables for all the
@@ -4309,11 +4428,8 @@ create_variable_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = hasunion;
if (!declsize
- || TREE_CODE (declsize) != INTEGER_CST
- || TREE_CODE (decltype) == UNION_TYPE
- || TREE_CODE (decltype) == QUAL_UNION_TYPE)
+ || !host_integerp (declsize, 1))
{
vi->is_unknown_size_var = true;
vi->fullsize = ~0;
@@ -4333,7 +4449,6 @@ create_variable_info_for (tree decl, const char *name)
stats.total_vars++;
if (use_field_sensitive
- && !notokay
&& !vi->is_unknown_size_var
&& var_can_have_subvars (decl)
&& VEC_length (fieldoff_s, fieldstack) > 1
@@ -4341,12 +4456,12 @@ create_variable_info_for (tree decl, const char *name)
{
unsigned int newindex = VEC_length (varinfo_t, varmap);
fieldoff_s *fo = NULL;
+ bool notokay = false;
unsigned int i;
for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
{
- if (! fo->size
- || TREE_CODE (fo->size) != INTEGER_CST
+ if (fo->has_unknown_size
|| fo->offset < 0)
{
notokay = true;
@@ -4377,11 +4492,12 @@ create_variable_info_for (tree decl, const char *name)
vi->is_unknown_size_var = 1;
vi->fullsize = ~0;
vi->size = ~0;
+ vi->is_full_var = true;
VEC_free (fieldoff_s, heap, fieldstack);
return index;
}
- vi->size = TREE_INT_CST_LOW (fo->size);
+ vi->size = fo->size;
vi->offset = fo->offset;
for (i = VEC_length (fieldoff_s, fieldstack) - 1;
i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
@@ -4394,28 +4510,27 @@ create_variable_info_for (tree decl, const char *name)
newindex = VEC_length (varinfo_t, varmap);
if (dump_file)
{
- if (fo->decl)
- asprintf (&tempname, "%s.%s",
- vi->name, alias_get_name (fo->decl));
- else
- asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC,
- vi->name, fo->offset);
+ asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
+ "+" HOST_WIDE_INT_PRINT_DEC,
+ vi->name, fo->offset, fo->size);
newname = ggc_strdup (tempname);
free (tempname);
}
newvi = new_var_info (decl, newindex, newname);
newvi->offset = fo->offset;
- newvi->size = TREE_INT_CST_LOW (fo->size);
+ newvi->size = fo->size;
newvi->fullsize = vi->fullsize;
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode)
- && (!fo->decl || could_have_pointers (fo->decl)))
+ && fo->may_have_pointers)
make_constraint_from (newvi, escaped_id);
stats.total_vars++;
}
}
+ else
+ vi->is_full_var = true;
VEC_free (fieldoff_s, heap, fieldstack);
@@ -4659,61 +4774,6 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
static bool have_alias_info = false;
-/* The list of SMT's that are in use by our pointer variables. This
- is the set of SMT's for all pointers that can point to anything. */
-static bitmap used_smts;
-
-/* Due to the ordering of points-to set calculation and SMT
- calculation being a bit co-dependent, we can't just calculate SMT
- used info whenever we want, we have to calculate it around the time
- that find_what_p_points_to is called. */
-
-/* Mark which SMT's are in use by points-to anything variables. */
-
-void
-set_used_smts (void)
-{
- int i;
- varinfo_t vi;
- used_smts = BITMAP_ALLOC (&pta_obstack);
-
- for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); i++)
- {
- tree var = vi->decl;
- varinfo_t withsolution = get_varinfo (find (i));
- tree smt;
- var_ann_t va;
- struct ptr_info_def *pi = NULL;
-
- /* For parm decls, the pointer info may be under the default
- def. */
- if (TREE_CODE (vi->decl) == PARM_DECL
- && gimple_default_def (cfun, var))
- pi = SSA_NAME_PTR_INFO (gimple_default_def (cfun, var));
- else if (TREE_CODE (var) == SSA_NAME)
- pi = SSA_NAME_PTR_INFO (var);
-
- /* Skip the special variables and those that can't be aliased. */
- if (vi->is_special_var
- || !SSA_VAR_P (var)
- || (pi && !pi->memory_tag_needed)
- || (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var))
- || !POINTER_TYPE_P (TREE_TYPE (var)))
- continue;
-
- if (TREE_CODE (var) == SSA_NAME)
- var = SSA_NAME_VAR (var);
-
- va = var_ann (var);
- if (!va)
- continue;
-
- smt = va->symbol_mem_tag;
- if (smt && bitmap_bit_p (withsolution->solution, anything_id))
- bitmap_set_bit (used_smts, DECL_UID (smt));
- }
-}
-
/* Given a pointer variable P, fill in its points-to set, or return
false if we can't.
Rather than return false for variables that point-to anything, we
@@ -5167,6 +5227,8 @@ init_base_vars (void)
static void
init_alias_vars (void)
{
+ use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
+
bitmap_obstack_initialize (&pta_obstack);
bitmap_obstack_initialize (&oldpta_obstack);
bitmap_obstack_initialize (&predbitmap_obstack);
@@ -5425,6 +5487,10 @@ compute_points_to_sets (void)
free_var_substitution_info (si);
build_succ_graph ();
+
+ if (dump_file && (dump_flags & TDF_GRAPH))
+ dump_constraint_graph (dump_file);
+
move_complex_constraints (graph);
if (dump_file)
diff --git a/gcc/tree-ssa-structalias.h b/gcc/tree-ssa-structalias.h
index 7d468b42f91..0d0d6bdf073 100644
--- a/gcc/tree-ssa-structalias.h
+++ b/gcc/tree-ssa-structalias.h
@@ -32,13 +32,15 @@ void update_mem_sym_stats_from_stmt (tree, tree, long, long);
extern void compute_points_to_sets (void);
extern void delete_points_to_sets (void);
extern void dump_constraint (FILE *, constraint_t);
+extern void dump_constraint_edge (FILE *, constraint_t);
extern void dump_constraints (FILE *);
+extern void dump_constraint_graph (FILE *);
extern void debug_constraint (constraint_t);
extern void debug_constraints (void);
+extern void debug_constraint_graph (void);
extern void dump_solution_for_var (FILE *, unsigned int);
extern void debug_solution_for_var (unsigned int);
extern void dump_sa_points_to_info (FILE *);
extern void debug_sa_points_to_info (void);
-extern void set_used_smts (void);
#endif /* TREE_SSA_STRUCTALIAS_H */
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 728c37d4d6d..f9228872dc2 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -605,6 +605,7 @@ execute_optimize_stdarg (void)
bool va_list_simple_ptr;
struct stdarg_info si;
const char *funcname = NULL;
+ tree cfun_va_list;
cfun->va_list_gpr_size = 0;
cfun->va_list_fpr_size = 0;
@@ -615,10 +616,11 @@ execute_optimize_stdarg (void)
if (dump_file)
funcname = lang_hooks.decl_printable_name (current_function_decl, 2);
- va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
- && (TREE_TYPE (va_list_type_node) == void_type_node
- || TREE_TYPE (va_list_type_node) == char_type_node);
- gcc_assert (is_gimple_reg_type (va_list_type_node) == va_list_simple_ptr);
+ cfun_va_list = targetm.fn_abi_va_list (cfun->decl);
+ va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
+ && (TREE_TYPE (cfun_va_list) == void_type_node
+ || TREE_TYPE (cfun_va_list) == char_type_node);
+ gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr);
FOR_EACH_BB (bb)
{
@@ -671,7 +673,7 @@ execute_optimize_stdarg (void)
ap = TREE_OPERAND (ap, 0);
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
- != TYPE_MAIN_VARIANT (va_list_type_node)
+ != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (cfun->decl))
|| TREE_CODE (ap) != VAR_DECL)
{
va_list_escapes = true;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 68d6b50d1bd..0ce5fc91ead 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -482,7 +482,7 @@ build_one_array (tree swtch, int num, tree arr_index_type, tree phi, tree tidx)
fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
NULL_TREE);
- load = build2 (GIMPLE_MODIFY_STMT, void_type_node, name, fetch);
+ load = build_gimple_modify_stmt (name, fetch);
SSA_NAME_DEF_STMT (name) = load;
bsi = bsi_for_stmt (swtch);
@@ -507,13 +507,17 @@ build_arrays (tree swtch)
tree phi = phi_nodes (info.final_bb);
int i;
+ bsi = bsi_for_stmt (swtch);
+
arr_index_type = build_index_type (info.range_size);
tidx = make_rename_temp (arr_index_type, "csti");
- sub = build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
- fold_convert (TREE_TYPE (info.index_expr), info.range_min));
- sub = build2 (GIMPLE_MODIFY_STMT, void_type_node, tidx, sub);
+ sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
+ fold_convert (TREE_TYPE (info.index_expr),
+ info.range_min));
+ sub = force_gimple_operand_bsi (&bsi, fold_convert (arr_index_type, sub),
+ false, NULL, true, BSI_SAME_STMT);
+ sub = build_gimple_modify_stmt (tidx, sub);
- bsi = bsi_for_stmt (swtch);
bsi_insert_before (&bsi, sub, BSI_SAME_STMT);
mark_symbols_for_renaming (sub);
info.arr_ref_first = sub;
@@ -539,8 +543,7 @@ gen_def_assigns (block_stmt_iterator *bsi)
NULL_TREE);
info.target_outbound_names[i] = name;
- assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, name,
- info.default_values[i]);
+ assign = build_gimple_modify_stmt (name, info.default_values[i]);
SSA_NAME_DEF_STMT (name) = assign;
bsi_insert_before (bsi, assign, BSI_SAME_STMT);
find_new_referenced_vars (&assign);
@@ -639,15 +642,17 @@ gen_inbound_check (tree swtch)
bsi = bsi_for_stmt (info.arr_ref_first);
tmp_u = make_rename_temp (utype, "csui");
- cast = build1 (NOP_EXPR, utype, info.index_expr);
- cast_assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp_u, cast);
+ cast = fold_convert (utype, info.index_expr);
+ cast_assign = build_gimple_modify_stmt (tmp_u, cast);
find_new_referenced_vars (&cast_assign);
bsi_insert_before (&bsi, cast_assign, BSI_SAME_STMT);
mark_symbols_for_renaming (cast_assign);
ulb = fold_convert (utype, info.range_min);
- minus = build2 (MINUS_EXPR, utype, tmp_u, ulb);
- minus_assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp_u, minus);
+ minus = fold_build2 (MINUS_EXPR, utype, tmp_u, ulb);
+ minus = force_gimple_operand_bsi (&bsi, minus, false, NULL, true,
+ BSI_SAME_STMT);
+ minus_assign = build_gimple_modify_stmt (tmp_u, minus);
find_new_referenced_vars (&minus_assign);
bsi_insert_before (&bsi, minus_assign, BSI_SAME_STMT);
mark_symbols_for_renaming (minus_assign);
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 09a2eafe119..92127b4b7af 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -138,14 +138,14 @@ suitable_for_tail_opt_p (void)
if (cfun->stdarg)
return false;
- /* No local variable nor structure field should be call-clobbered. We
+ /* No local variable nor structure field should be call-used. We
ignore any kind of memory tag, as these are not real variables. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
if (!is_global_var (var)
&& !MTAG_P (var)
- && (gimple_aliases_computed_p (cfun) ? is_call_clobbered (var)
+ && (gimple_aliases_computed_p (cfun)? is_call_used (var)
: TREE_ADDRESSABLE (var)))
return false;
}
diff --git a/gcc/tree.c b/gcc/tree.c
index d9e4e7f18db..97b53bd951c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1827,6 +1827,24 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
return node;
}
+/* Return the elements of a CONSTRUCTOR as a TREE_LIST. */
+
+tree
+ctor_to_list (tree ctor)
+{
+ tree list = NULL_TREE;
+ tree *p = &list;
+ unsigned ix;
+ tree purpose, val;
+
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), ix, purpose, val)
+ {
+ *p = build_tree_list (purpose, val);
+ p = &TREE_CHAIN (*p);
+ }
+
+ return list;
+}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
@@ -7377,7 +7395,16 @@ build_common_tree_nodes_2 (int short_double)
complex_long_double_type_node = build_complex_type (long_double_type_node);
/* Make fixed-point nodes based on sat/non-sat and signed/unsigned. */
-#define MAKE_FIXED_TYPE_NODE(KIND,WIDTH,SIZE) \
+#define MAKE_FIXED_TYPE_NODE(KIND,SIZE) \
+ sat_ ## KIND ## _type_node = \
+ make_sat_signed_ ## KIND ## _type (SIZE); \
+ sat_unsigned_ ## KIND ## _type_node = \
+ make_sat_unsigned_ ## KIND ## _type (SIZE); \
+ KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
+ unsigned_ ## KIND ## _type_node = \
+ make_unsigned_ ## KIND ## _type (SIZE);
+
+#define MAKE_FIXED_TYPE_NODE_WIDTH(KIND,WIDTH,SIZE) \
sat_ ## WIDTH ## KIND ## _type_node = \
make_sat_signed_ ## KIND ## _type (SIZE); \
sat_unsigned_ ## WIDTH ## KIND ## _type_node = \
@@ -7388,10 +7415,10 @@ build_common_tree_nodes_2 (int short_double)
/* Make fixed-point type nodes based on four different widths. */
#define MAKE_FIXED_TYPE_NODE_FAMILY(N1,N2) \
- MAKE_FIXED_TYPE_NODE (N1, short_, SHORT_ ## N2 ## _TYPE_SIZE) \
- MAKE_FIXED_TYPE_NODE (N1, , N2 ## _TYPE_SIZE) \
- MAKE_FIXED_TYPE_NODE (N1, long_, LONG_ ## N2 ## _TYPE_SIZE) \
- MAKE_FIXED_TYPE_NODE (N1, long_long_, LONG_LONG_ ## N2 ## _TYPE_SIZE)
+ MAKE_FIXED_TYPE_NODE_WIDTH (N1, short_, SHORT_ ## N2 ## _TYPE_SIZE) \
+ MAKE_FIXED_TYPE_NODE (N1, N2 ## _TYPE_SIZE) \
+ MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_, LONG_ ## N2 ## _TYPE_SIZE) \
+ MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_long_, LONG_LONG_ ## N2 ## _TYPE_SIZE)
/* Make fixed-point mode nodes based on sat/non-sat and signed/unsigned. */
#define MAKE_FIXED_MODE_NODE(KIND,NAME,MODE) \
diff --git a/gcc/tree.h b/gcc/tree.h
index c00ad54cf05..e6b9f9cf65e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1586,6 +1586,9 @@ struct tree_vec GTY(())
/* In a CONSTRUCTOR node. */
#define CONSTRUCTOR_ELTS(NODE) (CONSTRUCTOR_CHECK (NODE)->constructor.elts)
+#define CONSTRUCTOR_ELT(NODE,IDX) \
+ (VEC_index (constructor_elt, CONSTRUCTOR_ELTS (NODE), IDX))
+#define CONSTRUCTOR_NELTS(NODE) (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (NODE)))
/* Iterate through the vector V of CONSTRUCTOR_ELT elements, yielding the
value of each element (stored within VAL). IX must be a scratch variable
@@ -4475,6 +4478,10 @@ extern int fields_length (const_tree);
extern bool initializer_zerop (const_tree);
+/* Given a CONSTRUCTOR CTOR, return the elements as a TREE_LIST. */
+
+extern tree ctor_to_list (tree);
+
/* Examine CTOR to discover:
* how many scalar fields are set to nonzero values,
and place it in *P_NZ_ELTS;
diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h
index 9c56af08486..6924e8c1732 100644
--- a/gcc/unwind-pe.h
+++ b/gcc/unwind-pe.h
@@ -71,6 +71,9 @@
include leb128. */
static unsigned int
+size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
+
+static unsigned int
size_of_encoded_value (unsigned char encoding)
{
if (encoding == DW_EH_PE_omit)
diff --git a/gcc/varray.c b/gcc/varray.c
index 45330397e0e..6464a816652 100644
--- a/gcc/varray.c
+++ b/gcc/varray.c
@@ -49,13 +49,13 @@ static htab_t varray_hash;
static hashval_t
hash_descriptor (const void *p)
{
- const struct varray_descriptor *d = p;
+ const struct varray_descriptor *d = (const struct varray_descriptor *) p;
return htab_hash_pointer (d->name);
}
static int
eq_descriptor (const void *p1, const void *p2)
{
- const struct varray_descriptor *d = p1;
+ const struct varray_descriptor *d = (const struct varray_descriptor *) p1;
return d->name == p2;
}
@@ -74,7 +74,7 @@ varray_descriptor (const char *name)
1);
if (*slot)
return *slot;
- *slot = xcalloc (sizeof (**slot), 1);
+ *slot = XCNEW (struct varray_descriptor);
(*slot)->name = name;
return *slot;
}
diff --git a/gcc/vec.h b/gcc/vec.h
index 10bdcc5f2e9..c07ee221584 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -480,6 +480,12 @@ typedef struct VEC(T,A) GTY \
VEC(T,B) base; \
} VEC(T,A)
+#define VEC_TA(T,B,A) \
+typedef struct VEC(T,A) \
+{ \
+ VEC(T,B) base; \
+} VEC(T,A)
+
/* Convert to base type. */
#define VEC_BASE(P) ((P) ? &(P)->base : 0)
@@ -491,11 +497,11 @@ static inline void VEC_OP (T,must_be,integral_type) (void) \
} \
\
VEC_T(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_P(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_I(T,A) \
struct vec_swallow_trailing_semi
@@ -507,11 +513,11 @@ static inline void VEC_OP (T,must_be,pointer_type) (void) \
} \
\
VEC_T_GTY(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_P(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_P(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_P(T,A) \
struct vec_swallow_trailing_semi
@@ -797,11 +803,11 @@ static inline T *VEC_OP (T,A,safe_insert) \
/* Vector of object. */
#define DEF_VEC_O(T) \
VEC_T_GTY(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_O(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_O(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_O(T,A) \
struct vec_swallow_trailing_semi
diff --git a/include/ChangeLog b/include/ChangeLog
index bf1af8da2cc..1636e982f79 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-07 Joel Brobecker <brobecker@adacore.com>
+
+ * safe-ctype.h: Add #include of ctype.h before redefining
+ the ctype.h macros.
+
+2008-07-04 Joel Brobecker <brobecker@adacore.com>
+
+ * safe-ctype.h: Remove #error when detecting that ctype.h has been
+ included. Redefine the various macros provided by ctype.h as
+ undefined variables.
+
2008-06-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* libiberty.h (XALLOCA, XDUP, XALLOCAVEC, XDUPVEC, XALLOCAVAR,
diff --git a/include/safe-ctype.h b/include/safe-ctype.h
index e59b357ccfb..0266bf1aa26 100644
--- a/include/safe-ctype.h
+++ b/include/safe-ctype.h
@@ -35,10 +35,6 @@ Boston, MA 02110-1301, USA. */
#ifndef SAFE_CTYPE_H
#define SAFE_CTYPE_H
-#ifdef isalpha
- #error "safe-ctype.h and ctype.h may not be used simultaneously"
-#endif
-
/* Determine host character set. */
#define HOST_CHARSET_UNKNOWN 0
#define HOST_CHARSET_ASCII 1
@@ -116,4 +112,39 @@ extern const unsigned char _sch_tolower[256];
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
+/* Prevent the users of safe-ctype.h from accidently using the routines
+ from ctype.h. Initially, the approach was to produce an error when
+ detecting that ctype.h has been included. But this was causing
+ trouble as ctype.h might get indirectly included as a result of
+ including another system header (for instance gnulib's stdint.h).
+ So we include ctype.h here and then immediately redefine its macros. */
+
+#include <ctype.h>
+#undef isalpha
+#define isalpha(c) do_not_use_isalpha_with_safe_ctype
+#undef isalnum
+#define isalnum(c) do_not_use_isalnum_with_safe_ctype
+#undef iscntrl
+#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
+#undef isdigit
+#define isdigit(c) do_not_use_isdigit_with_safe_ctype
+#undef isgraph
+#define isgraph(c) do_not_use_isgraph_with_safe_ctype
+#undef islower
+#define islower(c) do_not_use_islower_with_safe_ctype
+#undef isprint
+#define isprint(c) do_not_use_isprint_with_safe_ctype
+#undef ispunct
+#define ispunct(c) do_not_use_ispunct_with_safe_ctype
+#undef isspace
+#define isspace(c) do_not_use_isspace_with_safe_ctype
+#undef isupper
+#define isupper(c) do_not_use_isupper_with_safe_ctype
+#undef isxdigit
+#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
+#undef toupper
+#define toupper(c) do_not_use_toupper_with_safe_ctype
+#undef tolower
+#define tolower(c) do_not_use_tolower_with_safe_ctype
+
#endif /* SAFE_CTYPE_H */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 7f069414f7e..2d29a309566 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-13 Andrew Haley <aph@redhat.com>
+
+ PR preprocessor/33305
+ * macro.c (replace_args): Print a warning for empty macro
+ arguments in C89 and C++.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* Makefile.in ($(srcdir)/aclocal.m4): Update dependencies.
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 016754bc952..edc2856551a 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1009,6 +1009,17 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
if (src->flags & PASTE_LEFT)
paste_flag = dest - 1;
}
+ else if (CPP_PEDANTIC (pfile) && ! macro->syshdr
+ && ! CPP_OPTION (pfile, c99)
+ && ! cpp_in_system_header (pfile))
+ {
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "invoking macro %s argument %d: "
+ "empty macro arguments are undefined"
+ " in ISO C90 and ISO C++98",
+ NODE_NAME (node),
+ src->val.arg_no);
+ }
/* Avoid paste on RHS (even case count == 0). */
if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT))
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 0bcffffc56a..348afc5d227 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,85 @@
+2008-07-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/64/t-softfp-compat: Update comments.
+
+2008-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/64/_divtc3-compat.c: Moved to ...
+ * config/i386/64/_divtc3.c: Here.
+
+ * config/i386/64/_multc3-compat.c: Moved to ...
+ * config/i386/64/_multc3.c: Here.
+
+ * config/i386/64/_powitf2-compat.c: Moved to ...
+ * config/i386/64/_powitf2.c: Here.
+
+ * config/i386/64/t-softfp-compat (libgcc2-tf-compats): Add
+ .c suffix instead of -compat.c.
+
+2008-07-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h (_FP_MUL_MEAT_S): Remove.
+ (_FP_MUL_MEAT_D): Ditto.
+ (_FP_DIV_MEAT_S): Ditto.
+ (_FP_DIV_MEAT_D): Ditto.
+
+2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * Makefile.in: Add support for __sync_* libgcc functions.
+
+2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * shared-object.mk ($(base)_s$(objext)): Remove -DSHARED.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR boostrap/36702
+ * config.host: Only include 32bit t-fprules-softfp for Darwin/x86
+ and Linux/x86. Include 64bit t-softfp-compat for Linux/x86.
+
+ * config/i386/64/t-fprules-softfp: Moved to ...
+ * config/i386/64/t-softfp-compat: This. New.
+
+2008-07-02 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h (FP_HANDLE_EXCEPTIONS) [FP_EX_INVALID]:
+ Initialize f with 0.0.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36669
+ * shared-object.mk ($(base)_s$(objext)): Add -DSHARED.
+
+ * config/i386/64/_divtc3-compat.c: New.
+ * config/i386/64/_multc3-compat.c: Likewise.
+ * config/i386/64/_powitf2-compat.c: Likewise.
+ * config/i386/64/eqtf2.c: Likewise.
+ * config/i386/64/getf2.c: Likewise.
+ * config/i386/64/letf2.c: Likewise.
+ * config/i386/64/t-fprules-softfp: Likewise.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.host: Add i386/${host_address}/t-fprules-softfp to
+ tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
+ i[34567]86-*-linux*, x86_64-*-linux*.
+
+ * configure.ac: Set host_address to 64 or 32 for x86.
+ * configure: Regenerated.
+
+ * Makefile.in (config.status): Also depend on
+ $(srcdir)/config.host.
+
+ * config/i386/32/t-fprules-softfp: New.
+ * config/i386/32/tf-signs.c: Likewise.
+
+ * config/i386/64/sfp-machine.h: New. Moved from gcc.
+
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h: New.
+
2008-06-26 Nathan Froyd <froydnj@codesourcery.com>
* config/rs6000/t-ppccomm: Remove rules that conflict with
@@ -73,8 +155,8 @@
Paolo Bonzini <bonzini@gnu.org>
PR target/30572
- * Makefile.in: Use @shlib_slibdir@ substitution to get correct install name
- on darwin.
+ * Makefile.in: Use @shlib_slibdir@ substitution to get
+ correct install name on darwin.
* config/t-slibgcc-darwin: Use @shlib_slibdir@ for -install_name.
2007-12-15 Hans-Peter Nilsson <hp@axis.com>
@@ -178,7 +260,7 @@
* config/i386/t-crtpc: New file.
* config.host (i[34567]86-*-linux*): Add i386/t-crtpc to tm-file.
- (x86_64-*-linux*): Ditto.
+ (x86_64-*-linux*): Ditto.
2007-02-30 Kai Tietz <kai.tietz@onevision.com>
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 94b6440f011..5718a501830 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
stamp-h: $(srcdir)/config.in config.status Makefile
CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
$(SHELL) ./config.status --recheck
include $(gcc_objdir)/libgcc.mvars
@@ -577,6 +577,54 @@ endif
endif
+ifeq ($(LIBGCC_SYNC),yes)
+libgcc-sync-size-funcs := $(foreach op, add sub or and xor nand, \
+ sync_fetch_and_$(op) \
+ sync_$(op)_and_fetch) \
+ sync_bool_compare_and_swap \
+ sync_val_compare_and_swap \
+ sync_lock_test_and_set
+
+libgcc-sync-size-funcs := $(foreach prefix, $(libgcc-sync-size-funcs), \
+ $(foreach suffix, 1 2 4 8 16, \
+ $(prefix)_$(suffix)))
+
+libgcc-sync-size-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-size-funcs))
+$(libgcc-sync-size-funcs-o): %$(objext): $(gcc_srcdir)/config/sync.c
+ $(gcc_compile) $(LIBGCC_SYNC_CFLAGS) \
+ -DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
+ -DSIZE=`echo "$*" | sed 's/.*_//'` \
+ -c $(gcc_srcdir)/config/sync.c $(vis_hide)
+libgcc-objects += $(libgcc-sync-size-funcs-o)
+
+libgcc-sync-funcs := sync_synchronize
+
+libgcc-sync-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-funcs))
+$(libgcc-sync-funcs-o): %$(objext): $(gcc_srcdir)/config/sync.c
+ $(gcc_compile) $(LIBGCC_SYNC_CFLAGS) \
+ -DL$* \
+ -c $(gcc_srcdir)/config/sync.c $(vis_hide)
+libgcc-objects += $(libgcc-sync-funcs-o)
+
+ifeq ($(enable_shared),yes)
+libgcc-sync-size-funcs-s-o = $(patsubst %,%_s$(objext), \
+ $(libgcc-sync-size-funcs))
+$(libgcc-sync-size-funcs-s-o): %_s$(objext): $(gcc_srcdir)/config/sync.c
+ $(gcc_s_compile) $(LIBGCC_SYNC_CFLAGS) \
+ -DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
+ -DSIZE=`echo "$*" | sed 's/.*_//'` \
+ -c $(gcc_srcdir)/config/sync.c
+libgcc-s-objects += $(libgcc-sync-size-funcs-s-o)
+
+libgcc-sync-funcs-s-o = $(patsubst %,%_s$(objext),$(libgcc-sync-funcs))
+$(libgcc-sync-funcs-s-o): %_s$(objext): $(gcc_srcdir)/config/sync.c
+ $(gcc_s_compile) $(LIBGCC_SYNC_CFLAGS) \
+ -DL$* \
+ -c $(gcc_srcdir)/config/sync.c
+libgcc-s-objects += $(libgcc-sync-funcs-s-o)
+endif
+endif
+
# Build fixed-point support.
ifeq ($(fixed_point),yes)
diff --git a/libgcc/config.host b/libgcc/config.host
index da652de0ed8..93d1dbfacbb 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -578,3 +578,21 @@ i[34567]86-*-linux* | x86_64-*-linux*)
tmake_file="${tmake_file} t-tls"
;;
esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+ i[34567]86-*-linux* | x86_64-*-linux*)
+ if test "${host_address}" = 32; then
+ tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+ fi
+ ;;
+esac
+
+case ${host} in
+i[34567]86-*-linux* | x86_64-*-linux*)
+ # Provide backward binary compatibility for 64bit Linux/x86.
+ if test "${host_address}" = 64; then
+ tmake_file="${tmake_file} i386/${host_address}/t-softfp-compat"
+ fi
+ ;;
+esac
diff --git a/libgcc/config/i386/32/sfp-machine.h b/libgcc/config/i386/32/sfp-machine.h
new file mode 100644
index 00000000000..746ae7c1287
--- /dev/null
+++ b/libgcc/config/i386/32/sfp-machine.h
@@ -0,0 +1,209 @@
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned int
+#define _FP_WS_TYPE signed int
+#define _FP_I_TYPE int
+
+/* The type of the result of a floating point comparison. This must
+ match `__libgcc_cmp_return__' in GCC for the target. */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ __asm__ ("add{l} {%11,%3|%3,%11}\n\t" \
+ "adc{l} {%9,%2|%2,%9}\n\t" \
+ "adc{l} {%7,%1|%1,%7}\n\t" \
+ "adc{l} {%5,%0|%0,%5}" \
+ : "=r" ((USItype) (r3)), \
+ "=&r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "%0" ((USItype) (x3)), \
+ "g" ((USItype) (y3)), \
+ "%1" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "%2" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "%3" ((USItype) (x0)), \
+ "g" ((USItype) (y0)))
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("add{l} {%8,%2|%2,%8}\n\t" \
+ "adc{l} {%6,%1|%1,%6}\n\t" \
+ "adc{l} {%4,%0|%0,%4}" \
+ : "=r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "%0" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "%1" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "%2" ((USItype) (x0)), \
+ "g" ((USItype) (y0)))
+
+/* FIXME: Change last operand constraint
+ from "im" to "g" when reload works properly. */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ __asm__ ("sub{l} {%11,%3|%3,%11}\n\t" \
+ "sbb{l} {%9,%2|%2,%9}\n\t" \
+ "sbb{l} {%7,%1|%1,%7}\n\t" \
+ "sbb{l} {%5,%0|%0,%5}" \
+ : "=r" ((USItype) (r3)), \
+ "=&r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "0" ((USItype) (x3)), \
+ "g" ((USItype) (y3)), \
+ "1" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "2" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "3" ((USItype) (x0)), \
+ "im" ((USItype) (y0)))
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("sub{l} {%8,%2|%2,%8}\n\t" \
+ "sbb{l} {%6,%1|%1,%6}\n\t" \
+ "sbb{l} {%4,%0|%0,%4}" \
+ : "=r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "0" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "1" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "2" ((USItype) (x0)), \
+ "g" ((USItype) (y0)))
+
+
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte, we have to pad it to
+ 16byte since soft-fp emulation is done in 16byte. */
+#define _FP_NANFRAC_E _FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S 1
+#define _FP_NANSIGN_D 1
+#define _FP_NANSIGN_E 1
+#define _FP_NANSIGN_Q 1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+ the case where we have two NaNs with same mantissas, but
+ different sign. Different operations pick up different NaNs. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if (_FP_FRAC_GT_##wc(X, Y) \
+ || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID 0x01
+#define FP_EX_DENORM 0x02
+#define FP_EX_DIVZERO 0x04
+#define FP_EX_OVERFLOW 0x08
+#define FP_EX_UNDERFLOW 0x10
+#define FP_EX_INEXACT 0x20
+
+struct fenv
+{
+ unsigned short int __control_word;
+ unsigned short int __unused1;
+ unsigned short int __status_word;
+ unsigned short int __unused2;
+ unsigned short int __tags;
+ unsigned short int __unused3;
+ unsigned int __eip;
+ unsigned short int __cs_selector;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
+ unsigned int __data_offset;
+ unsigned short int __data_selector;
+ unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS \
+ do { \
+ if (_fex & FP_EX_INVALID) \
+ { \
+ float f = 0.0; \
+ __asm__ __volatile__ ("fdiv %0" : "+t" (f)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_DIVZERO) \
+ { \
+ float f = 1.0, g = 0.0; \
+ __asm__ __volatile__ ("fdivp" : "=t" (f) \
+ : "0" (f), "u" (g) \
+ : "st(1)"); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_OVERFLOW) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_OVERFLOW; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_UNDERFLOW) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_UNDERFLOW; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_INEXACT) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_INEXACT; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ } while (0)
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 0xc00
+#define FP_RND_PINF 0x800
+#define FP_RND_MINF 0x400
+
+#define _FP_DECL_EX \
+ unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ ("fnstcw %0" : "=m" (_fcw)); \
+ } while (0)
+
+#define FP_ROUNDMODE (_fcw & 0xc00)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME. */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing. If these functions ever return
+ anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+ CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
diff --git a/libgcc/config/i386/32/t-fprules-softfp b/libgcc/config/i386/32/t-fprules-softfp
new file mode 100644
index 00000000000..8e7f3233b71
--- /dev/null
+++ b/libgcc/config/i386/32/t-fprules-softfp
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
diff --git a/libgcc/config/i386/32/tf-signs.c b/libgcc/config/i386/32/tf-signs.c
new file mode 100644
index 00000000000..1b19b601269
--- /dev/null
+++ b/libgcc/config/i386/32/tf-signs.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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. */
+
+union _FP_UNION_Q
+{
+ __float128 flt;
+ struct
+ {
+ unsigned long frac0 : 32;
+ unsigned long frac1 : 32;
+ unsigned long frac2 : 32;
+ unsigned long frac3 : 16;
+ unsigned exp : 15;
+ unsigned sign : 1;
+ } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+ union _FP_UNION_Q A, B;
+
+ A.flt = a;
+ B.flt = b;
+ A.bits.sign = B.bits.sign;
+
+ return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+ union _FP_UNION_Q A;
+
+ A.flt = a;
+ A.bits.sign = 0;
+
+ return A.flt;
+}
diff --git a/libgcc/config/i386/64/_divtc3.c b/libgcc/config/i386/64/_divtc3.c
new file mode 100644
index 00000000000..57ee350b7cd
--- /dev/null
+++ b/libgcc/config/i386/64/_divtc3.c
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __divtc3 __divtc3_shared
+#endif
+
+#define L_divtc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __divtc3
+extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
+
+asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
+asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/_multc3.c b/libgcc/config/i386/64/_multc3.c
new file mode 100644
index 00000000000..49141a9384f
--- /dev/null
+++ b/libgcc/config/i386/64/_multc3.c
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __multc3 __multc3_shared
+#endif
+
+#define L_multc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __multc3
+extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
+
+asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
+asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/_powitf2.c b/libgcc/config/i386/64/_powitf2.c
new file mode 100644
index 00000000000..3bc3c904de7
--- /dev/null
+++ b/libgcc/config/i386/64/_powitf2.c
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/eqtf2.c b/libgcc/config/i386/64/eqtf2.c
new file mode 100644
index 00000000000..d9baba689be
--- /dev/null
+++ b/libgcc/config/i386/64/eqtf2.c
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/getf2.c b/libgcc/config/i386/64/getf2.c
new file mode 100644
index 00000000000..30885cc0caf
--- /dev/null
+++ b/libgcc/config/i386/64/getf2.c
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/letf2.c b/libgcc/config/i386/64/letf2.c
new file mode 100644
index 00000000000..231f981c84c
--- /dev/null
+++ b/libgcc/config/i386/64/letf2.c
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
diff --git a/libgcc/config/i386/64/sfp-machine.h b/libgcc/config/i386/64/sfp-machine.h
new file mode 100644
index 00000000000..190e3cb0e81
--- /dev/null
+++ b/libgcc/config/i386/64/sfp-machine.h
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison. This must
+ match `__libgcc_cmp_return__' in GCC for the target. */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S _FP_QNANBIT_S
+#define _FP_NANFRAC_D _FP_QNANBIT_D
+#define _FP_NANFRAC_E _FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S 1
+#define _FP_NANSIGN_D 1
+#define _FP_NANSIGN_E 1
+#define _FP_NANSIGN_Q 1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+ the case where we have two NaNs with same mantissas, but
+ different sign. Different operations pick up different NaNs. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if (_FP_FRAC_GT_##wc(X, Y) \
+ || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ else \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID 0x01
+#define FP_EX_DENORM 0x02
+#define FP_EX_DIVZERO 0x04
+#define FP_EX_OVERFLOW 0x08
+#define FP_EX_UNDERFLOW 0x10
+#define FP_EX_INEXACT 0x20
+
+struct fenv
+{
+ unsigned short int __control_word;
+ unsigned short int __unused1;
+ unsigned short int __status_word;
+ unsigned short int __unused2;
+ unsigned short int __tags;
+ unsigned short int __unused3;
+ unsigned int __eip;
+ unsigned short int __cs_selector;
+ unsigned int __opcode:11;
+ unsigned int __unused4:5;
+ unsigned int __data_offset;
+ unsigned short int __data_selector;
+ unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS \
+ do { \
+ if (_fex & FP_EX_INVALID) \
+ { \
+ float f = 0.0; \
+ __asm__ __volatile__ ("divss %0, %0 " : : "x" (f)); \
+ } \
+ if (_fex & FP_EX_DIVZERO) \
+ { \
+ float f = 1.0, g = 0.0; \
+ __asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g)); \
+ } \
+ if (_fex & FP_EX_OVERFLOW) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_OVERFLOW; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_UNDERFLOW) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_UNDERFLOW; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ if (_fex & FP_EX_INEXACT) \
+ { \
+ struct fenv temp; \
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (temp)); \
+ temp.__status_word |= FP_EX_INEXACT; \
+ __asm__ __volatile__ ("fldenv %0" : : "m" (temp)); \
+ __asm__ __volatile__ ("fwait"); \
+ } \
+ } while (0)
+
+#define FP_RND_NEAREST 0
+#define FP_RND_ZERO 0xc00
+#define FP_RND_PINF 0x800
+#define FP_RND_MINF 0x400
+
+#define _FP_DECL_EX \
+ unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE \
+ do { \
+ __asm__ ("fnstcw %0" : "=m" (_fcw)); \
+ } while (0)
+
+#define FP_ROUNDMODE (_fcw & 0xc00)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME. */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing. If these functions ever return
+ anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+ CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
diff --git a/libgcc/config/i386/64/t-softfp-compat b/libgcc/config/i386/64/t-softfp-compat
new file mode 100644
index 00000000000..afaa526ae29
--- /dev/null
+++ b/libgcc/config/i386/64/t-softfp-compat
@@ -0,0 +1,15 @@
+# When TFmode was first added to x86-64 in gcc 4.3.0, some TFmode
+# support functions got improper versions by accident. Here we
+# correct the version and provide backward binary compatibility.
+
+# Filter out the following TFmode functions.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix .c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
diff --git a/libgcc/configure b/libgcc/configure
index 80cbebbb426..75bf9034b1a 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >&6
fixed_point=$libgcc_cv_fixed_point
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+ cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+ eval `${CC-cc} -E conftest.c | grep host_address=`
+ rm -f conftest.c
+ ;;
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index e3eb80a2148..1238d742450 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is supported], [libgcc_cv_fixed_point],
fixed_point=$libgcc_cv_fixed_point
AC_SUBST(fixed_point)
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+ cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+ eval `${CC-cc} -E conftest.c | grep host_address=`
+ rm -f conftest.c
+ ;;
+esac
+
# Collect host-machine-specific information.
. ${srcdir}/config.host
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 6e3a729fc7a..c845606c803 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,32 @@
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36341
+ PR fortran/34670
+ * m4/matmul.m4: Add bounds checking.
+ * m4/matmull.m4: Likewise.
+ * generated/matmul_c10.c: Regenerated.
+ * generated/matmul_c16.c: Regenerated.
+ * generated/matmul_c4.c: Regenerated.
+ * generated/matmul_c8.c: Regenerated.
+ * generated/matmul_i1.c: Regenerated.
+ * generated/matmul_i16.c: Regenerated.
+ * generated/matmul_i2.c: Regenerated.
+ * generated/matmul_i4.c: Regenerated.
+ * generated/matmul_i8.c: Regenerated.
+ * generated/matmul_l16.c: Regenerated.
+ * generated/matmul_l4.c: Regenerated.
+ * generated/matmul_l8.c: Regenerated.
+ * generated/matmul_r10.c: Regenerated.
+ * generated/matmul_r16.c: Regenerated.
+ * generated/matmul_r4.c: Regenerated.
+ * generated/matmul_r8.c: Regenerated.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * acinclude.m4 (LIBGFOR_CHECK_GTHR_DEFAULT): Fix configure cache
+ variable name.
+ * configure: Regenerate.
+
2008-07-01 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/36676
diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
index d1994b49d90..9f8ae54fab6 100644
--- a/libgfortran/acinclude.m4
+++ b/libgfortran/acinclude.m4
@@ -86,10 +86,10 @@ if (foovar > 10) return __sync_add_and_fetch (&foovar, -1);],
dnl Check if threads are supported.
AC_DEFUN([LIBGFOR_CHECK_GTHR_DEFAULT], [
AC_CACHE_CHECK([configured target thread model],
- target_thread_file, [
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`])
+ libgfor_cv_target_thread_file, [
+libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`])
- if test $target_thread_file != single; then
+ if test $libgfor_cv_target_thread_file != single; then
AC_DEFINE(HAVE_GTHR_DEFAULT, 1,
[Define if the compiler has a thread header that is non single.])
fi])
diff --git a/libgfortran/configure b/libgfortran/configure
index 7f3b690f4b6..95a980d5e2c 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -33082,16 +33082,16 @@ _ACEOF
echo "$as_me:$LINENO: checking configured target thread model" >&5
echo $ECHO_N "checking configured target thread model... $ECHO_C" >&6
-if test "${target_thread_file+set}" = set; then
+if test "${libgfor_cv_target_thread_file+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
+libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
fi
-echo "$as_me:$LINENO: result: $target_thread_file" >&5
-echo "${ECHO_T}$target_thread_file" >&6
+echo "$as_me:$LINENO: result: $libgfor_cv_target_thread_file" >&5
+echo "${ECHO_T}$libgfor_cv_target_thread_file" >&6
- if test $target_thread_file != single; then
+ if test $libgfor_cv_target_thread_file != single; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_GTHR_DEFAULT 1
diff --git a/libgfortran/generated/matmul_c10.c b/libgfortran/generated/matmul_c10.c
index 08c2044dd8b..0e378626f96 100644
--- a/libgfortran/generated/matmul_c10.c
+++ b/libgfortran/generated/matmul_c10.c
@@ -135,6 +135,47 @@ matmul_c10 (gfc_array_c10 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_10) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c16.c b/libgfortran/generated/matmul_c16.c
index 6a2a6390967..34cc51dbd78 100644
--- a/libgfortran/generated/matmul_c16.c
+++ b/libgfortran/generated/matmul_c16.c
@@ -135,6 +135,47 @@ matmul_c16 (gfc_array_c16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c4.c b/libgfortran/generated/matmul_c4.c
index 6dcf6fea56a..fdfea1df955 100644
--- a/libgfortran/generated/matmul_c4.c
+++ b/libgfortran/generated/matmul_c4.c
@@ -135,6 +135,47 @@ matmul_c4 (gfc_array_c4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c8.c b/libgfortran/generated/matmul_c8.c
index 8bc619d879f..9d6694922f1 100644
--- a/libgfortran/generated/matmul_c8.c
+++ b/libgfortran/generated/matmul_c8.c
@@ -135,6 +135,47 @@ matmul_c8 (gfc_array_c8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i1.c b/libgfortran/generated/matmul_i1.c
index ca16ed40b2f..34fd7c51b78 100644
--- a/libgfortran/generated/matmul_i1.c
+++ b/libgfortran/generated/matmul_i1.c
@@ -135,6 +135,47 @@ matmul_i1 (gfc_array_i1 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_1) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i16.c b/libgfortran/generated/matmul_i16.c
index 33c62ae4152..0c7c5d8f396 100644
--- a/libgfortran/generated/matmul_i16.c
+++ b/libgfortran/generated/matmul_i16.c
@@ -135,6 +135,47 @@ matmul_i16 (gfc_array_i16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i2.c b/libgfortran/generated/matmul_i2.c
index e3119acbd41..5d55847edce 100644
--- a/libgfortran/generated/matmul_i2.c
+++ b/libgfortran/generated/matmul_i2.c
@@ -135,6 +135,47 @@ matmul_i2 (gfc_array_i2 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_2) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i4.c b/libgfortran/generated/matmul_i4.c
index a1b8c50f051..a80f14940c8 100644
--- a/libgfortran/generated/matmul_i4.c
+++ b/libgfortran/generated/matmul_i4.c
@@ -135,6 +135,47 @@ matmul_i4 (gfc_array_i4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i8.c b/libgfortran/generated/matmul_i8.c
index eee73ac88f0..91499c793e6 100644
--- a/libgfortran/generated/matmul_i8.c
+++ b/libgfortran/generated/matmul_i8.c
@@ -135,6 +135,47 @@ matmul_i8 (gfc_array_i8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_l16.c b/libgfortran/generated/matmul_l16.c
index b2b86ecfed1..b604edfb2ca 100644
--- a/libgfortran/generated/matmul_l16.c
+++ b/libgfortran/generated/matmul_l16.c
@@ -99,6 +99,47 @@ matmul_l16 (gfc_array_l16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_l4.c b/libgfortran/generated/matmul_l4.c
index 9a6cb1d357d..5aed0fe2ba0 100644
--- a/libgfortran/generated/matmul_l4.c
+++ b/libgfortran/generated/matmul_l4.c
@@ -99,6 +99,47 @@ matmul_l4 (gfc_array_l4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_l8.c b/libgfortran/generated/matmul_l8.c
index 7d4e35e82e3..26baad32136 100644
--- a/libgfortran/generated/matmul_l8.c
+++ b/libgfortran/generated/matmul_l8.c
@@ -99,6 +99,47 @@ matmul_l8 (gfc_array_l8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_r10.c b/libgfortran/generated/matmul_r10.c
index 58dfe75814f..931e2bdc0f0 100644
--- a/libgfortran/generated/matmul_r10.c
+++ b/libgfortran/generated/matmul_r10.c
@@ -135,6 +135,47 @@ matmul_r10 (gfc_array_r10 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_10) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r16.c b/libgfortran/generated/matmul_r16.c
index a6a93be91fb..16ec175be0c 100644
--- a/libgfortran/generated/matmul_r16.c
+++ b/libgfortran/generated/matmul_r16.c
@@ -135,6 +135,47 @@ matmul_r16 (gfc_array_r16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r4.c b/libgfortran/generated/matmul_r4.c
index 1154d41a33f..47d976415d0 100644
--- a/libgfortran/generated/matmul_r4.c
+++ b/libgfortran/generated/matmul_r4.c
@@ -135,6 +135,47 @@ matmul_r4 (gfc_array_r4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r8.c b/libgfortran/generated/matmul_r8.c
index 7bce2533b41..a359ffd8fd3 100644
--- a/libgfortran/generated/matmul_r8.c
+++ b/libgfortran/generated/matmul_r8.c
@@ -135,6 +135,47 @@ matmul_r8 (gfc_array_r8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/m4/matmul.m4 b/libgfortran/m4/matmul.m4
index 181efa3b654..a43b430c2e3 100644
--- a/libgfortran/m4/matmul.m4
+++ b/libgfortran/m4/matmul.m4
@@ -136,6 +136,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray,
= internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
'
sinclude(`matmul_asm_'rtype_code`.m4')dnl
`
diff --git a/libgfortran/m4/matmull.m4 b/libgfortran/m4/matmull.m4
index 54afa8a238e..800444564f7 100644
--- a/libgfortran/m4/matmull.m4
+++ b/libgfortran/m4/matmull.m4
@@ -100,6 +100,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray,
= internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index d0c1d068dbb..1caf0ef248b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,16 @@
+2008-07-08 Matthias Klose <doko@ubuntu.com>
+
+ * libtool-version: Bump soversion.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * gnu/gcj/convert/make-trie.h: New.
+ * gnu/gcj/convert/gen-from-JIS.c: Include it.
+ * gnu/gcj/convert/make-trie.c: Likewise.
+ Fix typos and compiler warnings, diagnose a missing argument.
+ * Makefile.am (gen_from_JIS_SOURCES): Add gnu/gcj/convert/make-trie.h.
+ * Makefile.in: Regenerate.
+
2008-06-30 Joshua Sumali <jsumali@redhat.com>
Andrew Haley <aph@redhat.com>
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index c074f5752a0..ce6dbd201f7 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -727,7 +727,8 @@ noinst_PROGRAMS = gen-from-JIS
gen_from_JIS_SOURCES = \
gnu/gcj/convert/gen-from-JIS.c \
- gnu/gcj/convert/make-trie.c
+ gnu/gcj/convert/make-trie.c \
+ gnu/gcj/convert/make-trie.h
gen_from_JIS_DEPENDENCIES = \
gnu/gcj/convert/JIS0201.h \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index ba487885efc..4aab2bcc835 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -471,7 +471,7 @@ gcj_dbtool_OBJECTS = $(am_gcj_dbtool_OBJECTS)
am_gcjh_OBJECTS =
gcjh_OBJECTS = $(am_gcjh_OBJECTS)
am__gen_from_JIS_SOURCES_DIST = gnu/gcj/convert/gen-from-JIS.c \
- gnu/gcj/convert/make-trie.c
+ gnu/gcj/convert/make-trie.c gnu/gcj/convert/make-trie.h
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@am_gen_from_JIS_OBJECTS = gnu/gcj/convert/gen-from-JIS.$(OBJEXT) \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.$(OBJEXT)
gen_from_JIS_OBJECTS = $(am_gen_from_JIS_OBJECTS)
@@ -8176,7 +8176,8 @@ extra_headers = java/lang/Object.h java/lang/Class.h
install_data_local_split = 50
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@gen_from_JIS_SOURCES = \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/gen-from-JIS.c \
-@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.c
+@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.c \
+@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.h
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@gen_from_JIS_DEPENDENCIES = \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/JIS0201.h \
diff --git a/libjava/gnu/gcj/convert/gen-from-JIS.c b/libjava/gnu/gcj/convert/gen-from-JIS.c
index 13745805ab8..d4cca14474e 100644
--- a/libjava/gnu/gcj/convert/gen-from-JIS.c
+++ b/libjava/gnu/gcj/convert/gen-from-JIS.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation
+/* Copyright (C) 1999, 2008 Free Software Foundation
This file is part of libgcj.
@@ -7,6 +7,10 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "make-trie.h"
+
struct chval
{
unsigned char b1; /* 1st byte */
@@ -59,6 +63,11 @@ main(int argc, char** argv)
int low1_uc = 0xFFFF, high1_uc = 0;
int low2_uc = 0xFFFF, high2_uc = 0;
int i; int row, col;
+ if (argc < 2)
+ {
+ fprintf (stderr, "missing argument!\n");
+ exit (-1);
+ }
if (strcmp (argv[1], "JIS0208") == 0)
chtab = chtab_0208;
else if (strcmp (argv[1], "JIS0212") == 0)
@@ -106,8 +115,7 @@ main(int argc, char** argv)
fprintf(out,"/* This file is automatically generated from %s.TXT. */\n",
argv[1]);
- fprintf(out,"#pragma GCC java_exceptions\n",
- argv[1]);
+ fprintf(out,"#pragma GCC java_exceptions\n");
fprintf(out, "unsigned short %s_to_Unicode[%d][%d] = {\n",
argv[1], max1 - min1 + 1, max2 - min2 + 1);
i = 0;
@@ -156,7 +164,7 @@ main(int argc, char** argv)
}
else
{
- fprintf (stderr, "error - char table our of order!\n");
+ fprintf (stderr, "error - char table out of order!\n");
exit (-1);
}
if (col != max2)
diff --git a/libjava/gnu/gcj/convert/make-trie.c b/libjava/gnu/gcj/convert/make-trie.c
index e89f70c5c9f..fe2d7892641 100644
--- a/libjava/gnu/gcj/convert/make-trie.c
+++ b/libjava/gnu/gcj/convert/make-trie.c
@@ -8,6 +8,7 @@ details. */
#include <stdio.h>
#include <stdlib.h>
+#include "make-trie.h"
typedef struct trie_node
{
diff --git a/libjava/libtool-version b/libjava/libtool-version
index 964dc4f4f01..db361f7b168 100644
--- a/libjava/libtool-version
+++ b/libjava/libtool-version
@@ -3,4 +3,4 @@
# a separate file so that version updates don't involve re-running
# automake.
# CURRENT:REVISION:AGE
-9:0:0
+10:0:0
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 44743b62b88..aabb9fd9eff 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in (install-info): New stub target.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure: Regenerate.
diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in
index ee9f6a1f3c5..f9538af5cda 100644
--- a/libobjc/Makefile.in
+++ b/libobjc/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Objective C runtime library.
# Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -270,9 +270,10 @@ exception_gc.lo: exception.c
doc: info dvi pdf html
# No install-html or install-pdf support
-.PHONY: install-html install-pdf
+.PHONY: install-html install-pdf install-info
install-html:
install-pdf:
+install-info:
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 42a56a22a93..da30a6a741e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,98 @@
+2008-07-08 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/type_traits: Add common_type.
+ * testsuite/20_util/common_type/requirements/
+ explicit_instantiation.cc: New.
+ * testsuite/20_util/common_type/requirements/
+ typedefs-1.cc: Likewise.
+
+2008-07-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/lib/libstdc++.exp (check_v3_target_stdint): New.
+ * testsuite/lib/dg-options.exp (dg-require-cstdint): New.
+ * testsuite/20_util/ratio/cons/cons1.cc: Use it.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops1.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops2.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops3.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp2.cc: Likewise.
+
+ * include/std/type_traits: Fix comment typo.
+
+2008-07-06 Roger Sayle <roger@eyesopen.com>
+
+ * include/std/system_error (is_error_code_enum): Use identifier
+ _Tp instead of _T to avoid conflict with system macro on Darwin.
+ (is_error_condition_enum): Likewise.
+
+2008-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/postypes.h: Do not include <stdint.h>.
+
+ * include/Makefile.am: Reorder.
+
+2008-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/std/ratio: Prefer __INTMAX_MAX__ to INTMAX_MAX (INTMAX_MIN).
+
+2008-07-05 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/ratio: Documentation for std::ratio class. Add conditions
+ to ratio_less to prevent overflow.
+ * testsuite/20_util/ratio/comparisons/comp2.cc: New.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Update dg-error line
+ numbers.
+
+2008-07-04 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/ratio: New, per N2661.
+ * include/Makefile.am: Update.
+ * include/Makefile.in: Regenerate.
+ * testsuite/20_util/ratio/cons/cons1.cc: New.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops1.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops2.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops3.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise.
+
+2008-07-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/36616
+ * testsuite/22_locale/time_put/put/char/4.cc: Just use es_ES instead.
+ * testsuite/22_locale/time_put/put/wchar_t/4.cc: Likewise.
+
+2008-07-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc:
+ Improve check on long double limits.
+ * testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc:
+ Likewise.
+ * testsuite/21_strings/basic_string/numeric_conversions/wchar_t/
+ stof.cc: Likewise.
+ * testsuite/21_strings/basic_string/numeric_conversions/wchar_t/
+ stod.cc: Likewise.
+
+2008-07-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * libsupc++/Makefile.am: Add initializer_list to the headers.
+ * libsupc++/Makefile.in: Regenerate.
+
+ * libsupc++/initializer_list: Minor cosmetic changes.
+
+2008-07-02 Jason Merrill <jason@redhat.com>
+
+ * libsupc++/initializer_list: Uglify and wrap in
+ __GXX_EXPERIMENTAL_CXX0X__.
+ * include/bits/stl_map.h (insert(initializer_list)): Wrap.
+
+2008-07-02 Jason Merrill <jason@redhat.com>
+
+ * libsupc++/initializer_list: New file.
+ * include/bits/stl_map.h (insert(initializer_list)): New method.
+
2008-06-30 Alfred E. Heggestad <aeh@db.org>
* include/backward/backward_warning.h: Fix typo.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index a8f48c7d282..89ac735b218 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -54,6 +54,7 @@ std_headers = \
${std_srcdir}/ostream \
${std_srcdir}/queue \
${std_srcdir}/random \
+ ${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/set \
${std_srcdir}/sstream \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ebd37c9020e..91374605548 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -310,6 +310,7 @@ std_headers = \
${std_srcdir}/ostream \
${std_srcdir}/queue \
${std_srcdir}/random \
+ ${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/set \
${std_srcdir}/sstream \
diff --git a/libstdc++-v3/include/bits/postypes.h b/libstdc++-v3/include/bits/postypes.h
index 2870a8e59a1..5ead488fa48 100644
--- a/libstdc++-v3/include/bits/postypes.h
+++ b/libstdc++-v3/include/bits/postypes.h
@@ -46,10 +46,6 @@
#include <cwchar> // For mbstate_t
-#ifdef _GLIBCXX_HAVE_STDINT_H
-#include <stdint.h> // For int64_t
-#endif
-
_GLIBCXX_BEGIN_NAMESPACE(std)
// The types streamoff, streampos and wstreampos and the class
@@ -68,7 +64,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* was typedef long.
*/
#ifdef _GLIBCXX_HAVE_INT64_T
- typedef int64_t streamoff;
+# if (__CHAR_BIT__ * __SIZEOF_LONG__ == 64)
+ typedef long streamoff;
+# else
+ typedef long long streamoff;
+# endif
#else
typedef long long streamoff;
#endif
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index a9486708ffe..cd85b9ab75d 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -64,6 +64,7 @@
#include <bits/functexcept.h>
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -468,6 +469,20 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
insert(const value_type& __x)
{ return _M_t._M_insert_unique(__x); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Attempts to insert a list of std::pairs into the %map.
+ * @param list A std::initializer_list<value_type> of pairs to be
+ * inserted.
+ *
+ * Complexity similar to that of the range constructor.
+ *
+ */
+ void
+ insert(std::initializer_list<value_type> __list)
+ { insert (__list.begin(), __list.end()); }
+#endif
+
/**
* @brief Attempts to insert a std::pair into the %map.
* @param position An iterator that serves as a hint as to where the
diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio
new file mode 100644
index 00000000000..9980571f160
--- /dev/null
+++ b/libstdc++-v3/include/std/ratio
@@ -0,0 +1,288 @@
+// <ratio> -*- C++ -*-
+
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file ratio
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_RATIO
+#define _GLIBCXX_RATIO 1
+
+#pragma GCC system_header
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#else
+
+#include <type_traits>
+#include <cstdint>
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+namespace std
+{
+ template<intmax_t _Pn>
+ struct __static_sign
+ : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
+ { };
+
+ template<intmax_t _Pn>
+ struct __static_abs
+ : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __static_gcd;
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __static_gcd
+ : __static_gcd<_Qn, (_Pn % _Qn)>
+ { };
+
+ template<intmax_t _Pn>
+ struct __static_gcd<_Pn, 0>
+ : integral_constant<intmax_t, __static_abs<_Pn>::value>
+ { };
+
+ template<intmax_t _Qn>
+ struct __static_gcd<0, _Qn>
+ : integral_constant<intmax_t, __static_abs<_Qn>::value>
+ { };
+
+ // Let c = 2^(half # of bits in an intmax_t)
+ // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
+ // The multiplication of N and M becomes,
+ // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
+ // Multiplication is safe if each term and the sum of the terms
+ // is representable by intmax_t.
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __safe_multiply
+ {
+ private:
+ static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
+
+ static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
+ static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
+ static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
+ static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
+
+ static_assert(__a1 == 0 || __b1 == 0,
+ "overflow in multiplication");
+ static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1),
+ "overflow in multiplication");
+ static_assert(__b0 * __a0 <= __INTMAX_MAX__,
+ "overflow in multiplication");
+ static_assert((__a0 * __b1 + __b0 * __a1) * __c <=
+ __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication");
+
+ public:
+ static const intmax_t value = _Pn * _Qn;
+ };
+
+ // Helpers for __safe_add
+ template<intmax_t _Pn, intmax_t _Qn, bool>
+ struct __add_overflow_check_impl
+ : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __add_overflow_check_impl<_Pn, _Qn, false>
+ : integral_constant<bool, (_Pn >= -__INTMAX_MAX__ - _Qn)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __add_overflow_check
+ : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __safe_add
+ {
+ static_assert(__add_overflow_check<_Pn, _Qn>::value != 0,
+ "overflow in addition");
+
+ static const intmax_t value = _Pn + _Qn;
+ };
+
+ /**
+ * @brief Provides compile-time rational arithmetic.
+ *
+ * This class template represents any finite rational number with a
+ * numerator and denominator representable by compile-time constants of
+ * type intmax_t. The ratio is simplified when instantiated.
+ *
+ * For example:
+ * @code
+ * std::ratio<7,-21>::num == -1;
+ * std::ratio<7,-21>::den == 3;
+ * @endcode
+ *
+ */
+ template<intmax_t _Num, intmax_t _Den = 1>
+ struct ratio
+ {
+ static_assert(_Den != 0, "denominator cannot be zero");
+ static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
+ "out of range");
+
+ // Note: sign(N) * abs(N) == N
+ static const intmax_t num =
+ _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
+
+ static const intmax_t den =
+ __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
+ };
+
+ template<intmax_t _Num, intmax_t _Den>
+ const intmax_t ratio<_Num, _Den>::num;
+
+ template<intmax_t _Num, intmax_t _Den>
+ const intmax_t ratio<_Num, _Den>::den;
+
+ template<typename _R1, typename _R2>
+ struct ratio_add
+ {
+ private:
+ static const intmax_t __gcd =
+ __static_gcd<_R1::den, _R2::den>::value;
+
+ public:
+ typedef ratio<
+ __safe_add<
+ __safe_multiply<_R1::num, (_R2::den / __gcd)>::value,
+ __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value,
+ __safe_multiply<_R1::den, (_R2::den / __gcd)>::value> type;
+ };
+
+ template<typename _R1, typename _R2>
+ struct ratio_subtract
+ {
+ typedef typename ratio_add<
+ _R1,
+ ratio<-_R2::num, _R2::den>>::type type;
+ };
+
+ template<typename _R1, typename _R2>
+ struct ratio_multiply
+ {
+ private:
+ static const intmax_t __gcd1 =
+ __static_gcd<_R1::num, _R2::den>::value;
+ static const intmax_t __gcd2 =
+ __static_gcd<_R2::num, _R1::den>::value;
+
+ public:
+ typedef ratio<
+ __safe_multiply<(_R1::num / __gcd1),
+ (_R2::num / __gcd2)>::value,
+ __safe_multiply<(_R1::den / __gcd2),
+ (_R2::den / __gcd1)>::value> type;
+ };
+
+ template<typename _R1, typename _R2>
+ struct ratio_divide
+ {
+ static_assert(_R2::num != 0, "division by 0");
+
+ typedef typename ratio_multiply<
+ _R1,
+ ratio<_R2::den, _R2::num>>::type type;
+ };
+
+ template<typename _R1, typename _R2>
+ struct ratio_equal
+ : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
+ { };
+
+ template<typename _R1, typename _R2>
+ struct ratio_not_equal
+ : integral_constant<bool, !ratio_equal<_R1, _R2>::value>
+ { };
+
+ template<typename _R1, typename _R2>
+ struct __ratio_less_simple_impl
+ : integral_constant<bool,
+ (__safe_multiply<_R1::num, _R2::den>::value
+ < __safe_multiply<_R2::num, _R1::den>::value)>
+ { };
+
+ // If the denominators are equal or the signs differ, we can just compare
+ // numerators, otherwise fallback to the simple cross-multiply method.
+ template<typename _R1, typename _R2>
+ struct __ratio_less_impl
+ : conditional<(_R1::den == _R2::den
+ || (__static_sign<_R1::num>::value
+ != __static_sign<_R2::num>::value)),
+ integral_constant<bool, (_R1::num < _R2::num)>,
+ __ratio_less_simple_impl<_R1, _R2>>::type
+ { };
+
+ template<typename _R1, typename _R2>
+ struct ratio_less
+ : __ratio_less_impl<_R1, _R2>::type
+ { };
+
+ template<typename _R1, typename _R2>
+ struct ratio_less_equal
+ : integral_constant<bool, !ratio_less<_R2, _R1>::value>
+ { };
+
+ template<typename _R1, typename _R2>
+ struct ratio_greater
+ : integral_constant<bool, ratio_less<_R2, _R1>::value>
+ { };
+
+ template<typename _R1, typename _R2>
+ struct ratio_greater_equal
+ : integral_constant<bool, !ratio_less<_R1, _R2>::value>
+ { };
+
+ typedef ratio<1, 1000000000000000000> atto;
+ typedef ratio<1, 1000000000000000> femto;
+ typedef ratio<1, 1000000000000> pico;
+ typedef ratio<1, 1000000000> nano;
+ typedef ratio<1, 1000000> micro;
+ typedef ratio<1, 1000> milli;
+ typedef ratio<1, 100> centi;
+ typedef ratio<1, 10> deci;
+ typedef ratio< 10, 1> deca;
+ typedef ratio< 100, 1> hecto;
+ typedef ratio< 1000, 1> kilo;
+ typedef ratio< 1000000, 1> mega;
+ typedef ratio< 1000000000, 1> giga;
+ typedef ratio< 1000000000000, 1> tera;
+ typedef ratio< 1000000000000000, 1> peta;
+ typedef ratio< 1000000000000000000, 1> exa;
+}
+
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+#endif //__GXX_EXPERIMENTAL_CXX0X__
+
+#endif //_GLIBCXX_RATIO
diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index 343eb6e83f7..b0585810663 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
class system_error;
/// is_error_code_enum
- template<typename _T>
+ template<typename _Tp>
struct is_error_code_enum : public false_type { };
template<>
@@ -61,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: public true_type { };
/// is_error_condition_enum
- template<typename _T>
+ template<typename _Tp>
struct is_error_condition_enum : public false_type { };
template<>
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 5fdc95ecad9..1a759187955 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -203,13 +203,13 @@ namespace std
: public integral_constant<bool, __has_trivial_destructor(_Tp)>
{ };
- /// has_nothrow_default_destructor
+ /// has_nothrow_default_constructor
template<typename _Tp>
struct has_nothrow_default_constructor
: public integral_constant<bool, __has_nothrow_constructor(_Tp)>
{ };
- /// has_nothrow_copy_destructor
+ /// has_nothrow_copy_constructor
template<typename _Tp>
struct has_nothrow_copy_constructor
: public integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -551,6 +551,41 @@ namespace std
// Integral, but don't define.
template<>
struct make_signed<bool>;
+
+ template<typename... _Tp>
+ struct common_type;
+
+ template<typename _Tp>
+ struct common_type<_Tp>
+ {
+ static_assert(sizeof(_Tp) > 0, "must be complete type");
+ typedef _Tp type;
+ };
+
+ template<typename _Tp, typename _Up>
+ class common_type<_Tp, _Up>
+ {
+ static_assert(sizeof(_Tp) > 0, "must be complete type");
+ static_assert(sizeof(_Up) > 0, "must be complete type");
+
+ static _Tp&& __t();
+ static _Up&& __u();
+
+ // HACK: Prevents optimization of ?: in the decltype
+ // expression when the condition is the literal, "true".
+ // See, PR36628.
+ static bool __true_or_false();
+
+ public:
+ typedef decltype(__true_or_false() ? __t() : __u()) type;
+ };
+
+ template<typename _Tp, typename _Up, typename... _Vp>
+ struct common_type<_Tp, _Up, _Vp...>
+ {
+ typedef typename
+ common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
+ };
}
#endif // __GXX_EXPERIMENTAL_CXX0X__
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index 366efa27428..c0412f0b8ed 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -1,6 +1,6 @@
## Makefile for the GNU C++ Support library.
##
-## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
+## Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
## Free Software Foundation, Inc.
##
## Process this file with automake to produce Makefile.in.
@@ -33,7 +33,8 @@ noinst_LTLIBRARIES = libsupc++convenience.la
headers = \
- exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h
+ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
+ initializer_list
if GLIBCXX_HOSTED
c_sources = \
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index c484bd5e082..a1cc257f807 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -357,7 +357,8 @@ toolexeclib_LTLIBRARIES = libsupc++.la
# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
noinst_LTLIBRARIES = libsupc++convenience.la
headers = \
- exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h
+ exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
+ initializer_list
@GLIBCXX_HOSTED_TRUE@c_sources = \
@GLIBCXX_HOSTED_TRUE@ cp-demangle.c
diff --git a/libstdc++-v3/libsupc++/initializer_list b/libstdc++-v3/libsupc++/initializer_list
new file mode 100644
index 00000000000..18fb15bc552
--- /dev/null
+++ b/libstdc++-v3/libsupc++/initializer_list
@@ -0,0 +1,72 @@
+// std::initializer_list support -*- C++ -*-
+
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#ifndef __CXX_INITIALIZER_LIST
+#define __CXX_INITIALIZER_LIST
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+#pragma GCC visibility push(default)
+
+#include <cstddef>
+
+namespace std
+{
+ template<class _E>
+ class initializer_list
+ {
+ const _E* __array;
+ size_t __len;
+
+ // The compiler can call a private constructor.
+ initializer_list(const _E* __a, size_t __l)
+ : __array(__a), __len(__l) { }
+
+ public:
+ initializer_list()
+ : __array(NULL), __len(0) { }
+
+ // Number of elements.
+ size_t size() const
+ { return __len; }
+
+ // First element.
+ const _E* begin() const
+ { return __array; }
+
+ // One past the last element.
+ const _E* end() const
+ { return begin() + size(); }
+ };
+}
+
+#pragma GCC visibility pop
+#endif // C++0x
+#endif // __CXX_INITIALIZER_LIST
diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc
new file mode 100644
index 00000000000..fcc5b2adf30
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+ typedef int test_type1;
+ typedef int& test_type2;
+ typedef double test_type3;
+ typedef float test_type4;
+
+ template struct common_type<test_type1>;
+ template struct common_type<test_type1, test_type2>;
+ template struct common_type<test_type1, test_type2, test_type3>;
+ template struct common_type<test_type1, test_type2, test_type3, test_type4>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc
new file mode 100644
index 00000000000..e4152e51d31
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc
@@ -0,0 +1,118 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2008 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+#define JOIN( X, Y ) DO_JOIN( X, Y )
+#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
+#define DO_JOIN2( X, Y ) X##Y
+
+#define COMMON_TYPE_TEST_1(type1, uid) \
+ typedef common_type<type1>::type JOIN(test_t,uid); \
+ VERIFY( (is_same<JOIN(test_t,uid), JOIN(test_t,uid)>::value) ); \
+ typedef common_type<const type1>::type JOIN(test_t,JOIN(uid,c)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,c)), \
+ JOIN(test_t,JOIN(uid,c))>::value) ); \
+ typedef common_type<volatile type1>::type JOIN(test_t,JOIN(uid,v)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,v)), \
+ JOIN(test_t,JOIN(uid,v))>::value) ); \
+ typedef common_type<const volatile type1>::type JOIN(test_t,JOIN(uid,cv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,cv)), \
+ JOIN(test_t,JOIN(uid,cv))>::value) ); \
+ typedef common_type<type1 &>::type JOIN(test_t,JOIN(uid,l)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,l)), \
+ JOIN(test_t,JOIN(uid,l))>::value) ); \
+ typedef common_type<const type1 &>::type JOIN(test_t,JOIN(uid,lc)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lc)), \
+ JOIN(test_t,JOIN(uid,lc))>::value) ); \
+ typedef common_type<volatile type1 &>::type JOIN(test_t,JOIN(uid,lv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lv)), \
+ JOIN(test_t,JOIN(uid,lv))>::value) ); \
+ typedef common_type<const volatile type1 &>::type JOIN(test_t,JOIN(uid,lcv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lcv)), \
+ JOIN(test_t,JOIN(uid,lcv))>::value) ); \
+ typedef common_type<type1 &&>::type JOIN(test_t,JOIN(uid,r)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,r)), \
+ JOIN(test_t,JOIN(uid,r))>::value) ); \
+ typedef common_type<const type1 &&>::type JOIN(test_t,JOIN(uid,rc)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rc)), \
+ JOIN(test_t,JOIN(uid,rc))>::value) ); \
+ typedef common_type<volatile type1 &&>::type JOIN(test_t,JOIN(uid,rv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rv)), \
+ JOIN(test_t,JOIN(uid,rv))>::value) ); \
+ typedef common_type<const volatile type1 &&>::type JOIN(test_t,JOIN(uid,rcv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rcv)), \
+ JOIN(test_t,JOIN(uid,rcv))>::value) )
+
+struct A { };
+struct B : A { };
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ using std::common_type;
+ using std::is_same;
+
+ // Positive tests.
+ COMMON_TYPE_TEST_1(int, 1);
+ COMMON_TYPE_TEST_1(double, 2);
+ COMMON_TYPE_TEST_1(A, 3);
+ COMMON_TYPE_TEST_1(B, 4);
+}
+
+#define COMMON_TYPE_TEST_2_IMPL(type1, type2, type3, uid) \
+ typedef common_type<type1, type2>::type JOIN(JOIN(test, uid),_t1); \
+ typedef common_type<type2, type1>::type JOIN(JOIN(test, uid),_t2); \
+ VERIFY( (is_same<JOIN(JOIN(test, uid),_t1), type3>::value) ); \
+ VERIFY( (is_same<JOIN(JOIN(test, uid),_t2), type3>::value) )
+
+#define NO_CV
+
+#define COMMON_TYPE_TEST_2(cv_qual, type1, type2, type3, uid) \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &, type2, type3, JOIN(uid,l)); \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &&, type2, type3, JOIN(uid,r))
+
+#define COMMON_TYPE_TEST_ALL_2(type1, type2, type3, uid) \
+ COMMON_TYPE_TEST_2(NO_CV, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(const, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(volatile, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(const volatile, type1, type2, type3, uid)
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ using std::common_type;
+ using std::is_same;
+
+ COMMON_TYPE_TEST_ALL_2(int, int, int, 1);
+ COMMON_TYPE_TEST_ALL_2(int, double, double, 2);
+ COMMON_TYPE_TEST_2(NO_CV, A, A, A, 3);
+ COMMON_TYPE_TEST_2(const, A, A, const A, 4);
+ COMMON_TYPE_TEST_2(NO_CV, B, A, A, 5);
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc
new file mode 100644
index 00000000000..c916b309998
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,3>>::value == 1 ));
+ VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,4>>::value == 0 ));
+
+ VERIFY( (std::ratio_not_equal<std::ratio<2,6>,
+ std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_not_equal<std::ratio<2,6>,
+ std::ratio<1,4>>::value == 1) );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY( (std::ratio_less<std::ratio<1,4>, std::ratio<1,3>>::value == 1) );
+ VERIFY( (std::ratio_less<std::ratio<-1,3>, std::ratio<1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<1,4>>::value == 0) );
+ VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<-1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_less_equal<std::ratio<-1,3>,
+ std::ratio<-1,3>>::value == 1) );
+ VERIFY( ( std::ratio_less_equal<std::ratio<1,4>,
+ std::ratio<1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_less_equal<std::ratio<1,4>,
+ std::ratio<-1,3>>::value == 0) );
+ VERIFY( (std::ratio_less_equal<std::ratio<1,3>,
+ std::ratio<-1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<1,4>>::value == 1) );
+ VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<-1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_greater<std::ratio<1,4>, std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_greater<std::ratio<-1,3>, std::ratio<1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,3>,
+ std::ratio<1,3>>::value == 1) );
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,3>,
+ std::ratio<-1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_greater_equal<std::ratio<-1,3>,
+ std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,4>,
+ std::ratio<1,3>>::value == 0) );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc
new file mode 100644
index 00000000000..56052e45328
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+static const std::intmax_t M = INTMAX_MAX;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ // No overflow with same denominator
+ VERIFY( (std::ratio_less<std::ratio<M - 2, M>,
+ std::ratio<M - 1, M>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<M - 1, M>,
+ std::ratio<M - 2, M>>::value == 0) );
+
+ // No overflow if signs differ
+ VERIFY( (std::ratio_less<std::ratio<-M, M - 1>,
+ std::ratio<M - 1, M - 2>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>,
+ std::ratio<-M, M - 1>>::value == 0) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc
new file mode 100644
index 00000000000..84860699ac8
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio<1,3> r0;
+ std::ratio<2,6> r1;
+ std::ratio<2,-6> r2;
+ std::ratio<-2,6> r3;
+
+ VERIFY( r0.num == 1 );
+ VERIFY( r0.den == 3 );
+
+ VERIFY( r1.num == r0.num );
+ VERIFY( r1.den == r0.den );
+ VERIFY( r2.num == -r0.num );
+ VERIFY( r2.den == r0.den );
+ VERIFY( r3.num == -r0.num );
+ VERIFY( r3.den == r0.den );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc
new file mode 100644
index 00000000000..570ea6cbc7d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc
@@ -0,0 +1,55 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+
+void
+test01()
+{
+ std::ratio<INTMAX_MAX, INTMAX_MAX> r1;
+ std::ratio<-INTMAX_MAX, INTMAX_MAX> r2;
+}
+
+void
+test02()
+{
+ std::ratio<INTMAX_MIN, 1> r1;
+}
+
+void
+test03()
+{
+ std::ratio<1, INTMAX_MIN> r1;
+}
+
+void
+test04()
+{
+ std::ratio<1,0> r1;
+}
+
+// { dg-error "instantiated from here" "" { target *-*-* } 35 }
+// { dg-error "instantiated from here" "" { target *-*-* } 41 }
+// { dg-error "instantiated from here" "" { target *-*-* } 47 }
+// { dg-error "denominator cannot be zero" "" { target *-*-* } 150 }
+// { dg-error "out of range" "" { target *-*-* } 151 }
+// { dg-excess-errors "In instantiation of" }
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc
new file mode 100644
index 00000000000..b05092dd8e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc
@@ -0,0 +1,75 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_add<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 19 );
+ VERIFY( r.den == 24 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_subtract<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == -1 );
+ VERIFY( r.den == 24 );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_multiply<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 5 );
+ VERIFY( r.den == 32 );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_divide<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 9 );
+ VERIFY( r.den == 10 );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc
new file mode 100644
index 00000000000..3d3241f3128
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc
@@ -0,0 +1,73 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+typedef std::ratio<1, INTMAX_MAX> one_over_max;
+typedef std::ratio<2, INTMAX_MAX> two_over_max;
+typedef std::ratio<INTMAX_MAX, 1> max_over_one;
+typedef std::ratio<INTMAX_MAX, 2> max_over_two;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_add<one_over_max, one_over_max>::type r1;
+
+ VERIFY( r1.num == two_over_max::num);
+ VERIFY( r1.den == two_over_max::den);
+
+ std::ratio_add<
+ std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>,
+ std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX );
+ VERIFY( r2.den == (INTMAX_MAX / 2) + 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_subtract<one_over_max, one_over_max>::type r1;
+
+ VERIFY( r1.num == 0);
+ VERIFY( r1.den == 1);
+
+ std::ratio_subtract<
+ std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>,
+ std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2;
+
+ VERIFY( r2.num == 1 );
+ VERIFY( r2.den == (INTMAX_MAX / 2) + 1 );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc
new file mode 100644
index 00000000000..2008275a216
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_multiply<
+ std::ratio<2, INTMAX_MAX>,
+ std::ratio<INTMAX_MAX, 2>>::type r1;
+
+ VERIFY( r1.num == 1 );
+ VERIFY( r1.den == 1 );
+
+ std::ratio_multiply<
+ std::ratio<INTMAX_MAX, 2>,
+ std::ratio<2 , INTMAX_MAX - 1>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX );
+ VERIFY( r2.den == INTMAX_MAX - 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_divide<
+ std::ratio<INTMAX_MAX, 2>,
+ std::ratio<INTMAX_MAX, 2>>::type r1;
+
+ VERIFY( r1.num == 1 );
+ VERIFY( r1.den == 1 );
+
+ std::ratio_divide<
+ std::ratio<INTMAX_MAX-1, 2>,
+ std::ratio<INTMAX_MAX, 2>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX - 1 );
+ VERIFY( r2.den == INTMAX_MAX );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc
new file mode 100644
index 00000000000..860f9f253b2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc
@@ -0,0 +1,48 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+
+void
+test01()
+{
+ std::ratio_add<std::ratio<INTMAX_MAX, 1>, std::ratio<1>>::type r1;
+}
+
+void
+test02()
+{
+ std::ratio_multiply<std::ratio<-INTMAX_MAX, 2>, std::ratio<3, 2>>::type r1;
+ std::ratio_multiply<std::ratio<INTMAX_MAX>, std::ratio<INTMAX_MAX>>::type r2;
+}
+
+// { dg-error "instantiated from here" "" { target *-*-* } 30 }
+// { dg-error "instantiated from here" "" { target *-*-* } 36 }
+// { dg-error "instantiated from here" "" { target *-*-* } 37 }
+// { dg-error "overflow in addition" "" { target *-*-* } 127 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 95 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 97 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 99 }
+// { dg-excess-errors "In instantiation of" }
+// { dg-excess-errors "out of range" }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
index f26a865684d..765c5a210ec 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stod.cc
@@ -107,7 +107,8 @@ test01()
}
VERIFY( test );
- if (sizeof(double) < sizeof(long double))
+ if ((numeric_limits<long double>::max() / 10000.0L)
+ > numeric_limits<double>::max())
{
test = false;
d1 = -1.0;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc
index 515769e18f7..5645c0af9b8 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc
@@ -107,7 +107,8 @@ test01()
}
VERIFY( test );
- if (sizeof(float) < sizeof(long double))
+ if ((numeric_limits<long double>::max() / 10000.0L)
+ > numeric_limits<float>::max())
{
test = false;
f1 = -1.0f;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
index c1ebbb228d9..e494f4282ba 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stod.cc
@@ -107,7 +107,8 @@ test01()
}
VERIFY( test );
- if (sizeof(double) < sizeof(long double))
+ if ((numeric_limits<long double>::max() / 10000.0L)
+ > numeric_limits<double>::max())
{
test = false;
d1 = -1.0;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc
index 6f443c8bf97..a6319f8e31e 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/numeric_conversions/wchar_t/stof.cc
@@ -107,7 +107,8 @@ test01()
}
VERIFY( test );
- if (sizeof(float) < sizeof(long double))
+ if ((numeric_limits<long double>::max() / 10000.0L)
+ > numeric_limits<float>::max())
{
test = false;
f1 = -1.0f;
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
index 2fb6cf6ae74..c28738d742b 100644
--- a/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
@@ -39,30 +39,22 @@ void test04()
// basic construction and sanity check
locale loc_c = locale::classic();
- locale loc_fr = locale("fr_FR@euro");
- VERIFY( loc_fr != loc_c );
+ locale loc_es = locale("es_ES");
+ VERIFY( loc_es != loc_c );
// create an ostream-derived object, cache the time_put facet
const string empty;
ostringstream oss;
- oss.imbue(loc_fr);
+ oss.imbue(loc_es);
const time_put<char>& tim_put = use_facet<time_put<char> >(oss.getloc());
iterator_type os_it04 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'a');
string result4 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result4 == "dim." );
-#else
- VERIFY( result4 == "dim" );
-#endif
+ VERIFY( result4 == "dom" );
- oss.str(empty); // "%d.%m.%Y"
+ oss.str(empty); // "%d/%m/%y"
iterator_type os_it27 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'x');
- string result27 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result27 == "04/04/1971" );
-#else
- VERIFY( result27 == "04.04.1971" );
-#endif
+ string result27 = oss.str(); // "04/04/71"
+ VERIFY( result27 == "04/04/71" );
oss.str(empty); // "%T"
iterator_type os_it28 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'X');
@@ -71,12 +63,8 @@ void test04()
oss.str(empty);
iterator_type os_it37 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'x', 'E');
- string result37 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result37 == "04/04/1971" );
-#else
- VERIFY( result37 == "04.04.1971" );
-#endif
+ string result37 = oss.str(); // "04/04/71"
+ VERIFY( result37 == "04/04/71" );
oss.str(empty);
iterator_type os_it38 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'X', 'E');
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
index 09920521945..c3d312da7d7 100644
--- a/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
@@ -39,30 +39,22 @@ void test04()
// basic construction and sanity check
locale loc_c = locale::classic();
- locale loc_fr = locale("fr_FR@euro");
- VERIFY( loc_fr != loc_c );
+ locale loc_es = locale("es_ES");
+ VERIFY( loc_es != loc_c );
// create an ostream-derived object, cache the time_put facet
const wstring empty;
wostringstream oss;
- oss.imbue(loc_fr);
+ oss.imbue(loc_es);
const time_put<wchar_t>& tim_put = use_facet<time_put<wchar_t> >(oss.getloc());
iterator_type os_it04 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'a');
wstring result4 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result4 == L"dim." );
-#else
- VERIFY( result4 == L"dim" );
-#endif
+ VERIFY( result4 == L"dom" );
- oss.str(empty); // "%d.%m.%Y"
+ oss.str(empty); // "%d/%m/%y"
iterator_type os_it27 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'x');
- wstring result27 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result27 == L"04/04/1971" );
-#else
- VERIFY( result27 == L"04.04.1971" );
-#endif
+ wstring result27 = oss.str(); // "04/04/71"
+ VERIFY( result27 == L"04/04/71" );
oss.str(empty); // "%T"
iterator_type os_it28 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'X');
@@ -71,12 +63,8 @@ void test04()
oss.str(empty);
iterator_type os_it37 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'x', 'E');
- wstring result37 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result37 == L"04/04/1971" );
-#else
- VERIFY( result37 == L"04.04.1971" );
-#endif
+ wstring result37 = oss.str(); // "04/04/71"
+ VERIFY( result37 == L"04/04/71" );
oss.str(empty);
iterator_type os_it38 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'X', 'E');
diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp
index 327b691fc0f..e2d22ae598b 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -88,3 +88,12 @@ proc dg-require-rvalref { args } {
}
return
}
+
+proc dg-require-cstdint { args } {
+ if { ![ check_v3_target_cstdint ] } {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ return
+ }
+ return
+}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index d6b372b80ef..d8c168defac 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1,6 +1,6 @@
# libstdc++ "tool init file" for DejaGNU
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
@@ -939,7 +939,7 @@ proc check_v3_target_debug_mode { } {
} else {
set et_debug_mode 0
- # Set up, compile, and execute a C++ test program that depends
+ # Set up and compile a C++ test program that depends
# on debug mode working.
set src debug_mode[pid].cc
set exe debug_mode[pid].exe
@@ -993,7 +993,7 @@ proc check_v3_target_parallel_mode { } {
} else {
set et_parallel_mode 0
- # Set up, compile, and execute a C++ test program that depends
+ # Set up and compile a C++ test program that depends
# on parallel mode working.
set src parallel_mode[pid].cc
set exe parallel_mode[pid].exe
@@ -1021,3 +1021,61 @@ proc check_v3_target_parallel_mode { } {
verbose "check_v3_target_parallel_mode: $et_parallel_mode" 2
return $et_parallel_mode
}
+
+proc check_v3_target_cstdint { } {
+ global cxxflags
+ global DEFAULT_CXXFLAGS
+ global et_cstdint
+
+ global tool
+
+ if { ![info exists et_cstdint_target_name] } {
+ set et_cstdint_target_name ""
+ }
+
+ # If the target has changed since we set the cached value, clear it.
+ set current_target [current_target_name]
+ if { $current_target != $et_cstdint_target_name } {
+ verbose "check_v3_target_cstdint: `$et_cstdint_target_name'" 2
+ set et_cstdint_target_name $current_target
+ if [info exists et_cstdint] {
+ verbose "check_v3_target_cstdint: removing cached result" 2
+ unset et_cstdint
+ }
+ }
+
+ if [info exists et_cstdint] {
+ verbose "check_v3_target_cstdint: using cached result" 2
+ } else {
+ set et_cstdint 0
+
+ # Set up and compile a C++0x test program that depends
+ # on the C99 stdint facilities to be available.
+ set src cstdint[pid].cc
+ set exe cstdint[pid].exe
+
+ set f [open $src "w"]
+ puts $f "#include <cstdint>"
+ puts $f "int main()"
+ puts $f "#ifdef _GLIBCXX_USE_C99_STDINT_TR1"
+ puts $f "{ return 0; }"
+ puts $f "#endif"
+ close $f
+
+ set cxxflags_saved $cxxflags
+ set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -std=gnu++0x -Werror"
+
+ set lines [v3_target_compile $src $exe executable ""]
+ set cxxflags $cxxflags_saved
+ file delete $src
+
+ if [string match "" $lines] {
+ # No error message, compilation succeeded.
+ set et_cstdint 1
+ } else {
+ verbose "check_v3_target_cstdint: compilation failed" 2
+ }
+ }
+ verbose "check_v3_target_cstdint: $et_cstdint" 2
+ return $et_cstdint
+}
diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog
index aaa34965ac9..f246a012cf5 100644
--- a/maintainer-scripts/ChangeLog
+++ b/maintainer-scripts/ChangeLog
@@ -1,3 +1,13 @@
+2008-07-04 Joseph Myers <joseph@codesourcery.com>
+
+ * crontab: Remove 4.1 snapshots job.
+ * update_version: Remove.
+ * gcc_release: Remove support for g77 and release status in
+ version.c.
+ * update_version_svn: Ignore 4.1 branch. Remove support for
+ updating files other than DATESTAMP.
+ * update_web_docs_svn: Remove support for g77 manual.
+
2008-02-18 Jakub Jelinek <jakub@redhat.com>
* crontab: Add 4.3 branch. Set trunk to 4.4.
diff --git a/maintainer-scripts/crontab b/maintainer-scripts/crontab
index 6ccf62db2ae..091c24d8249 100644
--- a/maintainer-scripts/crontab
+++ b/maintainer-scripts/crontab
@@ -1,7 +1,6 @@
16 0 * * * sh /home/gccadmin/scripts/update_version_svn
50 0 * * * sh /home/gccadmin/scripts/update_web_docs_svn
55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx_svn
-32 22 * * 1 sh /home/gccadmin/scripts/gcc_release -s 4.1:branches/gcc-4_1-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 3 sh /home/gccadmin/scripts/gcc_release -s 4.2:branches/gcc-4_2-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 4 sh /home/gccadmin/scripts/gcc_release -s 4.3:branches/gcc-4_3-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 5 sh /home/gccadmin/scripts/gcc_release -s 4.4:trunk -l -d /sourceware/snapshot-tmp/gcc all
diff --git a/maintainer-scripts/gcc_release b/maintainer-scripts/gcc_release
index bacb25b0ceb..467ec4e4aca 100755
--- a/maintainer-scripts/gcc_release
+++ b/maintainer-scripts/gcc_release
@@ -139,25 +139,14 @@ EOF
fi
done
- # Update gcc/DEV-PHASE if it exists, otherwise gcc/version.c.
-
- if [ -f ${SOURCE_DIRECTORY}/gcc/DEV-PHASE ]; then
- [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` = ${RELEASE} ] || \
- error "Release number ${RELEASE} does not match BASE-VER"
- (changedir ${SOURCE_DIRECTORY}/gcc && \
- : > DEV-PHASE && \
- ${SVN} -q ci -m 'Mark as release' DEV-PHASE) || \
- error "Could not update DEV-PHASE"
- else
- for x in gcc/version.c; do
- y=`basename ${x}`
- (changedir `dirname ${SOURCE_DIRECTORY}/${x}` && \
- sed -e 's|version_string\[\] = \".*\"|version_string\[\] = \"'${RELEASE}'\"|g' < ${y} > ${y}.new && \
- mv ${y}.new ${y} && \
- ${SVN} -q ci -m 'Update version' ${y}) || \
- error "Could not update ${x}"
- done
- fi
+ # Update gcc/DEV-PHASE.
+
+ [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` = ${RELEASE} ] || \
+ error "Release number ${RELEASE} does not match BASE-VER"
+ (changedir ${SOURCE_DIRECTORY}/gcc && \
+ : > DEV-PHASE && \
+ ${SVN} -q ci -m 'Mark as release' DEV-PHASE) || \
+ error "Could not update DEV-PHASE"
# Make sure we tag the sources for a final release.
TAG="tags/gcc_`echo ${RELEASE} | tr . _`_release"
@@ -297,7 +286,6 @@ build_tarfiles() {
# Now, build one for each of the languages.
maybe_build_tarfile gcc-ada-${RELEASE} ${ADA_DIRS}
maybe_build_tarfile gcc-g++-${RELEASE} ${CPLUSPLUS_DIRS}
- maybe_build_tarfile gcc-g77-${RELEASE} ${FORTRAN_DIRS}
maybe_build_tarfile gcc-fortran-${RELEASE} ${FORTRAN95_DIRS}
maybe_build_tarfile gcc-java-${RELEASE} ${JAVA_DIRS}
maybe_build_tarfile gcc-objc-${RELEASE} ${OBJECTIVEC_DIRS}
@@ -305,7 +293,7 @@ build_tarfiles() {
# The core is everything else.
EXCLUDES=""
- for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN_DIRS} ${FORTRAN95_DIRS}\
+ for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN95_DIRS}\
${JAVA_DIRS} ${OBJECTIVEC_DIRS} ${TESTSUITE_DIRS}; do
EXCLUDES="${EXCLUDES} --exclude $x"
done
@@ -328,7 +316,7 @@ build_diffs() {
old_vers=${old_file%.tar.bz2}
old_vers=${old_vers#gcc-}
inform "Building diffs against version $old_vers"
- for f in gcc gcc-ada gcc-g++ gcc-g77 gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do
+ for f in gcc gcc-ada gcc-g++ gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do
old_tar=${old_dir}/${f}-${old_vers}.tar.bz2
new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.bz2
if [ ! -e $old_tar ]; then
@@ -453,7 +441,6 @@ with the following options: <code>"svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revisi
snapshot_print gcc-ada-${RELEASE}.tar.bz2 "Ada front end and runtime"
snapshot_print gcc-fortran-${RELEASE}.tar.bz2 "Fortran front end and runtime"
snapshot_print gcc-g++-${RELEASE}.tar.bz2 "C++ front end and runtime"
- snapshot_print gcc-g77-${RELEASE}.tar.bz2 "Fortran 77 front end and runtime"
snapshot_print gcc-java-${RELEASE}.tar.bz2 "Java front end and runtime"
snapshot_print gcc-objc-${RELEASE}.tar.bz2 "Objective-C front end and runtime"
snapshot_print gcc-testsuite-${RELEASE}.tar.bz2 "The GCC testsuite"
@@ -560,7 +547,6 @@ SOURCE_DIRECTORY=""
# tar files. These are all relative to the top of the source tree.
ADA_DIRS="gcc/ada libada gnattools"
CPLUSPLUS_DIRS="gcc/cp libstdc++-v3"
-FORTRAN_DIRS="gcc/f libf2c"
FORTRAN95_DIRS="gcc/fortran libgfortran"
JAVA_DIRS="gcc/java libjava libffi fastjar zlib boehm-gc"
OBJECTIVEC_DIRS="gcc/objc gcc/objcp libobjc"
@@ -707,7 +693,6 @@ SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}"
# relative to the WORKING_DIRECTORY.
ADA_DIRS=`adjust_dirs ${ADA_DIRS}`
CPLUSPLUS_DIRS=`adjust_dirs ${CPLUSPLUS_DIRS}`
-FORTRAN_DIRS=`adjust_dirs ${FORTRAN_DIRS}`
FORTRAN95_DIRS=`adjust_dirs ${FORTRAN95_DIRS}`
JAVA_DIRS=`adjust_dirs ${JAVA_DIRS}`
OBJECTIVEC_DIRS=`adjust_dirs ${OBJECTIVEC_DIRS}`
diff --git a/maintainer-scripts/update_version b/maintainer-scripts/update_version
deleted file mode 100755
index 2217052332c..00000000000
--- a/maintainer-scripts/update_version
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/sh
-#
-# Update the current version date in all files in the tree containing
-# it. Consider all release branches except those matching the regular
-# expression in $IGNORE_BRANCHES, and also consider those branches listed
-# in $ADD_BRANCHES.
-
-CVSROOT=${CVSROOT:-/cvs/gcc}
-IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3)-branch'
-ADD_BRANCHES='HEAD autovect-branch dfp-branch'
-
-# Run this from /tmp.
-export CVSROOT
-/bin/rm -rf /tmp/$$
-/bin/mkdir /tmp/$$
-cd /tmp/$$
-
-# The path to cvs.
-CVS=${CVS:-/usr/local/bin/cvs}
-
-# Compute the branches which we should update.
-$CVS co gcc/ChangeLog
-BRANCHES=`$CVS status -v gcc/ChangeLog \
- | awk '{print $1;}' \
- | egrep 'gcc-[0-9]+_[0-9]+-branch$' \
- | egrep -v $IGNORE_BRANCHES`
-# Always update the mainline.
-BRANCHES="${BRANCHES} ${ADD_BRANCHES}"
-
-# ARGS is passed to 'cvs co'
-CURR_DATE=`/bin/date +"%Y%m%d"`
-
-# version is contained within a char*
-textstring_FILES="gcc/gcc/version.c"
-
-# version is contained within a #define
-cppdefine_FILES="gcc/libstdc++-v3/include/bits/c++config"
-
-# version is all there is
-datestamp_FILES="gcc/gcc/DATESTAMP"
-
-FILES="$textstring_FILES $cppdefine_FILES $datestamp_FILES"
-
-# Assume all will go well.
-RESULT=0
-
-for BRANCH in $BRANCHES; do
- echo "Working on \"$BRANCH\"."
- # Check out the files on the branch. HEAD is a special case; if
- # you check out files with -r HEAD, CVS will not let you check
- # in changes.
- if test "$BRANCH" = HEAD; then
- ${CVS} co $FILES
- else
- ${CVS} co -r $BRANCH $FILES
- fi
-
- # There are no files to commit yet.
- COMMIT_FILES=""
-
- for file in $textstring_FILES; do
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(.*\"[^ ]*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $cppdefine_FILES; do
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(#.*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $datestamp_FILES; do
- if test -f $file; then
- echo ${CURR_DATE} > $file.new
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- if test -n "$COMMIT_FILES" \
- && ! ${CVS} commit -m "Daily bump." $COMMIT_FILES; then
- # If we could not commit the files, indicate failure.
- RESULT=1
- fi
-
- # Remove the files.
- rm -rf gcc
-done
-
-/bin/rm -rf /tmp/$$
-exit $RESULT
diff --git a/maintainer-scripts/update_version_svn b/maintainer-scripts/update_version_svn
index ba47687cd4f..1c87f1c50e9 100755
--- a/maintainer-scripts/update_version_svn
+++ b/maintainer-scripts/update_version_svn
@@ -6,7 +6,7 @@
# in $ADD_BRANCHES.
SVNROOT=${SVNROOT:-"file:///svn/gcc"}
-IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3|3_4|4_0)-branch'
+IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3|3_4|4_0|4_1)-branch'
ADD_BRANCHES='HEAD autovect-branch'
# Run this from /tmp.
@@ -29,17 +29,10 @@ BRANCHES="${BRANCHES} ${ADD_BRANCHES}"
# ARGS is passed to 'cvs co'
CURR_DATE=`/bin/date +"%Y%m%d"`
-# version is contained within a char*
-textstring_FILES="gcc/version.c"
-
-# version is contained within a #define
-cppdefine_FILES="libstdc++-v3/include/bits/c++config"
-
# version is all there is
datestamp_FILES="gcc/DATESTAMP"
-FILES="$textstring_FILES $cppdefine_FILES $datestamp_FILES"
-DIRS="$textstring_DIRS $cppdefine_DIRS $datestamp_DIRS"
+FILES="$datestamp_FILES"
# Assume all will go well.
RESULT=0
@@ -60,40 +53,6 @@ for BRANCH in $BRANCHES; do
# There are no files to commit yet.
COMMIT_FILES=""
-
- for file in $textstring_FILES; do
- dirname=`basename $file`
- file=`basename $file`
- file="$dirname/$file"
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(.*\"[^ ]*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $cppdefine_FILES; do
- dirname=`basename $file`
- file=`basename $file`
- file="$dirname/$file"
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(#.*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
for file in $datestamp_FILES; do
dirname=`basename $file`
diff --git a/maintainer-scripts/update_web_docs_svn b/maintainer-scripts/update_web_docs_svn
index 0fa9992b399..74098b4ac4d 100755
--- a/maintainer-scripts/update_web_docs_svn
+++ b/maintainer-scripts/update_web_docs_svn
@@ -17,7 +17,6 @@ MANUALS="cpp
gcc
gccint
gcj
- g77
gfortran
gfc-internals
gnat_ug_unx