From eb4a8628c92f7bc6e2987f98db938f50b8be95f5 Mon Sep 17 00:00:00 2001 From: hjl Date: Thu, 29 Apr 2010 17:35:42 +0000 Subject: [PATCH] Merged r158704 through r158906 into branch. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/ifunc@158907 138bc75d-0d04-0410-961f-82ee72b054a4 --- ChangeLog | 19 + Makefile.def | 1 + Makefile.in | 1 + configure | 255 +-- configure.ac | 96 +- gcc/ChangeLog | 630 ++++++- gcc/DATESTAMP | 2 +- gcc/Makefile.in | 11 + gcc/ada/ChangeLog | 5 + gcc/ada/gcc-interface/trans.c | 12 +- gcc/c-common.c | 6 +- gcc/c-common.h | 6 +- gcc/c-cppbuiltin.c | 13 + gcc/c-omp.c | 14 +- gcc/c-opts.c | 26 + gcc/c-parser.c | 4 +- gcc/c-tree.h | 16 +- gcc/c-typeck.c | 62 +- gcc/c.opt | 8 + gcc/cfgloop.h | 6 +- gcc/cgraph.c | 360 +++- gcc/cgraph.h | 153 +- gcc/cgraphunit.c | 110 +- gcc/cif-code.def | 4 + gcc/collect2.c | 22 +- gcc/common.opt | 18 +- gcc/config.gcc | 4 + gcc/config.in | 6 + gcc/config/alpha/elf.h | 42 +- gcc/config/alpha/osf5.h | 8 + gcc/config/arm/arm.c | 53 +- gcc/config/arm/unknown-elf.h | 6 +- gcc/config/i386/cygming.h | 5 + gcc/config/i386/darwin.h | 1 + gcc/config/i386/i386.c | 17 +- gcc/config/i386/i386.h | 9 +- gcc/config/i386/mingw-w64.h | 17 +- gcc/config/i386/mingw32.h | 22 +- gcc/config/i386/t-cygming | 2 +- gcc/config/i386/winnt.c | 15 +- gcc/config/mmix/mmix.md | 4 +- gcc/configure | 94 +- gcc/configure.ac | 53 +- gcc/cp/ChangeLog | 75 + gcc/cp/call.c | 10 +- gcc/cp/class.c | 69 +- gcc/cp/cp-tree.h | 7 +- gcc/cp/decl.c | 32 +- gcc/cp/error.c | 89 +- gcc/cp/init.c | 8 + gcc/cp/name-lookup.c | 4 + gcc/cp/search.c | 1 + gcc/cp/semantics.c | 122 +- gcc/cp/tree.c | 32 +- gcc/df-problems.c | 12 +- gcc/doc/cpp.texi | 3 +- gcc/doc/cppopts.texi | 7 + gcc/doc/extend.texi | 16 +- gcc/doc/gimple.texi | 33 +- gcc/doc/invoke.texi | 51 +- gcc/doc/standards.texi | 11 +- gcc/dwarf2out.c | 5 +- gcc/final.c | 7 +- gcc/fortran/ChangeLog | 24 + gcc/fortran/gfc-internals.texi | 2 +- gcc/fortran/gfortran.texi | 2 +- gcc/fortran/invoke.texi | 2 +- gcc/fortran/resolve.c | 4 +- gcc/fortran/simplify.c | 7 + gcc/fortran/trans-array.c | 92 +- gcc/fortran/trans-stmt.c | 2 +- gcc/fortran/trans-types.c | 26 +- gcc/fortran/trans-types.h | 2 +- gcc/function.c | 2 - gcc/function.h | 15 - gcc/fwprop.c | 5 +- gcc/gimple.c | 3 +- gcc/gimplify.c | 84 +- gcc/ginclude/float.h | 39 + gcc/ifcvt.c | 2 +- gcc/ipa-cp.c | 7 +- gcc/ipa-inline.c | 10 +- gcc/ipa-prop.c | 245 ++- gcc/ipa-prop.h | 52 +- gcc/ipa-pure-const.c | 191 ++- gcc/ipa-reference.c | 3 +- gcc/ipa.c | 275 ++- gcc/lto-cgraph.c | 211 ++- gcc/lto-section-in.c | 2 + gcc/lto-streamer-in.c | 26 +- gcc/lto-streamer-out.c | 94 +- gcc/lto-streamer.c | 64 +- gcc/lto-streamer.h | 7 +- gcc/lto-symtab.c | 36 +- gcc/lto/ChangeLog | 59 + gcc/lto/Make-lang.in | 7 +- gcc/lto/lto-coff.c | 845 ++++++++++ gcc/lto/lto-coff.h | 406 +++++ gcc/lto/lto-elf.c | 16 +- gcc/lto/lto-lang.c | 6 +- gcc/lto/lto.c | 316 ++-- gcc/lto/lto.h | 14 +- gcc/opts.c | 1 + gcc/passes.c | 53 +- gcc/plugin.c | 15 +- gcc/plugin.h | 27 +- gcc/po/ChangeLog | 4 + gcc/po/sv.po | 1659 +++++------------- gcc/predict.c | 50 +- gcc/testsuite/ChangeLog | 291 ++++ gcc/testsuite/g++.dg/cpp0x/defaulted2.C | 4 +- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C | 7 + gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C | 13 + gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C | 17 + gcc/testsuite/g++.dg/cpp0x/pr42844-2.C | 38 + gcc/testsuite/g++.dg/init/pr29043.C | 52 + gcc/testsuite/g++.dg/init/pr42844.C | 56 + gcc/testsuite/g++.dg/ipa/pr43812.C | 38 + gcc/testsuite/g++.dg/lookup/scoped5.C | 4 +- gcc/testsuite/g++.dg/lookup/scoped8.C | 2 +- gcc/testsuite/g++.dg/lto/20100423-2_0.C | 14 + gcc/testsuite/g++.dg/lto/20100423-3_0.C | 14 + gcc/testsuite/g++.dg/other/pr40561.C | 38 + gcc/testsuite/g++.dg/template/dependent-expr5.C | 6 +- gcc/testsuite/g++.dg/template/pr23510.C | 2 +- gcc/testsuite/g++.dg/template/recurse.C | 3 +- gcc/testsuite/g++.dg/template/recurse2.C | 1 + gcc/testsuite/g++.dg/template/sfinae17.C | 28 + gcc/testsuite/g++.dg/template/sfinae18.C | 10 + gcc/testsuite/g++.dg/torture/pr43880.C | 16 + gcc/testsuite/g++.dg/tree-ssa/pr27549.C | 1 + gcc/testsuite/g++.dg/uninit-pred-1_a.C | 63 + gcc/testsuite/g++.dg/uninit-pred-1_b.C | 63 + gcc/testsuite/g++.dg/uninit-pred-2_a.C | 62 + gcc/testsuite/g++.dg/uninit-pred-2_b.C | 62 + gcc/testsuite/g++.dg/uninit-pred-loop-1_a.cc | 21 + gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc | 21 + gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc | 23 + gcc/testsuite/g++.dg/uninit-pred-loop_1.cc | 21 + gcc/testsuite/g++.dg/warn/string1.C | 2 +- gcc/testsuite/g++.old-deja/g++.brendan/nest1.C | 2 +- gcc/testsuite/g++.old-deja/g++.mike/dyncast8.C | 6 +- gcc/testsuite/gcc.dg/Walways-true-1.c | 16 +- gcc/testsuite/gcc.dg/Walways-true-2.c | 8 +- gcc/testsuite/gcc.dg/Warray-bounds-8.c | 20 + .../gcc.dg/{c99-float-1.c => c1x-float-1.c} | 44 +- gcc/testsuite/gcc.dg/c90-float-1.c | 40 +- gcc/testsuite/gcc.dg/c99-float-1.c | 38 +- gcc/testsuite/gcc.dg/const-1.c | 57 + gcc/testsuite/gcc.dg/const-uniq-1.c | 19 + gcc/testsuite/gcc.dg/ipa/iinline-1.c | 4 +- gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c | 4 +- gcc/testsuite/gcc.dg/lto/20091209-1_0.c | 23 + gcc/testsuite/gcc.dg/lto/20100426_0.c | 7 + gcc/testsuite/gcc.dg/lto/const-uniq_0.c | 16 + gcc/testsuite/gcc.dg/lto/const-uniq_1.c | 23 + gcc/testsuite/gcc.dg/misc-column.c | 2 +- gcc/testsuite/gcc.dg/plugin/plugin.exp | 12 + gcc/testsuite/gcc.dg/{ => plugin}/plugindir1.c | 0 gcc/testsuite/gcc.dg/{ => plugin}/plugindir2.c | 0 gcc/testsuite/gcc.dg/{ => plugin}/plugindir3.c | 0 gcc/testsuite/gcc.dg/{ => plugin}/plugindir4.c | 0 gcc/testsuite/gcc.dg/pr32207.c | 9 + gcc/testsuite/gcc.dg/pure-2.c | 57 + gcc/testsuite/gcc.dg/tree-ssa/tailcall-6.c | 33 + gcc/testsuite/gcc.dg/uninit-11.c | 4 +- gcc/testsuite/gcc.dg/uninit-5.c | 4 +- gcc/testsuite/gcc.dg/uninit-pred-2_a.c | 28 + gcc/testsuite/gcc.dg/uninit-pred-2_b.c | 29 + gcc/testsuite/gcc.dg/uninit-pred-2_c.c | 48 + gcc/testsuite/gcc.dg/uninit-pred-3_a.c | 28 + gcc/testsuite/gcc.dg/uninit-pred-3_b.c | 33 + gcc/testsuite/gcc.dg/uninit-pred-3_c.c | 28 + gcc/testsuite/gcc.dg/uninit-pred-3_d.c | 28 + gcc/testsuite/gcc.dg/uninit-pred-3_e.c | 28 + gcc/testsuite/gcc.dg/uninit-pred-4_a.c | 43 + gcc/testsuite/gcc.dg/uninit-pred-4_b.c | 40 + gcc/testsuite/gcc.dg/uninit-pred-5_a.c | 41 + gcc/testsuite/gcc.dg/uninit-pred-5_b.c | 41 + gcc/testsuite/gcc.dg/uninit-pred-6_a.c | 40 + gcc/testsuite/gcc.dg/uninit-pred-6_b.c | 46 + gcc/testsuite/gcc.dg/uninit-pred-6_c.c | 46 + gcc/testsuite/gcc.dg/uninit-pred-6_d.c | 24 + gcc/testsuite/gcc.dg/uninit-pred-6_e.c | 43 + gcc/testsuite/gcc.dg/uninit-pred-7_a.c | 54 + gcc/testsuite/gcc.dg/uninit-pred-7_b.c | 23 + gcc/testsuite/gcc.dg/uninit-pred-7_c.c | 33 + gcc/testsuite/gcc.dg/uninit-pred-8_a.c | 45 + gcc/testsuite/gcc.dg/uninit-pred-8_b.c | 45 + gcc/testsuite/gcc.dg/uninit-pred-8_c.c | 39 + gcc/testsuite/gcc.dg/uninit-pred-9_a.c | 23 + gcc/testsuite/gcc.dg/uninit-pred-9_b.c | 44 + gcc/testsuite/gcc.dg/vect/bb-slp-23.c | 54 + gcc/testsuite/gcc.dg/warn-addr-cmp.c | 16 +- gcc/testsuite/gcc.target/arm/thumb-stackframe.c | 13 + gcc/testsuite/gcc.target/i386/pr43766.c | 2 +- gcc/testsuite/gfortran.dg/assignment_2.f90 | 1 + gcc/testsuite/gfortran.dg/coarray_11.f90 | 8 + gcc/testsuite/gfortran.dg/coarray_12.f90 | 77 + gcc/testsuite/gfortran.dg/coarray_7.f90 | 27 +- gcc/testsuite/gfortran.dg/default_format_2.f90 | 2 +- .../gfortran.dg/default_format_denormal_1.f90 | 2 +- .../gfortran.dg/default_format_denormal_2.f90 | 2 +- .../gfortran.dg/elemental_args_check_2.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/id-18.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/id-2.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/id-4.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr37980.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr38953.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr40982.f90 | 2 + gcc/testsuite/gfortran.dg/graphite/pr41924.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42050.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42180.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42181.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42185.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42186.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42393-1.f90 | 1 + gcc/testsuite/gfortran.dg/graphite/pr42393.f90 | 1 + .../gfortran.dg/host_assoc_blockdata_1.f90 | 1 + .../gfortran.dg/host_assoc_blockdata_2.f90 | 1 + gcc/testsuite/gfortran.dg/intent_out_3.f90 | 1 + gcc/testsuite/gfortran.dg/internal_pack_4.f90 | 1 + gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 | 1 + gcc/testsuite/gfortran.dg/pr41347.f90 | 1 + gcc/testsuite/gfortran.dg/pr41928.f90 | 1 + gcc/testsuite/gfortran.dg/pr42166.f90 | 1 + gcc/testsuite/gfortran.dg/pr43505.f90 | 1 + gcc/testsuite/gfortran.dg/private_type_11.f90 | 1 + gcc/testsuite/gfortran.dg/private_type_12.f90 | 1 + gcc/testsuite/gfortran.dg/proc_decl_23.f90 | 1 + gcc/testsuite/gfortran.dg/recursive_check_3.f90 | 1 + .../gfortran.dg/redefined_intrinsic_assignment.f90 | 1 + gcc/testsuite/gfortran.dg/select_type_4.f90 | 1 + .../gfortran.dg/vect/fast-math-real8-pr40801.f90 | 1 + gcc/testsuite/gfortran.dg/vect/vect-gems.f90 | 1 + .../gfortran.dg/where_operator_assign_4.f90 | 1 + gcc/testsuite/gfortran.dg/whole_file_11.f90 | 2 + gcc/testsuite/lib/dg-pch.exp | 20 +- gcc/testsuite/lib/lto.exp | 17 + gcc/testsuite/lib/objc-torture.exp | 65 +- gcc/testsuite/lib/plugin-support.exp | 4 + gcc/testsuite/lib/prune.exp | 2 +- gcc/testsuite/obj-c++.dg/stubify-1.mm | 6 +- gcc/testsuite/obj-c++.dg/stubify-2.mm | 8 +- gcc/testsuite/objc.dg/next-runtime-1.m | 3 +- gcc/testsuite/objc.dg/pch/pch.exp | 17 +- gcc/testsuite/objc.dg/stret-2.m | 1 + gcc/testsuite/objc.dg/stubify-1.m | 3 +- gcc/testsuite/objc.dg/stubify-2.m | 7 +- gcc/testsuite/objc.dg/symtab-1.m | 4 +- gcc/timevar.def | 2 + gcc/tlink.c | 4 + gcc/tree-flow.h | 2 + gcc/tree-inline.c | 119 +- gcc/tree-pass.h | 11 +- gcc/tree-ssa-loop-ivopts.c | 11 +- gcc/tree-ssa-structalias.c | 309 ++-- gcc/tree-ssa-uninit.c | 1762 ++++++++++++++++++++ gcc/tree-ssa.c | 89 +- gcc/tree-vect-data-refs.c | 91 +- gcc/tree-vect-slp.c | 13 + gcc/tree-vect-stmts.c | 16 +- gcc/tree-vectorizer.h | 54 +- gcc/tree-vrp.c | 48 +- gcc/tree.c | 7 +- gcc/tree.h | 266 +-- gcc/unwind-dw2.c | 3 +- gcc/varasm.c | 210 ++- gcc/varpool.c | 99 +- include/ChangeLog | 9 +- include/filenames.h | 2 - libcpp/ChangeLog | 7 + libcpp/include/cpplib.h | 3 +- libcpp/init.c | 5 + libgomp/ChangeLog | 6 + libgomp/testsuite/libgomp.c++/pr43893.C | 125 ++ libgomp/testsuite/libgomp.c/pr43893.c | 61 + libjava/classpath/ChangeLog | 15 + .../gnu/javax/print/ipp/IppPrintService.java | 11 +- .../classpath/gnu/javax/print/ipp/IppRequest.java | 8 + .../classpath/gnu/javax/print/ipp/IppResponse.java | 11 +- .../java/util/concurrent/CopyOnWriteArrayList.java | 7 +- .../lib/gnu/javax/print/ipp/IppPrintService.class | Bin 20186 -> 20439 bytes .../javax/print/ipp/IppRequest$RequestWriter.class | Bin 9227 -> 9426 bytes .../lib/gnu/javax/print/ipp/IppRequest.class | Bin 8604 -> 8604 bytes .../print/ipp/IppResponse$ResponseReader.class | Bin 13156 -> 13186 bytes .../lib/gnu/javax/print/ipp/IppResponse.class | Bin 2476 -> 2476 bytes .../util/concurrent/CopyOnWriteArrayList$1.class | Bin 2314 -> 2314 bytes .../util/concurrent/CopyOnWriteArrayList$2.class | Bin 1350 -> 1350 bytes .../util/concurrent/CopyOnWriteArrayList$3.class | Bin 2115 -> 2115 bytes .../CopyOnWriteArrayList$RandomAccessSubList.class | Bin 1081 -> 1081 bytes .../concurrent/CopyOnWriteArrayList$SubList.class | Bin 4878 -> 4878 bytes .../util/concurrent/CopyOnWriteArrayList.class | Bin 11229 -> 11264 bytes libstdc++-v3/ChangeLog | 36 + libstdc++-v3/doc/html/api.html | 2 +- libstdc++-v3/doc/html/faq.html | 2 +- libstdc++-v3/doc/html/manual/abi.html | 20 +- libstdc++-v3/doc/html/manual/algorithms.html | 2 +- libstdc++-v3/doc/html/manual/api.html | 4 +- .../doc/html/manual/appendix_contributing.html | 2 +- libstdc++-v3/doc/html/manual/appendix_free.html | 2 +- libstdc++-v3/doc/html/manual/appendix_gpl.html | 4 +- libstdc++-v3/doc/html/manual/appendix_porting.html | 2 +- libstdc++-v3/doc/html/manual/atomics.html | 2 +- libstdc++-v3/doc/html/manual/backwards.html | 48 +- libstdc++-v3/doc/html/manual/bitmap_allocator.html | 2 +- libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html | 4 +- libstdc++-v3/doc/html/manual/bk01pt03ch18s03.html | 2 +- libstdc++-v3/doc/html/manual/bk01pt03ch19s02.html | 2 +- libstdc++-v3/doc/html/manual/bk01pt03ch19s07.html | 2 +- libstdc++-v3/doc/html/manual/bk01pt03pr01.html | 2 +- libstdc++-v3/doc/html/manual/concurrency.html | 2 +- libstdc++-v3/doc/html/manual/containers.html | 2 +- libstdc++-v3/doc/html/manual/diagnostics.html | 2 +- .../doc/html/manual/documentation_style.html | 8 +- libstdc++-v3/doc/html/manual/extensions.html | 2 +- libstdc++-v3/doc/html/manual/facets.html | 54 +- libstdc++-v3/doc/html/manual/intro.html | 2 +- libstdc++-v3/doc/html/manual/io.html | 2 +- libstdc++-v3/doc/html/manual/iterators.html | 2 +- libstdc++-v3/doc/html/manual/localization.html | 16 +- libstdc++-v3/doc/html/manual/memory.html | 42 +- libstdc++-v3/doc/html/manual/numerics.html | 2 +- libstdc++-v3/doc/html/manual/parallel_mode.html | 4 +- libstdc++-v3/doc/html/manual/profile_mode.html | 2 +- libstdc++-v3/doc/html/manual/spine.html | 4 +- libstdc++-v3/doc/html/manual/status.html | 42 +- libstdc++-v3/doc/html/manual/strings.html | 2 +- libstdc++-v3/doc/html/manual/support.html | 2 +- libstdc++-v3/doc/html/manual/test.html | 2 +- libstdc++-v3/doc/html/manual/using.html | 2 +- libstdc++-v3/doc/html/manual/using_exceptions.html | 16 +- libstdc++-v3/doc/html/manual/using_headers.html | 12 +- libstdc++-v3/doc/html/manual/utilities.html | 2 +- libstdc++-v3/doc/xml/manual/status_cxx200x.xml | 692 ++++---- libstdc++-v3/include/c_global/cstdlib | 4 +- libstdc++-v3/src/future.cc | 4 +- libstdc++-v3/src/system_error.cc | 4 + .../testsuite/22_locale/codecvt/unshift/char/1.cc | 6 +- libstdc++-v3/testsuite/util/testsuite_error.h | 6 +- 340 files changed, 11336 insertions(+), 3716 deletions(-) create mode 100644 gcc/lto/lto-coff.c create mode 100644 gcc/lto/lto-coff.h create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr42844-2.C create mode 100644 gcc/testsuite/g++.dg/init/pr29043.C create mode 100644 gcc/testsuite/g++.dg/init/pr42844.C create mode 100644 gcc/testsuite/g++.dg/ipa/pr43812.C create mode 100644 gcc/testsuite/g++.dg/lto/20100423-2_0.C create mode 100644 gcc/testsuite/g++.dg/lto/20100423-3_0.C create mode 100644 gcc/testsuite/g++.dg/other/pr40561.C create mode 100644 gcc/testsuite/g++.dg/template/sfinae17.C create mode 100644 gcc/testsuite/g++.dg/template/sfinae18.C create mode 100644 gcc/testsuite/g++.dg/torture/pr43880.C create mode 100644 gcc/testsuite/g++.dg/uninit-pred-1_a.C create mode 100644 gcc/testsuite/g++.dg/uninit-pred-1_b.C create mode 100644 gcc/testsuite/g++.dg/uninit-pred-2_a.C create mode 100644 gcc/testsuite/g++.dg/uninit-pred-2_b.C create mode 100644 gcc/testsuite/g++.dg/uninit-pred-loop-1_a.cc create mode 100644 gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc create mode 100644 gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc create mode 100644 gcc/testsuite/g++.dg/uninit-pred-loop_1.cc create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-8.c copy gcc/testsuite/gcc.dg/{c99-float-1.c => c1x-float-1.c} (71%) create mode 100644 gcc/testsuite/gcc.dg/const-1.c create mode 100644 gcc/testsuite/gcc.dg/const-uniq-1.c create mode 100644 gcc/testsuite/gcc.dg/lto/20091209-1_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/20100426_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/const-uniq_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/const-uniq_1.c rename gcc/testsuite/gcc.dg/{ => plugin}/plugindir1.c (100%) rename gcc/testsuite/gcc.dg/{ => plugin}/plugindir2.c (100%) rename gcc/testsuite/gcc.dg/{ => plugin}/plugindir3.c (100%) rename gcc/testsuite/gcc.dg/{ => plugin}/plugindir4.c (100%) create mode 100644 gcc/testsuite/gcc.dg/pr32207.c create mode 100644 gcc/testsuite/gcc.dg/pure-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-6.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-2_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-2_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-2_c.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-3_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-3_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-3_c.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-3_d.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-3_e.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-4_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-4_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-5_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-5_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-6_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-6_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-6_c.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-6_d.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-6_e.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-7_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-7_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-7_c.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-8_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-8_b.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-8_c.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-9_a.c create mode 100644 gcc/testsuite/gcc.dg/uninit-pred-9_b.c create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-23.c create mode 100644 gcc/testsuite/gcc.target/arm/thumb-stackframe.c create mode 100644 gcc/testsuite/gfortran.dg/coarray_12.f90 create mode 100644 gcc/tree-ssa-uninit.c create mode 100644 libgomp/testsuite/libgomp.c++/pr43893.C create mode 100644 libgomp/testsuite/libgomp.c/pr43893.c rewrite libjava/classpath/lib/gnu/javax/print/ipp/IppPrintService.class (63%) diff --git a/ChangeLog b/ChangeLog index 8a1a4c71668..64b2de3354d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-04-27 Roland McGrath + H.J. Lu + + * configure.ac (--enable-gold): Support both, both/gold and + both/bfd to add gold to configdirs without removing ld. + * configure: Regenerated. + + * Makefile.def: Add install-gold dependency to install-ld. + * Makefile.in: Regenerated. + +2010-04-27 Dave Korn + + PR lto/42776 + * configure.ac (--enable-lto): Refactor handling so libelf tests + are only performed inside then-clause of ACX_ELF_TARGET_IFELSE, + and allow LTO to be explicitly enabled on non-ELF platforms that + are known to support it inside else-clause. + * configure: Regenerate. + 2010-04-20 Eric Botcazou * configure.ac (BUILD_CONFIG): Redirect output to /dev/null. diff --git a/Makefile.def b/Makefile.def index 7dce69994cf..325d845f3a5 100644 --- a/Makefile.def +++ b/Makefile.def @@ -425,6 +425,7 @@ dependencies = { module=all-ld; on=all-build-bison; }; dependencies = { module=all-ld; on=all-build-byacc; }; dependencies = { module=all-ld; on=all-build-flex; }; dependencies = { module=all-ld; on=all-intl; }; +dependencies = { module=install-ld; on=install-gold; }; dependencies = { module=configure-gold; on=configure-intl; }; dependencies = { module=all-gold; on=all-libiberty; }; dependencies = { module=all-gold; on=all-intl; }; diff --git a/Makefile.in b/Makefile.in index 93f66b6fd7c..d1d8b323ba3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -58231,6 +58231,7 @@ all-stage3-ld: maybe-all-stage3-intl all-stage4-ld: maybe-all-stage4-intl all-stageprofile-ld: maybe-all-stageprofile-intl all-stagefeedback-ld: maybe-all-stagefeedback-intl +install-ld: maybe-install-gold configure-gold: maybe-configure-intl configure-stage1-gold: maybe-configure-stage1-intl diff --git a/configure b/configure index 91986d8b971..90b754e55b0 100755 --- a/configure +++ b/configure @@ -1483,7 +1483,7 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-gold use gold instead of ld + --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]] --enable-libada build libada directory --enable-libssp build libssp directory --enable-build-with-cxx build with C++ compiler instead of C compiler @@ -2901,7 +2901,7 @@ host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib l # know that we are building the simulator. # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. -# If --enable-gold is used, "gold" will replace "ld". +# If --enable-gold is used, "gold" may replace "ld". host_tools="texinfo byacc flex bison binutils gas ld fixincludes gcc cgen sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. @@ -3069,6 +3069,11 @@ case ${with_newlib} in esac # Handle --enable-gold. +# --enable-gold Build only gold +# --disable-gold [default] Build only ld +# --enable-gold=both Build both gold and ld, ld is default +# --enable-gold=both/ld Same +# --enable-gold=both/gold Build both gold and ld, gold is default, ld is renamed ld.bfd # Check whether --enable-gold was given. if test "${enable_gold+set}" = set; then : @@ -3077,32 +3082,47 @@ else ENABLE_GOLD=no fi -if test "${ENABLE_GOLD}" = "yes"; then - # Check for ELF target. - is_elf=no - case "${target}" in - *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ - | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ - | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${ENABLE_GOLD}" in + yes|both|both/gold|both/ld) + # Check for ELF target. + is_elf=no + case "${target}" in + *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ + | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ + | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${target}" in + *-*-linux*aout* | *-*-linux*oldld*) + ;; + *) + is_elf=yes + ;; + esac + esac + + if test "$is_elf" = "yes"; then + # Check for target supported by gold. case "${target}" in - *-*-linux*aout* | *-*-linux*oldld*) - ;; - *) - is_elf=yes + i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) + case "${ENABLE_GOLD}" in + both*) + configdirs="$configdirs gold" + ;; + *) + configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" + ;; + esac + ENABLE_GOLD=yes ;; esac + fi + ;; + no) + ;; + *) + as_fn_error "invalid --enable-gold argument" "$LINENO" 5 + ;; esac - if test "$is_elf" = "yes"; then - # Check for target supported by gold. - case "${target}" in - i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) - configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" - ;; - esac - fi -fi - # Configure extra directories which are host specific case "${host}" in @@ -5997,95 +6017,7 @@ fi - - -target_elf=no -case $target in - *-darwin* | *-aix* | *-cygwin* | *-mingw* | *-aout* | *-*coff* | \ - *-msdosdjgpp* | *-netware* | *-vms* | *-wince* | *-*-pe* | \ - alpha*-dec-osf* | *-interix* | hppa[12]*-*-hpux*) - target_elf=no - ;; - *) - target_elf=yes - ;; -esac - -if test $target_elf = yes; then : - -else - if test x"$default_enable_lto" = x"yes" ; then - enable_lto=no -else - if test x"$enable_lto" = x"yes"; then - as_fn_error "LTO support requires an ELF target." "$LINENO" 5 - fi -fi -default_enable_lto=no -fi - - -if test x"$enable_lto" = x"yes" ; then - # Make sure that libelf.h and gelf.h are available. - -# Check whether --with-libelf was given. -if test "${with_libelf+set}" = set; then : - withval=$with_libelf; -fi - - - -# Check whether --with-libelf_include was given. -if test "${with_libelf_include+set}" = set; then : - withval=$with_libelf_include; -fi - - - -# Check whether --with-libelf_lib was given. -if test "${with_libelf_lib+set}" = set; then : - withval=$with_libelf_lib; -fi - - - saved_CFLAGS="$CFLAGS" - saved_CPPFLAGS="$CPPFLAGS" - saved_LIBS="$LIBS" - - case $with_libelf in - "") - libelflibs="-lelf" - libelfinc="-I/usr/include/libelf" - ;; - *) - libelflibs="-L$with_libelf/lib -lelf" - libelfinc="-I$with_libelf/include -I$with_libelf/include/libelf" - LIBS="$libelflibs $LIBS" - ;; - esac - - if test "x$with_libelf_include" != x; then - libelfinc="-I$with_libelf_include" - fi - - if test "x$with_libelf_lib" != x; then - libelflibs="-L$with_libelf_lib -lelf" - LIBS="$libelflibs $LIBS" - fi - - if test "x$with_libelf$with_libelf_include$with_libelf_lib" = x \ - && test -d ${srcdir}/libelf; then - libelflibs='-L$$r/$(HOST_SUBDIR)/libelf/lib -lelf ' - libelfinc='-D__LIBELF_INTERNAL__ -I$$r/$(HOST_SUBDIR)/libelf/lib -I$$s/libelf/lib' - LIBS="$libelflibs $LIBS" - - else - - CFLAGS="$CFLAGS $libelfinc" - CPPFLAGS="$CPPFLAGS $libelfinc" - LIBS="$LIBS $libelflibs" - - ac_ext=c +ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -6483,7 +6415,83 @@ fi done -for ac_header in libelf.h + + + +target_elf=no +case $target in + *-darwin* | *-aix* | *-cygwin* | *-mingw* | *-aout* | *-*coff* | \ + *-msdosdjgpp* | *-netware* | *-vms* | *-wince* | *-*-pe* | \ + alpha*-dec-osf* | *-interix* | hppa[12]*-*-hpux*) + target_elf=no + ;; + *) + target_elf=yes + ;; +esac + +if test $target_elf = yes; then : + if test x"$enable_lto" = x"yes" ; then + # Make sure that libelf.h and gelf.h are available. + +# Check whether --with-libelf was given. +if test "${with_libelf+set}" = set; then : + withval=$with_libelf; +fi + + + +# Check whether --with-libelf_include was given. +if test "${with_libelf_include+set}" = set; then : + withval=$with_libelf_include; +fi + + + +# Check whether --with-libelf_lib was given. +if test "${with_libelf_lib+set}" = set; then : + withval=$with_libelf_lib; +fi + + + saved_CFLAGS="$CFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + saved_LIBS="$LIBS" + + case $with_libelf in + "") + libelflibs="-lelf" + libelfinc="-I/usr/include/libelf" + ;; + *) + libelflibs="-L$with_libelf/lib -lelf" + libelfinc="-I$with_libelf/include -I$with_libelf/include/libelf" + LIBS="$libelflibs $LIBS" + ;; + esac + + if test "x$with_libelf_include" != x; then + libelfinc="-I$with_libelf_include" + fi + + if test "x$with_libelf_lib" != x; then + libelflibs="-L$with_libelf_lib -lelf" + LIBS="$libelflibs $LIBS" + fi + + if test "x$with_libelf$with_libelf_include$with_libelf_lib" = x \ + && test -d ${srcdir}/libelf; then + libelflibs='-L$$r/$(HOST_SUBDIR)/libelf/lib -lelf ' + libelfinc='-D__LIBELF_INTERNAL__ -I$$r/$(HOST_SUBDIR)/libelf/lib -I$$s/libelf/lib' + LIBS="$libelflibs $LIBS" + + else + + CFLAGS="$CFLAGS $libelfinc" + CPPFLAGS="$CPPFLAGS $libelfinc" + LIBS="$LIBS $libelflibs" + + for ac_header in libelf.h do : ac_fn_c_check_header_mongrel "$LINENO" "libelf.h" "ac_cv_header_libelf_h" "$ac_includes_default" if test "x$ac_cv_header_libelf_h" = x""yes; then : @@ -6668,6 +6676,27 @@ to specify its location." "$LINENO" 5 fi +else + if test x"$default_enable_lto" = x"yes" ; then + # On non-ELF platforms, LTO must be explicitly enabled. + enable_lto=no + else + # Apart from ELF platforms, only Windows supports LTO so far. It + # would also be nice to check the binutils support, but we don't + # have gcc_GAS_CHECK_FEATURE available here. For now, we'll just + # warn during gcc/ subconfigure; unless you're bootstrapping with + # -flto it won't be needed until after installation anyway. + case $target in + *-cygwin*|*-mingw*) ;; + *) if test x"$enable_lto" = x"yes"; then + as_fn_error "LTO support is not enabled for this target." "$LINENO" 5 + fi + ;; + esac + fi + default_enable_lto=no +fi + # By default, C is the only stage 1 language. diff --git a/configure.ac b/configure.ac index c46fc4d9946..ba690241e35 100644 --- a/configure.ac +++ b/configure.ac @@ -174,7 +174,7 @@ host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib l # know that we are building the simulator. # binutils, gas and ld appear in that order because it makes sense to run # "make check" in that particular order. -# If --enable-gold is used, "gold" will replace "ld". +# If --enable-gold is used, "gold" may replace "ld". host_tools="texinfo byacc flex bison binutils gas ld fixincludes gcc cgen sid sim gdb make patch prms send-pr gprof etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool diff rcs fileutils shellutils time textutils wdiff find uudecode hello tar gzip indent recode release sed utils guile perl gawk findutils gettext zip fastjar gnattools" # libgcj represents the runtime libraries only used by gcj. @@ -315,37 +315,57 @@ case ${with_newlib} in esac # Handle --enable-gold. +# --enable-gold Build only gold +# --disable-gold [default] Build only ld +# --enable-gold=both Build both gold and ld, ld is default +# --enable-gold=both/ld Same +# --enable-gold=both/gold Build both gold and ld, gold is default, ld is renamed ld.bfd AC_ARG_ENABLE(gold, -[ --enable-gold use gold instead of ld], +[[ --enable-gold[=ARG] build gold [ARG={both}[/{gold,ld}]]]], ENABLE_GOLD=$enableval, ENABLE_GOLD=no) -if test "${ENABLE_GOLD}" = "yes"; then - # Check for ELF target. - is_elf=no - case "${target}" in - *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ - | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ - | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${ENABLE_GOLD}" in + yes|both|both/gold|both/ld) + # Check for ELF target. + is_elf=no + case "${target}" in + *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ + | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ + | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*) + case "${target}" in + *-*-linux*aout* | *-*-linux*oldld*) + ;; + *) + is_elf=yes + ;; + esac + esac + + if test "$is_elf" = "yes"; then + # Check for target supported by gold. case "${target}" in - *-*-linux*aout* | *-*-linux*oldld*) - ;; - *) - is_elf=yes + i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) + case "${ENABLE_GOLD}" in + both*) + configdirs="$configdirs gold" + ;; + *) + configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" + ;; + esac + ENABLE_GOLD=yes ;; esac + fi + ;; + no) + ;; + *) + AC_MSG_ERROR([invalid --enable-gold argument]) + ;; esac - if test "$is_elf" = "yes"; then - # Check for target supported by gold. - case "${target}" in - i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*) - configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`" - ;; - esac - fi -fi - # Configure extra directories which are host specific case "${host}" in @@ -1637,17 +1657,8 @@ AC_ARG_ENABLE(lto, enable_lto=$enableval, enable_lto=yes; default_enable_lto=yes) -ACX_ELF_TARGET_IFELSE([], -if test x"$default_enable_lto" = x"yes" ; then - enable_lto=no -else - if test x"$enable_lto" = x"yes"; then - AC_MSG_ERROR([LTO support requires an ELF target.]) - fi -fi -default_enable_lto=no) -if test x"$enable_lto" = x"yes" ; then +ACX_ELF_TARGET_IFELSE([if test x"$enable_lto" = x"yes" ; then # Make sure that libelf.h and gelf.h are available. AC_ARG_WITH(libelf, [ --with-libelf=PATH Specify prefix directory for the installed libelf package Equivalent to --with-libelf-include=PATH/include @@ -1783,7 +1794,24 @@ to specify its location.]) # Flags needed for libelf. AC_SUBST(libelflibs) AC_SUBST(libelfinc) -fi +fi],[if test x"$default_enable_lto" = x"yes" ; then + # On non-ELF platforms, LTO must be explicitly enabled. + enable_lto=no + else + # Apart from ELF platforms, only Windows supports LTO so far. It + # would also be nice to check the binutils support, but we don't + # have gcc_GAS_CHECK_FEATURE available here. For now, we'll just + # warn during gcc/ subconfigure; unless you're bootstrapping with + # -flto it won't be needed until after installation anyway. + case $target in + *-cygwin*|*-mingw*) ;; + *) if test x"$enable_lto" = x"yes"; then + AC_MSG_ERROR([LTO support is not enabled for this target.]) + fi + ;; + esac + fi + default_enable_lto=no]) # By default, C is the only stage 1 language. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8ee8c208976..23f10f33905 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,622 @@ +2010-04-29 H.J. Lu + + PR bootstrap/43935 + * plugin.h (flag_plugin_added): Moved out of + invoke_plugin_callbacks. + +2010-04-29 Richard Guenther + + PR bootstrap/43935 + * plugin.h (invoke_plugin_callbacks): Annotate arguments + with ATTRIBUTE_UNUSED. + +2010-04-29 H.J. Lu + + PR target/43921 + * config/i386/i386.c (get_some_local_dynamic_name): Replace + INSN_P with NONDEBUG_INSN_P. + (distance_non_agu_define): Likewise. + (distance_agu_use): Likewise. + +2010-04-29 Bernd Schmidt + + From Dominique d'Humieres + PR bootstrap/43858 + * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs to compute + test_set. + +2010-04-29 Brian Hackett + + * plugin.h (invoke_plugin_callbacks): New inline function. + * plugin.c (flag_plugin_added): New global flag. + (add_new_plugin): Initialize above flag. + (invoke_plugin_callbacks): Rename to ... + (invoke_plugin_callbacks_full): ... this. + +2010-04-28 Jan Hubicka + + * lto-symtab.c (lto_symtab_entry_def) Add vnode. + (lto_varpool_replace_node): New. + (lto_symtab_resolve_symbols): Resolve varpool nodes. + (lto_symtab_merge_decls_1): Prefer decls with varpool node. + (lto_symtab_merge_cgraph_nodes_1): Merge varpools. + * cgraph.h (varpool_node_ptr): New type. + (varpool_node_ptr): New vector. + (varpool_node_set_def): New structure. + (varpool_node_set): New type. + (varpool_node_set): New vector. + (varpool_node_set_element_def): New structure. + (varpool_node_set_element, const_varpool_node_set_element): New types. + (varpool_node_set_iterator): New type. + (varpool_node): Add prev pointers, add used_from_other_partition, + in_other_partition. + (varpool_node_set_new, varpool_node_set_find, varpool_node_set_add, + varpool_node_set_remove, dump_varpool_node_set, debug_varpool_node_set, + varpool_get_node, varpool_remove_node): Declare. + (vsi_end_p, vsi_next, vsi_node, vsi_start, varpool_node_in_set_p, + varpool_node_set_size): New inlines. + * cgraph.c (dump_cgraph_node): Dump asm names of aliases. + * tree-pass.h (varpool_node_set_def): Forward declare. + (ipa_opt_pass_d): Summary writting takes vnode sets too. + (ipa_write_optimization_summaries): Update prototype. + * ipa-cp.c (ipcp_write_summary): Update. + * ipa-reference.c (ipa_reference_write_summary): Update. + * lto-cgraph.c (lto_output_varpool_node): New static function. + (output_varpool): New function. + (input_varpool_node): New static function. + (input_varpool_1): New function. + (input_cgraph): Input varpool. + * ipa-pure-const.c (pure_const_write_summary): Update. + * lto-streamer-out.c (lto_output): Update, output varpool too. + (write_global_stream): Kill WPA hack. + (produce_asm_for_decls): Update. + (output_alias_pair_p): Handle variables. + (output_unreferenced_globals): Output only needed partition of varpool. + * ipa-inline.c (inline_write_summary): Update. + * lto-streamer-in.c (lto_input_tree_ref, lto_input_tree): Do not build cgraph. + * lto-section-in.c (lto_section_name): Add varpool and jump funcs. + * ipa.c (hash_varpool_node_set_element, eq_varpool_node_set_element, + varpool_node_set_new, varpool_node_set_add, + varpool_node_set_remove, varpool_node_set_find, dump_varpool_node_set, + debug_varpool_node_set): New functions. + * passes.c (rest_of_decl_compilation): when in LTO do not finalize. + (execute_one_pass): Process new decls too. + (ipa_write_summaries_2): Pass around vsets. + (ipa_write_summaries_1): Likewise. + (ipa_write_summaries): Build vset; be more selective about cgraph nodes + to add. + (ipa_write_optimization_summaries_1): Pass around vsets. + (ipa_write_optimization_summaries): Likewise. + * varpool.c (varpool_get_node): New. + (varpool_node): Update doubly linked lists. + (varpool_remove_node): New. + (dump_varpool_node): More dumping. + (varpool_enqueue_needed_node): Update doubly linked lists. + (decide_is_variable_needed): Kill ltrans hack. + (varpool_finalize_decl): Kill lto hack. + (varpool_assemble_decl): Skip decls in other partitions. + (varpool_assemble_pending_decls): Update doubly linkes lists. + (varpool_empty_needed_queue): Likewise. + (varpool_extra_name_alias): Likewise. + * lto-streamer.c (lto_get_section_name): Add vars section. + * lto-streamer.h (lto_section_type): Update. + (output_varpool, input_varpool): Declare. + +2010-04-28 Mike Stump + + * config/i386/darwin.h (CC1_SPEC): Ignore -mdynamic-no-pic for now. + +2010-04-28 Eric Botcazou + + * lto-streamer-in.c (unpack_ts_type_value_fields): Replace test for + record or union type with RECORD_OR_UNION_TYPE_P predicate. + (lto_input_ts_type_tree_pointers): Likewise. + * lto-streamer-out.c (pack_ts_type_value_fields): Likewise. + (lto_output_ts_type_tree_pointers): Likewise. + +2010-04-28 Eric Botcazou + + Uniquization of constants at the Tree level + * tree.h (DECL_IN_CONSTANT_POOL): New macro. + (tree_decl_with_vis): Add in_constant_pool bit, move shadowed_for_var_p + bit to the end. + (tree_output_constant_def): Declare. + * gimplify.c (gimplify_init_constructor): When using block copy, first + uniquize the constant constructor on the RHS. + * lto-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Deal with + DECL_IN_CONSTANT_POOL flag. + * lto-streamer-out.c (pack_ts_decl_with_vis_value_fields): Likewise. + * varasm.c (make_decl_rtl): Deal with variables belonging to the global + constant pool. + (assemble_variable): Deal with symbols belonging to the tree constant + pool. + (get_constant_section): Add ALIGN parameter and simplify. + (build_constant_desc): Build a VAR_DECL and attach it to the symbol. + (assemble_constant_contents): Use the expression of the VAR_DECL. + (output_constant_def_contents): Use the alignment of the VAR_DECL. + (tree_output_constant_def): New global function. + (mark_constant): Use the expression of the VAR_DECL. + (place_block_symbol): Use the alignment of the VAR_DECL and the size of + its expression. + (output_object_block): Likewise and assemble the expression. + +2010-04-28 Eric Botcazou + + * lto-streamer.c [LTO_STREAMER_DEBUG] (tree_htab, tree_hash_entry, + hash_tree, eq_tree): New tree hash table. + (lto_streamer_init) [LTO_STREAMER_DEBUG]: Initialize it. + [LTO_STREAMER_DEBUG] (lto_orig_address_map, lto_orig_address_get, + lto_orig_address_remove): Reimplement. + +2010-04-28 Xinliang David Li + + PR c/42643 + * tree-ssa-uninit.c (can_skip_redundant_opnd): New function. + (compute_uninit_opnds_pos): New function. + (is_non_loop_exit_postdominating): New function. + (compute_control_dep_chain): New function. + (find_pdom): New function. + (convert_control_dep_chain_into_preds): New function. + (find_predicates): New function. + (find_control_equiv_block): New function. + (collect_phi_def_edges): New function. + (find_def_preds): New function. + (find_dom): New function. + (dump_predicates): New function. + (get_cmp_code): New function. + (is_value_included_in): New function. + (find_matching_predicate_in_rest_chains): New function. + (use_pred_not_overlap_with_undef_path_pred): New function. + (is_use_properly_guarded): New function. + (normalize_cond_1): New function. + (is_and_or_or): New function. + (normalize_cond): New function. + (is_gcond_subset_of): New function. + (is_subset_of_any): New function. + (is_or_set_subset_of): New function. + (is_and_set_subset_of): New function. + (is_norm_cond_subset_of): New function. + (is_pred_expr_subset_of): New function. + (is_pred_chain_subset_of): New function. + (is_included_in): New function. + (is_superset_of): New function. + (find_uninit_use): New function. + (warn_uninitialized_phi): New function. + (compute_possibly_undefined_names): New function. + (ssa_undefined_value_p): New function. + (execute_late_warn_uninitialized): New function. + * tree-ssa.c (ssa_undefined_value_p): Removed. + (warn_uninit): Changed to extern. + (warn_uninitialized_phi): Removed. + (warn_uninitialized_vars): Changed to extern. + (execute_late_warn_uninitialized): Removed + * tree-flow.h: Add new prototypes. + * timevar.def: Add new time variable. + * Makefile.in: Add new build file. + +2010-04-28 Uros Bizjak + + * config/alpha/elf.h (ASM_DECLARE_OBJECT_NAME): Use gnu_unique_object + type if available. + +2010-04-28 Rainer Orth + + PR target/22224 + * config/alpha/osf5.h (ASM_OUTPUT_LOCAL): Redefine. + +2010-04-28 Martin Jambor + + * cgraph.h (struct cgraph_node): New field indirect_calls. + (struct cgraph_indirect_call_info): New type. + (struct cgraph_edge): Removed field indirect_call. New fields + indirect_info, indirect_inlining_edge and indirect_unknown_callee. + (cgraph_create_indirect_edge): Declare. + (cgraph_make_edge_direct): Likewise. + (enum LTO_cgraph_tags): New item LTO_cgraph_indirect_edge. + * ipa-prop.h (struct ipa_param_call_note): Removed. + (struct ipa_node_params): Removed field param_calls. + (ipa_create_all_structures_for_iinln): Declare. + * cgraph.c: Described indirect edges and uids in initial comment. + (cgraph_add_edge_to_call_site_hash): New function. + (cgraph_edge): Search also among the indirect edges, use + cgraph_add_edge_to_call_site_hash to add edges to the call site hash. + (cgraph_set_call_stmt): Possibly turn an indirect edge into a direct + one, use cgraph_add_edge_to_call_site_hash to add edges to the call + site hash. + (initialize_inline_failed): Assign a reason to indirect edges. + (cgraph_create_edge_1): New function. + (cgraph_create_edge): Moved some functionality to + cgraph_create_edge_1. + (cgraph_create_indirect_edge): New function. + (cgraph_edge_remove_callee): Add an assert checking for + non-indirectness. + (cgraph_edge_remove_caller): Special-case indirect edges. + (cgraph_remove_edge): Likewise. + (cgraph_set_edge_callee): New function. + (cgraph_redirect_edge_callee): Use cgraph_set_edge_callee. + (cgraph_make_edge_direct): New function. + (cgraph_update_edges_for_call_stmt_node): Do nothing only when also + the declaration of the call statement matches. + (cgraph_node_remove_callees): Special-case indirect edges. + (cgraph_clone_edge): Likewise. + (cgraph_clone_node): Clone also the indirect edges. + (dump_cgraph_node): Dump indirect_inlining_edge flag instead of + indirect_call, dump count of indirect_calls edges. + * ipa-prop.c (iinlining_processed_edges): New variable. + (ipa_note_param_call): Create indirect edges instead of + creating notes. New parameter node. + (ipa_analyze_call_uses): New parameter node, pass it on to + ipa_note_param_call. + (ipa_analyze_stmt_uses): Likewise. + (ipa_analyze_params_uses): Pass node to ipa_analyze_stmt_uses. + (print_edge_addition_message): Work on edges rather than on notes. + (update_call_notes_after_inlining): Likewise, renamed to + update_indirect_edges_after_inlining. + (ipa_create_all_structures_for_iinln): New function. + (ipa_free_node_params_substructures): Do not free notes. + (ipa_edge_duplication_hook): Propagate bits within + iinlining_processed_edges bitmap. + (ipa_node_duplication_hook): Do not duplicate notes. + (free_all_ipa_structures_after_ipa_cp): Renamed to + ipa_free_all_structures_after_ipa_cp. + (free_all_ipa_structures_after_iinln): Renamed to + ipa_free_all_structures_after_iinln.g + (ipa_write_param_call_note): Removed. + (ipa_read_param_call_note): Removed. + (ipa_write_indirect_edge_info): New function. + (ipa_read_indirect_edge_info): Likewise. + (ipa_write_node_info): Do not stream notes, do stream information + in indirect edges. + (ipa_read_node_info): Likewise. + (lto_ipa_fixup_call_notes): Removed. + * ipa-cp.c (pass_ipa_cp): Set stmt_fixup to NULL. + * ipa-inline.c (pass_ipa_inline): Likewise. + * cgraphunit.c (verify_cgraph_node): Check also indirect edges. + * cif-code.def (INDIRECT_UNKNOWN_CALL): New reason. + * tree-inline.c (copy_bb): Removed an unnecessary double check for + is_gimple_call. + * tree-inline.c (get_indirect_callee_fndecl): Do not consider indirect + edges. + * lto-cgraph.c (output_outgoing_cgraph_edges): New function. + (output_cgraph): Stream also indirect edges. + (lto_output_edge): Added capability to stream indirect edges. + (input_edge): Likewise. + (input_cgraph_1): Likewise. + * lto-streamer-in.c (fixup_call_stmt_edges_1): Fixup also statements + of indirect edges. + +2010-04-28 Richard Guenther + + PR tree-optimization/43879 + PR tree-optimization/43909 + * tree-ssa-structalias.c (struct variable_info): Add + only_restrict_pointers flag. + (new_var_info): Initialize it. Increment stats.total_vars here. + (create_function_info_for): Do not increment stats.total_vars + here. + (get_function_part_constraint): Fix build with C++. + (insert_into_field_list): Remove. + (push_fields_onto_fieldstack): Properly merge fields. + (create_variable_info_for): Split and simplify. + (create_variable_info_for_1): New piece. + (intra_create_variable_infos): Properly make restrict constraints + from parameters. + +2010-04-28 Richard Guenther + + PR c++/43880 + * tree-inline.c (copy_bind_expr): Also copy bind expr vars + value-exprs. + +2010-04-27 Manuel López-Ibáñez + Jan Hubicka + + * doc/invoke.texi (-Wsuggest-attribute=const, + -Wsuggest-attribute=pure): Document. + * ipa-pure-const.c: Include toplev.h, intl.h and opts.h. + (function_always_visible_to_compiler_p, + suggest_attribute, warn_function_pure, warn_function_const): + New functions. + (check_call): Improve debug info. + (analyze_function): Do not check availability. + (add_new_function): Check availability. + (propagate): Output warnings. + (skip_function_for_local_pure_const): New function. + (local_pure_const): Use it; output warnings. + * common.opt (Wsuggest-attribute=const, + Wsuggest-attribute=pure): New. + +2010-04-27 Jakub Jelinek + + * dwarf2out.c (def_cfa_1): After DW_CFA_def_cfa_expression + force using DW_CFA_def_cfa instead of DW_CFA_def_cfa_register + or DW_CFA_def_cfa_offset{,_sf}. + +2010-04-27 Eric Botcazou + + * tree.h: Fix truncated long macros. + +2010-04-27 Kai Tietz + + * collect2.c (TARGET_64BIT): Redefine to target's default. + * tlink.c: Likewise. + * config/i386/cygming.h (USER_LABEL_PREFIX): Define + dependent to TARGET_64BIT and USE_MINGW64_LEADING_UNDERSCORES. + * config/i386/i386.h (CRT_CALL_STATIC_FUNCTION): Use + for underscoring __USER_LABEL_PREFIX__. + * config/i386/mingw-w64.h (SUB_LINK_ENTRY): New macro. + (SUB_LINK_ENTRY32): New. + (SUB_LINK_ENTRY64): New. + (LINK_SPEC): Replace entry point spec by SUB_LINK_ENTRY. + * config/i386/mingw32 (SUB_LINK_ENTRY32): New. + (SUB_LINK_ENTRY64): New. + (SUB_LINK_ENTRY): New. + (LINK_SPEC): Use SUB_LINK_ENTRY instead of hard-coded entry-point. + (DWARF2_UNWIND_INFO): Error out for use of dw2 unwind when + x64 target is choosen. + * config.in (USE_MINGW64_LEADING_UNDERSCORES): New. + * configure: Regenerated. + * configure.ac (leading-mingw64-underscores): Option added. + +2010-04-27 Jan Hubicka + + * doc/invoke.texi (-fipa-profile): Document. + * opts.c (decode_options): Enable ipa-profile at -O1. + * timevar.def (TV_IPA_PROFILE): Define. + * common.opt (fipa-profile): Add. + * cgraph.c (cgraph_clone_node): Set local flag and clear vtable method + flag for clones. + (cgraph_propagate_frequency): Handle only local ones. + * tree-pass.h (pass_ipa_profile): Declare. + * ipa-profile.c (gate_profile): Use flag_ipa_profile. + (pass_ipa_profile): Use TV_IPA_PROFILE. + * ipa.c (ipa_profile): New function. + (gate_ipa_profile): Likewise. + (pass_ipa_profile): New global variable. + * passes.c (pass_ipa_profile): New. + +2010-04-27 Nathan Froyd + + * config/arm/arm.c (arm_expand_builtin): Remove redundant declaration. + +2010-04-27 Martin Jambor + + PR middle-end/43812 + * ipa.c (dissolve_same_comdat_group_list): New function. + (function_and_variable_visibility): Call + dissolve_same_comdat_group_list when comdat group contains external or + newly local nodes. + * cgraphunit.c (verify_cgraph_node): Verify that same_comdat_group + lists are circular and that they contain only DECL_ONE_ONLY nodes. + +2010-04-27 Eric Botcazou + + * varasm.c (decode_addr_const): Handle special case of INDIRECT_REF. + (const_hash_1) : New case. + (compare_constant) : Likewise. + : Deal with LABEL_REFs. + (copy_constant) : New case. + +2010-04-27 Jan Hubicka + + * cgraph.c (cgraph_propagate_frequency): New function. + * cgraph.h (cgraph_propagate_frequency): Declare. + * ipa-inline.c (cgraph_clone_inlined_nodes): Call + cgraph_propagate_frequency. + +2010-04-27 Jakub Jelinek + + * unwind-dw2.c (_Unwind_DebugHook): Add used and noclone attributes. + +2010-04-27 Bernd Schmidt + + PR target/40657 + * config/arm/arm.c (thumb1_extra_regs_pushed): New function. + (thumb1_expand_prologue, thumb1_output_function_prologue): Call it + here to determine which regs to push and how much stack to reserve. + +2010-04-27 Jie Zhang + + * doc/gimple.texi (gimple_statement_with_ops): Remove + addresses_taken field. + (gimple_statement_with_memory_ops): Likewise. + +2010-04-27 Jan Hubicka + + * tree-inline.c (eni_inlining_weights): Remove. + (estimate_num_insns): Special case more builtins. + +2010-04-27 Shujing Zhao + + PR c/32207 + * c-typeck.c (build_binary_op): Move forward check for comparison + pointer with null pointer constant and adjust the diagnostic message. + +2010-04-27 Dave Korn + + PR lto/42776 + * configure.ac (gcc_cv_as_section_has_align): Set if installed + binutils supports extended .section directive needed by LTO, or + warn if older binutils found. + (LTO_BINARY_READER): New AC_SUBST'd variable. + (LTO_USE_LIBELF): Likewise. + * gcc/config.gcc (lto_binary_reader): New target-specific configure + variable. + * gcc/Makefile.in (LTO_BINARY_READER): Import AC_SUBST'd autoconf var. + (LTO_USE_LIBELF): Likewise. + * configure: Regenerate. + + * collect2.c (is_elf): Rename from this ... + (is_elf_or_coff): ... to this, and recognize and allow i386 COFF + object files in addition to ELF-formatted ones. + (scan_prog_file): Caller updated. Also allow for LTO info marker + symbol to be prefixed or not by an extra underscore. + + * config/i386/t-cygming (winnt.o): Also depend on LTO_STREAMER_H. + * config/i386/winnt.c: Also #include lto-streamer.h + (i386_pe_asm_named_section): Specify 1-byte section alignment for + LTO named sections. + (i386_pe_asm_output_aligned_decl_common): Add comment. + (i386_pe_maybe_record_exported_symbol): Allow decl arg to be NULL. + +2010-04-27 Hans-Peter Nilsson + + PR target/43889 + * config/mmix/mmix.md ("*divdi3_nonknuth", "*moddi3_nonknuth"): + Add missing earlyclobber for second alternative. + +2010-04-26 Bernd Schmidt + + * df-problems.c (df_simulate_initialize_forwards): Set, don't clear, + bits for artificial defs at the top of the block. + * fwprop.c (single_def_use_enter_block): Don't call it. + +2010-04-26 Jack Howarth + + PR 43715 + * gcc/configure.ac: Use "$gcc_cv_nm -g" on darwin + instead of "$gcc_cv_objdump -T". + Use "-undefined dynamic_lookup" on darwin. + * gcc/configure: Regenerate. + +2010-04-26 Jakub Jelinek + + PR c/43893 + * c-omp.c (c_finish_omp_for): Handle also EQ_EXPR. + +2010-04-26 Nathan Froyd + + * c-parser.c (struct c_token): Move location field up. + * c-tree.h (struct c_typespec): Move expr_const_operands field up. + (struct c_declspecs): Convert typespec_word, storage_class, and + default_int_p into bitfields. + (struct c_declarator): Move loc field up. + +2010-04-26 Nathan Froyd + + * cfgloop.h (struct loop): Move can_be_parallel field up. + * ipa-prop.h (struct ip_node_params): Move bitfields up. + * tree-ssa-loop-ivopts.c (struct version_info): Move inv_id field + down. + (struct iv_cand): Convert pos field into a bitfield. + * tree-vectorizer.h (struct _loop_vec_info): Move loop_line_number + field up. + (struct _stmt_vec_info): Shuffle fields for better packing. + +2010-04-26 Eric Botcazou + + * varasm.c (IN_NAMED_SECTION): Remove guard. + * config/arm/unknown-elf.h (IN_NAMED_SECTION): Rename to... + (IN_NAMED_SECTION_P): ...this. + (ASM_OUTPUT_ALIGNED_BSS): Adjust for above renaming. + (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Likewise. + +2010-04-26 Eric Botcazou + + * gimplify.c (gimplify_cond_expr): Use THEN_ and ELSE_ local variables. + Use VOID_TYPE_P for all void type tests. Adjust TYPE variable instead + of shadowing it. Fix comments. + +2010-04-26 Jan Hubicka + + * cgraph.c (cgraph_create_node): Set node frequency to normal. + (cgraph_clone_node): Copy function frequency. + * cgraph.h (node_frequency): New enum + (struct cgraph_node): Add. + * final.c (rest_of_clean_state): Update. + * lto-cgraph.c (lto_output_node): Output node frequency. + (input_overwrite_node): Input node frequency. + * tre-ssa-loop-ivopts (computation_cost): Update. + * lto-streamer-out.c (output_function): Do not output function + frequency. + * predict.c (maybe_hot_frequency_p): Update and handle functions + executed once. + (cgraph_maybe_hot_edge_p): Likewise; use cgraph frequency instead of + attribute lookup. + (probably_never_executed_bb_p, optimize_function_for_size_p): Update. + (compute_function_frequency): Set noreturn functions to be executed + once. + (choose_function_section): Update. + * lto-streamer-in.c (input_function): Do not input function frequency. + * function.c (allocate_struct_function): Do not initialize function + frequency. + * function.h (function_frequency): Remove. + (struct function): Remove function frequency. + * ipa-profile.c (CGRAPH_NODE_FREQUENCY): Remove. + (try_update): Update. + * tree-inline.c (initialize_cfun): Do not update function frequency. + * passes.c (pass_init_dump_file): Update. + * i386.c (ix86_compute_frame_layout): Update. + (ix86_pad_returns): Update. + +2010-04-26 Jie Zhang + + PR tree-optimization/43833 + * tree-vrp.c (range_int_cst_p): New. + (range_int_cst_singleton_p): New. + (extract_range_from_binary_expr): Optimize BIT_AND_EXPR case + when both operands are constants. Use range_int_cst_p in + BIT_IOR_EXPR case. + +2010-04-26 Jan Hubicka + + * cgraphunit.c (cgraph_copy_node_for_versioning): Fix profile updating. + +2010-04-26 Richard Guenther + + PR lto/43080 + * gimple.c (gimple_decl_printable_name): Deal gracefully + with a NULL DECL_NAME. + +2010-04-26 Richard Guenther + + PR lto/42425 + * tree.c (free_lang_data_in_type): Do not free TYPE_CONTEXT + if emitting debug information and it is either a function + or a namespace decl. + +2010-04-26 Ira Rosen + + * tree-vectorizer.h (struct _stmt_vec_info): Add new field to + determine if the statement is vectorizable, and a macro to access it. + * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): + Skip statements that can't be vectorized. If the analysis fails, + mark the statement as unvectorizable if vectorizing basic block. + (vect_compute_data_refs_alignment): Likewise. + (vect_verify_datarefs_alignment): Skip statements marked as + unvectorizable. Add print. + (vect_analyze_group_access): Skip statements that can't be + vectorized. If the analysis fails, mark the statement as + unvectorizable if vectorizing basic block. + (vect_analyze_data_ref_accesses, vect_analyze_data_refs): Likewise. + * tree-vect-stmts.c (vectorizable_store): Fix the number of + generated stmts for SLP. + (new_stmt_vec_info): Initialize the new field. + * tree-vect-slp.c (vect_build_slp_tree): Fail to vectorize + statements marked as unvectorizable. + +2010-04-25 Joseph Myers + + * c-common.c (flag_isoc1x): New. + (flag_isoc99): Update comment. + * c-common.h (flag_isoc1x): New. + (flag_isoc99): Update comment. + * c-cppbuiltin.c (builtin_define_float_constants): Also define + ___DECIMAL_DIG__. + * c-opts.c (set_std_c1x): New. + (c_common_handle_option): Handle -std=c1x and -std=gnu1x. + (set_std_c89, set_std_c99): Also set flag_isoc1x to 0. + * c.opt (-std=c1x, -std=gnu1x): New options. + * doc/cpp.texi: Mention -std=c1x. + * doc/cppopts.texi (-std=c1x, -std=gnu1x): Document. + * doc/extend.texi: Mention -std=c1x and -std=gnu1x. + * doc/invoke.texi (-std=c1x, -std=gnu1x): Document. + * doc/standards.texi: Mention C1X. + * ginclude/float.h (FLT_DECIMAL_DIG, DBL_DECIMAL_DIG, + LDBL_DECIMAL_DIG, FLT_HAS_SUBNORM, DBL_HAS_SUBNORM, + LDBL_HAS_SUBNORM, FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN): + Define for C1X. + 2010-04-25 Uros Bizjak * config/i386/gmon-sol2.c (_mcleanup): Change format string @@ -433,9 +1052,9 @@ (input_overwrite_node): Input new flags. * passes.c (ipa_write_summaries): Do not call lto_new_extern_inline_states. - * lto-section-out.c (forced_extern_inline, lto_new_extern_inline_states, - lto_delete_extern_inline_states, lto_force_functions_extern_inline, - lto_forced_extern_inline_p): Kill. + * lto-section-out.c (forced_extern_inline, + lto_new_extern_inline_states lto_delete_extern_inline_states, + lto_force_functions_extern_inline, lto_forced_extern_inline_p): Kill. * lto-streamer.h (lto_new_extern_inline_states, * lto_delete_extern_inline_states, lto_force_functions_extern_inline, lto_forced_extern_inline_p): Kill. @@ -1013,7 +1632,7 @@ * double-int.h (HOST_BITS_PER_DOUBLE_INT): Define. (double_int_not, double_int_lshift, double_int_rshift): Declare. (double_int_negative_p): Convert to static inline function. - * double-int.c (double_int_lshift, double_int_lshift): Add new function. + * double-int.c (double_int_lshift, double_int_lshift): New functions. (double_int_negative_p): Remove. * tree.h (lshift_double, rshift_double): * tree.c (build_low_bits_mask): Clean up, use double_int_* functions. @@ -4900,7 +5519,8 @@ (TARGET_VECTORIZE_BUILTIN_VEC_PERM): Likewise. (TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK): Likewise. - * doc/tm.texi (TARGET_VECTORIZE_BUILTIN_CONVERSION): Fix argument types. + * doc/tm.texi (TARGET_VECTORIZE_BUILTIN_CONVERSION): Fix argument + types. * doc/tm.texi (TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Fix argument types. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6debf8ff5ec..b6b2ee64823 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20100425 +20100429 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c82bf15482e..d924f3ba790 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -326,6 +326,10 @@ LIBELFINC = @LIBELFINC@ # Set to 'yes' if the LTO front end is enabled. enable_lto = @enable_lto@ +# Set according to LTO object file format. +LTO_BINARY_READER = @LTO_BINARY_READER@ +LTO_USE_LIBELF = @LTO_USE_LIBELF@ + # Compiler needed for plugin support PLUGINCC = @CC@ @@ -1381,6 +1385,7 @@ OBJS-common = \ tree-ssa-threadedge.o \ tree-ssa-threadupdate.o \ tree-ssa-uncprop.o \ + tree-ssa-uninit.o \ tree-ssa.o \ tree-ssanames.o \ tree-stdarg.o \ @@ -2284,6 +2289,12 @@ tree-ssa-structalias.o: tree-ssa-structalias.c \ $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \ $(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \ gt-tree-ssa-structalias.h $(CGRAPH_H) $(ALIAS_H) pointer-set.h +tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ + $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ + $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ + $(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) $(BITMAP_H) \ + $(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \ + $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \ $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index c5dac667602..6303c3927c4 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2010-04-28 Eric Botcazou + + * gcc-interface/trans.c (gnat_gimplify_expr) : Uniquize + constant constructors before taking their address. + 2010-04-25 Eric Botcazou * exp_dbug.ads: Fix outdated description. Mention link between XVS diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 84fa1387870..743a6521094 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -6036,16 +6036,8 @@ gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p, the reference is in an elaboration procedure. */ if (TREE_CONSTANT (op)) { - tree new_var = create_tmp_var_raw (TREE_TYPE (op), "C"); - TREE_ADDRESSABLE (new_var) = 1; - gimple_add_tmp_var (new_var); - - TREE_READONLY (new_var) = 1; - TREE_STATIC (new_var) = 1; - DECL_INITIAL (new_var) = op; - - TREE_OPERAND (expr, 0) = new_var; - recompute_tree_invariant_for_addr_expr (expr); + tree addr = build_fold_addr_expr (tree_output_constant_def (op)); + *expr_p = fold_convert (TREE_TYPE (expr), addr); } /* Otherwise explicitly create the local temporary. That's required diff --git a/gcc/c-common.c b/gcc/c-common.c index bc075ad3d13..c8a2ff1099b 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -280,10 +280,14 @@ int flag_cond_mismatch; int flag_isoc94; -/* Nonzero means use the ISO C99 dialect of C. */ +/* Nonzero means use the ISO C99 (or C1X) dialect of C. */ int flag_isoc99; +/* Nonzero means use the ISO C1X dialect of C. */ + +int flag_isoc1x; + /* Nonzero means that we have builtin functions, and main is an int. */ int flag_hosted = 1; diff --git a/gcc/c-common.h b/gcc/c-common.h index 6ed38490cb6..8dadc247f86 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -595,10 +595,14 @@ extern int flag_cond_mismatch; extern int flag_isoc94; -/* Nonzero means use the ISO C99 dialect of C. */ +/* Nonzero means use the ISO C99 (or C1X) dialect of C. */ extern int flag_isoc99; +/* Nonzero means use the ISO C1X dialect of C. */ + +extern int flag_isoc1x; + /* Nonzero means that we have builtin functions, and main is an int. */ extern int flag_hosted; diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c index 1565aac23db..fa4d9a1ca01 100644 --- a/gcc/c-cppbuiltin.c +++ b/gcc/c-cppbuiltin.c @@ -105,6 +105,7 @@ builtin_define_float_constants (const char *name_prefix, char name[64], buf[128]; int dig, min_10_exp, max_10_exp; int decimal_dig; + int type_decimal_dig; fmt = REAL_MODE_FORMAT (TYPE_MODE (type)); gcc_assert (fmt->b != 10); @@ -198,8 +199,20 @@ builtin_define_float_constants (const char *name_prefix, if (decimal_dig < d_decimal_dig) decimal_dig++; } + /* Similar, for this type rather than long double. */ + { + double type_d_decimal_dig = 1 + fmt->p * log10_b; + type_decimal_dig = type_d_decimal_dig; + if (type_decimal_dig < type_d_decimal_dig) + type_decimal_dig++; + } if (type == long_double_type_node) builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig); + else + { + sprintf (name, "__%s_DECIMAL_DIG__", name_prefix); + builtin_define_with_int_value (name, type_decimal_dig); + } /* Since, for the supported formats, B is always a power of 2, we construct the following numbers directly as a hexadecimal diff --git a/gcc/c-omp.c b/gcc/c-omp.c index eb6f3ef78de..012a632b214 100644 --- a/gcc/c-omp.c +++ b/gcc/c-omp.c @@ -1,7 +1,7 @@ /* This file contains routines to construct GNU OpenMP constructs, called from parsing in the C and C++ front ends. - Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Richard Henderson , Diego Novillo . @@ -301,7 +301,8 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv, || TREE_CODE (cond) == LE_EXPR || TREE_CODE (cond) == GT_EXPR || TREE_CODE (cond) == GE_EXPR - || TREE_CODE (cond) == NE_EXPR) + || TREE_CODE (cond) == NE_EXPR + || TREE_CODE (cond) == EQ_EXPR) { tree op0 = TREE_OPERAND (cond, 0); tree op1 = TREE_OPERAND (cond, 1); @@ -346,18 +347,21 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv, cond_ok = true; } - if (TREE_CODE (cond) == NE_EXPR) + if (TREE_CODE (cond) == NE_EXPR + || TREE_CODE (cond) == EQ_EXPR) { if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))) cond_ok = false; else if (operand_equal_p (TREE_OPERAND (cond, 1), TYPE_MIN_VALUE (TREE_TYPE (decl)), 0)) - TREE_SET_CODE (cond, GT_EXPR); + TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR + ? GT_EXPR : LE_EXPR); else if (operand_equal_p (TREE_OPERAND (cond, 1), TYPE_MAX_VALUE (TREE_TYPE (decl)), 0)) - TREE_SET_CODE (cond, LT_EXPR); + TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR + ? LT_EXPR : GE_EXPR); else cond_ok = false; } diff --git a/gcc/c-opts.c b/gcc/c-opts.c index a680f2d79bd..66101b7eded 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -112,6 +112,7 @@ static void set_std_cxx98 (int); static void set_std_cxx0x (int); static void set_std_c89 (int, int); static void set_std_c99 (int); +static void set_std_c1x (int); static void check_deps_environment_vars (void); static void handle_deferred_opts (void); static void sanitize_cpp_opts (void); @@ -1066,6 +1067,16 @@ c_common_handle_option (size_t scode, const char *arg, int value) set_std_c99 (false /* ISO */); break; + case OPT_std_c1x: + if (!preprocessing_asm_p) + set_std_c1x (true /* ISO */); + break; + + case OPT_std_gnu1x: + if (!preprocessing_asm_p) + set_std_c1x (false /* ISO */); + break; + case OPT_trigraphs: cpp_opts->trigraphs = 1; break; @@ -1704,6 +1715,7 @@ set_std_c89 (int c94, int iso) flag_no_nonansi_builtin = iso; flag_isoc94 = c94; flag_isoc99 = 0; + flag_isoc1x = 0; } /* Set the C 99 standard (without GNU extensions if ISO). */ @@ -1714,6 +1726,20 @@ set_std_c99 (int iso) flag_no_asm = iso; flag_no_nonansi_builtin = iso; flag_iso = iso; + flag_isoc1x = 0; + flag_isoc99 = 1; + flag_isoc94 = 1; +} + +/* Set the C 1X standard draft (without GNU extensions if ISO). */ +static void +set_std_c1x (int iso) +{ + cpp_set_lang (parse_in, iso ? CLK_STDC1X: CLK_GNUC1X); + flag_no_asm = iso; + flag_no_nonansi_builtin = iso; + flag_iso = iso; + flag_isoc1x = 1; flag_isoc99 = 1; flag_isoc94 = 1; } diff --git a/gcc/c-parser.c b/gcc/c-parser.c index a8feb27b883..cbdee1eb8a1 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -156,10 +156,10 @@ typedef struct GTY (()) c_token { /* If this token is a CPP_PRAGMA, this indicates the pragma that was seen. Otherwise it is PRAGMA_NONE. */ ENUM_BITFIELD (pragma_kind) pragma_kind : 8; - /* The value associated with this token, if any. */ - tree value; /* The location at which this token was found. */ location_t location; + /* The value associated with this token, if any. */ + tree value; } c_token; /* A parser structure recording information about the state and diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 681fe9b4ffe..50ed9db08a8 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -160,6 +160,9 @@ enum c_typespec_kind { struct c_typespec { /* What kind of type specifier this is. */ enum c_typespec_kind kind; + /* Whether the expression has operands suitable for use in constant + expressions. */ + bool expr_const_operands; /* The specifier itself. */ tree spec; /* An expression to be evaluated before the type specifier, in the @@ -171,9 +174,6 @@ struct c_typespec { expression itself (as opposed to the array sizes) forms no part of the type and so needs to be recorded separately. */ tree expr; - /* Whether the expression has operands suitable for use in constant - expressions. */ - bool expr_const_operands; }; /* A storage class specifier. */ @@ -220,11 +220,11 @@ struct c_declspecs { NULL; attributes (possibly from multiple lists) will be passed separately. */ tree attrs; - /* Any type specifier keyword used such as "int", not reflecting - modifiers such as "short", or cts_none if none. */ - enum c_typespec_keyword typespec_word; /* The storage class specifier, or csc_none if none. */ enum c_storage_class storage_class; + /* Any type specifier keyword used such as "int", not reflecting + modifiers such as "short", or cts_none if none. */ + ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8; /* Whether any expressions in typeof specifiers may appear in constant expressions. */ BOOL_BITFIELD expr_const_operands : 1; @@ -252,7 +252,7 @@ struct c_declspecs { BOOL_BITFIELD deprecated_p : 1; /* Whether the type defaulted to "int" because there were no type specifiers. */ - BOOL_BITFIELD default_int_p; + BOOL_BITFIELD default_int_p : 1; /* Whether "long" was specified. */ BOOL_BITFIELD long_p : 1; /* Whether "long" was specified more than once. */ @@ -319,9 +319,9 @@ struct c_arg_info { struct c_declarator { /* The kind of declarator. */ enum c_declarator_kind kind; + location_t id_loc; /* Currently only set for cdk_id, cdk_array. */ /* Except for cdk_id, the contained declarator. For cdk_id, NULL. */ struct c_declarator *declarator; - location_t id_loc; /* Currently only set for cdk_id, cdk_array. */ union { /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract declarator. */ diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 4baa8b4786a..935c4675df4 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -9503,6 +9503,46 @@ build_binary_op (location_t location, enum tree_code code, && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE)) short_compare = 1; + else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) + { + if (TREE_CODE (op0) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) + { + if (code == EQ_EXPR) + warning_at (location, + OPT_Waddress, + "the comparison will always evaluate as % " + "for the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + else + warning_at (location, + OPT_Waddress, + "the comparison will always evaluate as % " + "for the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + } + result_type = type0; + } + else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) + { + if (TREE_CODE (op1) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) + { + if (code == EQ_EXPR) + warning_at (location, + OPT_Waddress, + "the comparison will always evaluate as % " + "for the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + else + warning_at (location, + OPT_Waddress, + "the comparison will always evaluate as % " + "for the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + } + result_type = type1; + } else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { tree tt0 = TREE_TYPE (type0); @@ -9516,10 +9556,6 @@ build_binary_op (location_t location, enum tree_code code, and both must be object or both incomplete. */ if (comp_target_types (location, type0, type1)) result_type = common_pointer_type (type0, type1); - else if (null_pointer_constant_p (orig_op0)) - result_type = type1; - else if (null_pointer_constant_p (orig_op1)) - result_type = type0; else if (!addr_space_superset (as0, as1, &as_common)) { error_at (location, "comparison of pointers to " @@ -9551,24 +9587,6 @@ build_binary_op (location_t location, enum tree_code code, (build_qualified_type (void_type_node, qual)); } } - else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) - { - if (TREE_CODE (op0) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) - warning_at (location, - OPT_Waddress, "the address of %qD will never be NULL", - TREE_OPERAND (op0, 0)); - result_type = type0; - } - else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) - { - if (TREE_CODE (op1) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) - warning_at (location, - OPT_Waddress, "the address of %qD will never be NULL", - TREE_OPERAND (op1, 0)); - result_type = type1; - } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; diff --git a/gcc/c.opt b/gcc/c.opt index 973acf46c21..2e1933cd0d1 100644 --- a/gcc/c.opt +++ b/gcc/c.opt @@ -961,6 +961,10 @@ become a part of the upcoming ISO C++ standard, dubbed C++0x. Note that the extensions enabled by this mode are experimental and may be removed in future releases of GCC. +std=c1x +C ObjC +Conform to the ISO 201X C standard draft (experimental and incomplete support) + std=c89 C ObjC Conform to the ISO 1990 C standard @@ -988,6 +992,10 @@ extensions that are likely to become a part of the upcoming ISO C++ standard, dubbed C++0x. Note that the extensions enabled by this mode are experimental and may be removed in future releases of GCC. +std=gnu1x +C ObjC +Conform to the ISO 201X C standard draft with GNU extensions (experimental and incomplete support) + std=gnu89 C ObjC Conform to the ISO 1990 C standard with GNU extensions diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 26f9050076a..4135ed7a250 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -148,6 +148,9 @@ struct GTY ((chain_next ("%h.next"))) loop { bool any_upper_bound; bool any_estimate; + /* True if the loop can be parallel. */ + bool can_be_parallel; + /* An integer estimation of the number of iterations. Estimate_state describes what is the state of the estimation. */ enum loop_estimation estimate_state; @@ -158,9 +161,6 @@ struct GTY ((chain_next ("%h.next"))) loop { /* Head of the cyclic list of the exits of the loop. */ struct loop_exit *exits; - /* True if the loop can be parallel. */ - bool can_be_parallel; - /* The single induction variable of the loop when the loop is in normal form. */ tree single_iv; diff --git a/gcc/cgraph.c b/gcc/cgraph.c index c5e0f3d940c..424c3f21aeb 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -34,10 +34,16 @@ The callgraph: based on DECL_UID. The call-graph nodes are created lazily using cgraph_node function when called for unknown declaration. - The callgraph at the moment does not represent indirect calls or calls - from other compilation unit. Flag NEEDED is set for each node that may - be accessed in such an invisible way and it shall be considered an - entry point to the callgraph. + The callgraph at the moment does not represent all indirect calls or calls + from other compilation units. Flag NEEDED is set for each node that may be + accessed in such an invisible way and it shall be considered an entry point + to the callgraph. + + On the other hand, the callgraph currently does contain some edges for + indirect calls with unknown callees which can be accessed through + indirect_calls field of a node. It should be noted however that at the + moment only calls which are potential candidates for indirect inlining are + added there. Interprocedural information: @@ -48,6 +54,9 @@ The callgraph: rtl_info used by RTL backend to propagate data from already compiled functions to their callers. + Moreover, each node has a uid which can be used to keep information in + on-the-side arrays. UIDs are reused and therefore reasonably dense. + Inlining plans: The function inlining information is decided in advance and maintained @@ -453,6 +462,7 @@ cgraph_create_node (void) cgraph_nodes->previous = node; node->previous = NULL; node->global.estimated_growth = INT_MIN; + node->frequency = NODE_FREQUENCY_NORMAL; cgraph_nodes = node; cgraph_n_nodes++; return node; @@ -722,6 +732,19 @@ edge_eq (const void *x, const void *y) return ((const struct cgraph_edge *) x)->call_stmt == y; } +/* Add call graph edge E to call site hash of its caller. */ + +static inline void +cgraph_add_edge_to_call_site_hash (struct cgraph_edge *e) +{ + void **slot; + slot = htab_find_slot_with_hash (e->caller->call_site_hash, + e->call_stmt, + htab_hash_pointer (e->call_stmt), + INSERT); + gcc_assert (!*slot); + *slot = e; +} /* Return the callgraph edge representing the GIMPLE_CALL statement CALL_STMT. */ @@ -742,26 +765,28 @@ cgraph_edge (struct cgraph_node *node, gimple call_stmt) solution. It is not good idea to add pointer into CALL_EXPR itself because we want to make possible having multiple cgraph nodes representing different clones of the same body before the body is actually cloned. */ - for (e = node->callees; e; e= e->next_callee) + for (e = node->callees; e; e = e->next_callee) { if (e->call_stmt == call_stmt) break; n++; } + if (!e) + for (e = node->indirect_calls; e; e = e->next_callee) + { + if (e->call_stmt == call_stmt) + break; + n++; + } + if (n > 100) { node->call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL); for (e2 = node->callees; e2; e2 = e2->next_callee) - { - void **slot; - slot = htab_find_slot_with_hash (node->call_site_hash, - e2->call_stmt, - htab_hash_pointer (e2->call_stmt), - INSERT); - gcc_assert (!*slot); - *slot = e2; - } + cgraph_add_edge_to_call_site_hash (e2); + for (e2 = node->indirect_calls; e2; e2 = e2->next_callee) + cgraph_add_edge_to_call_site_hash (e2); } return e; @@ -773,26 +798,31 @@ cgraph_edge (struct cgraph_node *node, gimple call_stmt) void cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt) { + tree decl; + if (e->caller->call_site_hash) { htab_remove_elt_with_hash (e->caller->call_site_hash, e->call_stmt, htab_hash_pointer (e->call_stmt)); } + e->call_stmt = new_stmt; + if (e->indirect_unknown_callee + && (decl = gimple_call_fndecl (new_stmt))) + { + /* Constant propagation (and possibly also inlining?) can turn an + indirect call into a direct one. */ + struct cgraph_node *new_callee = cgraph_node (decl); + + cgraph_make_edge_direct (e, new_callee); + } + push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); e->can_throw_external = stmt_can_throw_external (new_stmt); pop_cfun (); if (e->caller->call_site_hash) - { - void **slot; - slot = htab_find_slot_with_hash (e->caller->call_site_hash, - e->call_stmt, - htab_hash_pointer - (e->call_stmt), INSERT); - gcc_assert (!*slot); - *slot = e; - } + cgraph_add_edge_to_call_site_hash (e); } /* Like cgraph_set_call_stmt but walk the clone tree and update all @@ -894,7 +924,9 @@ initialize_inline_failed (struct cgraph_edge *e) { struct cgraph_node *callee = e->callee; - if (!callee->analyzed) + if (e->indirect_unknown_callee) + e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL; + else if (!callee->analyzed) e->inline_failed = CIF_BODY_NOT_AVAILABLE; else if (callee->local.redefined_extern_inline) e->inline_failed = CIF_REDEFINED_EXTERN_INLINE; @@ -906,15 +938,16 @@ initialize_inline_failed (struct cgraph_edge *e) e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED; } -/* Create edge from CALLER to CALLEE in the cgraph. */ +/* Allocate a cgraph_edge structure and fill it with data according to the + parameters of which only CALLEE can be NULL (when creating an indirect call + edge). */ -struct cgraph_edge * -cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, - gimple call_stmt, gcov_type count, int freq, int nest) +static struct cgraph_edge * +cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee, + gimple call_stmt, gcov_type count, int freq, int nest) { struct cgraph_edge *edge; - /* LTO does not actually have access to the call_stmt since these have not been loaded yet. */ if (call_stmt) @@ -940,47 +973,83 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, } edge->aux = NULL; - edge->caller = caller; edge->callee = callee; + edge->prev_caller = NULL; + edge->next_caller = NULL; + edge->prev_callee = NULL; + edge->next_callee = NULL; + + edge->count = count; + gcc_assert (count >= 0); + edge->frequency = freq; + gcc_assert (freq >= 0); + gcc_assert (freq <= CGRAPH_FREQ_MAX); + edge->loop_nest = nest; + edge->call_stmt = call_stmt; push_cfun (DECL_STRUCT_FUNCTION (caller->decl)); edge->can_throw_external = call_stmt ? stmt_can_throw_external (call_stmt) : false; pop_cfun (); - edge->prev_caller = NULL; + edge->call_stmt_cannot_inline_p = + (call_stmt ? gimple_call_cannot_inline_p (call_stmt) : false); + if (call_stmt && caller->call_site_hash) + cgraph_add_edge_to_call_site_hash (edge); + + edge->indirect_info = NULL; + edge->indirect_inlining_edge = 0; + + return edge; +} + +/* Create edge from CALLER to CALLEE in the cgraph. */ + +struct cgraph_edge * +cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, + gimple call_stmt, gcov_type count, int freq, int nest) +{ + struct cgraph_edge *edge = cgraph_create_edge_1 (caller, callee, call_stmt, + count, freq, nest); + + edge->indirect_unknown_callee = 0; + initialize_inline_failed (edge); + edge->next_caller = callee->callers; if (callee->callers) callee->callers->prev_caller = edge; - edge->prev_callee = NULL; edge->next_callee = caller->callees; if (caller->callees) caller->callees->prev_callee = edge; caller->callees = edge; callee->callers = edge; - edge->count = count; - gcc_assert (count >= 0); - edge->frequency = freq; - gcc_assert (freq >= 0); - gcc_assert (freq <= CGRAPH_FREQ_MAX); - edge->loop_nest = nest; - edge->indirect_call = 0; - edge->call_stmt_cannot_inline_p = - (call_stmt ? gimple_call_cannot_inline_p (call_stmt) : false); - if (call_stmt && caller->call_site_hash) - { - void **slot; - slot = htab_find_slot_with_hash (caller->call_site_hash, - edge->call_stmt, - htab_hash_pointer - (edge->call_stmt), - INSERT); - gcc_assert (!*slot); - *slot = edge; - } + return edge; +} + + +/* Create an indirect edge with a yet-undetermined callee where the call + statement destination is a formal parameter of the caller with index + PARAM_INDEX. */ + +struct cgraph_edge * +cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt, + gcov_type count, int freq, int nest) +{ + struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt, + count, freq, nest); + + edge->indirect_unknown_callee = 1; initialize_inline_failed (edge); + edge->indirect_info = GGC_NEW (struct cgraph_indirect_call_info); + edge->indirect_info->param_index = -1; + + edge->next_callee = caller->indirect_calls; + if (caller->indirect_calls) + caller->indirect_calls->prev_callee = edge; + caller->indirect_calls = edge; + return edge; } @@ -989,6 +1058,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, static inline void cgraph_edge_remove_callee (struct cgraph_edge *e) { + gcc_assert (!e->indirect_unknown_callee); if (e->prev_caller) e->prev_caller->next_caller = e->next_caller; if (e->next_caller) @@ -1007,7 +1077,12 @@ cgraph_edge_remove_caller (struct cgraph_edge *e) if (e->next_callee) e->next_callee->prev_callee = e->prev_callee; if (!e->prev_callee) - e->caller->callees = e->next_callee; + { + if (e->indirect_unknown_callee) + e->caller->indirect_calls = e->next_callee; + else + e->caller->callees = e->next_callee; + } if (e->caller->call_site_hash) htab_remove_elt_with_hash (e->caller->call_site_hash, e->call_stmt, @@ -1036,8 +1111,9 @@ cgraph_remove_edge (struct cgraph_edge *e) /* Call all edge removal hooks. */ cgraph_call_edge_removal_hooks (e); - /* Remove from callers list of the callee. */ - cgraph_edge_remove_callee (e); + if (!e->indirect_unknown_callee) + /* Remove from callers list of the callee. */ + cgraph_edge_remove_callee (e); /* Remove from callees list of the callers. */ cgraph_edge_remove_caller (e); @@ -1046,6 +1122,20 @@ cgraph_remove_edge (struct cgraph_edge *e) cgraph_free_edge (e); } +/* Set callee of call graph edge E and add it to the corresponding set of + callers. */ + +static void +cgraph_set_edge_callee (struct cgraph_edge *e, struct cgraph_node *n) +{ + e->prev_caller = NULL; + if (n->callers) + n->callers->prev_caller = e; + e->next_caller = n->callers; + n->callers = e; + e->callee = n; +} + /* Redirect callee of E to N. The function does not update underlying call expression. */ @@ -1056,12 +1146,37 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n) cgraph_edge_remove_callee (e); /* Insert to callers list of the new callee. */ - e->prev_caller = NULL; - if (n->callers) - n->callers->prev_caller = e; - e->next_caller = n->callers; - n->callers = e; - e->callee = n; + cgraph_set_edge_callee (e, n); +} + +/* Make an indirect EDGE with an unknown callee an ordinary edge leading to + CALLEE. */ + +void +cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee) +{ + edge->indirect_unknown_callee = 0; + + /* Get the edge out of the indirect edge list. */ + if (edge->prev_callee) + edge->prev_callee->next_callee = edge->next_callee; + if (edge->next_callee) + edge->next_callee->prev_callee = edge->prev_callee; + if (!edge->prev_callee) + edge->caller->indirect_calls = edge->next_callee; + + /* Put it into the normal callee list */ + edge->prev_callee = NULL; + edge->next_callee = edge->caller->callees; + if (edge->caller->callees) + edge->caller->callees->prev_callee = edge; + edge->caller->callees = edge; + + /* Insert to callers list of the new callee. */ + cgraph_set_edge_callee (edge, callee); + + /* We need to re-determine the inlining status of the edge. */ + initialize_inline_failed (edge); } @@ -1090,9 +1205,10 @@ cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node, if (e) { - /* See if the call is already there. It might be because of indirect - inlining already found it. */ - if (new_call && e->callee->decl == new_call) + /* See if the edge is already there and has the correct callee. It + might be so because of indirect inlining has already updated + it. */ + if (new_call && e->callee && e->callee->decl == new_call) return; /* Otherwise remove edge and create new one; we can't simply redirect @@ -1170,7 +1286,8 @@ cgraph_node_remove_callees (struct cgraph_node *node) { f = e->next_callee; cgraph_call_edge_removal_hooks (e); - cgraph_edge_remove_callee (e); + if (!e->indirect_unknown_callee) + cgraph_edge_remove_callee (e); cgraph_free_edge (e); } node->callees = NULL; @@ -1626,6 +1743,8 @@ void dump_cgraph_node (FILE *f, struct cgraph_node *node) { struct cgraph_edge *edge; + int indirect_calls_count = 0; + fprintf (f, "%s/%i(%i)", cgraph_node_name (node), node->uid, node->pid); dump_addr (f, " @", (void *)node); @@ -1707,8 +1826,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) edge->frequency / (double)CGRAPH_FREQ_BASE); if (!edge->inline_failed) fprintf(f, "(inlined) "); - if (edge->indirect_call) - fprintf(f, "(indirect) "); + if (edge->indirect_inlining_edge) + fprintf(f, "(indirect_inlining) "); if (edge->can_throw_external) fprintf(f, "(can throw external) "); } @@ -1720,8 +1839,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) edge->callee->uid); if (!edge->inline_failed) fprintf(f, "(inlined) "); - if (edge->indirect_call) - fprintf(f, "(indirect) "); + if (edge->indirect_inlining_edge) + fprintf(f, "(indirect_inlining) "); if (edge->count) fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ", (HOST_WIDEST_INT)edge->count); @@ -1735,6 +1854,12 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) } fprintf (f, "\n"); + for (edge = node->indirect_calls; edge; edge = edge->next_callee) + indirect_calls_count++; + if (indirect_calls_count) + fprintf (f, " has %i outgoing edges for indirect calls.\n", + indirect_calls_count); + if (node->same_body) { struct cgraph_node *n; @@ -1752,6 +1877,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) (int)n->thunk.virtual_offset_p); fprintf (f, ")"); } + if (DECL_ASSEMBLER_NAME_SET_P (n->decl)) + fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl))); } fprintf (f, "\n"); } @@ -1854,11 +1981,30 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, freq = e->frequency * (gcov_type) freq_scale / CGRAPH_FREQ_BASE; if (freq > CGRAPH_FREQ_MAX) freq = CGRAPH_FREQ_MAX; - new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq, - e->loop_nest + loop_nest); + + if (e->indirect_unknown_callee) + { + tree decl; + + if (call_stmt && (decl = gimple_call_fndecl (call_stmt))) + { + struct cgraph_node *callee = cgraph_node (decl); + new_edge = cgraph_create_edge (n, callee, call_stmt, count, freq, + e->loop_nest + loop_nest); + } + else + { + new_edge = cgraph_create_indirect_edge (n, call_stmt, count, freq, + e->loop_nest + loop_nest); + new_edge->indirect_info->param_index = e->indirect_info->param_index; + } + } + else + new_edge = cgraph_create_edge (n, e->callee, call_stmt, count, freq, + e->loop_nest + loop_nest); new_edge->inline_failed = e->inline_failed; - new_edge->indirect_call = e->indirect_call; + new_edge->indirect_inlining_edge = e->indirect_inlining_edge; new_edge->lto_stmt_uid = stmt_uid; if (update_original) { @@ -1896,9 +2042,12 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, new_node->analyzed = n->analyzed; new_node->local = n->local; new_node->local.externally_visible = false; + new_node->local.local = true; + new_node->local.vtable_method = false; new_node->global = n->global; new_node->rtl = n->rtl; new_node->count = count; + new_node->frequency = n->frequency; new_node->clone = n->clone; new_node->clone.tree_map = 0; if (n->count) @@ -1929,6 +2078,10 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid, count_scale, freq, loop_nest, update_original); + for (e = n->indirect_calls; e; e = e->next_callee) + cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid, + count_scale, freq, loop_nest, update_original); + new_node->next_sibling_clone = n->clones; if (n->clones) n->clones->prev_sibling_clone = new_node; @@ -2305,4 +2458,67 @@ cgraph_set_looping_const_or_pure_flag (struct cgraph_node *node, DECL_LOOPING_CONST_OR_PURE_P (alias->decl) = looping_const_or_pure; } +/* See if the frequency of NODE can be updated based on frequencies of its + callers. */ +bool +cgraph_propagate_frequency (struct cgraph_node *node) +{ + bool maybe_unlikely_executed = true, maybe_executed_once = true; + struct cgraph_edge *edge; + if (!node->local.local) + return false; + gcc_assert (node->analyzed); + if (node->frequency == NODE_FREQUENCY_HOT) + return false; + if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) + return false; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node)); + for (edge = node->callers; + edge && (maybe_unlikely_executed || maybe_executed_once); + edge = edge->next_caller) + { + if (!edge->frequency) + continue; + switch (edge->caller->frequency) + { + case NODE_FREQUENCY_UNLIKELY_EXECUTED: + break; + case NODE_FREQUENCY_EXECUTED_ONCE: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Called by %s that is executed once\n", cgraph_node_name (node)); + maybe_unlikely_executed = false; + if (edge->loop_nest) + { + maybe_executed_once = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Called in loop\n"); + } + break; + case NODE_FREQUENCY_HOT: + case NODE_FREQUENCY_NORMAL: + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Called by %s that is normal or hot\n", cgraph_node_name (node)); + maybe_unlikely_executed = false; + maybe_executed_once = false; + break; + } + } + if (maybe_unlikely_executed) + { + node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; + if (dump_file) + fprintf (dump_file, "Node %s promoted to unlikely executed.\n", cgraph_node_name (node)); + return true; + } + if (maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE) + { + node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; + if (dump_file) + fprintf (dump_file, "Node %s promoted to executed once.\n", cgraph_node_name (node)); + return true; + } + return false; +} + #include "gt-cgraph.h" diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 6bc565a2d17..f063cb4a41f 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -175,6 +175,21 @@ struct GTY(()) cgraph_clone_info bitmap combined_args_to_skip; }; +enum node_frequency { + /* This function most likely won't be executed at all. + (set only when profile feedback is available or via function attribute). */ + NODE_FREQUENCY_UNLIKELY_EXECUTED, + /* For functions that are known to be executed once (i.e. constructors, destructors + and main function. */ + NODE_FREQUENCY_EXECUTED_ONCE, + /* The default value. */ + NODE_FREQUENCY_NORMAL, + /* Optimize this function hard + (set only when profile feedback is available or via function attribute). */ + NODE_FREQUENCY_HOT +}; + + /* The cgraph data structure. Each function decl has assigned cgraph_node listing callees and callers. */ @@ -184,6 +199,9 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { struct cgraph_edge *callers; struct cgraph_node *next; struct cgraph_node *previous; + /* List of edges representing indirect calls with a yet undetermined + callee. */ + struct cgraph_edge *indirect_calls; /* For nested functions points to function the node is nested in. */ struct cgraph_node *origin; /* Points to first nested function, if any. */ @@ -256,7 +274,7 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { /* Set once the function has been instantiated and its callee lists created. */ unsigned analyzed : 1; - /* Set when function is available in the other LTO partition. */ + /* Set when function is available in the other LTRANS partition. */ unsigned in_other_partition : 1; /* Set when function is scheduled to be processed by local passes. */ unsigned process : 1; @@ -267,6 +285,9 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { /* Set for alias and thunk nodes, same_body points to the node they are alias of and they are linked through the next/previous pointers. */ unsigned same_body_alias : 1; + /* How commonly executed the node is. Initialized during branch + probabilities pass. */ + ENUM_BITFIELD (node_frequency) frequency : 2; }; typedef struct cgraph_node *cgraph_node_ptr; @@ -284,12 +305,33 @@ struct GTY(()) cgraph_node_set_def PTR GTY ((skip)) aux; }; +typedef struct varpool_node *varpool_node_ptr; + +DEF_VEC_P(varpool_node_ptr); +DEF_VEC_ALLOC_P(varpool_node_ptr,heap); +DEF_VEC_ALLOC_P(varpool_node_ptr,gc); + +/* A varpool node set is a collection of varpool nodes. A varpool node + can appear in multiple sets. */ +struct GTY(()) varpool_node_set_def +{ + htab_t GTY((param_is (struct varpool_node_set_element_def))) hashtab; + VEC(varpool_node_ptr, gc) *nodes; + PTR GTY ((skip)) aux; +}; + typedef struct cgraph_node_set_def *cgraph_node_set; DEF_VEC_P(cgraph_node_set); DEF_VEC_ALLOC_P(cgraph_node_set,gc); DEF_VEC_ALLOC_P(cgraph_node_set,heap); +typedef struct varpool_node_set_def *varpool_node_set; + +DEF_VEC_P(varpool_node_set); +DEF_VEC_ALLOC_P(varpool_node_set,gc); +DEF_VEC_ALLOC_P(varpool_node_set,heap); + /* A cgraph node set element contains an index in the vector of nodes in the set. */ struct GTY(()) cgraph_node_set_element_def @@ -308,6 +350,24 @@ typedef struct unsigned index; } cgraph_node_set_iterator; +/* A varpool node set element contains an index in the vector of nodes in + the set. */ +struct GTY(()) varpool_node_set_element_def +{ + struct varpool_node *node; + HOST_WIDE_INT index; +}; + +typedef struct varpool_node_set_element_def *varpool_node_set_element; +typedef const struct varpool_node_set_element_def *const_varpool_node_set_element; + +/* Iterator structure for varpool node sets. */ +typedef struct +{ + varpool_node_set set; + unsigned index; +} varpool_node_set_iterator; + #define DEFCIFCODE(code, string) CIF_ ## code, /* Reasons for inlining failures. */ typedef enum { @@ -315,6 +375,14 @@ typedef enum { CIF_N_REASONS } cgraph_inline_failed_t; +/* Structure containing additional information about an indirect call. */ + +struct GTY(()) cgraph_indirect_call_info +{ + /* Index of the parameter that is called. */ + int param_index; +}; + struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge { /* Expected number of executions: calculated in profile.c. */ gcov_type count; @@ -325,6 +393,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap struct cgraph_edge *prev_callee; struct cgraph_edge *next_callee; gimple call_stmt; + /* Additional information about an indirect call. Not cleared when an edge + becomes direct. */ + struct cgraph_indirect_call_info *indirect_info; PTR GTY ((skip (""))) aux; /* When equal to CIF_OK, inline this call. Otherwise, points to the explanation why function was not inlined. */ @@ -340,8 +411,12 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap int uid; /* Depth of loop nest, 1 means no loop nest. */ unsigned short int loop_nest; - /* Whether this edge describes a call that was originally indirect. */ - unsigned int indirect_call : 1; + /* Whether this edge was made direct by indirect inlining. */ + unsigned int indirect_inlining_edge : 1; + /* Whether this edge describes an indirect call with an undetermined + callee. */ + unsigned int indirect_unknown_callee : 1; + /* Whether this edge is still a dangling */ /* True if the corresponding CALL stmt cannot be inlined. */ unsigned int call_stmt_cannot_inline_p : 1; /* Can this call throw externally? */ @@ -362,9 +437,9 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap); struct GTY((chain_next ("%h.next"))) varpool_node { tree decl; /* Pointer to the next function in varpool_nodes. */ - struct varpool_node *next; + struct varpool_node *next, *prev; /* Pointer to the next function in varpool_nodes_queue. */ - struct varpool_node *next_needed; + struct varpool_node *next_needed, *prev_needed; /* For normal nodes a pointer to the first extra name alias. For alias nodes a pointer to the normal node. */ struct varpool_node *extra_name; @@ -389,6 +464,10 @@ struct GTY((chain_next ("%h.next"))) varpool_node { /* Set for aliases once they got through assemble_alias. Also set for extra name aliases in varpool_extra_name_alias. */ unsigned alias : 1; + /* Set when variable is used from other LTRANS partition. */ + unsigned used_from_other_partition : 1; + /* Set when variable is available in the other LTRANS partition. */ + unsigned in_other_partition : 1; }; /* Every top level asm statement is put into a cgraph_asm_node. */ @@ -443,7 +522,8 @@ void cgraph_node_remove_callees (struct cgraph_node *node); struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_node *, gimple, gcov_type, int, int); - +struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, + gcov_type, int, int); struct cgraph_node * cgraph_get_node (tree); struct cgraph_node *cgraph_node (tree); bool cgraph_same_body_alias (tree, tree); @@ -469,6 +549,7 @@ struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type, int, int, bool, VEC(cgraph_edge_p,heap) *); void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *); +void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *); struct cgraph_asm_node *cgraph_add_asm_node (tree); @@ -539,6 +620,7 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); void cgraph_materialize_all_clones (void); gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *); +bool cgraph_propagate_frequency (struct cgraph_node *node); /* In cgraphbuild.c */ unsigned int rebuild_cgraph_edges (void); void reset_inline_failed (struct cgraph_node *); @@ -555,6 +637,13 @@ void cgraph_node_set_remove (cgraph_node_set, struct cgraph_node *); void dump_cgraph_node_set (FILE *, cgraph_node_set); void debug_cgraph_node_set (cgraph_node_set); +varpool_node_set varpool_node_set_new (void); +varpool_node_set_iterator varpool_node_set_find (varpool_node_set, + struct varpool_node *); +void varpool_node_set_add (varpool_node_set, struct varpool_node *); +void varpool_node_set_remove (varpool_node_set, struct varpool_node *); +void dump_varpool_node_set (FILE *, varpool_node_set); +void debug_varpool_node_set (varpool_node_set); /* In predict.c */ bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e); @@ -577,6 +666,9 @@ void cgraph_make_decl_local (tree); void cgraph_make_node_local (struct cgraph_node *); bool cgraph_node_can_be_local_p (struct cgraph_node *); + +struct varpool_node * varpool_get_node (tree decl); +void varpool_remove_node (struct varpool_node *node); bool varpool_assemble_pending_decls (void); bool varpool_assemble_decl (struct varpool_node *node); bool varpool_analyze_pending_decls (void); @@ -638,6 +730,7 @@ enum LTO_cgraph_tags LTO_cgraph_overwritable_node, LTO_cgraph_unavail_node, LTO_cgraph_edge, + LTO_cgraph_indirect_edge, LTO_cgraph_last_tag }; @@ -694,6 +787,54 @@ cgraph_node_set_size (cgraph_node_set set) return htab_elements (set->hashtab); } +/* Return true if iterator VSI points to nothing. */ +static inline bool +vsi_end_p (varpool_node_set_iterator vsi) +{ + return vsi.index >= VEC_length (varpool_node_ptr, vsi.set->nodes); +} + +/* Advance iterator VSI. */ +static inline void +vsi_next (varpool_node_set_iterator *vsi) +{ + vsi->index++; +} + +/* Return the node pointed to by VSI. */ +static inline struct varpool_node * +vsi_node (varpool_node_set_iterator vsi) +{ + return VEC_index (varpool_node_ptr, vsi.set->nodes, vsi.index); +} + +/* Return an iterator to the first node in SET. */ +static inline varpool_node_set_iterator +vsi_start (varpool_node_set set) +{ + varpool_node_set_iterator vsi; + + vsi.set = set; + vsi.index = 0; + return vsi; +} + +/* Return true if SET contains NODE. */ +static inline bool +varpool_node_in_set_p (struct varpool_node *node, varpool_node_set set) +{ + varpool_node_set_iterator vsi; + vsi = varpool_node_set_find (set, node); + return !vsi_end_p (vsi); +} + +/* Return number of nodes in SET. */ +static inline size_t +varpool_node_set_size (varpool_node_set set) +{ + return htab_elements (set->hashtab); +} + /* Uniquize all constants that appear in memory. Each constant in memory thus far output is recorded in `const_desc_table'. */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 608a4af7c46..c1729bccf20 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -382,6 +382,7 @@ cgraph_process_new_functions (void) tree fndecl; struct cgraph_node *node; + varpool_analyze_pending_decls (); /* Note that this queue may grow as its being processed, as the new functions may generate new ones. */ while (cgraph_new_nodes) @@ -437,6 +438,7 @@ cgraph_process_new_functions (void) break; } cgraph_call_function_insertion_hooks (node); + varpool_analyze_pending_decls (); } return output; } @@ -623,6 +625,24 @@ verify_cgraph_node (struct cgraph_node *node) error ("Inline clone is needed"); error_found = true; } + for (e = node->indirect_calls; e; e = e->next_callee) + { + if (e->aux) + { + error ("aux field set for indirect edge from %s", + identifier_to_locale (cgraph_node_name (e->caller))); + error_found = true; + } + if (!e->indirect_unknown_callee + || !e->indirect_info) + { + error ("An indirect edge from %s is not marked as indirect or has " + "associated indirect_info, the corresponding statement is: ", + identifier_to_locale (cgraph_node_name (e->caller))); + debug_gimple_stmt (e->call_stmt); + error_found = true; + } + } for (e = node->callers; e; e = e->next_caller) { if (e->count < 0) @@ -730,6 +750,32 @@ verify_cgraph_node (struct cgraph_node *node) error ("double linked list of clones corrupted"); error_found = true; } + if (node->same_comdat_group) + { + struct cgraph_node *n = node->same_comdat_group; + + if (!DECL_ONE_ONLY (node->decl)) + { + error ("non-DECL_ONE_ONLY node in a same_comdat_group list"); + error_found = true; + } + if (n == node) + { + error ("node is alone in a comdat group"); + error_found = true; + } + do + { + if (!n->same_comdat_group) + { + error ("same_comdat_group is not a circular list"); + error_found = true; + break; + } + n = n->same_comdat_group; + } + while (n != node); + } if (node->analyzed && gimple_has_body_p (node->decl) && !TREE_ASM_WRITTEN (node->decl) @@ -749,10 +795,10 @@ verify_cgraph_node (struct cgraph_node *node) gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - tree decl; - if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt))) + if (is_gimple_call (stmt)) { struct cgraph_edge *e = cgraph_edge (node, stmt); + tree decl = gimple_call_fndecl (stmt); if (e) { if (e->aux) @@ -761,25 +807,38 @@ verify_cgraph_node (struct cgraph_node *node) debug_gimple_stmt (stmt); error_found = true; } - if (e->callee->same_body_alias) + if (!e->indirect_unknown_callee) { - error ("edge points to same body alias:"); - debug_tree (e->callee->decl); - error_found = true; + if (e->callee->same_body_alias) + { + error ("edge points to same body alias:"); + debug_tree (e->callee->decl); + error_found = true; + } + else if (!node->global.inlined_to + && !e->callee->global.inlined_to + && decl + && !clone_of_p (cgraph_node (decl), + e->callee)) + { + error ("edge points to wrong declaration:"); + debug_tree (e->callee->decl); + fprintf (stderr," Instead of:"); + debug_tree (decl); + error_found = true; + } } - else if (!node->global.inlined_to - && !e->callee->global.inlined_to - && !clone_of_p (cgraph_node (decl), e->callee)) + else if (decl) { - error ("edge points to wrong declaration:"); - debug_tree (e->callee->decl); - fprintf (stderr," Instead of:"); - debug_tree (decl); + error ("an indirect edge with unknown callee " + "corresponding to a call_stmt with " + "a known declaration:"); error_found = true; + debug_gimple_stmt (e->call_stmt); } e->aux = (void *)1; } - else + else if (decl) { error ("missing callgraph edge for call stmt:"); debug_gimple_stmt (stmt); @@ -795,7 +854,7 @@ verify_cgraph_node (struct cgraph_node *node) for (e = node->callees; e; e = e->next_callee) { - if (!e->aux && !e->indirect_call) + if (!e->aux) { error ("edge %s->%s has no corresponding call_stmt", identifier_to_locale (cgraph_node_name (e->caller)), @@ -805,6 +864,17 @@ verify_cgraph_node (struct cgraph_node *node) } e->aux = 0; } + for (e = node->indirect_calls; e; e = e->next_callee) + { + if (!e->aux) + { + error ("an indirect edge from %s has no corresponding call_stmt", + identifier_to_locale (cgraph_node_name (e->caller))); + debug_gimple_stmt (e->call_stmt); + error_found = true; + } + e->aux = 0; + } } if (error_found) { @@ -2043,7 +2113,7 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version, VEC(cgraph_edge_p,heap) *redirect_callers) { struct cgraph_node *new_version; - struct cgraph_edge *e, *new_e; + struct cgraph_edge *e; struct cgraph_edge *next_callee; unsigned i; @@ -2062,10 +2132,10 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version, also cloned. */ for (e = old_version->callees;e; e=e->next_callee) { - new_e = cgraph_clone_edge (e, new_version, e->call_stmt, - e->lto_stmt_uid, 0, e->frequency, - e->loop_nest, true); - new_e->count = e->count; + cgraph_clone_edge (e, new_version, e->call_stmt, + e->lto_stmt_uid, REG_BR_PROB_BASE, + CGRAPH_FREQ_BASE, + e->loop_nest, true); } /* Fix recursive calls. If OLD_VERSION has a recursive call after the diff --git a/gcc/cif-code.def b/gcc/cif-code.def index 2de63b62178..4898486c315 100644 --- a/gcc/cif-code.def +++ b/gcc/cif-code.def @@ -84,3 +84,7 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, N_("mismatched arguments")) /* Call was originally indirect. */ DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, N_("originally indirect function call not considered for inlining")) + +/* Ths edge represents an indirect edge with a yet-undetermined callee . */ +DEFCIFCODE(INDIRECT_UNKNOWN_CALL, + N_("indirect function call with a yet undetermined callee")) diff --git a/gcc/collect2.c b/gcc/collect2.c index 120369a2662..481f73990f9 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -35,6 +35,10 @@ along with GCC; see the file COPYING3. If not see # define SIGCHLD SIGCLD #endif +/* TARGET_64BIT may be defined to use driver specific functionality. */ +#undef TARGET_64BIT +#define TARGET_64BIT TARGET_64BIT_DEFAULT + #ifndef LIBRARY_PATH_ENV #define LIBRARY_PATH_ENV "LIBRARY_PATH" #endif @@ -2548,19 +2552,21 @@ write_aix_file (FILE *stream, struct id *list) be in ELF format. */ static bool -is_elf (const char *prog_name) +is_elf_or_coff (const char *prog_name) { FILE *f; char buf[4]; static char magic[4] = { 0x7f, 'E', 'L', 'F' }; + static char coffmag[2] = { 0x4c, 0x01 }; - f = fopen (prog_name, "r"); + f = fopen (prog_name, "rb"); if (f == NULL) return false; if (fread (buf, sizeof (buf), 1, f) != 1) buf[0] = 0; fclose (f); - return memcmp (buf, magic, sizeof (magic)) == 0; + return memcmp (buf, magic, sizeof (magic)) == 0 + || memcmp (buf, coffmag, sizeof (coffmag)) == 0; } /* Generic version to scan the name list of the loaded program for @@ -2587,10 +2593,10 @@ scan_prog_file (const char *prog_name, scanpass which_pass, if (which_pass == PASS_SECOND) return; - /* LTO objects must be in ELF format. This check prevents + /* LTO objects must be in a known format. This check prevents us from accepting an archive containing LTO objects, which gcc cannnot currently handle. */ - if (which_pass == PASS_LTOINFO && !is_elf (prog_name)) + if (which_pass == PASS_LTOINFO && !is_elf_or_coff (prog_name)) return; /* If we do not have an `nm', complain. */ @@ -2670,9 +2676,9 @@ scan_prog_file (const char *prog_name, scanpass which_pass, /* Look for the LTO info marker symbol, and add filename to the LTO objects list if found. */ for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++) - if (ch == ' ' - && (strncmp (p + 1, "__gnu_lto_v1", 12) == 0) - && ISSPACE (p[13])) + if (ch == ' ' && p[1] == '_' && p[2] == '_' + && (strncmp (p + (p[3] == '_' ? 2 : 1), "__gnu_lto_v1", 12) == 0) + && ISSPACE (p[p[3] == '_' ? 14 : 13])) { add_lto_object (<o_objects, prog_name); diff --git a/gcc/common.opt b/gcc/common.opt index 70b2c9050bf..e62e3d583a0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -180,6 +180,14 @@ Wstrict-overflow= Common Joined UInteger Var(warn_strict_overflow) Init(-1) Warning Warn about optimizations that assume that signed overflow is undefined +Wsuggest-attribute=const +Common Var(warn_suggest_attribute_const) Warning +Warn about functions which might be candidates for __attribute__((const)) + +Wsuggest-attribute=pure +Common Var(warn_suggest_attribute_pure) Warning +Warn about functions which might be candidates for __attribute__((pure)) + Wswitch Common Var(warn_switch) Warning Warn about enumerated switches, with no default, missing a case @@ -693,14 +701,18 @@ fipa-cp-clone Common Report Var(flag_ipa_cp_clone) Optimization Perform cloning to make Interprocedural constant propagation stronger -fipa-pure-const -Common Report Var(flag_ipa_pure_const) Init(0) Optimization -Discover pure and const functions +fipa-profile +Common Report Var(flag_ipa_profile) Init(0) Optimization +Perform interprocedural profile propagation fipa-pta Common Report Var(flag_ipa_pta) Init(0) Optimization Perform interprocedural points-to analysis +fipa-pure-const +Common Report Var(flag_ipa_pure_const) Init(0) Optimization +Discover pure and const functions + fipa-reference Common Report Var(flag_ipa_reference) Init(0) Optimization Discover readonly and non addressable static variables diff --git a/gcc/config.gcc b/gcc/config.gcc index 88631ff66e6..73be7152037 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -200,6 +200,8 @@ default_use_cxa_atexit=no target_gtfiles= need_64bit_hwint= need_64bit_isa= +# Selects the object file format reader/writer used by LTO. +lto_binary_reader=lto-elf # Don't carry these over build->host->target. Please. xm_file= @@ -1324,6 +1326,7 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*) thread_file='posix' fi use_gcc_stdint=wrap + lto_binary_reader=lto-coff ;; i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h" @@ -1391,6 +1394,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*) cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o" default_use_cxa_atexit=yes use_gcc_stdint=wrap + lto_binary_reader=lto-coff case ${enable_threads} in "" | yes | win32) thread_file='win32' tmake_file="${tmake_file} i386/t-gthr-win32" diff --git a/gcc/config.in b/gcc/config.in index 9525625630f..7b04bbcb856 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1679,6 +1679,12 @@ #endif +/* Define if we should use leading underscore on 64 bit mingw targets */ +#ifndef USED_FOR_TARGET +#undef USE_MINGW64_LEADING_UNDERSCORES +#endif + + /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h index 24ab5f66b8c..d2bf732543d 100644 --- a/gcc/config/alpha/elf.h +++ b/gcc/config/alpha/elf.h @@ -272,20 +272,36 @@ do { \ /* Write the extra assembler code needed to declare an object properly. */ +#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT +#define USE_GNU_UNIQUE_OBJECT 1 +#else +#define USE_GNU_UNIQUE_OBJECT 0 +#endif + #undef ASM_DECLARE_OBJECT_NAME -#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ - do { \ - HOST_WIDE_INT size; \ - ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \ - size_directive_output = 0; \ - if (!flag_inhibit_size_directive \ - && DECL_SIZE (DECL) \ - && (size = int_size_in_bytes (TREE_TYPE (DECL))) > 0) \ - { \ - size_directive_output = 1; \ - ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \ - } \ - ASM_OUTPUT_LABEL(FILE, NAME); \ +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + do { \ + HOST_WIDE_INT size; \ + \ + /* For template static data member instantiations or \ + inline fn local statics, use gnu_unique_object so that \ + they will be combined even under RTLD_LOCAL. */ \ + if (USE_GNU_UNIQUE_OBJECT \ + && !DECL_ARTIFICIAL (DECL) && DECL_ONE_ONLY (DECL)) \ + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object"); \ + else \ + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \ + \ + size_directive_output = 0; \ + if (!flag_inhibit_size_directive \ + && (DECL) && DECL_SIZE (DECL)) \ + { \ + size_directive_output = 1; \ + size = int_size_in_bytes (TREE_TYPE (DECL)); \ + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \ + } \ + \ + ASM_OUTPUT_LABEL (FILE, NAME); \ } while (0) /* Output the size directive for a decl in rest_of_decl_compilation diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h index 406eda4c4f3..67348bb2f97 100644 --- a/gcc/config/alpha/osf5.h +++ b/gcc/config/alpha/osf5.h @@ -238,6 +238,14 @@ __enable_execute_stack (void *addr) \ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \ : DW_EH_PE_aligned) +/* The Tru64 UNIX assembler warns on .lcomm with SIZE 0, so use 1 in that + case. */ +#undef ASM_OUTPUT_LOCAL +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \ +( fputs ("\t.lcomm ", (FILE)), \ + assemble_name ((FILE), (NAME)), \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE) ? (SIZE) : 1)) + /* This is how we tell the assembler that a symbol is weak. */ #define ASM_OUTPUT_WEAK_ALIAS(FILE, NAME, VALUE) \ diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 8d21b8782f0..884a1bdace9 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -151,7 +151,6 @@ static bool arm_memory_load_p (rtx); static bool arm_cirrus_insn_p (rtx); static void cirrus_reorg (rtx); static void arm_init_builtins (void); -static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int); static void arm_init_iwmmxt_builtins (void); static rtx safe_vector_operand (rtx, enum machine_mode); static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx); @@ -19402,6 +19401,51 @@ thumb_compute_initial_elimination_offset (unsigned int from, unsigned int to) } } +/* Given the stack offsets and register mask in OFFSETS, decide + how many additional registers to push instead of subtracting + a constant from SP. */ +static int +thumb1_extra_regs_pushed (arm_stack_offsets *offsets) +{ + HOST_WIDE_INT amount = offsets->outgoing_args - offsets->saved_regs; + unsigned long live_regs_mask = offsets->saved_regs_mask; + /* Extract a mask of the ones we can give to the Thumb's push instruction. */ + unsigned long l_mask = live_regs_mask & 0x40ff; + /* Then count how many other high registers will need to be pushed. */ + unsigned long high_regs_pushed = bit_count (live_regs_mask & 0x0f00); + int n_free; + + /* If the stack frame size is 512 exactly, we can save one load + instruction, which should make this a win even when optimizing + for speed. */ + if (!optimize_size && amount != 512) + return 0; + + /* Can't do this if there are high registers to push, or if we + are not going to do a push at all. */ + if (high_regs_pushed != 0 || l_mask == 0) + return 0; + + /* Don't do this if thumb1_expand_prologue wants to emit instructions + between the push and the stack frame allocation. */ + if ((flag_pic && arm_pic_register != INVALID_REGNUM) + || (!frame_pointer_needed && CALLER_INTERWORKING_SLOT_SIZE > 0)) + return 0; + + for (n_free = 0; n_free < 8 && !(live_regs_mask & 1); live_regs_mask >>= 1) + n_free++; + + if (n_free == 0) + return 0; + gcc_assert (amount / 4 * 4 == amount); + + if (amount >= 512 && (amount - n_free * 4) < 512) + return (amount - 508) / 4; + if (amount <= n_free * 4) + return amount / 4; + return 0; +} + /* Generate the rest of a function's prologue. */ void thumb1_expand_prologue (void) @@ -19438,6 +19482,7 @@ thumb1_expand_prologue (void) stack_pointer_rtx); amount = offsets->outgoing_args - offsets->saved_regs; + amount -= 4 * thumb1_extra_regs_pushed (offsets); if (amount) { if (amount < 512) @@ -19742,7 +19787,11 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED) register. */ else if ((l_mask & 0xff) != 0 || (high_regs_pushed == 0 && l_mask)) - thumb_pushpop (f, l_mask, 1, &cfa_offset, l_mask); + { + unsigned long mask = l_mask; + mask |= (1 << thumb1_extra_regs_pushed (offsets)) - 1; + thumb_pushpop (f, mask, 1, &cfa_offset, mask); + } if (high_regs_pushed) { diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h index 6f5839a4537..2d1706319fe 100644 --- a/gcc/config/arm/unknown-elf.h +++ b/gcc/config/arm/unknown-elf.h @@ -52,7 +52,7 @@ #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG /* Return a nonzero value if DECL has a section attribute. */ -#define IN_NAMED_SECTION(DECL) \ +#define IN_NAMED_SECTION_P(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ && DECL_SECTION_NAME (DECL) != NULL_TREE) @@ -60,7 +60,7 @@ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ do \ { \ - if (IN_NAMED_SECTION (DECL)) \ + if (IN_NAMED_SECTION_P (DECL)) \ switch_to_section (get_named_section (DECL, NULL, 0)); \ else \ switch_to_section (bss_section); \ @@ -77,7 +77,7 @@ #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \ do \ { \ - if ((DECL) != NULL && IN_NAMED_SECTION (DECL)) \ + if ((DECL) != NULL && IN_NAMED_SECTION_P (DECL)) \ switch_to_section (get_named_section (DECL, NULL, 0)); \ else \ switch_to_section (bss_section); \ diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index a726bb4455e..71a5d8d99c9 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -39,6 +39,11 @@ along with GCC; see the file COPYING3. If not see #undef DEFAULT_ABI #define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI) +#if ! defined (USE_MINGW64_LEADING_UNDERSCORES) +#undef USER_LABEL_PREFIX +#define USER_LABEL_PREFIX (TARGET_64BIT ? "" : "_") +#endif + #undef DBX_REGISTER_NUMBER #define DBX_REGISTER_NUMBER(n) \ (TARGET_64BIT ? dbx64_register_map[n] \ diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h index f95d9c9d94d..f2c8984ab84 100644 --- a/gcc/config/i386/darwin.h +++ b/gcc/config/i386/darwin.h @@ -92,6 +92,7 @@ along with GCC; see the file COPYING3. If not see #undef CC1_SPEC #define CC1_SPEC "%(cc1_cpu) \ + %machine->use_fast_prologue_epilogue_nregs != frame->nregs) { int count = frame->nregs; + struct cgraph_node *node = cgraph_node (current_function_decl); cfun->machine->use_fast_prologue_epilogue_nregs = count; /* The fast prologue uses move instead of push to save registers. This @@ -8024,9 +8025,9 @@ ix86_compute_frame_layout (struct ix86_frame *frame) slow to use many of them. */ if (count) count = (count - 1) * FAST_PROLOGUE_INSN_COUNT; - if (cfun->function_frequency < FUNCTION_FREQUENCY_NORMAL + if (node->frequency < NODE_FREQUENCY_NORMAL || (flag_branch_probabilities - && cfun->function_frequency < FUNCTION_FREQUENCY_HOT)) + && node->frequency < NODE_FREQUENCY_HOT)) cfun->machine->use_fast_prologue_epilogue = false; else cfun->machine->use_fast_prologue_epilogue @@ -11419,7 +11420,7 @@ get_some_local_dynamic_name (void) return cfun->machine->some_ld_name; for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) - if (INSN_P (insn) + if (NONDEBUG_INSN_P (insn) && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0)) return cfun->machine->some_ld_name; @@ -13665,7 +13666,7 @@ distance_non_agu_define (unsigned int regno1, unsigned int regno2, rtx prev = PREV_INSN (insn); while (prev && distance < LEA_SEARCH_THRESHOLD) { - if (INSN_P (prev)) + if (NONDEBUG_INSN_P (prev)) { distance++; for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++) @@ -13705,7 +13706,7 @@ distance_non_agu_define (unsigned int regno1, unsigned int regno2, && prev != insn && distance < LEA_SEARCH_THRESHOLD) { - if (INSN_P (prev)) + if (NONDEBUG_INSN_P (prev)) { distance++; for (def_rec = DF_INSN_DEFS (prev); *def_rec; def_rec++) @@ -13751,7 +13752,7 @@ distance_agu_use (unsigned int regno0, rtx insn) rtx next = NEXT_INSN (insn); while (next && distance < LEA_SEARCH_THRESHOLD) { - if (INSN_P (next)) + if (NONDEBUG_INSN_P (next)) { distance++; @@ -13800,7 +13801,7 @@ distance_agu_use (unsigned int regno0, rtx insn) && next != insn && distance < LEA_SEARCH_THRESHOLD) { - if (INSN_P (next)) + if (NONDEBUG_INSN_P (next)) { distance++; @@ -26706,7 +26707,7 @@ ix86_pad_returns (void) replace = true; /* Empty functions get branch mispredict even when the jump destination is not visible to us. */ - if (!prev && cfun->function_frequency > FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + if (!prev && !optimize_function_for_size_p (cfun)) replace = true; } if (replace) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 4b83370c9a6..163cda189d0 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2148,9 +2148,12 @@ do { \ /* Switch to init or fini section via SECTION_OP, emit a call to FUNC, and switch back. For x86 we do this only to save a few bytes that would otherwise be unused in the text section. */ -#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ - asm (SECTION_OP "\n\t" \ - "call " USER_LABEL_PREFIX #FUNC "\n" \ +#define CRT_MKSTR2(VAL) #VAL +#define CRT_MKSTR(x) CRT_MKSTR2(x) + +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n\t" \ + "call " CRT_MKSTR(__USER_LABEL_PREFIX__) #FUNC "\n" \ TEXT_SECTION_ASM_OP); /* Print operand X (an rtx) in assembler syntax to file FILE. diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h index 85840826674..3aafb933dd4 100644 --- a/gcc/config/i386/mingw-w64.h +++ b/gcc/config/i386/mingw-w64.h @@ -39,6 +39,8 @@ along with GCC; see the file COPYING3. If not see #define ASM_SPEC "%{v:-v} %{n} %{T} %{Ym,*} %{Yd,*} \ %{Wa,*:%*} %{m32:--32} %{m64:--64}" +#undef SPEC_32 +#undef SPEC_64 #if TARGET_64BIT_DEFAULT #define SPEC_32 "m32" #define SPEC_64 "!m32" @@ -47,8 +49,21 @@ along with GCC; see the file COPYING3. If not see #define SPEC_64 "m64" #endif +#undef SUB_LINK_ENTRY32 +#undef SUB_LINK_ENTRY64 +#define SUB_LINK_ENTRY32 "-e _DllMainCRTStartup@12" +#if defined(USE_MINGW64_LEADING_UNDERSCORES) +#define SUB_LINK_ENTRY64 "-e _DllMainCRTStartup" +#else +#define SUB_LINK_ENTRY64 "-e DllMainCRTStartup" +#endif + +#undef SUB_LINK_SPEC +#undef SUB_LINK_ENTRY #define SUB_LINK_SPEC "%{" SPEC_64 ":-m i386pep} %{" SPEC_32 ":-m i386pe}" +#define SUB_LINK_ENTRY "%{" SPEC_64 ":" SUB_LINK_ENTRY64 "} %{" SPEC_32 ":" SUB_LINK_ENTRY32 "}" +#undef MULTILIB_DEFAULTS #if TARGET_64BIT_DEFAULT #define MULTILIB_DEFAULTS { "m64" } #else @@ -61,5 +76,5 @@ along with GCC; see the file COPYING3. If not see %{shared: %{mdll: %eshared and mdll are not compatible}} \ %{shared: --shared} %{mdll:--dll} \ %{static:-Bstatic} %{!static:-Bdynamic} \ - %{shared|mdll: -e _DllMainCRTStartup@12 --enable-auto-image-base} \ + %{shared|mdll: " SUB_LINK_ENTRY " --enable-auto-image-base} \ %(shared_libgcc_undefs)" diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h index 2e877d8d2f0..e08ea1cd90c 100644 --- a/gcc/config/i386/mingw32.h +++ b/gcc/config/i386/mingw32.h @@ -47,6 +47,22 @@ along with GCC; see the file COPYING3. If not see } \ while (0) +#undef SUB_LINK_ENTRY32 +#undef SUB_LINK_ENTRY64 +#define SUB_LINK_ENTRY32 "-e _DllMainCRTStartup@12" +#if defined(USE_MINGW64_LEADING_UNDERSCORES) +#define SUB_LINK_ENTRY64 "-e _DllMainCRTStartup" +#else +#define SUB_LINK_ENTRY64 "-e DllMainCRTStartup" +#endif + +#undef SUB_LINK_ENTRY +#if TARGET_64BIT_DEFAULT +#define SUB_LINK_ENTRY SUB_LINK_ENTRY64 +#else +#define SUB_LINK_ENTRY SUB_LINK_ENTRY32 +#endif + /* Override the standard choice of /usr/include as the default prefix to try when searching for header files. */ #undef STANDARD_INCLUDE_DIR @@ -66,6 +82,10 @@ along with GCC; see the file COPYING3. If not see /* Weak symbols do not get resolved if using a Windows dll import lib. Make the unwind registration references strong undefs. */ #if DWARF2_UNWIND_INFO +/* DW2-unwind is just available for 32-bit mode. */ +#if TARGET_64BIT_DEFAULT +#error DW2 unwind is not available for 64-bit. +#endif #define SHARED_LIBGCC_UNDEFS_SPEC \ "%{shared-libgcc: -u ___register_frame_info -u ___deregister_frame_info}" #else @@ -81,7 +101,7 @@ along with GCC; see the file COPYING3. If not see %{shared: %{mdll: %eshared and mdll are not compatible}} \ %{shared: --shared} %{mdll:--dll} \ %{static:-Bstatic} %{!static:-Bdynamic} \ - %{shared|mdll: -e _DllMainCRTStartup@12 --enable-auto-image-base} \ + %{shared|mdll: " SUB_LINK_ENTRY " --enable-auto-image-base} \ %(shared_libgcc_undefs)" /* Include in the mingw32 libraries with libgcc */ diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming index 4268633b7c8..e9f94a79b3c 100644 --- a/gcc/config/i386/t-cygming +++ b/gcc/config/i386/t-cygming @@ -30,7 +30,7 @@ LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/w32api/include winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \ - $(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H) + $(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/i386/winnt.c diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 725f3a168b3..f7f4d2845ba 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "ggc.h" #include "target.h" +#include "lto-streamer.h" /* i386/PE specific attribute support. @@ -465,6 +466,12 @@ i386_pe_asm_named_section (const char *name, unsigned int flags, *f++ = 's'; } + /* LTO sections need 1-byte alignment to avoid confusing the + zlib decompression algorithm with trailing zero pad bytes. */ + if (strncmp (name, LTO_SECTION_NAME_PREFIX, + strlen (LTO_SECTION_NAME_PREFIX)) == 0) + *f++ = '0'; + *f = '\0'; fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars); @@ -485,6 +492,8 @@ i386_pe_asm_named_section (const char *name, unsigned int flags, } } +/* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */ + void i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl, const char *name, HOST_WIDE_INT size, @@ -581,7 +590,8 @@ static GTY(()) struct export_list *export_head; these, so that we can output the export list at the end of the assembly. We used to output these export symbols in each function, but that causes problems with GNU ld when the sections are - linkonce. */ + linkonce. Beware, DECL may be NULL if compile_file() is emitting + the LTO marker. */ void i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data) @@ -589,6 +599,9 @@ i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data) rtx symbol; struct export_list *p; + if (!decl) + return; + symbol = XEXP (DECL_RTL (decl), 0); gcc_assert (GET_CODE (symbol) == SYMBOL_REF); if (!SYMBOL_REF_DLLEXPORT_P (symbol)) diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md index 44263e47f64..8c3109b57b3 100644 --- a/gcc/config/mmix/mmix.md +++ b/gcc/config/mmix/mmix.md @@ -333,7 +333,7 @@ ;; The %2-is-%1-case is there just to make sure things don't fail. Could ;; presumably happen with optimizations off; no evidence. (define_insn "*divdi3_nonknuth" - [(set (match_operand:DI 0 "register_operand" "=&r,r") + [(set (match_operand:DI 0 "register_operand" "=&r,&r") (div:DI (match_operand:DI 1 "register_operand" "r,r") (match_operand:DI 2 "register_operand" "1,r"))) (clobber (match_scratch:DI 3 "=1,1")) @@ -359,7 +359,7 @@ DIVU %0,%1,%2\;NEGU %1,0,%0\;CSN %0,$255,%1") ;; The %2-is-%1-case is there just to make sure things don't fail. Could ;; presumably happen with optimizations off; no evidence. (define_insn "*moddi3_nonknuth" - [(set (match_operand:DI 0 "register_operand" "=&r,r") + [(set (match_operand:DI 0 "register_operand" "=&r,&r") (mod:DI (match_operand:DI 1 "register_operand" "r,r") (match_operand:DI 2 "register_operand" "1,r"))) (clobber (match_scratch:DI 3 "=1,1")) diff --git a/gcc/configure b/gcc/configure index 53f5eb8e806..17effdae994 100755 --- a/gcc/configure +++ b/gcc/configure @@ -671,6 +671,8 @@ subdirs slibdir dollar gcc_tooldir +LTO_USE_LIBELF +LTO_BINARY_READER enable_lto MAINT zlibinc @@ -893,6 +895,7 @@ enable_initfini_array enable_sjlj_exceptions with_system_libunwind enable_secureplt +enable_leading_mingw64_underscores enable_cld enable_win32_registry enable_static @@ -1590,6 +1593,8 @@ Optional Features: --enable-sjlj-exceptions arrange to use setjmp/longjmp exception handling --enable-secureplt enable -msecure-plt by default for PowerPC + --enable-leading-mingw64-underscores + Enable leading underscores on 64 bit mingw targets --enable-cld enable -mcld by default for 32bit x86 --disable-win32-registry disable lookup of installation paths in the @@ -10683,6 +10688,17 @@ if test "${enable_secureplt+set}" = set; then : fi +# Check whether --enable-leading-mingw64-underscores was given. +if test "${enable_leading_mingw64_underscores+set}" = set; then : + enableval=$enable_leading_mingw64_underscores; +fi + +if test x"$enable_leading_mingw64_underscores" = xyes ; then : + +$as_echo "#define USE_MINGW64_LEADING_UNDERSCORES 1" >>confdefs.h + +fi + # Check whether --enable-cld was given. if test "${enable_cld+set}" = set; then : enableval=$enable_cld; @@ -17092,7 +17108,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17095 "configure" +#line 17111 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17198,7 +17214,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 17201 "configure" +#line 17217 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -22942,6 +22958,48 @@ if test $gcc_cv_as_ix86_pe_secrel32 = yes; then $as_echo "#define HAVE_GAS_PE_SECREL32_RELOC 1" >>confdefs.h fi + # Test if the assembler supports the extended form of the .section + # directive that specifies section alignment. LTO support uses this, + # but normally only after installation, so we warn but don't fail the + # configure if LTO is enabled but the assembler does not support it. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .section with alignment" >&5 +$as_echo_n "checking assembler for .section with alignment... " >&6; } +if test "${gcc_cv_as_section_has_align+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_section_has_align=no + if test $in_tree_gas = yes; then + if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 20 \) \* 1000 + 1` + then gcc_cv_as_section_has_align=yes +fi + elif test x$gcc_cv_as != x; then + echo '.section lto_test,"dr0"' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -fatal-warnings -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_section_has_align=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_section_has_align" >&5 +$as_echo "$gcc_cv_as_section_has_align" >&6; } + + if test x$gcc_cv_as_section_has_align != xyes; then + case ",$enable_languages," in + *,lto,*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded." >&5 +$as_echo "$as_me: WARNING: LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded." >&2;} + ;; + esac + fi ;; esac @@ -25078,6 +25136,17 @@ $as_echo "#define ENABLE_LTO 1" >>confdefs.h enable_lto=yes + # LTO needs to speak the platform's object file format, and has a + # number of implementations of the required binary file access APIs. + # ELF is the most common, and default. We only link libelf if ELF + # is indeed the selected format. + LTO_BINARY_READER=${lto_binary_reader} + LTO_USE_LIBELF=-lelf + if test "x$lto_binary_reader" != "xlto-elf" ; then + LTO_USE_LIBELF= + fi + + ;; *) ;; esac @@ -25276,17 +25345,25 @@ fi pluginlibs= if test x"$enable_plugin" = x"yes"; then + case "${host}" in + *-*-darwin*) + export_sym_check="$gcc_cv_nm -g" + ;; + *) + export_sym_check="$gcc_cv_objdump -T" + ;; + esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exported symbols" >&5 $as_echo_n "checking for exported symbols... " >&6; } echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1 - if $gcc_cv_objdump -T conftest | grep foobar > /dev/null; then + if $export_sym_check conftest | grep foobar > /dev/null; then : # No need to use a flag else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -rdynamic" >&5 $as_echo_n "checking for -rdynamic... " >&6; } ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1 - if $gcc_cv_objdump -T conftest | grep foobar > /dev/null; then + if $export_sym_check conftest | grep foobar > /dev/null; then plugin_rdynamic=yes pluginlibs="-rdynamic" else @@ -25362,7 +25439,14 @@ fi # Check that we can build shared objects with -fPIC -shared saved_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -fPIC -shared" + case "${host}" in + *-*-darwin*) + LDFLAGS="$LDFLAGS -fPIC -shared -undefined dynamic_lookup" + ;; + *) + LDFLAGS="$LDFLAGS -fPIC -shared" + ;; + esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fPIC -shared" >&5 $as_echo_n "checking for -fPIC -shared... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/gcc/configure.ac b/gcc/configure.ac index 2f571e6482d..cd31f4e6db8 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1568,6 +1568,14 @@ AC_ARG_ENABLE(secureplt, [ --enable-secureplt enable -msecure-plt by default for PowerPC], [], []) +AC_ARG_ENABLE(leading-mingw64-underscores, + AS_HELP_STRING([--enable-leading-mingw64-underscores], + [Enable leading underscores on 64 bit mingw targets]), + [],[]) +AS_IF([ test x"$enable_leading_mingw64_underscores" = xyes ], + [AC_DEFINE(USE_MINGW64_LEADING_UNDERSCORES, 1, + [Define if we should use leading underscore on 64 bit mingw targets])]) + AC_ARG_ENABLE(cld, [ --enable-cld enable -mcld by default for 32bit x86], [], [enable_cld=no]) @@ -3202,6 +3210,19 @@ foo: nop rm -f conftest], [AC_DEFINE(HAVE_GAS_PE_SECREL32_RELOC, 1, [Define if your assembler and linker support 32-bit section relative relocs via '.secrel32 label'.])]) + # Test if the assembler supports the extended form of the .section + # directive that specifies section alignment. LTO support uses this, + # but normally only after installation, so we warn but don't fail the + # configure if LTO is enabled but the assembler does not support it. + gcc_GAS_CHECK_FEATURE([.section with alignment], gcc_cv_as_section_has_align, + [2,20,1],-fatal-warnings,[.section lto_test,"dr0"]) + if test x$gcc_cv_as_section_has_align != xyes; then + case ",$enable_languages," in + *,lto,*) + AC_MSG_WARN([LTO for $target requires binutils >= 2.20.1, but version found appears insufficient; LTO will not work until binutils is upgraded.]) + ;; + esac + fi ;; esac @@ -4270,6 +4291,17 @@ changequote([,])dnl AC_DEFINE(ENABLE_LTO, 1, [Define to enable LTO support.]) enable_lto=yes AC_SUBST(enable_lto) + # LTO needs to speak the platform's object file format, and has a + # number of implementations of the required binary file access APIs. + # ELF is the most common, and default. We only link libelf if ELF + # is indeed the selected format. + LTO_BINARY_READER=${lto_binary_reader} + LTO_USE_LIBELF=-lelf + if test "x$lto_binary_reader" != "xlto-elf" ; then + LTO_USE_LIBELF= + fi + AC_SUBST(LTO_BINARY_READER) + AC_SUBST(LTO_USE_LIBELF) ;; *) ;; esac @@ -4456,15 +4488,23 @@ enable_plugin=yes; default_plugin=yes) pluginlibs= if test x"$enable_plugin" = x"yes"; then + case "${host}" in + *-*-darwin*) + export_sym_check="$gcc_cv_nm -g" + ;; + *) + export_sym_check="$gcc_cv_objdump -T" + ;; + esac AC_MSG_CHECKING([for exported symbols]) echo "int main() {return 0;} int foobar() {return 0;}" > conftest.c ${CC} ${CFLAGS} ${LDFLAGS} conftest.c -o conftest > /dev/null 2>&1 - if $gcc_cv_objdump -T conftest | grep foobar > /dev/null; then + if $export_sym_check conftest | grep foobar > /dev/null; then : # No need to use a flag else AC_MSG_CHECKING([for -rdynamic]) ${CC} ${CFLAGS} ${LDFLAGS} -rdynamic conftest.c -o conftest > /dev/null 2>&1 - if $gcc_cv_objdump -T conftest | grep foobar > /dev/null; then + if $export_sym_check conftest | grep foobar > /dev/null; then plugin_rdynamic=yes pluginlibs="-rdynamic" else @@ -4484,7 +4524,14 @@ if test x"$enable_plugin" = x"yes"; then # Check that we can build shared objects with -fPIC -shared saved_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -fPIC -shared" + case "${host}" in + *-*-darwin*) + LDFLAGS="$LDFLAGS -fPIC -shared -undefined dynamic_lookup" + ;; + *) + LDFLAGS="$LDFLAGS -fPIC -shared" + ;; + esac AC_MSG_CHECKING([for -fPIC -shared]) AC_TRY_LINK( [extern int X;],[return X == 0;], diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6dec7c38cad..03bf79b820a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,78 @@ +2010-04-28 Manuel López-Ibáñez + + PR c++/9335 + * error.c (print_instantiation_partial_context_line): Handle + recursive instantiation. + (print_instantiation_partial_context): Likewise. + +2010-04-27 Jason Merrill + + * init.c (perform_member_init): Check CLASS_TYPE_P. + +2010-04-27 Fabien Chêne + + PR c++/29043 + * init.c (perform_member_init): check for uninitialized const or + reference members, including array types. + +2010-04-24 Jason Merrill + + * tree.c (get_fns): Split out from get_first_fn. + * cp-tree.h: Declare it. + * search.c (shared_member_p): Use it. + * semantics.c (finish_qualified_id_expr): Simplify. + (finish_id_expression): Simplify. + + * semantics.c (finish_non_static_data_member): Call maybe_dummy_object + whenever object is NULL_TREE. Don't do 'this' capture here. + (finish_qualified_id_expr): Pass NULL_TREE. + (finish_id_expression): Likewise. + (lambda_expr_this_capture): Likewise. + + * semantics.c (finish_qualified_id_expr): Use maybe_dummy_object + rather than checking current_class_ref directly. + (finish_call_expr): Likewise. + + PR c++/43856 + * name-lookup.c (qualify_lookup): Disqualify lambda op(). + * class.c (current_nonlambda_class_type): New fn. + * semantics.c (nonlambda_method_basetype): New. + * cp-tree.h: Declare them. + * tree.c (maybe_dummy_object): Handle implicit 'this' capture. + + * semantics.c (baselink_for_fns): Correct BASELINK_BINFO. + + PR c++/43875 + * semantics.c (lambda_return_type): Complain about + braced-init-list. + + PR c++/43790 + * tree.c (cv_unqualified): Handle error_mark_node. + + PR c++/41468 + * call.c (convert_like_real) [ck_ambig]: Just return error_mark_node + if we don't want errors. + + PR c++/41468 + * class.c (convert_to_base): Add complain parameter. Pass + ba_quiet to lookup_base if we don't want errors. + (build_vfield_ref): Pass complain to convert_to_base. + * call.c (convert_like_real): Likewise. + (initialize_reference): Likewise. + (perform_direct_initialization_if_possible): Pass complain to + convert_like_real. + * cp-tree.h: Adjust. + +2010-04-27 Fabien Chêne + Jason Merrill + + PR c++/42844 + * decl.c (check_for_uninitialized_const_var): Handle classes that need + constructing, too. + (check_initializer): Call it for classes that need constructing, too. + * class.c (in_class_defaulted_default_constructor): New. + * cp-tree.h: Declare it. + 2010-04-20 Jason Merrill PR c++/9335 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 73f65c991db..859dc5cd757 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4952,6 +4952,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, } return expr; case ck_ambig: + if (!(complain & tf_error)) + return error_mark_node; /* Call build_user_type_conversion again for the error. */ return build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL); @@ -5024,7 +5026,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* Build an expression for `*((base*) &expr)'. */ expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain); expr = convert_to_base (expr, build_pointer_type (totype), - !c_cast_p, /*nonnull=*/true); + !c_cast_p, /*nonnull=*/true, complain); expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain); return expr; } @@ -5147,7 +5149,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, case ck_ptr: if (convs->base_p) expr = convert_to_base (expr, totype, !c_cast_p, - /*nonnull=*/false); + /*nonnull=*/false, complain); return build_nop (totype, expr); case ck_pmem: @@ -7589,7 +7591,7 @@ perform_direct_initialization_if_possible (tree type, expr = convert_like_real (conv, expr, NULL_TREE, 0, 0, /*issue_conversion_warnings=*/false, c_cast_p, - tf_warning_or_error); + complain); /* Free all the conversions we allocated. */ obstack_free (&conversion_obstack, p); @@ -7815,7 +7817,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup, expr = convert_to_base (expr, build_pointer_type (base_conv_type), /*check_access=*/true, - /*nonnull=*/true); + /*nonnull=*/true, complain); expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr); } else diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b097c142bfd..f82cdc14878 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1,6 +1,6 @@ /* Functions related to building classes and their related objects. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -506,10 +506,12 @@ build_simple_base_path (tree expr, tree binfo) assumed to be non-NULL. */ tree -convert_to_base (tree object, tree type, bool check_access, bool nonnull) +convert_to_base (tree object, tree type, bool check_access, bool nonnull, + tsubst_flags_t complain) { tree binfo; tree object_type; + base_access access; if (TYPE_PTR_P (TREE_TYPE (object))) { @@ -519,8 +521,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull) else object_type = TREE_TYPE (object); + access = check_access ? ba_check : ba_unique; + if (!(complain & tf_error)) + access |= ba_quiet; binfo = lookup_base (object_type, type, - check_access ? ba_check : ba_unique, + access, NULL); if (!binfo || binfo == error_mark_node) return error_mark_node; @@ -575,7 +580,7 @@ build_vfield_ref (tree datum, tree type) /* First, convert to the requested type. */ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type)) datum = convert_to_base (datum, type, /*check_access=*/false, - /*nonnull=*/true); + /*nonnull=*/true, tf_warning_or_error); /* Second, the requested type may not be the owner of its own vptr. If not, convert to the base class that owns it. We cannot use @@ -4177,6 +4182,34 @@ type_has_user_nondefault_constructor (tree t) return false; } +/* Returns the defaulted constructor if T has one. Otherwise, returns + NULL_TREE. */ + +tree +in_class_defaulted_default_constructor (tree t) +{ + tree fns, args; + + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) + return NULL_TREE; + + for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + + if (DECL_DEFAULTED_IN_CLASS_P (fn)) + { + args = FUNCTION_FIRST_USER_PARMTYPE (fn); + while (args && TREE_PURPOSE (args)) + args = TREE_CHAIN (args); + if (!args || args == void_list_node) + return fn; + } + } + + return NULL_TREE; +} + /* Returns true iff FN is a user-provided function, i.e. user-declared and not defaulted at its first declaration; or explicit, private, protected, or non-const. */ @@ -5938,6 +5971,34 @@ currently_open_derived_class (tree t) return NULL_TREE; } +/* Returns the innermost class type which is not a lambda closure type. */ + +tree +current_nonlambda_class_type (void) +{ + int i; + + /* We start looking from 1 because entry 0 is from global scope, + and has no type. */ + for (i = current_class_depth; i > 0; --i) + { + tree c; + if (i == current_class_depth) + c = current_class_type; + else + { + if (current_class_stack[i].hidden) + break; + c = current_class_stack[i].type; + } + if (!c) + continue; + if (!LAMBDA_TYPE_P (c)) + return c; + } + return NULL_TREE; +} + /* When entering a class scope, all enclosing class scopes' names with static meaning (static variables, static functions, types and enumerators) have to be visible. This recursive function calls diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5afa0ea66cd..6c0b9f0bae0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4575,7 +4575,8 @@ extern void validate_conversion_obstack (void); extern tree build_vfield_ref (tree, tree); extern tree build_base_path (enum tree_code, tree, tree, int); -extern tree convert_to_base (tree, tree, bool, bool); +extern tree convert_to_base (tree, tree, bool, bool, + tsubst_flags_t); extern tree convert_to_base_statically (tree, tree); extern tree build_vtbl_ref (tree, tree); extern tree build_vfn_ref (tree, tree); @@ -4585,6 +4586,7 @@ extern void resort_type_method_vec (void *, void *, extern bool add_method (tree, tree, tree); extern bool currently_open_class (tree); extern tree currently_open_derived_class (tree); +extern tree current_nonlambda_class_type (void); extern tree finish_struct (tree, tree); extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); @@ -4617,6 +4619,7 @@ extern void check_for_override (tree, tree); extern void push_class_stack (void); extern void pop_class_stack (void); extern bool type_has_user_nondefault_constructor (tree); +extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_default_constructor (tree); @@ -5216,6 +5219,7 @@ extern tree add_capture (tree, tree, tree, bool, bool); extern tree add_default_capture (tree, tree, tree); extern void register_capture_members (tree); extern tree lambda_expr_this_capture (tree); +extern tree nonlambda_method_basetype (void); extern void maybe_add_lambda_conv_op (tree); /* in tree.c */ @@ -5261,6 +5265,7 @@ extern tree hash_tree_cons (tree, tree, tree); extern tree hash_tree_chain (tree, tree); extern tree build_qualified_name (tree, tree, tree, bool); extern int is_overloaded_fn (tree); +extern tree get_fns (tree); extern tree get_first_fn (tree); extern tree ovl_cons (tree, tree); extern tree build_overload (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3a42ce9c900..efeda920733 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,6 +1,6 @@ /* Process declarations and variables for C++ compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -4725,7 +4725,7 @@ maybe_commonize_var (tree decl) static void check_for_uninitialized_const_var (tree decl) { - tree type = TREE_TYPE (decl); + tree type = strip_array_types (TREE_TYPE (decl)); if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl) && DECL_INITIAL (decl) == NULL) @@ -4737,11 +4737,28 @@ check_for_uninitialized_const_var (tree decl) else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (type) != REFERENCE_TYPE && CP_TYPE_CONST_P (type) - && !TYPE_NEEDS_CONSTRUCTING (type) + && (!TYPE_NEEDS_CONSTRUCTING (type) + || !type_has_user_provided_default_constructor (type)) && !DECL_INITIAL (decl)) - error ("uninitialized const %qD", decl); -} + { + permerror (DECL_SOURCE_LOCATION (decl), + "uninitialized const %qD", decl); + if (CLASS_TYPE_P (type) + && !type_has_user_provided_default_constructor (type)) + { + tree defaulted_ctor; + + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)), + "%q#T has no user-provided default constructor", type); + defaulted_ctor = in_class_defaulted_default_constructor (type); + if (defaulted_ctor) + inform (DECL_SOURCE_LOCATION (defaulted_ctor), + "constructor is not user-provided because it is " + "explicitly defaulted in the class body"); + } + } +} /* Structure holding the current initializer being processed by reshape_init. CUR is a pointer to the current element being processed, END is a pointer @@ -5294,7 +5311,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) else if (DECL_EXTERNAL (decl)) ; else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type)) - return build_aggr_init_full_exprs (decl, init, flags); + { + check_for_uninitialized_const_var (decl); + return build_aggr_init_full_exprs (decl, init, flags); + } else if (MAYBE_CLASS_TYPE_P (type)) { tree core_type = strip_array_types (type); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index b03c83ff152..4ac70f74b69 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2733,31 +2733,45 @@ print_instantiation_full_context (diagnostic_context *context) static void print_instantiation_partial_context_line (diagnostic_context *context, - const struct tinst_level *t, location_t loc) + const struct tinst_level *t, + location_t loc, bool recursive_p) { expanded_location xloc; xloc = expand_location (loc); - if (t != NULL) { - const char *str; - str = decl_as_string_translate (t->decl, - TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE); - if (flag_show_column) - pp_verbatim (context->printer, - _("%s:%d:%d: instantiated from %qs\n"), - xloc.file, xloc.line, xloc.column, str); - else - pp_verbatim (context->printer, - _("%s:%d: instantiated from %qs\n"), - xloc.file, xloc.line, str); - } else { - if (flag_show_column) - pp_verbatim (context->printer, _("%s:%d:%d: instantiated from here"), - xloc.file, xloc.line, xloc.column); - else - pp_verbatim (context->printer, _("%s:%d: instantiated from here"), - xloc.file, xloc.line); - } + if (t != NULL) + { + const char *str; + str = decl_as_string_translate (t->decl, + TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE); + if (flag_show_column) + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d:%d: recursively instantiated from %qs\n") + : _("%s:%d:%d: instantiated from %qs\n"), + xloc.file, xloc.line, xloc.column, str); + else + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d: recursively instantiated from %qs\n") + : _("%s:%d: recursively instantiated from %qs\n"), + xloc.file, xloc.line, str); + } + else + { + if (flag_show_column) + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d:%d: recursively instantiated from here") + : _("%s:%d:%d: instantiated from here"), + xloc.file, xloc.line, xloc.column); + else + pp_verbatim (context->printer, + recursive_p + ? _("%s:%d: recursively instantiated from here") + : _("%s:%d: instantiated from here"), + xloc.file, xloc.line); + } } /* Same as print_instantiation_full_context but less verbose. */ @@ -2769,9 +2783,14 @@ print_instantiation_partial_context (diagnostic_context *context, struct tinst_level *t; int n_total = 0; int n; + location_t prev_loc = loc; for (t = t0; t != NULL; t = t->next) - n_total++; + if (prev_loc != t->locus) + { + prev_loc = t->locus; + n_total++; + } t = t0; @@ -2781,11 +2800,13 @@ print_instantiation_partial_context (diagnostic_context *context, for (n = 0; n < 5; n++) { gcc_assert (t != NULL); - print_instantiation_partial_context_line (context, t, loc); + if (loc != t->locus) + print_instantiation_partial_context_line (context, t, loc, + /*recursive_p=*/false); loc = t->locus; t = t->next; } - if (skip > 1) + if (t != NULL && skip > 1) { expanded_location xloc; xloc = expand_location (loc); @@ -2799,18 +2820,26 @@ print_instantiation_partial_context (diagnostic_context *context, xloc.file, xloc.line, skip); do { - loc = t->locus; - t = t->next; - } while (--skip > 0); + loc = t->locus; + t = t->next; + } while (t != NULL && --skip > 0); } } - for (; t != NULL; t = t->next) + while (t != NULL) { - print_instantiation_partial_context_line (context, t, loc); + while (t->next != NULL && t->locus == t->next->locus) + { + loc = t->locus; + t = t->next; + } + print_instantiation_partial_context_line (context, t, loc, + t->locus == loc); loc = t->locus; + t = t->next; } - print_instantiation_partial_context_line (context, NULL, loc); + print_instantiation_partial_context_line (context, NULL, loc, + /*recursive_p=*/false); pp_base_newline (context->printer); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e1dee1d10dc..5f0f665afe4 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -506,6 +506,7 @@ perform_member_init (tree member, tree init) { if (init == NULL_TREE) { + tree core_type; /* member traversal: note it leaves init NULL */ if (TREE_CODE (type) == REFERENCE_TYPE) permerror (DECL_SOURCE_LOCATION (current_function_decl), @@ -515,6 +516,13 @@ perform_member_init (tree member, tree init) permerror (DECL_SOURCE_LOCATION (current_function_decl), "uninitialized member %qD with % type %qT", member, type); + + core_type = strip_array_types (type); + if (CLASS_TYPE_P (core_type) + && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type) + || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))) + diagnose_uninitialized_cst_or_ref_member (core_type, + /*using_new=*/false); } else if (TREE_CODE (init) == TREE_LIST) /* There was an explicit member initialization. Do some work diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b4ac49f5c32..5586bf7f969 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3807,6 +3807,10 @@ qualify_lookup (tree val, int flags) if (cp_unevaluated_operand && TREE_CODE (val) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (val)) return false; + /* None of the lookups that use qualify_lookup want the op() from the + lambda; they want the one from the enclosing class. */ + if (TREE_CODE (val) == FUNCTION_DECL && LAMBDA_FUNCTION_P (val)) + return false; return true; } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 772ae3b1fbe..11011e7f334 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -973,6 +973,7 @@ shared_member_p (tree t) return 1; if (is_overloaded_fn (t)) { + t = get_fns (t); for (; t; t = OVL_NEXT (t)) { tree fn = OVL_CURRENT (t); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ea01eb31378..d4ce01496ee 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1424,17 +1424,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) { gcc_assert (TREE_CODE (decl) == FIELD_DECL); - if (!object && cp_unevaluated_operand != 0) + if (!object) { - /* DR 613: Can use non-static data members without an associated - object in sizeof/decltype/alignof. */ tree scope = qualifying_scope; if (scope == NULL_TREE) scope = context_for_name_lookup (decl); object = maybe_dummy_object (scope, NULL); } - if (!object) + /* DR 613: Can use non-static data members without an associated + object in sizeof/decltype/alignof. */ + if (is_dummy_object (object) && cp_unevaluated_operand == 0 + && (!processing_template_decl || !current_class_ref)) { if (current_function_decl && DECL_STATIC_FUNCTION_P (current_function_decl)) @@ -1446,19 +1447,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) return error_mark_node; } - /* If decl is a non-capture field and object has a lambda type, - then we have a reference to a member of 'this' from a - lambda inside a non-static member function, and we must get to decl - through the 'this' capture. If decl is not a member of that object, - either, then its access will still fail later. */ - if (LAMBDA_TYPE_P (TREE_TYPE (object)) - && !LAMBDA_TYPE_P (DECL_CONTEXT (decl))) - object = cp_build_indirect_ref (lambda_expr_this_capture - (CLASSTYPE_LAMBDA_EXPR - (TREE_TYPE (object))), - RO_NULL, - /*complain=*/tf_warning_or_error); - if (current_class_ptr) TREE_USED (current_class_ptr) = 1; if (processing_template_decl && !qualifying_scope) @@ -1494,21 +1482,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) else { tree access_type = TREE_TYPE (object); - tree lookup_context = context_for_name_lookup (decl); - - while (!DERIVED_FROM_P (lookup_context, access_type)) - { - access_type = TYPE_CONTEXT (access_type); - while (access_type && DECL_P (access_type)) - access_type = DECL_CONTEXT (access_type); - - if (!access_type) - { - error ("object missing in reference to %q+D", decl); - error ("from this location"); - return error_mark_node; - } - } perform_or_defer_access_check (TYPE_BINFO (access_type), decl, decl); @@ -1683,24 +1656,21 @@ finish_qualified_id_expr (tree qualifying_class, else if (TREE_CODE (expr) == FIELD_DECL) { push_deferring_access_checks (dk_no_check); - expr = finish_non_static_data_member (expr, current_class_ref, + expr = finish_non_static_data_member (expr, NULL_TREE, qualifying_class); pop_deferring_access_checks (); } else if (BASELINK_P (expr) && !processing_template_decl) { - tree fns; + tree ob; /* See if any of the functions are non-static members. */ - fns = BASELINK_FUNCTIONS (expr); - if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) - fns = TREE_OPERAND (fns, 0); /* If so, the expression may be relative to 'this'. */ - if (!shared_member_p (fns) - && current_class_ref - && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref))) + if (!shared_member_p (expr) + && (ob = maybe_dummy_object (qualifying_class, NULL), + !is_dummy_object (ob))) expr = (build_class_member_access_expr - (maybe_dummy_object (qualifying_class, NULL), + (ob, expr, BASELINK_ACCESS_BINFO (expr), /*preserve_reference=*/false, @@ -2002,31 +1972,18 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual, . operator.... [Otherwise] a contrived object of type T becomes the implied object argument. - This paragraph is unclear about this situation: + In this situation: struct A { void f(); }; struct B : public A {}; struct C : public A { void g() { B::f(); }}; - In particular, for `B::f', this paragraph does not make clear - whether "the class of that member function" refers to `A' or - to `B'. We believe it refers to `B'. */ - if (current_class_type - && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - current_class_type) - && current_class_ref) - object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - NULL); - else - { - tree representative_fn; + "the class of that member function" refers to `A'. But 11.2 + [class.access.base] says that we need to convert 'this' to B* as + part of the access, so we pass 'B' to maybe_dummy_object. */ - representative_fn = BASELINK_FUNCTIONS (fn); - if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR) - representative_fn = TREE_OPERAND (representative_fn, 0); - representative_fn = get_first_fn (representative_fn); - object = build_dummy_object (DECL_CONTEXT (representative_fn)); - } + object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), + NULL); if (processing_template_decl) { @@ -2692,7 +2649,8 @@ baselink_for_fns (tree fns) if (!cl) cl = DECL_CONTEXT (fn); cl = TYPE_BINFO (cl); - return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE); + return build_baselink (TYPE_BINFO (DECL_CONTEXT (fn)), cl, fns, + /*optype=*/NULL_TREE); } /* Returns true iff DECL is an automatic variable from a function outside @@ -3073,7 +3031,7 @@ finish_id_expression (tree id_expression, already. Turn off checking to avoid duplicate errors. */ push_deferring_access_checks (dk_no_check); decl = finish_non_static_data_member - (decl, current_class_ref, + (decl, NULL_TREE, /*qualifying_scope=*/NULL_TREE); pop_deferring_access_checks (); return decl; @@ -3154,7 +3112,7 @@ finish_id_expression (tree id_expression, Access checking has been performed during name lookup already. Turn off checking to avoid duplicate errors. */ push_deferring_access_checks (dk_no_check); - decl = finish_non_static_data_member (decl, current_class_ref, + decl = finish_non_static_data_member (decl, NULL_TREE, /*qualifying_scope=*/NULL_TREE); pop_deferring_access_checks (); } @@ -3162,10 +3120,7 @@ finish_id_expression (tree id_expression, { tree first_fn; - first_fn = decl; - if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR) - first_fn = TREE_OPERAND (first_fn, 0); - first_fn = get_first_fn (first_fn); + first_fn = get_first_fn (decl); if (TREE_CODE (first_fn) == TEMPLATE_DECL) first_fn = DECL_TEMPLATE_RESULT (first_fn); @@ -5521,6 +5476,11 @@ tree lambda_return_type (tree expr) { tree type; + if (BRACE_ENCLOSED_INITIALIZER_P (expr)) + { + warning (0, "cannot deduce lambda return type from a braced-init-list"); + return void_type_node; + } if (type_dependent_expression_p (expr)) { type = cxx_make_type (DECLTYPE_TYPE); @@ -5850,7 +5810,7 @@ lambda_expr_this_capture (tree lambda) gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda)); result = finish_non_static_data_member (this_capture, - current_class_ref, + NULL_TREE, /*qualifying_scope=*/NULL_TREE); /* If 'this' is captured, each use of 'this' is transformed into an @@ -5863,6 +5823,32 @@ lambda_expr_this_capture (tree lambda) return result; } +/* Returns the method basetype of the innermost non-lambda function, or + NULL_TREE if none. */ + +tree +nonlambda_method_basetype (void) +{ + tree fn, type; + if (!current_class_ref) + return NULL_TREE; + + type = current_class_type; + if (!LAMBDA_TYPE_P (type)) + return type; + + /* Find the nearest enclosing non-lambda function. */ + fn = TYPE_NAME (type); + do + fn = decl_function_context (fn); + while (fn && LAMBDA_FUNCTION_P (fn)); + + if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)) + return NULL_TREE; + + return TYPE_METHOD_BASETYPE (TREE_TYPE (fn)); +} + /* If the closure TYPE has a static op(), also add a conversion to function pointer. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 27ced53a2b4..4d25cac186c 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -934,7 +934,12 @@ cp_build_qualified_type_real (tree type, tree cv_unqualified (tree type) { - int quals = TYPE_QUALS (type); + int quals; + + if (type == error_mark_node) + return type; + + quals = TYPE_QUALS (type); quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE); return cp_build_qualified_type (type, quals); } @@ -1347,7 +1352,7 @@ really_overloaded_fn (tree x) } tree -get_first_fn (tree from) +get_fns (tree from) { gcc_assert (is_overloaded_fn (from)); /* A baselink is also considered an overloaded function. */ @@ -1358,7 +1363,13 @@ get_first_fn (tree from) from = BASELINK_FUNCTIONS (from); if (TREE_CODE (from) == TEMPLATE_ID_EXPR) from = TREE_OPERAND (from, 0); - return OVL_CURRENT (from); + return from; +} + +tree +get_first_fn (tree from) +{ + return OVL_CURRENT (get_fns (from)); } /* Return a new OVL node, concatenating it with the old one. */ @@ -2288,11 +2299,11 @@ maybe_dummy_object (tree type, tree* binfop) { tree decl, context; tree binfo; + tree current = current_nonlambda_class_type (); - if (current_class_type - && (binfo = lookup_base (current_class_type, type, - ba_unique | ba_quiet, NULL))) - context = current_class_type; + if (current + && (binfo = lookup_base (current, type, ba_any, NULL))) + context = current; else { /* Reference from a nested class member function. */ @@ -2310,6 +2321,13 @@ maybe_dummy_object (tree type, tree* binfop) && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)), current_class_type)) decl = current_class_ref; + else if (current != current_class_type + && context == nonlambda_method_basetype ()) + /* In a lambda, need to go through 'this' capture. */ + decl = (cp_build_indirect_ref + ((lambda_expr_this_capture + (CLASSTYPE_LAMBDA_EXPR (current_class_type))), + RO_NULL, tf_warning_or_error)); else decl = build_dummy_object (context); diff --git a/gcc/df-problems.c b/gcc/df-problems.c index fb899096e49..dbb469e1e2f 100644 --- a/gcc/df-problems.c +++ b/gcc/df-problems.c @@ -3913,13 +3913,9 @@ df_simulate_finalize_backwards (basic_block bb, bitmap live) the block, starting with the first one. ----------------------------------------------------------------------------*/ -/* Apply the artificial uses and defs at the top of BB in a forwards - direction. ??? This is wrong; defs mark the point where a pseudo - becomes live when scanning forwards (unless a def is unused). Since - there are no REG_UNUSED notes for artificial defs, passes that - require artificial defs probably should not call this function - unless (as is the case for fwprop) they are correct when liveness - bitmaps are *under*estimated. */ +/* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or + DF_LR_IN for basic block BB, for forward scanning by marking artificial + defs live. */ void df_simulate_initialize_forwards (basic_block bb, bitmap live) @@ -3931,7 +3927,7 @@ df_simulate_initialize_forwards (basic_block bb, bitmap live) { df_ref def = *def_rec; if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) - bitmap_clear_bit (live, DF_REF_REGNO (def)); + bitmap_set_bit (live, DF_REF_REGNO (def)); } } diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 02e2be78c15..7a250bd72ec 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -215,7 +215,8 @@ Standard C@. In its default mode, the GNU C preprocessor does not do a few things required by the standard. These are features which are rarely, if ever, used, and may cause surprising changes to the meaning of a program which does not expect them. To get strict ISO Standard C, -you should use the @option{-std=c90} or @option{-std=c99} options, depending +you should use the @option{-std=c90}, @option{-std=c99} or +@option{-std=c1x} options, depending on which version of the standard you want. To get all the mandatory diagnostics, you must also use @option{-pedantic}. @xref{Invocation}. diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi index e73f77d4f44..b5c77c7e990 100644 --- a/gcc/doc/cppopts.texi +++ b/gcc/doc/cppopts.texi @@ -392,6 +392,9 @@ The 1990 C standard, as amended in 1994. The revised ISO C standard, published in December 1999. Before publication, this was known as C9X@. +@item c1x +The next version of the ISO C standard, still under development. + @item gnu90 @itemx gnu89 The 1990 C standard plus GNU extensions. This is the default. @@ -400,6 +403,10 @@ The 1990 C standard plus GNU extensions. This is the default. @itemx gnu9x The 1999 C standard plus GNU extensions. +@item gnu1x +The next version of the ISO C standard, still under development, plus +GNU extensions. + @item c++98 The 1998 ISO C++ standard plus amendments. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d486ffb080a..31eb458ff9a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4960,8 +4960,10 @@ into their callers with the option @option{-finline-functions}. GCC implements three different semantics of declaring a function inline. One is available with @option{-std=gnu89} or @option{-fgnu89-inline} or when @code{gnu_inline} attribute is present -on all inline declarations, another when @option{-std=c99} or -@option{-std=gnu99} (without @option{-fgnu89-inline}), and the third +on all inline declarations, another when +@option{-std=c99}, @option{-std=c1x}, +@option{-std=gnu99} or @option{-std=gnu1x} +(without @option{-fgnu89-inline}), and the third is used when compiling C++. To declare a function inline, use the @code{inline} keyword in its @@ -5892,10 +5894,12 @@ a general-purpose header file that should be usable by all programs, including ISO C programs. The keywords @code{asm}, @code{typeof} and @code{inline} are not available in programs compiled with @option{-ansi} or @option{-std} (although @code{inline} can be used in a -program compiled with @option{-std=c99}). The ISO C99 keyword +program compiled with @option{-std=c99} or @option{-std=c1x}). The +ISO C99 keyword @code{restrict} is only available when @option{-std=gnu99} (which will eventually be the default) or @option{-std=c99} (or the equivalent -@option{-std=iso9899:1999}) is used. +@option{-std=iso9899:1999}), or an option for a later standard +version, is used. The way to solve these problems is to put @samp{__} at the beginning and end of each problematical keyword. For example, use @code{__asm__} @@ -6881,8 +6885,8 @@ be emitted. @opindex ansi @opindex std -Outside strict ISO C mode (@option{-ansi}, @option{-std=c90} or -@option{-std=c99}), the functions +Outside strict ISO C mode (@option{-ansi}, @option{-std=c90}, +@option{-std=c99} or @option{-std=c1x}), the functions @code{_exit}, @code{alloca}, @code{bcmp}, @code{bzero}, @code{dcgettext}, @code{dgettext}, @code{dremf}, @code{dreml}, @code{drem}, @code{exp10f}, @code{exp10l}, @code{exp10}, @code{ffsll}, diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi index 1c742b27402..16692c57450 100644 --- a/gcc/doc/gimple.texi +++ b/gcc/doc/gimple.texi @@ -212,24 +212,18 @@ common fields are placed in @code{gimple_statement_with_ops_base} which is then inherited from the other two tuples. -@multitable {@code{addresses_taken}} {56 + 8 * @code{num_ops} bytes} +@multitable {@code{def_ops}} {48 + 8 * @code{num_ops} bytes} @item @code{gsbase} @tab 256 -@item @code{addresses_taken} @tab 64 @item @code{def_ops} @tab 64 @item @code{use_ops} @tab 64 @item @code{op} @tab @code{num_ops} * 64 -@item Total size @tab 56 + 8 * @code{num_ops} bytes +@item Total size @tab 48 + 8 * @code{num_ops} bytes @end multitable @itemize @bullet @item @code{gsbase} Inherited from @code{struct gimple_statement_base}. -@item @code{addresses_taken} -Bitmap holding the UIDs of all the @code{VAR_DECL}s whose addresses are -taken by this statement. For example, a statement of the form -@code{p = &b} will have the UID for symbol @code{b} in this set. - @item @code{def_ops} Array of pointers into the operand array indicating all the slots that contain a variable written-to by the statement. This array is @@ -254,18 +248,17 @@ vector (@code{gimple_statement_with_memory_ops_base} and @code{gimple_statement_with_memory_ops}). -@multitable {@code{addresses_taken}} {88 + 8 * @code{num_ops} bytes} -@item Field @tab Size (bits) -@item @code{gsbase} @tab 256 -@item @code{addresses_taken} @tab 64 -@item @code{def_ops} @tab 64 -@item @code{use_ops} @tab 64 -@item @code{vdef_ops} @tab 64 -@item @code{vuse_ops} @tab 64 -@item @code{stores} @tab 64 -@item @code{loads} @tab 64 -@item @code{op} @tab @code{num_ops} * 64 -@item Total size @tab 88 + 8 * @code{num_ops} bytes +@multitable {@code{vdef_ops}} {80 + 8 * @code{num_ops} bytes} +@item Field @tab Size (bits) +@item @code{gsbase} @tab 256 +@item @code{def_ops} @tab 64 +@item @code{use_ops} @tab 64 +@item @code{vdef_ops} @tab 64 +@item @code{vuse_ops} @tab 64 +@item @code{stores} @tab 64 +@item @code{loads} @tab 64 +@item @code{op} @tab @code{num_ops} * 64 +@item Total size @tab 80 + 8 * @code{num_ops} bytes @end multitable @itemize @bullet diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 0e39234b3b4..fefb0abd1d5 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -257,6 +257,7 @@ Objective-C and Objective-C++ Dialects}. -Wsign-compare -Wsign-conversion -Wstack-protector @gol -Wstrict-aliasing -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol +-Wsuggest-attribute=@r{[}const@r{|}pure@r{]} @gol -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized @gol -Wunknown-pragmas -Wno-pragmas @gol @@ -344,7 +345,7 @@ Objective-C and Objective-C++ Dialects}. -fgcse-sm -fif-conversion -fif-conversion2 -findirect-inlining @gol -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol -finline-small-functions -fipa-cp -fipa-cp-clone -fipa-matrix-reorg -fipa-pta @gol --fipa-pure-const -fipa-reference -fipa-struct-reorg @gol +-fipa-profile -fipa-pure-const -fipa-reference -fipa-struct-reorg @gol -fipa-type-escape -fira-algorithm=@var{algorithm} @gol -fira-region=@var{region} -fira-coalesce @gol -fira-loop-pressure -fno-ira-share-save-slots @gol @@ -1500,6 +1501,12 @@ ISO C99. Note that this standard is not yet fully supported; see @w{@uref{http://gcc.gnu.org/c99status.html}} for more information. The names @samp{c9x} and @samp{iso9899:199x} are deprecated. +@item c1x +ISO C1X, the draft of the next revision of the ISO C standard. +Support is limited and experimental and features enabled by this +option may be changed or removed if changed in or removed from the +standard draft. + @item gnu90 @itemx gnu89 GNU dialect of ISO C90 (including some C99 features). This @@ -1510,6 +1517,11 @@ is the default for C code. GNU dialect of ISO C99. When ISO C99 is fully implemented in GCC, this will become the default. The name @samp{gnu9x} is deprecated. +@item gnu1x +GNU dialect of ISO C1X. Support is limited and experimental and +features enabled by this option may be changed or removed if changed +in or removed from the standard draft. + @item c++98 The 1998 ISO C++ standard plus amendments. Same as @option{-ansi} for C++ code. @@ -3610,11 +3622,36 @@ comparisons, so this warning level will give a very large number of false positives. @end table +@item -Wsuggest-attribute=@r{[}const@r{|}pure@r{]} +@opindex Wsuggest-attribute= +@opindex Wno-suggest-attribute= +Warn for cases where adding an attribute may be beneficial. The +attributes currently supported are listed below. + +@table @gcctabopt +@item -Wsuggest-attribute=pure +@itemx -Wsuggest-attribute=const +@opindex Wsuggest-attribute=pure +@opindex Wno-suggest-attribute=pure +@opindex Wsuggest-attribute=const +@opindex Wno-suggest-attribute=const + +Warn about functions which might be candidates for attributes +@code{pure} or @code{const}. The compiler only warns for functions +visible in other compilation units or if it cannot prove that the +function returns normally. A function returns normally if it doesn't +contain an infinite loop nor returns abnormally by throwing, calling +@code{abort()} or trapping. This analysis requires option +@option{-fipa-pure-const}, which is enabled by default at @option{-O} +and higher. Higher optimization levels improve the accuracy of the +analysis. +@end table + @item -Warray-bounds @opindex Wno-array-bounds @opindex Warray-bounds This option is only active when @option{-ftree-vrp} is active -(default for -O2 and above). It warns about subscripts to arrays +(default for @option{-O2} and above). It warns about subscripts to arrays that are always out of bounds. This warning is enabled by @option{-Wall}. @item -Wno-div-by-zero @@ -5751,6 +5788,7 @@ compilation time. -fif-conversion2 @gol -fif-conversion @gol -fipa-pure-const @gol +-fipa-profile @gol -fipa-reference @gol -fmerge-constants -fsplit-wide-types @gol @@ -6591,6 +6629,15 @@ and reference analysis. This option can cause excessive memory and compile-time usage on large compilation units. It is not enabled by default at any optimization level. +@item -fipa-profile +@opindex fipa-profile +Perform interprocedural profile propagation. The functions called only from +cold functions are marked as cold. Also functions executed once (such as +@code{cold}, @code{noreturn}, static constructors or destructors) are identified. Cold +functions and loop less parts of functions executed once are then optimized for +size. +Enabled by default at @option{-O} and higher. + @item -fipa-cp @opindex fipa-cp Perform interprocedural constant propagation. diff --git a/gcc/doc/standards.texi b/gcc/doc/standards.texi index b9761bb30d6..f6d8acd6a72 100644 --- a/gcc/doc/standards.texi +++ b/gcc/doc/standards.texi @@ -33,6 +33,8 @@ with some exceptions, and possibly with some extensions. @cindex C99 @cindex ISO C9X @cindex C9X +@cindex ISO C1X +@cindex C1X @cindex Technical Corrigenda @cindex TC1 @cindex Technical Corrigendum 1 @@ -93,14 +95,19 @@ Errors in the 1999 ISO C standard were corrected in three Technical Corrigenda published in 2001, 2004 and 2007. GCC does not support the uncorrected version. +A fourth version of the C standard, known as @dfn{C1X}, is under +development; GCC has limited preliminary support for parts of this +standard, enabled with @option{-std=c1x}. + By default, GCC provides some extensions to the C language that on rare occasions conflict with the C standard. @xref{C Extensions,,Extensions to the C Language Family}. Use of the @option{-std} options listed above will disable these extensions where they conflict with the C standard version selected. You may also select an extended version of the C language explicitly with -@option{-std=gnu90} (for C90 with GNU extensions) or @option{-std=gnu99} -(for C99 with GNU extensions). The default, if no C language dialect +@option{-std=gnu90} (for C90 with GNU extensions), @option{-std=gnu99} +(for C99 with GNU extensions) or @option{-std=gnu1x} (for C1X with GNU +extensions). The default, if no C language dialect options are given, is @option{-std=gnu90}; this will change to @option{-std=gnu99} in some future release when the C99 support is complete. Some features that are part of the C99 standard are diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e7e2e8f9a72..1f72f906d38 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1040,7 +1040,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p) cfi = new_cfi (); - if (loc.reg == old_cfa.reg && !loc.indirect) + if (loc.reg == old_cfa.reg && !loc.indirect && !old_cfa.indirect) { /* Construct a "DW_CFA_def_cfa_offset " instruction, indicating the CFA register did not change but the offset did. The data @@ -1056,7 +1056,8 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p) #ifndef MIPS_DEBUGGING_INFO /* SGI dbx thinks this means no offset. */ else if (loc.offset == old_cfa.offset && old_cfa.reg != INVALID_REGNUM - && !loc.indirect) + && !loc.indirect + && !old_cfa.indirect) { /* Construct a "DW_CFA_def_cfa_register " instruction, indicating the CFA register has changed to but the diff --git a/gcc/final.c b/gcc/final.c index e2b7461bbbe..5011b6c5cac 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -4374,14 +4374,17 @@ rest_of_clean_state (void) else { const char *aname; + struct cgraph_node *node = cgraph_node (current_function_decl); aname = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); fprintf (final_output, "\n;; Function (%s) %s\n\n", aname, - cfun->function_frequency == FUNCTION_FREQUENCY_HOT + node->frequency == NODE_FREQUENCY_HOT ? " (hot)" - : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED ? " (unlikely executed)" + : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + ? " (executed once)" : ""); flag_dump_noaddr = flag_dump_unnumbered = 1; diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a45ba4f8080..5bde472edf4 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,27 @@ +2010-04-28 Tobias Burnus + + PR fortran/18918 + PR fortran/43919 + * simplify.c (simplify_cobound): Handle scalar coarrays. + +2010-04-27 Tobias Burnus + + * gfc-internals.texi: Update copyright year. + * gfortran.texi: Ditto. + * invoke.texi: Ditto. + +2010-04-27 Tobias Burnus + + PR fortran/18918 + * resolve.c (resolve_allocate_expr): Allow array coarrays. + * trans-types.h (gfc_get_array_type_bounds): Update prototype. + * trans-types.c (gfc_get_array_type_bounds, + gfc_get_array_descriptor_base): Add corank argument. + * trans-array.c (gfc_array_init_size): Handle corank. + (gfc_trans_create_temp_array, gfc_array_allocate, + gfc_conv_expr_descriptor): Add corank argument to call. + * trans-stmt.c (gfc_trans_pointer_assign_need_temp): Ditto. + 2010-04-24 Steven G. Kargl PR fortran/30073 diff --git a/gcc/fortran/gfc-internals.texi b/gcc/fortran/gfc-internals.texi index 4e812103606..f01393e3d68 100644 --- a/gcc/fortran/gfc-internals.texi +++ b/gcc/fortran/gfc-internals.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename gfc-internals.info -@set copyrights-gfortran 2007-2008 +@set copyrights-gfortran 2007-2010 @include gcc-common.texi diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 8a89699fc49..989a926cb86 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1,7 +1,7 @@ \input texinfo @c -*-texinfo-*- @c %**start of header @setfilename gfortran.info -@set copyrights-gfortran 1999-2008 +@set copyrights-gfortran 1999-2010 @include gcc-common.texi diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 0a3dd7d12d1..7b3fa6d4baf 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -5,7 +5,7 @@ @ignore @c man begin COPYRIGHT -Copyright @copyright{} 2004, 2005, 2006, 2007, 2008, 2009 +Copyright @copyright{} 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index aeccffb60ca..135eda4d53b 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -6561,9 +6561,9 @@ check_symbols: goto failure; } - if (codimension) + if (codimension && ar->as->rank == 0) { - gfc_error ("Sorry, allocatable coarrays are no yet supported coarray " + gfc_error ("Sorry, allocatable scalar coarrays are not yet supported " "at %L", &e->where); goto failure; } diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 1838c0071ea..a40cec103d9 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -2936,6 +2936,13 @@ simplify_cobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper) switch (ref->u.ar.type) { case AR_ELEMENT: + if (ref->next == NULL) + { + gcc_assert (ref->u.ar.as->corank > 0 + && ref->u.ar.as->rank == 0); + as = ref->u.ar.as; + goto done; + } as = NULL; continue; diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 1b56189d941..e20406c9451 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -725,7 +725,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, /* Initialize the descriptor. */ type = - gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1, + gfc_get_array_type_bounds (eltype, info->dimen, 0, loop->from, loop->to, 1, GFC_ARRAY_UNKNOWN, true); desc = gfc_create_var (type, "atmp"); GFC_DECL_PACKED_ARRAY (desc) = 1; @@ -3819,7 +3819,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) /*GCC ARRAYS*/ static tree -gfc_array_init_size (tree descriptor, int rank, tree * poffset, +gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock) { @@ -3917,6 +3917,43 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset, stride = gfc_evaluate_now (stride, pblock); } + for (n = rank; n < rank + corank; n++) + { + ubound = upper[n]; + + /* Set lower bound. */ + gfc_init_se (&se, NULL); + if (lower == NULL || lower[n] == NULL) + { + gcc_assert (n == rank + corank - 1); + se.expr = gfc_index_one_node; + } + else + { + if (ubound || n == rank + corank - 1) + { + gfc_conv_expr_type (&se, lower[n], gfc_array_index_type); + gfc_add_block_to_block (pblock, &se.pre); + } + else + { + se.expr = gfc_index_one_node; + ubound = lower[n]; + } + } + gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n], + se.expr); + + if (n < rank + corank - 1) + { + gfc_init_se (&se, NULL); + gcc_assert (ubound); + gfc_conv_expr_type (&se, ubound, gfc_array_index_type); + gfc_add_block_to_block (pblock, &se.pre); + gfc_conv_descriptor_ubound_set (pblock, descriptor, gfc_rank_cst[n], se.expr); + } + } + /* The stride is the number of elements in the array, so multiply by the size of an element to get the total size. */ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); @@ -3965,7 +4002,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) gfc_expr **lower; gfc_expr **upper; gfc_ref *ref, *prev_ref = NULL; - bool allocatable_array; + bool allocatable_array, coarray; ref = expr->ref; @@ -3981,29 +4018,40 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) if (ref == NULL || ref->type != REF_ARRAY) return false; - /* Return if this is a scalar coarray. */ - if (!prev_ref && !expr->symtree->n.sym->attr.dimension) + if (!prev_ref) { - gcc_assert (expr->symtree->n.sym->attr.codimension); - return false; + allocatable_array = expr->symtree->n.sym->attr.allocatable; + coarray = expr->symtree->n.sym->attr.codimension; } - else if (prev_ref && !prev_ref->u.c.component->attr.dimension) + else { - gcc_assert (prev_ref->u.c.component->attr.codimension); - return false; + allocatable_array = prev_ref->u.c.component->attr.allocatable; + coarray = prev_ref->u.c.component->attr.codimension; } - if (!prev_ref) - allocatable_array = expr->symtree->n.sym->attr.allocatable; - else - allocatable_array = prev_ref->u.c.component->attr.allocatable; + /* Return if this is a scalar coarray. */ + if ((!prev_ref && !expr->symtree->n.sym->attr.dimension) + || (prev_ref && !prev_ref->u.c.component->attr.dimension)) + { + gcc_assert (coarray); + return false; + } /* Figure out the size of the array. */ switch (ref->u.ar.type) { case AR_ELEMENT: - lower = NULL; - upper = ref->u.ar.start; + if (!coarray) + { + lower = NULL; + upper = ref->u.ar.start; + break; + } + /* Fall through. */ + + case AR_SECTION: + lower = ref->u.ar.start; + upper = ref->u.ar.end; break; case AR_FULL: @@ -4013,18 +4061,14 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) upper = ref->u.ar.as->upper; break; - case AR_SECTION: - lower = ref->u.ar.start; - upper = ref->u.ar.end; - break; - default: gcc_unreachable (); break; } - size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset, - lower, upper, &se->pre); + size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, + ref->u.ar.as->corank, &offset, lower, upper, + &se->pre); /* Allocate memory to store the data. */ pointer = gfc_conv_descriptor_data_get (se->expr); @@ -5299,7 +5343,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) { /* Otherwise make a new one. */ parmtype = gfc_get_element_type (TREE_TYPE (desc)); - parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0, loop.from, loop.to, 0, GFC_ARRAY_UNKNOWN, false); parm = gfc_create_var (parmtype, "parm"); diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 0b215f2395d..edffb9bfd8f 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -2822,7 +2822,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, /* Make a new descriptor. */ parmtype = gfc_get_element_type (TREE_TYPE (desc)); - parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0, loop.from, loop.to, 1, GFC_ARRAY_UNKNOWN, true); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index e359a480c71..9d5378492cd 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1222,8 +1222,8 @@ gfc_build_array_type (tree type, gfc_array_spec * as, if (as->type == AS_ASSUMED_SHAPE) akind = GFC_ARRAY_ASSUMED_SHAPE; - return gfc_get_array_type_bounds (type, as->rank, lbound, ubound, 0, akind, - restricted); + return gfc_get_array_type_bounds (type, as->rank, as->corank, lbound, + ubound, 0, akind, restricted); } /* Returns the struct descriptor_dimension type. */ @@ -1538,20 +1538,21 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, /* Return or create the base type for an array descriptor. */ static tree -gfc_get_array_descriptor_base (int dimen, bool restricted) +gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted) { tree fat_type, fieldlist, decl, arraytype; - char name[16 + GFC_RANK_DIGITS + 1]; + char name[16 + 2*GFC_RANK_DIGITS + 1 + 1]; int idx = 2 * (dimen - 1) + restricted; - gcc_assert (dimen >= 1 && dimen <= GFC_MAX_DIMENSIONS); + gcc_assert (dimen >= 1 && codimen + dimen <= GFC_MAX_DIMENSIONS); if (gfc_array_descriptor_base[idx]) return gfc_array_descriptor_base[idx]; /* Build the type node. */ fat_type = make_node (RECORD_TYPE); - sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT, dimen); + sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT "_" + GFC_RANK_PRINTF_FORMAT, dimen, codimen); TYPE_NAME (fat_type) = get_identifier (name); /* Add the data member as the first element of the descriptor. */ @@ -1583,7 +1584,7 @@ gfc_get_array_descriptor_base (int dimen, bool restricted) build_array_type (gfc_get_desc_dim_type (), build_range_type (gfc_array_index_type, gfc_index_zero_node, - gfc_rank_cst[dimen - 1])); + gfc_rank_cst[codimen + dimen - 1])); decl = build_decl (input_location, FIELD_DECL, get_identifier ("dim"), arraytype); @@ -1604,20 +1605,20 @@ gfc_get_array_descriptor_base (int dimen, bool restricted) /* Build an array (descriptor) type with given bounds. */ tree -gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound, +gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, tree * ubound, int packed, enum gfc_array_kind akind, bool restricted) { - char name[8 + GFC_RANK_DIGITS + GFC_MAX_SYMBOL_LEN]; + char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN]; tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype; const char *type_name; int n; - base_type = gfc_get_array_descriptor_base (dimen, restricted); + base_type = gfc_get_array_descriptor_base (dimen, codimen, restricted); fat_type = build_distinct_type_copy (base_type); /* Make sure that nontarget and target array type have the same canonical type (and same stub decl for debug info). */ - base_type = gfc_get_array_descriptor_base (dimen, false); + base_type = gfc_get_array_descriptor_base (dimen, codimen, false); TYPE_CANONICAL (fat_type) = base_type; TYPE_STUB_DECL (fat_type) = TYPE_STUB_DECL (base_type); @@ -1628,7 +1629,8 @@ gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound, type_name = IDENTIFIER_POINTER (tmp); else type_name = "unknown"; - sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen, + sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_" + GFC_RANK_PRINTF_FORMAT "_%.*s", dimen, codimen, GFC_MAX_SYMBOL_LEN, type_name); TYPE_NAME (fat_type) = get_identifier (name); diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h index 87feea3dfaf..0b962114b96 100644 --- a/gcc/fortran/trans-types.h +++ b/gcc/fortran/trans-types.h @@ -72,7 +72,7 @@ tree gfc_type_for_mode (enum machine_mode, int); tree gfc_build_uint_type (int); tree gfc_get_element_type (tree); -tree gfc_get_array_type_bounds (tree, int, tree *, tree *, int, +tree gfc_get_array_type_bounds (tree, int, int, tree *, tree *, int, enum gfc_array_kind, bool); tree gfc_get_nodesc_array_type (tree, gfc_array_spec *, gfc_packed, bool); diff --git a/gcc/function.c b/gcc/function.c index f78bc98af28..949480ca9d0 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4115,8 +4115,6 @@ allocate_struct_function (tree fndecl, bool abstract_p) cfun = GGC_CNEW (struct function); - cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL; - init_eh_for_function (); if (init_machine_status) diff --git a/gcc/function.h b/gcc/function.h index fb2965a2c6b..e5e03384718 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -176,17 +176,6 @@ typedef struct ipa_opt_pass_d *ipa_opt_pass; DEF_VEC_P(ipa_opt_pass); DEF_VEC_ALLOC_P(ipa_opt_pass,heap); -enum function_frequency { - /* This function most likely won't be executed at all. - (set only when profile feedback is available or via function attribute). */ - FUNCTION_FREQUENCY_UNLIKELY_EXECUTED, - /* The default value. */ - FUNCTION_FREQUENCY_NORMAL, - /* Optimize this function hard - (set only when profile feedback is available or via function attribute). */ - FUNCTION_FREQUENCY_HOT -}; - struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ struct rtx_constant_pool *pool; @@ -538,10 +527,6 @@ struct GTY(()) function { function. */ unsigned int va_list_fpr_size : 8; - /* How commonly executed the function is. Initialized during branch - probabilities pass. */ - ENUM_BITFIELD (function_frequency) function_frequency : 2; - /* Nonzero if function being compiled can call setjmp. */ unsigned int calls_setjmp : 1; diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 7ac64aa5e00..6e65093859d 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -228,7 +228,10 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP); process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP); - df_simulate_initialize_forwards (bb, local_lr); + + /* We don't call df_simulate_initialize_forwards, as it may overestimate + the live registers if there are unused artificial defs. We prefer + liveness to be underestimated. */ FOR_BB_INSNS (bb, insn) if (INSN_P (insn)) diff --git a/gcc/gimple.c b/gcc/gimple.c index aab6ef25f34..6d439c553a2 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -4579,7 +4579,8 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt) const char * gimple_decl_printable_name (tree decl, int verbosity) { - gcc_assert (decl && DECL_NAME (decl)); + if (!DECL_NAME (decl)) + return NULL; if (DECL_ASSEMBLER_NAME_SET_P (decl)) { diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ad101d52d00..1bd8fc6a1fe 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2867,71 +2867,67 @@ static enum gimplify_status gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) { tree expr = *expr_p; - tree tmp, type, arm1, arm2; + tree type = TREE_TYPE (expr); + location_t loc = EXPR_LOCATION (expr); + tree tmp, arm1, arm2; enum gimplify_status ret; tree label_true, label_false, label_cont; bool have_then_clause_p, have_else_clause_p; gimple gimple_cond; enum tree_code pred_code; gimple_seq seq = NULL; - location_t loc = EXPR_LOCATION (*expr_p); - - type = TREE_TYPE (expr); /* If this COND_EXPR has a value, copy the values into a temporary within the arms. */ - if (! VOID_TYPE_P (type)) + if (!VOID_TYPE_P (type)) { + tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2); tree result; - /* If an rvalue is ok or we do not require an lvalue, avoid creating - an addressable temporary. */ - if (((fallback & fb_rvalue) - || !(fallback & fb_lvalue)) + /* If either an rvalue is ok or we do not require an lvalue, create the + temporary. But we cannot do that if the type is addressable. */ + if (((fallback & fb_rvalue) || !(fallback & fb_lvalue)) && !TREE_ADDRESSABLE (type)) { if (gimplify_ctxp->allow_rhs_cond_expr /* If either branch has side effects or could trap, it can't be evaluated unconditionally. */ - && !TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1)) - && !generic_expr_could_trap_p (TREE_OPERAND (*expr_p, 1)) - && !TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 2)) - && !generic_expr_could_trap_p (TREE_OPERAND (*expr_p, 2))) + && !TREE_SIDE_EFFECTS (then_) + && !generic_expr_could_trap_p (then_) + && !TREE_SIDE_EFFECTS (else_) + && !generic_expr_could_trap_p (else_)) return gimplify_pure_cond_expr (expr_p, pre_p); - result = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp"); - ret = GS_ALL_DONE; + tmp = create_tmp_var (type, "iftmp"); + result = tmp; } + + /* Otherwise, only create and copy references to the values. */ else { - tree type = build_pointer_type (TREE_TYPE (expr)); + type = build_pointer_type (type); - if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node) - TREE_OPERAND (expr, 1) = - build_fold_addr_expr_loc (loc, TREE_OPERAND (expr, 1)); + if (!VOID_TYPE_P (TREE_TYPE (then_))) + then_ = build_fold_addr_expr_loc (loc, then_); - if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) - TREE_OPERAND (expr, 2) = - build_fold_addr_expr_loc (loc, TREE_OPERAND (expr, 2)); + if (!VOID_TYPE_P (TREE_TYPE (else_))) + else_ = build_fold_addr_expr_loc (loc, else_); + + expr + = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_); tmp = create_tmp_var (type, "iftmp"); - - expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0), - TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2)); - result = build_fold_indirect_ref_loc (loc, tmp); } - /* Build the then clause, 't1 = a;'. But don't build an assignment - if this branch is void; in C++ it can be, if it's a throw. */ - if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node) - TREE_OPERAND (expr, 1) - = build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp, TREE_OPERAND (expr, 1)); + /* Build the new then clause, `tmp = then_;'. But don't build the + assignment if the value is void; in C++ it can be if it's a throw. */ + if (!VOID_TYPE_P (TREE_TYPE (then_))) + TREE_OPERAND (expr, 1) = build2 (MODIFY_EXPR, type, tmp, then_); - /* Build the else clause, 't1 = b;'. */ - if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) - TREE_OPERAND (expr, 2) - = build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp, TREE_OPERAND (expr, 2)); + /* Similarly, build the new else clause, `tmp = else_;'. */ + if (!VOID_TYPE_P (TREE_TYPE (else_))) + TREE_OPERAND (expr, 2) = build2 (MODIFY_EXPR, type, tmp, else_); TREE_TYPE (expr) = void_type_node; recalculate_side_effects (expr); @@ -3762,25 +3758,11 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && num_nonzero_elements > 1 && !can_move_by_pieces (size, align)) { - tree new_tree; - if (notify_temp_creation) return GS_ERROR; - new_tree = create_tmp_var_raw (type, "C"); - - gimple_add_tmp_var (new_tree); - TREE_STATIC (new_tree) = 1; - TREE_READONLY (new_tree) = 1; - DECL_INITIAL (new_tree) = ctor; - if (align > DECL_ALIGN (new_tree)) - { - DECL_ALIGN (new_tree) = align; - DECL_USER_ALIGN (new_tree) = 1; - } - walk_tree (&DECL_INITIAL (new_tree), force_labels_r, NULL, NULL); - - TREE_OPERAND (*expr_p, 1) = new_tree; + walk_tree (&ctor, force_labels_r, NULL, NULL); + TREE_OPERAND (*expr_p, 1) = tree_output_constant_def (ctor); /* This is no longer an assignment of a CONSTRUCTOR, but we still may have processing to do on the LHS. So diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h index 9969f1c883a..5c472c54375 100644 --- a/gcc/ginclude/float.h +++ b/gcc/ginclude/float.h @@ -157,6 +157,45 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif /* C99 */ +#if defined (__STDC_VERSION__) && __STDC_VERSION__ > 199901L +/* Versions of DECIMAL_DIG for each floating-point type. */ +#undef FLT_DECIMAL_DIG +#undef DBL_DECIMAL_DIG +#undef LDBL_DECIMAL_DIG +#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__ +#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__ +#define LDBL_DECIMAL_DIG __DECIMAL_DIG__ + +/* Whether types support subnormal numbers. */ +#undef FLT_HAS_SUBNORM +#undef DBL_HAS_SUBNORM +#undef LDBL_HAS_SUBNORM +#define FLT_HAS_SUBNORM __FLT_HAS_DENORM__ +#define DBL_HAS_SUBNORM __DBL_HAS_DENORM__ +#define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__ + +/* Minimum positive values, including subnormals. */ +#undef FLT_TRUE_MIN +#undef DBL_TRUE_MIN +#undef LDBL_TRUE_MIN +#if __FLT_HAS_DENORM__ +#define FLT_TRUE_MIN __FLT_DENORM_MIN__ +#else +#define FLT_TRUE_MIN __FLT_MIN__ +#endif +#if __DBL_HAS_DENORM__ +#define DBL_TRUE_MIN __DBL_DENORM_MIN__ +#else +#define DBL_TRUE_MIN __DBL_MIN__ +#endif +#if __LDBL_HAS_DENORM__ +#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__ +#else +#define LDBL_TRUE_MIN __LDBL_MIN__ +#endif + +#endif /* C1X */ + #ifdef __STDC_WANT_DEC_FP__ /* Draft Technical Report 24732, extension for decimal floating-point arithmetic: Characteristic of decimal floating types . */ diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index dcf44b8facf..1ef32414aaa 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4083,7 +4083,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, { if (INSN_P (insn)) { - df_simulate_find_noclobber_defs (insn, test_set); + df_simulate_find_defs (insn, test_set); df_simulate_one_insn_backwards (test_bb, insn, test_live); } prev = PREV_INSN (insn); diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index ca7c0e6b7c9..6e83b899b43 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1282,7 +1282,7 @@ ipcp_driver (void) ipcp_print_profile_data (dump_file); } /* Free all IPCP structures. */ - free_all_ipa_structures_after_ipa_cp (); + ipa_free_all_structures_after_ipa_cp (); if (dump_file) fprintf (dump_file, "\nIPA constant propagation end\n"); return 0; @@ -1304,7 +1304,8 @@ ipcp_generate_summary (void) /* Write ipcp summary for nodes in SET. */ static void -ipcp_write_summary (cgraph_node_set set) +ipcp_write_summary (cgraph_node_set set, + varpool_node_set vset ATTRIBUTE_UNUSED) { ipa_prop_write_jump_functions (set); } @@ -1346,7 +1347,7 @@ struct ipa_opt_pass_d pass_ipa_cp = ipcp_read_summary, /* read_summary */ NULL, /* write_optimization_summary */ NULL, /* read_optimization_summary */ - lto_ipa_fixup_call_notes, /* stmt_fixup */ + NULL, /* stmt_fixup */ 0, /* TODOs */ NULL, /* function_transform */ NULL, /* variable_transform */ diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index fbd695d129c..5146c3c3cad 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -285,6 +285,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, + inline_summary (e->callee)->estimated_self_stack_size; if (e->callee->global.inlined_to->global.estimated_stack_size < peak) e->callee->global.inlined_to->global.estimated_stack_size = peak; + cgraph_propagate_frequency (e->callee); /* Recursively clone all bodies. */ for (e = e->callee->callees; e; e = e->next_callee) @@ -1321,6 +1322,8 @@ cgraph_decide_inlining (void) cgraph_remove_function_insertion_hook (function_insertion_hook_holder); if (in_lto_p && flag_indirect_inlining) ipa_update_after_lto_read (); + if (flag_indirect_inlining) + ipa_create_all_structures_for_iinln (); max_count = 0; max_benefit = 0; @@ -1441,7 +1444,7 @@ cgraph_decide_inlining (void) /* Free ipa-prop structures if they are no longer needed. */ if (flag_indirect_inlining) - free_all_ipa_structures_after_iinln (); + ipa_free_all_structures_after_iinln (); if (dump_file) fprintf (dump_file, @@ -2094,7 +2097,8 @@ inline_read_summary (void) active, we don't need to write them twice. */ static void -inline_write_summary (cgraph_node_set set) +inline_write_summary (cgraph_node_set set, + varpool_node_set vset ATTRIBUTE_UNUSED) { if (flag_indirect_inlining && !flag_ipa_cp) ipa_prop_write_jump_functions (set); @@ -2137,7 +2141,7 @@ struct ipa_opt_pass_d pass_ipa_inline = inline_read_summary, /* read_summary */ NULL, /* write_optimization_summary */ NULL, /* read_optimization_summary */ - lto_ipa_fixup_call_notes, /* stmt_fixup */ + NULL, /* stmt_fixup */ 0, /* TODOs */ inline_transform, /* function_transform */ NULL, /* variable_transform */ diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index af00175124d..7ab3a3e607c 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -41,6 +41,10 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector; /* Vector where the parameter infos are actually stored. */ VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector; +/* Bitmap with all UIDs of call graph edges that have been already processed + by indirect inlining. */ +static bitmap iinlining_processed_edges; + /* Holders of ipa cgraph hooks: */ static struct cgraph_edge_hook_list *edge_removal_hook_holder; static struct cgraph_node_hook_list *node_removal_hook_holder; @@ -745,39 +749,31 @@ ipa_is_ssa_with_stmt_def (tree t) return false; } -/* Creates a new note describing a call to a parameter number FORMAL_ID and - attaches it to the linked list of INFO. It also sets the called flag of the - parameter. STMT is the corresponding call statement. */ +/* Create a new indirect call graph edge describing a call to a parameter + number FORMAL_ID and and set the called flag of the parameter. NODE is the + caller. STMT is the corresponding call statement. */ static void -ipa_note_param_call (struct ipa_node_params *info, int formal_id, - gimple stmt) +ipa_note_param_call (struct cgraph_node *node, int formal_id, gimple stmt) { - struct ipa_param_call_note *note; + struct cgraph_edge *cs; basic_block bb = gimple_bb (stmt); + int freq; - note = XCNEW (struct ipa_param_call_note); - note->formal_id = formal_id; - note->stmt = stmt; - note->lto_stmt_uid = gimple_uid (stmt); - note->count = bb->count; - note->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb); - note->loop_nest = bb->loop_depth; - - note->next = info->param_calls; - info->param_calls = note; - - return; + freq = compute_call_stmt_bb_frequency (current_function_decl, bb); + cs = cgraph_create_indirect_edge (node, stmt, bb->count, freq, + bb->loop_depth); + cs->indirect_info->param_index = formal_id; } -/* Analyze the CALL and examine uses of formal parameters of the caller +/* Analyze the CALL and examine uses of formal parameters of the caller NODE (described by INFO). Currently it checks whether the call calls a pointer that is a formal parameter and if so, the parameter is marked with the - called flag and a note describing the call is created. This is very simple - for ordinary pointers represented in SSA but not-so-nice when it comes to - member pointers. The ugly part of this function does nothing more than - tries to match the pattern of such a call. An example of such a pattern is - the gimple dump below, the call is on the last line: + called flag and an indirect call graph edge describing the call is created. + This is very simple for ordinary pointers represented in SSA but not-so-nice + when it comes to member pointers. The ugly part of this function does + nothing more than trying to match the pattern of such a call. An example of + such a pattern is the gimple dump below, the call is on the last line: : f$__delta_5 = f.__delta; @@ -817,7 +813,8 @@ ipa_note_param_call (struct ipa_node_params *info, int formal_id, */ static void -ipa_analyze_call_uses (struct ipa_node_params *info, gimple call) +ipa_analyze_call_uses (struct cgraph_node *node, struct ipa_node_params *info, + gimple call) { tree target = gimple_call_fn (call); gimple def; @@ -838,7 +835,7 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call) /* assuming TREE_CODE (var) == PARM_DECL */ index = ipa_get_param_decl_index (info, var); if (index >= 0) - ipa_note_param_call (info, index, call); + ipa_note_param_call (node, index, call); return; } @@ -935,20 +932,21 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call) index = ipa_get_param_decl_index (info, rec); if (index >= 0 && !ipa_is_param_modified (info, index)) - ipa_note_param_call (info, index, call); + ipa_note_param_call (node, index, call); return; } -/* Analyze the statement STMT with respect to formal parameters (described in - INFO) and their uses. Currently it only checks whether formal parameters - are called. */ +/* Analyze the call statement STMT with respect to formal parameters (described + in INFO) of caller given by NODE. Currently it only checks whether formal + parameters are called. */ static void -ipa_analyze_stmt_uses (struct ipa_node_params *info, gimple stmt) +ipa_analyze_stmt_uses (struct cgraph_node *node, struct ipa_node_params *info, + gimple stmt) { if (is_gimple_call (stmt)) - ipa_analyze_call_uses (info, stmt); + ipa_analyze_call_uses (node, info, stmt); } /* Scan the function body of NODE and inspect the uses of formal parameters. @@ -973,7 +971,7 @@ ipa_analyze_params_uses (struct cgraph_node *node) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); - ipa_analyze_stmt_uses (info, stmt); + ipa_analyze_stmt_uses (node, info, stmt); } } @@ -1029,9 +1027,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, by JFUNC. NODE is the node where the call is. */ static void -print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt, - struct ipa_jump_func *jfunc, - struct cgraph_node *node) +print_edge_addition_message (FILE *f, struct cgraph_edge *e, + struct ipa_jump_func *jfunc) { fprintf (f, "ipa-prop: Discovered an indirect call to a known target ("); if (jfunc->type == IPA_JF_CONST_MEMBER_PTR) @@ -1042,8 +1039,8 @@ print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt, else print_node_brief(f, "", jfunc->value.constant, 0); - fprintf (f, ") in %s: ", cgraph_node_name (node)); - print_gimple_stmt (f, nt->stmt, 2, TDF_SLIM); + fprintf (f, ") in %s: ", cgraph_node_name (e->caller)); + print_gimple_stmt (f, e->call_stmt, 2, TDF_SLIM); } /* Update the param called notes associated with NODE when CS is being inlined, @@ -1053,41 +1050,47 @@ print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt, unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */ static bool -update_call_notes_after_inlining (struct cgraph_edge *cs, - struct cgraph_node *node, - VEC (cgraph_edge_p, heap) **new_edges) +update_indirect_edges_after_inlining (struct cgraph_edge *cs, + struct cgraph_node *node, + VEC (cgraph_edge_p, heap) **new_edges) { - struct ipa_node_params *info = IPA_NODE_REF (node); struct ipa_edge_args *top = IPA_EDGE_REF (cs); - struct ipa_param_call_note *nt; + struct cgraph_edge *ie, *next_ie; bool res = false; - for (nt = info->param_calls; nt; nt = nt->next) + ipa_check_create_edge_args (); + + for (ie = node->indirect_calls; ie; ie = next_ie) { + struct cgraph_indirect_call_info *ici = ie->indirect_info; struct ipa_jump_func *jfunc; - if (nt->processed) + next_ie = ie->next_callee; + if (bitmap_bit_p (iinlining_processed_edges, ie->uid)) continue; + /* If we ever use indirect edges for anything other than indirect + inlining, we will need to skip those with negative param_indices. */ + gcc_assert (ici->param_index >= 0); + /* We must check range due to calls with variable number of arguments: */ - if (nt->formal_id >= ipa_get_cs_argument_count (top)) + if (ici->param_index >= ipa_get_cs_argument_count (top)) { - nt->processed = true; + bitmap_set_bit (iinlining_processed_edges, ie->uid); continue; } - jfunc = ipa_get_ith_jump_func (top, nt->formal_id); + jfunc = ipa_get_ith_jump_func (top, ici->param_index); if (jfunc->type == IPA_JF_PASS_THROUGH && jfunc->value.pass_through.operation == NOP_EXPR) - nt->formal_id = jfunc->value.pass_through.formal_id; + ici->param_index = jfunc->value.pass_through.formal_id; else if (jfunc->type == IPA_JF_CONST || jfunc->type == IPA_JF_CONST_MEMBER_PTR) { struct cgraph_node *callee; - struct cgraph_edge *new_indirect_edge; tree decl; - nt->processed = true; + bitmap_set_bit (iinlining_processed_edges, ie->uid); if (jfunc->type == IPA_JF_CONST_MEMBER_PTR) decl = jfunc->value.member_cst.pfn; else @@ -1105,32 +1108,29 @@ update_call_notes_after_inlining (struct cgraph_edge *cs, res = true; if (dump_file) - print_edge_addition_message (dump_file, nt, jfunc, node); - - new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt, - nt->count, nt->frequency, - nt->loop_nest); - new_indirect_edge->lto_stmt_uid = nt->lto_stmt_uid; - new_indirect_edge->indirect_call = 1; - ipa_check_create_edge_args (); + print_edge_addition_message (dump_file, ie, jfunc); + + cgraph_make_edge_direct (ie, callee); + ie->indirect_inlining_edge = 1; if (new_edges) - VEC_safe_push (cgraph_edge_p, heap, *new_edges, new_indirect_edge); + VEC_safe_push (cgraph_edge_p, heap, *new_edges, ie); top = IPA_EDGE_REF (cs); } else { - /* Ancestor jum functions and pass theoughs with operations should + /* Ancestor jump functions and pass theoughs with operations should not be used on parameters that then get called. */ gcc_assert (jfunc->type == IPA_JF_UNKNOWN); - nt->processed = true; + bitmap_set_bit (iinlining_processed_edges, ie->uid); } } + return res; } /* Recursively traverse subtree of NODE (including node) made of inlined cgraph_edges when CS has been inlined and invoke - update_call_notes_after_inlining on all nodes and + update_indirect_edges_after_inlining on all nodes and update_jump_functions_after_inlining on all non-inlined edges that lead out of this subtree. Newly discovered indirect edges will be added to *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were @@ -1144,7 +1144,7 @@ propagate_info_to_inlined_callees (struct cgraph_edge *cs, struct cgraph_edge *e; bool res; - res = update_call_notes_after_inlining (cs, node, new_edges); + res = update_indirect_edges_after_inlining (cs, node, new_edges); for (e = node->callees; e; e = e->next_callee) if (!e->inline_failed) @@ -1216,13 +1216,6 @@ ipa_free_node_params_substructures (struct ipa_node_params *info) if (info->params) free (info->params); - while (info->param_calls) - { - struct ipa_param_call_note *note = info->param_calls; - info->param_calls = note->next; - free (note); - } - memset (info, 0, sizeof (*info)); } @@ -1317,6 +1310,10 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, new_args->jump_functions = (struct ipa_jump_func *) duplicate_ggc_array (old_args->jump_functions, sizeof (struct ipa_jump_func) * arg_count); + + if (iinlining_processed_edges + && bitmap_bit_p (iinlining_processed_edges, src->uid)) + bitmap_set_bit (iinlining_processed_edges, dst->uid); } /* Hook that is called by cgraph.c when a node is duplicated. */ @@ -1326,7 +1323,6 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst, __attribute__((unused)) void *data) { struct ipa_node_params *old_info, *new_info; - struct ipa_param_call_note *note; int param_count; ipa_check_create_node_params (); @@ -1340,17 +1336,6 @@ ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst, sizeof (struct ipa_param_descriptor) * param_count); new_info->ipcp_orig_node = old_info->ipcp_orig_node; new_info->count_scale = old_info->count_scale; - - for (note = old_info->param_calls; note; note = note->next) - { - struct ipa_param_call_note *nn; - - nn = (struct ipa_param_call_note *) - xcalloc (1, sizeof (struct ipa_param_call_note)); - memcpy (nn, note, sizeof (struct ipa_param_call_note)); - nn->next = new_info->param_calls; - new_info->param_calls = nn; - } } /* Register our cgraph hooks if they are not already there. */ @@ -1387,11 +1372,19 @@ ipa_unregister_cgraph_hooks (void) node_duplication_hook_holder = NULL; } +/* Allocate all necessary data strucutures necessary for indirect inlining. */ + +void +ipa_create_all_structures_for_iinln (void) +{ + iinlining_processed_edges = BITMAP_ALLOC (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_structures_after_ipa_cp (void) { if (!flag_indirect_inlining) { @@ -1405,8 +1398,10 @@ free_all_ipa_structures_after_ipa_cp (void) longer needed after indirect inlining. */ void -free_all_ipa_structures_after_iinln (void) +ipa_free_all_structures_after_iinln (void) { + BITMAP_FREE (iinlining_processed_edges); + ipa_free_all_edge_args (); ipa_free_all_node_params (); ipa_unregister_cgraph_hooks (); @@ -1974,40 +1969,31 @@ ipa_read_jump_function (struct lto_input_block *ib, } } -/* Stream out a parameter call note. */ +/* Stream out parts of cgraph_indirect_call_info corresponding to CS that are + relevant to indirect inlining to OB. */ static void -ipa_write_param_call_note (struct output_block *ob, - struct ipa_param_call_note *note) +ipa_write_indirect_edge_info (struct output_block *ob, + struct cgraph_edge *cs) { - gcc_assert (!note->processed); - lto_output_uleb128_stream (ob->main_stream, gimple_uid (note->stmt)); - lto_output_sleb128_stream (ob->main_stream, note->formal_id); - lto_output_sleb128_stream (ob->main_stream, note->count); - lto_output_sleb128_stream (ob->main_stream, note->frequency); - lto_output_sleb128_stream (ob->main_stream, note->loop_nest); + struct cgraph_indirect_call_info *ii = cs->indirect_info; + + lto_output_sleb128_stream (ob->main_stream, ii->param_index); } -/* Read in a parameter call note. */ +/* Read in parts of cgraph_indirect_call_info corresponding to CS that are + relevant to indirect inlining from IB. */ static void -ipa_read_param_call_note (struct lto_input_block *ib, - struct ipa_node_params *info) - +ipa_read_indirect_edge_info (struct lto_input_block *ib, + struct data_in *data_in ATTRIBUTE_UNUSED, + struct cgraph_edge *cs) { - struct ipa_param_call_note *note = XCNEW (struct ipa_param_call_note); - - note->lto_stmt_uid = (unsigned int) lto_input_uleb128 (ib); - note->formal_id = (int) lto_input_sleb128 (ib); - note->count = (gcov_type) lto_input_sleb128 (ib); - note->frequency = (int) lto_input_sleb128 (ib); - note->loop_nest = (int) lto_input_sleb128 (ib); + struct cgraph_indirect_call_info *ii = cs->indirect_info; - note->next = info->param_calls; - info->param_calls = note; + ii->param_index = (int) lto_input_sleb128 (ib); } - /* Stream out NODE info to OB. */ static void @@ -2019,8 +2005,6 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) int j; struct cgraph_edge *e; struct bitpack_d *bp; - int note_count = 0; - struct ipa_param_call_note *note; encoder = ob->decl_state->cgraph_node_encoder; node_ref = lto_cgraph_encoder_encode (encoder, node); @@ -2046,12 +2030,8 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node) for (j = 0; j < ipa_get_cs_argument_count (args); j++) ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j)); } - - for (note = info->param_calls; note; note = note->next) - note_count++; - lto_output_uleb128_stream (ob->main_stream, note_count); - for (note = info->param_calls; note; note = note->next) - ipa_write_param_call_note (ob, note); + for (e = node->indirect_calls; e; e = e->next_callee) + ipa_write_indirect_edge_info (ob, e); } /* Srtream in NODE info from IB. */ @@ -2064,7 +2044,6 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, int k; struct cgraph_edge *e; struct bitpack_d *bp; - int i, note_count; ipa_initialize_node_params (node); @@ -2094,10 +2073,8 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node, for (k = 0; k < ipa_get_cs_argument_count (args); k++) ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in); } - - note_count = lto_input_uleb128 (ib); - for (i = 0; i < note_count; i++) - ipa_read_param_call_note (ib, info); + for (e = node->indirect_calls; e; e = e->next_callee) + ipa_read_indirect_edge_info (ib, data_in, e); } /* Write jump functions for nodes in SET. */ @@ -2222,29 +2199,3 @@ ipa_update_after_lto_read (void) ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); } } - -/* Walk param call notes of NODE and set their call statements given the uid - stored in each note and STMTS which is an array of statements indexed by the - uid. */ - -void -lto_ipa_fixup_call_notes (struct cgraph_node *node, gimple *stmts) -{ - struct ipa_node_params *info; - struct ipa_param_call_note *note; - - ipa_check_create_node_params (); - info = IPA_NODE_REF (node); - note = info->param_calls; - /* If there are no notes or they have already been fixed up (the same fixup - is called for both inlining and ipa-cp), there's nothing to do. */ - if (!note || note->stmt) - return; - - do - { - note->stmt = stmts[note->lto_stmt_uid]; - note = note->next; - } - while (note); -} diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 4cb2469818c..5a293d90181 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -135,32 +135,6 @@ struct ipcp_lattice tree constant; }; -/* Each instance of the following structure describes a statement that calls a - function parameter. Those referring to statements within the same function - are linked in a list. */ -struct ipa_param_call_note -{ - /* Expected number of executions: calculated in profile.c. */ - gcov_type count; - /* Linked list's next */ - struct ipa_param_call_note *next; - /* Statement that contains the call to the parameter above. */ - gimple stmt; - /* When in LTO, we the above stmt will be NULL and we need an uid. */ - unsigned int lto_stmt_uid; - /* Index of the parameter that is called. */ - int formal_id; - /* Expected frequency of executions within the function. see cgraph_edge in - cgraph.h for more on this. */ - int frequency; - /* Depth of loop nest, 1 means no loop nest. */ - unsigned short int loop_nest; - /* Set when we have already found the target to be a compile time constant - and turned this into an edge or when the note was found unusable for some - reason. */ - bool processed; -}; - /* Structure describing a single formal parameter. */ struct ipa_param_descriptor { @@ -181,11 +155,18 @@ struct ipa_node_params this function's parameters would not be analyzed by the different stages of IPA CP. */ int param_count; + /* Whether this function is called with variable number of actual + arguments. */ + unsigned called_with_var_arguments : 1; + /* Whether the modification analysis has already been performed. */ + unsigned modification_analysis_done : 1; + /* Whether the param uses analysis has already been performed. */ + unsigned uses_analysis_done : 1; + /* Whether the function is enqueued in an ipa_func_list. */ + unsigned node_enqueued : 1; /* Pointer to an array of structures describing individual formal parameters. */ struct ipa_param_descriptor *params; - /* List of structures enumerating calls to a formal parameter. */ - struct ipa_param_call_note *param_calls; /* Only for versioned nodes this field would not be NULL, it points to the node that IPA cp cloned from. */ struct cgraph_node *ipcp_orig_node; @@ -195,16 +176,6 @@ struct ipa_node_params the profiling information of the original function and the versioned one. */ gcov_type count_scale; - - /* Whether this function is called with variable number of actual - arguments. */ - unsigned called_with_var_arguments : 1; - /* Whether the modification analysis has already been performed. */ - unsigned modification_analysis_done : 1; - /* Whether the param uses analysis has already been performed. */ - unsigned uses_analysis_done : 1; - /* Whether the function is enqueued in an ipa_func_list. */ - unsigned node_enqueued : 1; }; /* ipa_node_params access functions. Please use these to access fields that @@ -338,8 +309,9 @@ 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 free_all_ipa_structures_after_iinln (void); +void ipa_create_all_structures_for_iinln (void); +void ipa_free_all_structures_after_ipa_cp (void); +void ipa_free_all_structures_after_iinln (void); void ipa_register_cgraph_hooks (void); /* This function ensures the array of node param infos is big enough to diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 4d0df50ac63..a0157beeafc 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -49,12 +49,15 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "flags.h" #include "timevar.h" +#include "toplev.h" #include "diagnostic.h" #include "langhooks.h" #include "target.h" #include "lto-streamer.h" #include "cfgloop.h" #include "tree-scalar-evolution.h" +#include "intl.h" +#include "opts.h" static struct pointer_set_t *visited_nodes; @@ -106,6 +109,71 @@ static struct cgraph_node_hook_list *function_insertion_hook_holder; static struct cgraph_2node_hook_list *node_duplication_hook_holder; static struct cgraph_node_hook_list *node_removal_hook_holder; +/* Try to guess if function body will always be visible to compiler + when compiling the call and whether compiler will be able + to propagate the information by itself. */ + +static bool +function_always_visible_to_compiler_p (tree decl) +{ + return (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl)); +} + +/* Emit suggestion about attribute ATTRIB_NAME for DECL. KNOWN_FINITE + is true if the function is known to be finite. The diagnostic is + controlled by OPTION. WARNED_ABOUT is a pointer_set unique for + OPTION, this function may initialize it and it is always returned + by the function. */ + +static struct pointer_set_t * +suggest_attribute (int option, tree decl, bool known_finite, + struct pointer_set_t *warned_about, + const char * attrib_name) +{ + if (!option_enabled (option)) + return warned_about; + if (TREE_THIS_VOLATILE (decl) + || (known_finite && function_always_visible_to_compiler_p (decl))) + return warned_about; + + if (!warned_about) + warned_about = pointer_set_create (); + if (pointer_set_contains (warned_about, decl)) + return warned_about; + pointer_set_insert (warned_about, decl); + warning_at (DECL_SOURCE_LOCATION (decl), + option, + known_finite + ? _("function might be candidate for attribute %<%s%>") + : _("function might be candidate for attribute %<%s%>" + " if it is known to return normally"), attrib_name); + return warned_about; +} + +/* Emit suggestion about __attribute_((pure)) for DECL. KNOWN_FINITE + is true if the function is known to be finite. */ + +static void +warn_function_pure (tree decl, bool known_finite) +{ + static struct pointer_set_t *warned_about; + + warned_about + = suggest_attribute (OPT_Wsuggest_attribute_pure, decl, + known_finite, warned_about, "pure"); +} + +/* Emit suggestion about __attribute_((const)) for DECL. KNOWN_FINITE + is true if the function is known to be finite. */ + +static void +warn_function_const (tree decl, bool known_finite) +{ + static struct pointer_set_t *warned_about; + warned_about + = suggest_attribute (OPT_Wsuggest_attribute_const, decl, + known_finite, warned_about, "const"); +} /* Init the function state. */ static void @@ -325,7 +393,11 @@ check_call (funct_state local, gimple call, bool ipa) /* When not in IPA mode, we can still handle self recursion. */ if (!ipa && callee_t == current_function_decl) - local->looping = true; + { + if (dump_file) + fprintf (dump_file, " Recursive call can loop.\n"); + local->looping = true; + } /* Either calle is unknown or we are doing local analysis. Look to see if there are any bits available for the callee (such as by declaration or because it is builtin) and process solely on the basis of @@ -353,12 +425,20 @@ check_call (funct_state local, gimple call, bool ipa) if (flags & ECF_CONST) { if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t)) - local->looping = true; + { + if (dump_file) + fprintf (dump_file, " calls looping pure.\n"); + local->looping = true; + } } else if (flags & ECF_PURE) { if (callee_t && DECL_LOOPING_CONST_OR_PURE_P (callee_t)) - local->looping = true; + { + if (dump_file) + fprintf (dump_file, " calls looping const.\n"); + local->looping = true; + } if (dump_file) fprintf (dump_file, " pure function call in not const\n"); if (local->pure_const_state == IPA_CONST) @@ -613,7 +693,8 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) since all we would be interested in are the addressof operations. */ visited_nodes = pointer_set_create (); - set_function_state (node, analyze_function (node, true)); + if (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE) + set_function_state (node, analyze_function (node, true)); pointer_set_destroy (visited_nodes); visited_nodes = NULL; } @@ -699,7 +780,8 @@ generate_summary (void) /* Serialize the ipa info for lto. */ static void -pure_const_write_summary (cgraph_node_set set) +pure_const_write_summary (cgraph_node_set set, + varpool_node_set vset ATTRIBUTE_UNUSED) { struct cgraph_node *node; struct lto_simple_output_block *ob @@ -947,19 +1029,27 @@ propagate (void) switch (this_state) { case IPA_CONST: - if (!TREE_READONLY (w->decl) && dump_file) - fprintf (dump_file, "Function found to be %sconst: %s\n", - this_looping ? "looping " : "", - cgraph_node_name (w)); + if (!TREE_READONLY (w->decl)) + { + warn_function_const (w->decl, !this_looping); + if (dump_file) + fprintf (dump_file, "Function found to be %sconst: %s\n", + this_looping ? "looping " : "", + cgraph_node_name (w)); + } cgraph_set_readonly_flag (w, true); cgraph_set_looping_const_or_pure_flag (w, this_looping); break; case IPA_PURE: - if (!DECL_PURE_P (w->decl) && dump_file) - fprintf (dump_file, "Function found to be %spure: %s\n", - this_looping ? "looping " : "", - cgraph_node_name (w)); + if (!DECL_PURE_P (w->decl)) + { + warn_function_pure (w->decl, !this_looping); + if (dump_file) + fprintf (dump_file, "Function found to be %spure: %s\n", + this_looping ? "looping " : "", + cgraph_node_name (w)); + } cgraph_set_pure_flag (w, true); cgraph_set_looping_const_or_pure_flag (w, this_looping); break; @@ -1112,17 +1202,11 @@ struct ipa_opt_pass_d pass_ipa_pure_const = NULL /* variable_transform */ }; -/* Simple local pass for pure const discovery reusing the analysis from - ipa_pure_const. This pass is effective when executed together with - other optimization passes in early optimization pass queue. */ +/* Return true if function should be skipped for local pure const analysis. */ -static unsigned int -local_pure_const (void) +static bool +skip_function_for_local_pure_const (struct cgraph_node *node) { - bool changed = false; - funct_state l; - struct cgraph_node *node; - /* Because we do not schedule pass_fixup_cfg over whole program after early optimizations we must not promote functions that are called by already processed functions. */ @@ -1130,16 +1214,35 @@ local_pure_const (void) { if (dump_file) fprintf (dump_file, "Function called in recursive cycle; ignoring\n"); - return 0; + return true; } - node = cgraph_node (current_function_decl); if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) { if (dump_file) - fprintf (dump_file, "Function has wrong visibility; ignoring\n"); - return 0; + fprintf (dump_file, "Function is not available or overwrittable; not analyzing.\n"); + return true; } + return false; +} + +/* Simple local pass for pure const discovery reusing the analysis from + ipa_pure_const. This pass is effective when executed together with + other optimization passes in early optimization pass queue. */ +static unsigned int +local_pure_const (void) +{ + bool changed = false; + funct_state l; + bool skip; + struct cgraph_node *node; + + node = cgraph_node (current_function_decl); + skip = skip_function_for_local_pure_const (node); + if (!warn_suggest_attribute_const + && !warn_suggest_attribute_pure + && skip) + return 0; l = analyze_function (node, false); switch (l->pure_const_state) @@ -1147,9 +1250,13 @@ local_pure_const (void) case IPA_CONST: if (!TREE_READONLY (current_function_decl)) { - cgraph_set_readonly_flag (node, true); - cgraph_set_looping_const_or_pure_flag (node, l->looping); - changed = true; + warn_function_const (current_function_decl, !l->looping); + if (!skip) + { + cgraph_set_readonly_flag (node, true); + cgraph_set_looping_const_or_pure_flag (node, l->looping); + changed = true; + } if (dump_file) fprintf (dump_file, "Function found to be %sconst: %s\n", l->looping ? "looping " : "", @@ -1159,8 +1266,11 @@ local_pure_const (void) else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) && !l->looping) { - cgraph_set_looping_const_or_pure_flag (node, false); - changed = true; + if (!skip) + { + cgraph_set_looping_const_or_pure_flag (node, false); + changed = true; + } if (dump_file) fprintf (dump_file, "Function found to be non-looping: %s\n", lang_hooks.decl_printable_name (current_function_decl, @@ -1169,11 +1279,15 @@ local_pure_const (void) break; case IPA_PURE: - if (!TREE_READONLY (current_function_decl)) + if (!DECL_PURE_P (current_function_decl)) { - cgraph_set_pure_flag (node, true); - cgraph_set_looping_const_or_pure_flag (node, l->looping); - changed = true; + if (!skip) + { + cgraph_set_pure_flag (node, true); + cgraph_set_looping_const_or_pure_flag (node, l->looping); + changed = true; + } + warn_function_pure (current_function_decl, !l->looping); if (dump_file) fprintf (dump_file, "Function found to be %spure: %s\n", l->looping ? "looping " : "", @@ -1183,8 +1297,11 @@ local_pure_const (void) else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl) && !l->looping) { - cgraph_set_looping_const_or_pure_flag (node, false); - changed = true; + if (!skip) + { + cgraph_set_looping_const_or_pure_flag (node, false); + changed = true; + } if (dump_file) fprintf (dump_file, "Function found to be non-looping: %s\n", lang_hooks.decl_printable_name (current_function_decl, diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 7183e65a7fd..2617072eb8a 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -1040,7 +1040,8 @@ write_node_summary_p (struct cgraph_node *node) /* Serialize the ipa info for lto. */ static void -ipa_reference_write_summary (cgraph_node_set set) +ipa_reference_write_summary (cgraph_node_set set, + varpool_node_set vset ATTRIBUTE_UNUSED) { struct cgraph_node *node; struct lto_simple_output_block *ob diff --git a/gcc/ipa.c b/gcc/ipa.c index 3a5ef16d2be..36fe714abb3 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -355,6 +355,21 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program) return false; } +/* Dissolve the same_comdat_group list in which NODE resides. */ + +static void +dissolve_same_comdat_group_list (struct cgraph_node *node) +{ + struct cgraph_node *n = node, *next; + do + { + next = n->same_comdat_group; + n->same_comdat_group = NULL; + n = next; + } + while (n != node); +} + /* Mark visibility of all functions. A local function is one whose calls can occur only in the current @@ -385,17 +400,17 @@ function_and_variable_visibility (bool whole_program) and simplifies later passes. */ if (node->same_comdat_group && DECL_EXTERNAL (node->decl)) { - struct cgraph_node *n = node, *next; - do - { +#ifdef ENABLE_CHECKING + struct cgraph_node *n; + + for (n = node->same_comdat_group; + n != node; + n = n->same_comdat_group) /* If at least one of same comdat group functions is external, all of them have to be, otherwise it is a front-end bug. */ gcc_assert (DECL_EXTERNAL (n->decl)); - next = n->same_comdat_group; - n->same_comdat_group = NULL; - n = next; - } - while (n != node); +#endif + dissolve_same_comdat_group_list (node); } gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl)) || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)); @@ -411,6 +426,12 @@ function_and_variable_visibility (bool whole_program) { gcc_assert (whole_program || !TREE_PUBLIC (node->decl)); cgraph_make_decl_local (node->decl); + if (node->same_comdat_group) + /* cgraph_externally_visible_p has already checked all other nodes + in the group and they will all be made local. We need to + dissolve the group at once so that the predicate does not + segfault though. */ + dissolve_same_comdat_group_list (node); } node->local.local = (cgraph_only_called_directly_p (node) && node->analyzed @@ -741,3 +762,241 @@ debug_cgraph_node_set (cgraph_node_set set) dump_cgraph_node_set (stderr, set); } +/* Hash a varpool node set element. */ + +static hashval_t +hash_varpool_node_set_element (const void *p) +{ + const_varpool_node_set_element element = (const_varpool_node_set_element) p; + return htab_hash_pointer (element->node); +} + +/* Compare two varpool node set elements. */ + +static int +eq_varpool_node_set_element (const void *p1, const void *p2) +{ + const_varpool_node_set_element e1 = (const_varpool_node_set_element) p1; + const_varpool_node_set_element e2 = (const_varpool_node_set_element) p2; + + return e1->node == e2->node; +} + +/* Create a new varpool node set. */ + +varpool_node_set +varpool_node_set_new (void) +{ + varpool_node_set new_node_set; + + new_node_set = GGC_NEW (struct varpool_node_set_def); + new_node_set->hashtab = htab_create_ggc (10, + hash_varpool_node_set_element, + eq_varpool_node_set_element, + NULL); + new_node_set->nodes = NULL; + return new_node_set; +} + +/* Add varpool_node NODE to varpool_node_set SET. */ + +void +varpool_node_set_add (varpool_node_set set, struct varpool_node *node) +{ + void **slot; + varpool_node_set_element element; + struct varpool_node_set_element_def dummy; + + dummy.node = node; + slot = htab_find_slot (set->hashtab, &dummy, INSERT); + + if (*slot != HTAB_EMPTY_ENTRY) + { + element = (varpool_node_set_element) *slot; + gcc_assert (node == element->node + && (VEC_index (varpool_node_ptr, set->nodes, element->index) + == node)); + return; + } + + /* Insert node into hash table. */ + element = + (varpool_node_set_element) GGC_NEW (struct varpool_node_set_element_def); + element->node = node; + element->index = VEC_length (varpool_node_ptr, set->nodes); + *slot = element; + + /* Insert into node vector. */ + VEC_safe_push (varpool_node_ptr, gc, set->nodes, node); +} + +/* Remove varpool_node NODE from varpool_node_set SET. */ + +void +varpool_node_set_remove (varpool_node_set set, struct varpool_node *node) +{ + void **slot, **last_slot; + varpool_node_set_element element, last_element; + struct varpool_node *last_node; + struct varpool_node_set_element_def dummy; + + dummy.node = node; + slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT); + if (slot == NULL) + return; + + element = (varpool_node_set_element) *slot; + gcc_assert (VEC_index (varpool_node_ptr, set->nodes, element->index) + == node); + + /* Remove from vector. We do this by swapping node with the last element + of the vector. */ + last_node = VEC_pop (varpool_node_ptr, set->nodes); + if (last_node != node) + { + dummy.node = last_node; + last_slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT); + last_element = (varpool_node_set_element) *last_slot; + gcc_assert (last_element); + + /* Move the last element to the original spot of NODE. */ + last_element->index = element->index; + VEC_replace (varpool_node_ptr, set->nodes, last_element->index, + last_node); + } + + /* Remove element from hash table. */ + htab_clear_slot (set->hashtab, slot); + ggc_free (element); +} + +/* Find NODE in SET and return an iterator to it if found. A null iterator + is returned if NODE is not in SET. */ + +varpool_node_set_iterator +varpool_node_set_find (varpool_node_set set, struct varpool_node *node) +{ + void **slot; + struct varpool_node_set_element_def dummy; + varpool_node_set_element element; + varpool_node_set_iterator vsi; + + dummy.node = node; + slot = htab_find_slot (set->hashtab, &dummy, NO_INSERT); + if (slot == NULL) + vsi.index = (unsigned) ~0; + else + { + element = (varpool_node_set_element) *slot; + gcc_assert (VEC_index (varpool_node_ptr, set->nodes, element->index) + == node); + vsi.index = element->index; + } + vsi.set = set; + + return vsi; +} + +/* Dump content of SET to file F. */ + +void +dump_varpool_node_set (FILE *f, varpool_node_set set) +{ + varpool_node_set_iterator iter; + + for (iter = vsi_start (set); !vsi_end_p (iter); vsi_next (&iter)) + { + struct varpool_node *node = vsi_node (iter); + dump_varpool_node (f, node); + } +} + +/* Dump content of SET to stderr. */ + +void +debug_varpool_node_set (varpool_node_set set) +{ + dump_varpool_node_set (stderr, set); +} + + +/* Simple ipa profile pass propagating frequencies across the callgraph. */ + +static unsigned int +ipa_profile (void) +{ + struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); + struct cgraph_edge *e; + int order_pos; + bool something_changed = false; + int i; + + order_pos = cgraph_postorder (order); + for (i = order_pos - 1; i >= 0; i--) + { + if (order[i]->local.local && cgraph_propagate_frequency (order[i])) + { + for (e = order[i]->callees; e; e = e->next_callee) + if (e->callee->local.local && !e->callee->aux) + { + something_changed = true; + e->callee->aux = (void *)1; + } + } + order[i]->aux = NULL; + } + + while (something_changed) + { + something_changed = false; + for (i = order_pos - 1; i >= 0; i--) + { + if (order[i]->aux && cgraph_propagate_frequency (order[i])) + { + for (e = order[i]->callees; e; e = e->next_callee) + if (e->callee->local.local && !e->callee->aux) + { + something_changed = true; + e->callee->aux = (void *)1; + } + } + order[i]->aux = NULL; + } + } + free (order); + return 0; +} + +static bool +gate_ipa_profile (void) +{ + return flag_ipa_profile; +} + +struct ipa_opt_pass_d pass_ipa_profile = +{ + { + IPA_PASS, + "ipa-profile", /* name */ + gate_ipa_profile, /* gate */ + ipa_profile, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IPA_PROFILE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + }, + NULL, /* generate_summary */ + NULL, /* write_summary */ + NULL, /* read_summary */ + NULL, /* write_optimization_summary */ + NULL, /* read_optimization_summary */ + NULL, /* stmt_fixup */ + 0, /* TODOs */ + NULL, /* function_transform */ + NULL /* variable_transform */ +}; diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index cb87143e4ac..6405432da3b 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -139,15 +139,21 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, intptr_t ref; struct bitpack_d *bp; - lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge); + if (edge->indirect_unknown_callee) + lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge); + else + lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge); ref = lto_cgraph_encoder_lookup (encoder, edge->caller); gcc_assert (ref != LCC_NOT_FOUND); lto_output_sleb128_stream (ob->main_stream, ref); - ref = lto_cgraph_encoder_lookup (encoder, edge->callee); - gcc_assert (ref != LCC_NOT_FOUND); - lto_output_sleb128_stream (ob->main_stream, ref); + if (!edge->indirect_unknown_callee) + { + ref = lto_cgraph_encoder_lookup (encoder, edge->callee); + gcc_assert (ref != LCC_NOT_FOUND); + lto_output_sleb128_stream (ob->main_stream, ref); + } lto_output_sleb128_stream (ob->main_stream, edge->count); @@ -157,7 +163,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, bp_pack_value (bp, edge->inline_failed, HOST_BITS_PER_INT); bp_pack_value (bp, edge->frequency, HOST_BITS_PER_INT); bp_pack_value (bp, edge->loop_nest, 30); - bp_pack_value (bp, edge->indirect_call, 1); + bp_pack_value (bp, edge->indirect_inlining_edge, 1); bp_pack_value (bp, edge->call_stmt_cannot_inline_p, 1); bp_pack_value (bp, edge->can_throw_external, 1); lto_output_bitpack (ob->main_stream, bp); @@ -286,6 +292,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (bp, node->process, 1); bp_pack_value (bp, node->alias, 1); bp_pack_value (bp, node->finalized_by_frontend, 1); + bp_pack_value (bp, node->frequency, 2); lto_output_bitpack (ob->main_stream, bp); bitpack_delete (bp); @@ -371,6 +378,45 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, lto_output_uleb128_stream (ob->main_stream, 0); } +/* Output the varpool NODE to OB. + If NODE is not in SET, then NODE is a boundary. */ + +static void +lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node, + varpool_node_set set) +{ + bool boundary_p = !varpool_node_in_set_p (node, set) && node->analyzed; + struct bitpack_d *bp; + struct varpool_node *alias; + int count = 0; + + lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl); + bp = bitpack_create (); + bp_pack_value (bp, node->externally_visible, 1); + bp_pack_value (bp, node->force_output, 1); + bp_pack_value (bp, node->finalized, 1); + gcc_assert (node->finalized || !node->analyzed); + gcc_assert (node->needed); + gcc_assert (!node->alias); + /* FIXME: We have no idea how we move references around. For moment assume that + everything is used externally. */ + bp_pack_value (bp, flag_wpa, 1); /* used_from_other_parition. */ + bp_pack_value (bp, boundary_p, 1); /* in_other_partition. */ + /* Also emit any extra name aliases. */ + for (alias = node->extra_name; alias; alias = alias->next) + count++; + bp_pack_value (bp, count != 0, 1); + lto_output_bitpack (ob->main_stream, bp); + bitpack_delete (bp); + + if (count) + { + lto_output_uleb128_stream (ob->main_stream, count); + for (alias = node->extra_name; alias; alias = alias->next) + lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); + } +} + /* Stream out profile_summary to OB. */ static void @@ -399,6 +445,25 @@ add_node_to (lto_cgraph_encoder_t encoder, struct cgraph_node *node) lto_cgraph_encoder_encode (encoder, node); } +/* Output all callees or indirect outgoing edges. EDGE must be the first such + edge. */ + +static void +output_outgoing_cgraph_edges (struct cgraph_edge *edge, + struct lto_simple_output_block *ob, + lto_cgraph_encoder_t encoder) +{ + if (!edge) + return; + + /* Output edges in backward direction, so the reconstructed callgraph match + and it is easy to associate call sites in the IPA pass summaries. */ + while (edge->next_callee) + edge = edge->next_callee; + for (; edge; edge = edge->prev_callee) + lto_output_edge (ob, edge, encoder); +} + /* Output the part of the cgraph in SET. */ void @@ -467,16 +532,8 @@ output_cgraph (cgraph_node_set set) for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) { node = csi_node (csi); - if (node->callees) - { - /* Output edges in backward direction, so the reconstructed callgraph - match and it is easy to associate call sites in the IPA pass summaries. */ - edge = node->callees; - while (edge->next_callee) - edge = edge->next_callee; - for (; edge; edge = edge->prev_callee) - lto_output_edge (ob, edge, encoder); - } + output_outgoing_cgraph_edges (node->callees, ob, encoder); + output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder); } lto_output_uleb128_stream (ob->main_stream, 0); @@ -496,7 +553,6 @@ output_cgraph (cgraph_node_set set) lto_destroy_simple_output_block (ob); } - /* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS, STACK_SIZE, SELF_TIME and SELF_SIZE. This is called either to initialize NODE or to replace the values in it, for instance because the first @@ -544,8 +600,35 @@ input_overwrite_node (struct lto_file_decl_data *file_data, node->process = bp_unpack_value (bp, 1); node->alias = bp_unpack_value (bp, 1); node->finalized_by_frontend = bp_unpack_value (bp, 1); + node->frequency = (enum node_frequency)bp_unpack_value (bp, 2); } +/* Output the part of the cgraph in SET. */ + +void +output_varpool (varpool_node_set set) +{ + struct varpool_node *node; + struct lto_simple_output_block *ob; + int len = 0; + + ob = lto_create_simple_output_block (LTO_section_varpool); + + for (node = varpool_nodes; node; node = node->next) + if (node->needed && node->analyzed) + len++; + + lto_output_uleb128_stream (ob->main_stream, len); + + /* Write out the nodes. We must first output a node and then its clones, + otherwise at a time reading back the node there would be nothing to clone + from. */ + for (node = varpool_nodes; node; node = node->next) + if (node->needed && node->analyzed) + lto_output_varpool_node (ob, node, set); + + lto_destroy_simple_output_block (ob); +} /* Read a node from input_block IB. TAG is the node's tag just read. Return the node read or overwriten. */ @@ -665,12 +748,57 @@ input_node (struct lto_file_decl_data *file_data, return node; } +/* Read a node from input_block IB. TAG is the node's tag just read. + Return the node read or overwriten. */ + +static struct varpool_node * +input_varpool_node (struct lto_file_decl_data *file_data, + struct lto_input_block *ib) +{ + int decl_index; + tree var_decl; + struct varpool_node *node; + struct bitpack_d *bp; + bool aliases_p; + int count; + + decl_index = lto_input_uleb128 (ib); + var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); + node = varpool_node (var_decl); + + bp = lto_input_bitpack (ib); + node->externally_visible = bp_unpack_value (bp, 1); + node->force_output = bp_unpack_value (bp, 1); + node->finalized = bp_unpack_value (bp, 1); + node->analyzed = 1; + node->used_from_other_partition = bp_unpack_value (bp, 1); + node->in_other_partition = bp_unpack_value (bp, 1); + aliases_p = bp_unpack_value (bp, 1); + if (node->finalized) + varpool_mark_needed_node (node); + bitpack_delete (bp); + if (aliases_p) + { + count = lto_input_uleb128 (ib); + for (; count > 0; count --) + { + tree decl = lto_file_decl_data_get_var_decl (file_data, + lto_input_uleb128 (ib)); + varpool_extra_name_alias (decl, var_decl); + } + } + return node; +} + -/* Read an edge from IB. NODES points to a vector of previously read - nodes for decoding caller and callee of the edge to be read. */ +/* Read an edge from IB. NODES points to a vector of previously read nodes for + decoding caller and callee of the edge to be read. If INDIRECT is true, the + edge being read is indirect (in the sense that it has + indirect_unknown_callee set). */ static void -input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes) +input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes, + bool indirect) { struct cgraph_node *caller, *callee; struct cgraph_edge *edge; @@ -686,9 +814,14 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes) if (caller == NULL || caller->decl == NULL_TREE) internal_error ("bytecode stream: no caller found while reading edge"); - callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); - if (callee == NULL || callee->decl == NULL_TREE) - internal_error ("bytecode stream: no callee found while reading edge"); + if (!indirect) + { + callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); + if (callee == NULL || callee->decl == NULL_TREE) + internal_error ("bytecode stream: no callee found while reading edge"); + } + else + callee = NULL; count = (gcov_type) lto_input_sleb128 (ib); @@ -706,10 +839,14 @@ input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes) || caller_resolution == LDPR_PREEMPTED_IR) return; - edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest); + if (indirect) + edge = cgraph_create_indirect_edge (caller, NULL, count, freq, nest); + else + edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest); + + edge->indirect_inlining_edge = bp_unpack_value (bp, 1); edge->lto_stmt_uid = stmt_id; edge->inline_failed = inline_failed; - edge->indirect_call = bp_unpack_value (bp, 1); edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1); edge->can_throw_external = bp_unpack_value (bp, 1); bitpack_delete (bp); @@ -732,7 +869,9 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, while (tag) { if (tag == LTO_cgraph_edge) - input_edge (ib, nodes); + input_edge (ib, nodes, false); + else if (tag == LTO_cgraph_indirect_edge) + input_edge (ib, nodes, true); else { node = input_node (file_data, ib, tag); @@ -780,6 +919,22 @@ input_cgraph_1 (struct lto_file_decl_data *file_data, VEC_free (cgraph_node_ptr, heap, nodes); } +/* Read a varpool from IB using the info in FILE_DATA. */ + +static void +input_varpool_1 (struct lto_file_decl_data *file_data, + struct lto_input_block *ib) +{ + unsigned HOST_WIDE_INT len; + + len = lto_input_uleb128 (ib); + while (len) + { + input_varpool_node (file_data, ib); + len--; + } +} + static struct gcov_ctr_summary lto_gcov_summary; /* Input profile_info from IB. */ @@ -835,6 +990,12 @@ input_cgraph (void) lto_destroy_simple_input_block (file_data, LTO_section_cgraph, ib, data, len); + ib = lto_create_simple_input_block (file_data, LTO_section_varpool, + &data, &len); + input_varpool_1 (file_data, ib); + lto_destroy_simple_input_block (file_data, LTO_section_varpool, + ib, data, len); + /* Assume that every file read needs to be processed by LTRANS. */ if (flag_wpa) lto_mark_file_for_ltrans (file_data); diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c index 4f2ae4ff37f..16fd0867805 100644 --- a/gcc/lto-section-in.c +++ b/gcc/lto-section-in.c @@ -52,6 +52,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] = "function_body", "static_initializer", "cgraph", + "varpool", + "jump_funcs" "ipa_pure_const", "ipa_reference", "symtab", diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 6afad5b612c..c45bfd0964a 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -358,8 +358,6 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in, case LTO_label_decl_ref: ix_u = lto_input_uleb128 (ib); result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u); - if (TREE_CODE (result) == VAR_DECL) - varpool_mark_needed_node (varpool_node (result)); break; default: @@ -1248,6 +1246,8 @@ fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts) struct cgraph_edge *cedge; for (cedge = node->callees; cedge; cedge = cedge->next_callee) cedge->call_stmt = stmts[cedge->lto_stmt_uid]; + for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee) + cedge->call_stmt = stmts[cedge->lto_stmt_uid]; } /* Fixup call_stmt pointers in NODE and all clones. */ @@ -1314,7 +1314,6 @@ input_function (tree fn_decl, struct data_in *data_in, fn->has_nonlocal_label = bp_unpack_value (bp, 1); fn->calls_alloca = bp_unpack_value (bp, 1); fn->calls_setjmp = bp_unpack_value (bp, 1); - fn->function_frequency = (enum function_frequency) bp_unpack_value (bp, 2); fn->va_list_fpr_size = bp_unpack_value (bp, 8); fn->va_list_gpr_size = bp_unpack_value (bp, 8); bitpack_delete (bp); @@ -1719,6 +1718,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1); + DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3); } @@ -1772,8 +1772,8 @@ unpack_ts_type_value_fields (struct bitpack_d *bp, tree expr) SET_TYPE_MODE (expr, mode); TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1); - TYPE_NEEDS_CONSTRUCTING(expr) = (unsigned) bp_unpack_value (bp, 1); - if (TREE_CODE (expr) == UNION_TYPE || TREE_CODE (expr) == RECORD_TYPE) + TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1); + if (RECORD_OR_UNION_TYPE_P (expr)) TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -2165,9 +2165,10 @@ lto_input_ts_type_tree_pointers (struct lto_input_block *ib, TYPE_VALUES (expr) = lto_input_tree (ib, data_in); else if (TREE_CODE (expr) == ARRAY_TYPE) TYPE_DOMAIN (expr) = lto_input_tree (ib, data_in); - else if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE) + else if (RECORD_OR_UNION_TYPE_P (expr)) TYPE_FIELDS (expr) = lto_input_tree (ib, data_in); - else if (TREE_CODE (expr) == FUNCTION_TYPE || TREE_CODE (expr) == METHOD_TYPE) + else if (TREE_CODE (expr) == FUNCTION_TYPE + || TREE_CODE (expr) == METHOD_TYPE) TYPE_ARG_TYPES (expr) = lto_input_tree (ib, data_in); else if (TREE_CODE (expr) == VECTOR_TYPE) TYPE_DEBUG_REPRESENTATION_TYPE (expr) = lto_input_tree (ib, data_in); @@ -2724,17 +2725,6 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in) the code and class. */ result = lto_get_builtin_tree (ib, data_in); } - else if (tag == LTO_var_decl_alias) - { - /* An extra_name alias for a variable. */ - unsigned HOST_WIDE_INT ix; - tree target; - ix = lto_input_uleb128 (ib); - result = lto_file_decl_data_get_var_decl (data_in->file_data, ix); - ix = lto_input_uleb128 (ib); - target = lto_file_decl_data_get_var_decl (data_in->file_data, ix); - varpool_extra_name_alias (result, target); - } else if (tag == lto_tree_code_to_tag (INTEGER_CST)) { /* For integer constants we only need the type and its hi/low diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index c9220254db9..0c8544cdb68 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -468,6 +468,7 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1); bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1); + bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1); bp_pack_value (bp, DECL_TLS_MODEL (expr), 3); } @@ -517,8 +518,8 @@ pack_ts_type_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, TYPE_MODE (expr), 7); bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1); bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1); - bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING(expr), 1); - if (TREE_CODE (expr) == UNION_TYPE || TREE_CODE (expr) == RECORD_TYPE) + bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1); + if (RECORD_OR_UNION_TYPE_P (expr)) bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1); bp_pack_value (bp, TYPE_PACKED (expr), 1); bp_pack_value (bp, TYPE_RESTRICT (expr), 1); @@ -946,9 +947,10 @@ lto_output_ts_type_tree_pointers (struct output_block *ob, tree expr, lto_output_tree_or_ref (ob, TYPE_VALUES (expr), ref_p); else if (TREE_CODE (expr) == ARRAY_TYPE) lto_output_tree_or_ref (ob, TYPE_DOMAIN (expr), ref_p); - else if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE) + else if (RECORD_OR_UNION_TYPE_P (expr)) lto_output_tree_or_ref (ob, TYPE_FIELDS (expr), ref_p); - else if (TREE_CODE (expr) == FUNCTION_TYPE || TREE_CODE (expr) == METHOD_TYPE) + else if (TREE_CODE (expr) == FUNCTION_TYPE + || TREE_CODE (expr) == METHOD_TYPE) lto_output_tree_or_ref (ob, TYPE_ARG_TYPES (expr), ref_p); else if (TREE_CODE (expr) == VECTOR_TYPE) lto_output_tree_or_ref (ob, TYPE_DEBUG_REPRESENTATION_TYPE (expr), ref_p); @@ -965,7 +967,7 @@ lto_output_ts_type_tree_pointers (struct output_block *ob, tree expr, lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p); /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists during fixup. */ - if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE) + if (RECORD_OR_UNION_TYPE_P (expr)) lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p); lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p); lto_output_tree_or_ref (ob, TYPE_CANONICAL (expr), ref_p); @@ -1866,7 +1868,6 @@ output_function (struct cgraph_node *node) bp_pack_value (bp, fn->has_nonlocal_label, 1); bp_pack_value (bp, fn->calls_alloca, 1); bp_pack_value (bp, fn->calls_setjmp, 1); - bp_pack_value (bp, fn->function_frequency, 2); bp_pack_value (bp, fn->va_list_fpr_size, 8); bp_pack_value (bp, fn->va_list_gpr_size, 8); lto_output_bitpack (ob->main_stream, bp); @@ -1929,22 +1930,14 @@ output_function (struct cgraph_node *node) the file processed by LTRANS. */ static bool -output_alias_pair_p (alias_pair *p, cgraph_node_set set) +output_alias_pair_p (alias_pair *p, cgraph_node_set set, varpool_node_set vset) { - cgraph_node_set_iterator csi; - struct cgraph_node *target_node; - - /* Always emit VAR_DECLs. FIXME lto, we should probably only emit - those VAR_DECLs that are instantiated in this file partition, but - we have no easy way of knowing this based on SET. */ if (TREE_CODE (p->decl) == VAR_DECL) - return true; + return varpool_node_in_set_p (varpool_node_for_asm (p->target), vset); /* Check if the assembler name for P->TARGET has its cgraph node in SET. */ gcc_assert (TREE_CODE (p->decl) == FUNCTION_DECL); - target_node = cgraph_node_for_asm (p->target); - csi = cgraph_node_set_find (set, target_node); - return (!csi_end_p (csi)); + return cgraph_node_in_set_p (cgraph_node_for_asm (p->target), set); } @@ -1952,7 +1945,7 @@ output_alias_pair_p (alias_pair *p, cgraph_node_set set) and labels. */ static void -output_unreferenced_globals (cgraph_node_set set) +output_unreferenced_globals (cgraph_node_set set, varpool_node_set vset) { struct output_block *ob; alias_pair *p; @@ -1973,40 +1966,28 @@ output_unreferenced_globals (cgraph_node_set set) symbols at link time if a file defines a global symbol but never references it. */ FOR_EACH_STATIC_VARIABLE (vnode) - { - tree var = vnode->decl; - - if (TREE_CODE (var) == VAR_DECL) - { - struct varpool_node *alias; - - /* Output the object in order to output references used in the - initialization. */ - lto_output_tree (ob, var, true); - - /* If it is public we also need a reference to the object itself. */ - if (TREE_PUBLIC (var)) - lto_output_tree_ref (ob, var); - - /* Also output any extra_name aliases for this variable. */ - for (alias = vnode->extra_name; alias; alias = alias->next) - { - lto_output_tree (ob, alias->decl, true); - output_record_start (ob, LTO_var_decl_alias); - lto_output_var_decl_index (ob->decl_state, ob->main_stream, - alias->decl); - lto_output_var_decl_index (ob->decl_state, ob->main_stream, - var); - } - } - } + if (vnode->needed && varpool_node_in_set_p (vnode, vset)) + { + tree var = vnode->decl; + + if (TREE_CODE (var) == VAR_DECL) + { + /* Output the object in order to output references used in the + initialization. */ + lto_output_tree (ob, var, true); + + /* If it is public we also need a reference to the object itself. */ + if (TREE_PUBLIC (var)) + lto_output_tree_ref (ob, var); + } + } output_zero (ob); /* Emit the alias pairs for the nodes in SET. */ for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++) { - if (output_alias_pair_p (p, set)) + if (output_alias_pair_p (p, set, vset)) { lto_output_tree_ref (ob, p->decl); lto_output_tree_ref (ob, p->target); @@ -2090,7 +2071,7 @@ lto_writer_init (void) /* Main entry point from the pass manager. */ static void -lto_output (cgraph_node_set set) +lto_output (cgraph_node_set set, varpool_node_set vset) { struct cgraph_node *node; struct lto_out_decl_state *decl_state; @@ -2123,6 +2104,7 @@ lto_output (cgraph_node_set set) have been renumbered so that edges can be associated with call statements using the statement UIDs. */ output_cgraph (set); + output_varpool (vset); lto_bitmap_free (output); } @@ -2177,20 +2159,6 @@ write_global_stream (struct output_block *ob, t = lto_tree_ref_encoder_get_tree (encoder, index); if (!lto_streamer_cache_lookup (ob->writer_cache, t, NULL)) lto_output_tree (ob, t, false); - - if (flag_wpa) - { - /* In WPA we should not emit multiple definitions of the - same symbol to all the files in the link set. If - T had already been emitted as the pervailing definition - in one file, do not emit it in the others. */ - /* FIXME lto. We should check if T belongs to the - file we are writing to. */ - if (TREE_CODE (t) == VAR_DECL - && TREE_PUBLIC (t) - && !DECL_EXTERNAL (t)) - TREE_ASM_WRITTEN (t) = 1; - } } } @@ -2443,7 +2411,7 @@ produce_symtab (struct lto_streamer_cache_d *cache) recover these on other side. */ static void -produce_asm_for_decls (cgraph_node_set set) +produce_asm_for_decls (cgraph_node_set set, varpool_node_set vset) { struct lto_out_decl_state *out_state; struct lto_out_decl_state *fn_out_state; @@ -2461,7 +2429,7 @@ produce_asm_for_decls (cgraph_node_set set) /* Write out unreferenced globals, alias pairs and labels. We defer doing this until now so that we can write out only what is needed. */ - output_unreferenced_globals (set); + output_unreferenced_globals (set, vset); memset (&header, 0, sizeof (struct lto_decl_header)); diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c index 46d61548e12..ec2a308f89f 100644 --- a/gcc/lto-streamer.c +++ b/gcc/lto-streamer.c @@ -160,6 +160,9 @@ lto_get_section_name (int section_type, const char *name) case LTO_section_cgraph: return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL); + case LTO_section_varpool: + return concat (LTO_SECTION_NAME_PREFIX, ".vars", NULL); + case LTO_section_jump_functions: return concat (LTO_SECTION_NAME_PREFIX, ".jmpfuncs", NULL); @@ -785,6 +788,31 @@ lto_streamer_cache_delete (struct lto_streamer_cache_d *c) } +#ifdef LTO_STREAMER_DEBUG +static htab_t tree_htab; + +struct tree_hash_entry +{ + tree key; + intptr_t value; +}; + +static hashval_t +hash_tree (const void *p) +{ + const struct tree_hash_entry *e = (const struct tree_hash_entry *) p; + return htab_hash_pointer (e->key); +} + +static int +eq_tree (const void *p1, const void *p2) +{ + const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1; + const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2; + return (e1->key == e2->key); +} +#endif + /* Initialization common to the LTO reader and writer. */ void @@ -795,6 +823,10 @@ lto_streamer_init (void) new TS_* astructure is added, the streamer should be updated to handle it. */ check_handled_ts_structures (); + +#ifdef LTO_STREAMER_DEBUG + tree_htab = htab_create (31, hash_tree, eq_tree, NULL); +#endif } @@ -823,10 +855,16 @@ gate_lto_out (void) void lto_orig_address_map (tree t, intptr_t orig_t) { - /* FIXME lto. Using the annotation field is quite hacky as it relies - on the GC not running while T is being rematerialized. It would - be cleaner to use a hash table here. */ - t->base.ann = (union tree_ann_d *) orig_t; + struct tree_hash_entry ent; + struct tree_hash_entry **slot; + + ent.key = t; + ent.value = orig_t; + slot + = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT); + gcc_assert (!*slot); + *slot = XNEW (struct tree_hash_entry); + **slot = ent; } @@ -836,7 +874,13 @@ lto_orig_address_map (tree t, intptr_t orig_t) intptr_t lto_orig_address_get (tree t) { - return (intptr_t) t->base.ann; + struct tree_hash_entry ent; + struct tree_hash_entry **slot; + + ent.key = t; + slot + = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT); + return (slot ? (*slot)->value : 0); } @@ -845,7 +889,15 @@ lto_orig_address_get (tree t) void lto_orig_address_remove (tree t) { - t->base.ann = NULL; + struct tree_hash_entry ent; + struct tree_hash_entry **slot; + + ent.key = t; + slot + = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT); + gcc_assert (slot); + free (*slot); + htab_clear_slot (tree_htab, (PTR *)slot); } #endif diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index a9544b5642a..c33feb62b01 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -217,9 +217,6 @@ enum LTO_tags /* Special for global streamer. Reference to previously-streamed node. */ LTO_tree_pickle_reference, - /* A decl which exists only to provide an extra symbol for another var. */ - LTO_var_decl_alias, - /* References to indexable tree nodes. These objects are stored in tables that are written separately from the function bodies that reference them. This way they can be instantiated even when the @@ -259,11 +256,11 @@ enum lto_section_type LTO_section_function_body, LTO_section_static_initializer, LTO_section_cgraph, + LTO_section_varpool, LTO_section_jump_functions, LTO_section_ipa_pure_const, LTO_section_ipa_reference, LTO_section_symtab, - LTO_section_wpa_fixup, LTO_section_opts, LTO_N_SECTION_TYPES /* Must be last. */ }; @@ -834,6 +831,8 @@ int lto_cgraph_encoder_encode (lto_cgraph_encoder_t, struct cgraph_node *); void lto_cgraph_encoder_delete (lto_cgraph_encoder_t encoder); void output_cgraph (cgraph_node_set); void input_cgraph (void); +void output_varpool (varpool_node_set); +void input_varpool (void); /* In lto-symtab.c. */ diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index 79eb3e48de6..a35d82fe3d4 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -44,6 +44,9 @@ struct GTY(()) lto_symtab_entry_def /* The cgraph node if decl is a function decl. Filled in during the merging process. */ struct cgraph_node *node; + /* The varpool node if decl is a variable decl. Filled in during the + merging process. */ + struct varpool_node *vnode; /* LTO file-data and symbol resolution for this decl. */ struct lto_file_decl_data * GTY((skip (""))) file_data; enum ld_plugin_symbol_resolution resolution; @@ -244,6 +247,26 @@ lto_cgraph_replace_node (struct cgraph_node *node, cgraph_remove_node (node); } +/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging + all edges and removing the old node. */ + +static void +lto_varpool_replace_node (struct varpool_node *vnode, + struct varpool_node *prevailing_node) +{ + /* Merge node flags. */ + if (vnode->needed) + { + gcc_assert (prevailing_node->analyzed); + varpool_mark_needed_node (prevailing_node); + } + gcc_assert (!vnode->finalized || prevailing_node->finalized); + gcc_assert (!vnode->analyzed || prevailing_node->analyzed); + + /* Finally remove the replaced node. */ + varpool_remove_node (vnode); +} + /* Merge two variable or function symbol table entries PREVAILING and ENTRY. Return false if the symbols are not fully compatible and a diagnostic should be emitted. */ @@ -406,6 +429,8 @@ lto_symtab_resolve_symbols (void **slot) { if (TREE_CODE (e->decl) == FUNCTION_DECL) e->node = cgraph_get_node (e->decl); + else if (TREE_CODE (e->decl) == VAR_DECL) + e->vnode = varpool_get_node (e->decl); } e = (lto_symtab_entry_t) *slot; @@ -559,6 +584,10 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED) while (!prevailing->node && prevailing->next) prevailing = prevailing->next; + if (TREE_CODE (prevailing->decl) == VAR_DECL) + while (!prevailing->vnode + && prevailing->next) + prevailing = prevailing->next; /* We do not stream varpool nodes, so the first decl has to be good enough for now. ??? For QOI choose a variable with readonly initializer @@ -625,7 +654,8 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED) lto_symtab_merge_decls_2 (slot); /* Drop all but the prevailing decl from the symtab. */ - if (TREE_CODE (prevailing->decl) != FUNCTION_DECL) + if (TREE_CODE (prevailing->decl) != FUNCTION_DECL + && TREE_CODE (prevailing->decl) != VAR_DECL) prevailing->next = NULL; return 1; @@ -650,8 +680,6 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) if (!prevailing->next) return 1; - gcc_assert (TREE_CODE (prevailing->decl) == FUNCTION_DECL); - /* Replace the cgraph node of each entry with the prevailing one. */ for (e = prevailing->next; e; e = e->next) { @@ -672,6 +700,8 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) } lto_cgraph_replace_node (e->node, prevailing->node); } + if (e->vnode != NULL) + lto_varpool_replace_node (e->vnode, prevailing->vnode); } /* Drop all but the prevailing decl from the symtab. */ diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 2ce58d742f3..5bf7a293f02 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,62 @@ +2010-04-28 Jan Hubicka + + * lto.c (lto_varpool_node_sets): New. + (lto_1_to_1_map): Partition varpool too. + (globalize_context_t, globalize_cross_file_statics, + lto_scan_statics_in_ref_table, lto_scan_statics_in_cgraph_node, + lto_scan_statics_in_remaining_global_vars): Remove. + (lto_promote_cross_file_statics): Rewrite. + (get_filename_for_set): Take vset argument. + (lto_wpa_write_files): Pass around vsets. + +2010-04-27 Dave Korn + + PR lto/42776 + * Make-lang.in (LTO_OBJS): Use LTO_BINARY_READER instead of + hardcoding 'lto-elf.o'. + ($(LTO_EXE)): Use LTO_USE_LIBELF instead of hardcoding '-lelf'. + + * lto-coff.h: New file. + * lto-coff.c: Likewise. + +2010-04-26 Richard Guenther + + * lto.c (lto_fixup_type): Deal with non-type TYPE_CONTEXT. + +2010-04-26 Dave Korn + + * lto.h (lto_elf_file_open): Rename prototype from this ... + (lto_obj_file_open): ... to this. + (lto_elf_file_close): Likewise ... + (lto_obj_file_close): ... and likewise. + (lto_elf_build_section_table): Likewise ... + (lto_obj_build_section_table): ... and likewise. + (lto_elf_begin_section): Likewise ... + (lto_obj_begin_section): ... and likewise. + (lto_elf_append_data): Likewise ... + (lto_obj_append_data): ... and likewise. + (lto_elf_end_section): Likewise ... + (lto_obj_end_section): ... and likewise. + * lto.c (lto_file_read): Update references to the above. + (lto_wpa_write_files): Likewise. + (lto_read_all_file_options): Likewise. + (read_cgraph_and_symbols): Likewise. + * lto-lang.c (LANG_HOOKS_BEGIN_SECTION): Likewise. + (LANG_HOOKS_APPEND_DATA): Likewise. + (LANG_HOOKS_END_SECTION): Likewise. + * lto-elf.c (lto_elf_file_open): Rename from this ... + (lto_obj_file_open): ... to this, updating any references. + (lto_elf_file_close): Likewise ... + (lto_obj_file_close): ... and likewise. + (lto_elf_build_section_table): Likewise ... + (lto_obj_build_section_table): ... and likewise. + (lto_elf_begin_section): Likewise ... + (lto_obj_begin_section): ... and likewise. + (lto_elf_append_data): Likewise ... + (lto_obj_append_data): ... and likewise. + (lto_elf_end_section): Likewise ... + (lto_obj_end_section): ... and likewise. + 2010-04-21 Jan Hubicka * lto.c (lto_fixup_tree): Do not call wpa fixup. diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in index 33b0d9af702..a06ab4a18a5 100644 --- a/gcc/lto/Make-lang.in +++ b/gcc/lto/Make-lang.in @@ -23,7 +23,7 @@ # The name of the LTO compiler. LTO_EXE = lto1$(exeext) # The LTO-specific object files inclued in $(LTO_EXE). -LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-elf.o attribs.o +LTO_OBJS = lto/lto-lang.o lto/lto.o lto/$(LTO_BINARY_READER).o attribs.o LTO_H = lto/lto.h $(HASHTAB_H) LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h LTO_TREE_H = lto/lto-tree.h $(LINKER_PLUGIN_API_H) @@ -73,7 +73,7 @@ lto-warn = $(STRICT_WARN) $(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS) $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \ - $(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS) -lelf + $(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS) $(LTO_USE_LIBELF) # Dependencies lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \ @@ -88,3 +88,6 @@ lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h opts.h \ $(LTO_TAGS_H) $(LTO_STREAMER_H) lto/lto-elf.o: lto/lto-elf.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \ toplev.h $(LTO_H) $(TM_H) $(LIBIBERTY_H) $(GGC_H) $(LTO_STREAMER_H) +lto/lto-coff.o: lto/lto-coff.c $(CONFIG_H) coretypes.h $(SYSTEM_H) \ + toplev.h $(LTO_H) $(TM_H) $(LIBIBERTY_H) $(GGC_H) $(LTO_STREAMER_H) \ + lto/lto-coff.h diff --git a/gcc/lto/lto-coff.c b/gcc/lto/lto-coff.c new file mode 100644 index 00000000000..1814cfdb82b --- /dev/null +++ b/gcc/lto/lto-coff.c @@ -0,0 +1,845 @@ +/* LTO routines for COFF object files. + Copyright 2009 Free Software Foundation, Inc. + Contributed by Dave Korn. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "toplev.h" +#include "lto.h" +#include "tm.h" +#include "libiberty.h" +#include "ggc.h" +#include "lto-streamer.h" +#include "lto/lto-coff.h" + + +/* Rather than implementing a libcoff to match libelf, or attempting to + integrate libbfd into GCC, this file is a self-contained (and very + minimal) COFF format object file reader/writer. The generated files + will contain a COFF header, a number of COFF section headers, the + section data itself, and a trailing string table for section names. */ + +/* Handle opening elf files on hosts, such as Windows, that may use + text file handling that will break binary access. */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* Known header magics for validation, as an array. */ + +static const unsigned int coff_machine_array[] = COFF_KNOWN_MACHINES; + +/* Number of valid entries (no sentinel) in array. */ + +#define NUM_COFF_KNOWN_MACHINES \ + (sizeof (coff_machine_array) / sizeof (coff_machine_array[0])) + +/* Cached object file header. */ + +static Coff_header cached_coff_hdr; + +/* Flag to indicate if we have read and cached any header yet. */ + +static bool cached_coff_hdr_valid = false; + +/* The current output file. */ + +static lto_file *current_out_file; + + +/* Sets the current output file to FILE. Returns the old output file or + NULL. */ + +lto_file * +lto_set_current_out_file (lto_file *file) +{ + lto_file *old_file = current_out_file; + current_out_file = file; + return old_file; +} + + +/* Returns the current output file. */ + +lto_file * +lto_get_current_out_file (void) +{ + return current_out_file; +} + + +/* COFF section structure constructor. */ + +static lto_coff_section * +coff_newsection (lto_coff_file *file, const char *name, size_t type) +{ + lto_coff_section *ptr, **chain_ptr_ptr; + + ptr = XCNEW (lto_coff_section); + ptr->name = name; + ptr->type = type; + + chain_ptr_ptr = &file->section_chain; + while (*chain_ptr_ptr) + chain_ptr_ptr = &(*chain_ptr_ptr)->next; + *chain_ptr_ptr = ptr; + + return ptr; +} + + +/* COFF section data block structure constructor. */ + +static lto_coff_data * +coff_newdata (lto_coff_section *sec) +{ + lto_coff_data *ptr, **chain_ptr_ptr; + + ptr = XCNEW (lto_coff_data); + + chain_ptr_ptr = &sec->data_chain; + while (*chain_ptr_ptr) + chain_ptr_ptr = &(*chain_ptr_ptr)->next; + *chain_ptr_ptr = ptr; + + return ptr; +} + + +/* Initialize FILE, an LTO file object for FILENAME. */ + +static void +lto_file_init (lto_file *file, const char *filename, off_t offset) +{ + file->filename = filename; + file->offset = offset; +} + +/* Return an error string after an error, or a predetermined one + if ERRCODE is not -1. */ + +static const char * +coff_errmsg (int errcode) +{ + return strerror (errcode == -1 ? errno : errcode); +} + +/* Returns a hash code for P. */ + +static hashval_t +hash_name (const void *p) +{ + const struct lto_section_slot *ds = (const struct lto_section_slot *) p; + return (hashval_t) htab_hash_string (ds->name); +} + +/* Returns nonzero if P1 and P2 are equal. */ + +static int +eq_name (const void *p1, const void *p2) +{ + const struct lto_section_slot *s1 = + (const struct lto_section_slot *) p1; + const struct lto_section_slot *s2 = + (const struct lto_section_slot *) p2; + + return strcmp (s1->name, s2->name) == 0; +} + + +/* Build a hash table whose key is the section names and whose data is + the start and size of each section in the .o file. */ + +htab_t +lto_obj_build_section_table (lto_file *lto_file) +{ + lto_coff_file *coff_file = (lto_coff_file *)lto_file; + lto_coff_section *sec; + htab_t section_hash_table; + ssize_t strtab_size; + char *strtab; + + section_hash_table = htab_create (37, hash_name, eq_name, free); + + /* Seek to start of string table. */ + if (coff_file->strtab_offs != lseek (coff_file->fd, + coff_file->base.offset + coff_file->strtab_offs, SEEK_SET)) + { + error ("altered or invalid COFF object file"); + return section_hash_table; + } + + strtab_size = coff_file->file_size - coff_file->strtab_offs; + strtab = XNEWVEC (char, strtab_size); + if (read (coff_file->fd, strtab, strtab_size) != strtab_size) + { + error ("invalid COFF object file string table"); + return section_hash_table; + } + + /* Scan sections looking at names. */ + COFF_FOR_ALL_SECTIONS(coff_file, sec) + { + struct lto_section_slot s_slot; + void **slot; + char *new_name; + int stringoffset; + char *name = (char *) &sec->coffsec.Name[0]; + + /* Skip dummy string section if by any chance we see it. */ + if (sec->type == 1) + continue; + + if (name[0] == '/') + { + if (1 != sscanf (&name[1], "%d", &stringoffset) + || stringoffset < 0 || stringoffset >= strtab_size) + { + error ("invalid COFF section name string"); + continue; + } + name = strtab + stringoffset; + } + else + { + /* If we cared about the VirtualSize field, we couldn't + crudely trash it like this to guarantee nul-termination + of the Name field. But we don't, so we do. */ + name[8] = 0; + } + if (strncmp (name, LTO_SECTION_NAME_PREFIX, + strlen (LTO_SECTION_NAME_PREFIX)) != 0) + continue; + + new_name = XNEWVEC (char, strlen (name) + 1); + strcpy (new_name, name); + s_slot.name = new_name; + slot = htab_find_slot (section_hash_table, &s_slot, INSERT); + if (*slot == NULL) + { + struct lto_section_slot *new_slot = XNEW (struct lto_section_slot); + + new_slot->name = new_name; + /* The offset into the file for this section. */ + new_slot->start = coff_file->base.offset + + COFF_GET(&sec->coffsec,PointerToRawData); + new_slot->len = COFF_GET(&sec->coffsec,SizeOfRawData); + *slot = new_slot; + } + else + { + error ("two or more sections for %s:", new_name); + return NULL; + } + } + + free (strtab); + return section_hash_table; +} + + +/* Begin a new COFF section named NAME with type TYPE in the current output + file. TYPE is an SHT_* macro from the libelf headers. */ + +static void +lto_coff_begin_section_with_type (const char *name, size_t type) +{ + lto_coff_file *file; + size_t sh_name; + + /* Grab the current output file and do some basic assertion checking. */ + file = (lto_coff_file *) lto_get_current_out_file (), + gcc_assert (file); + gcc_assert (!file->scn); + + /* Create a new section. */ + file->scn = coff_newsection (file, name, type); + if (!file->scn) + fatal_error ("could not create a new COFF section: %s", coff_errmsg (-1)); + + /* Add a string table entry and record the offset. */ + gcc_assert (file->shstrtab_stream); + sh_name = file->shstrtab_stream->total_size; + lto_output_data_stream (file->shstrtab_stream, name, strlen (name) + 1); + + /* Initialize the section header. */ + file->scn->strtab_offs = sh_name; +} + + +/* Begin a new COFF section named NAME in the current output file. */ + +void +lto_obj_begin_section (const char *name) +{ + lto_coff_begin_section_with_type (name, 0); +} + + +/* Append DATA of length LEN to the current output section. BASE is a pointer + to the output page containing DATA. It is freed once the output file has + been written. */ + +void +lto_obj_append_data (const void *data, size_t len, void *block) +{ + lto_coff_file *file; + lto_coff_data *coff_data; + struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block; + + /* Grab the current output file and do some basic assertion checking. */ + file = (lto_coff_file *) lto_get_current_out_file (); + gcc_assert (file); + gcc_assert (file->scn); + + coff_data = coff_newdata (file->scn); + if (!coff_data) + fatal_error ("could not append data to COFF section: %s", coff_errmsg (-1)); + + coff_data->d_buf = CONST_CAST (void *, data); + coff_data->d_size = len; + + /* Chain all data blocks (from all sections) on one singly-linked + list for freeing en masse after the file is closed. */ + base->ptr = (char *)file->data; + file->data = base; +} + + +/* End the current output section. This just does some assertion checking + and sets the current output file's scn member to NULL. */ + +void +lto_obj_end_section (void) +{ + lto_coff_file *file; + + /* Grab the current output file and validate some basic assertions. */ + file = (lto_coff_file *) lto_get_current_out_file (); + gcc_assert (file); + gcc_assert (file->scn); + + file->scn = NULL; +} + + +/* Validate's COFF_FILE's executable header and, if cached_coff_hdr is + uninitialized, caches the results. Also records the section header string + table's section index. Returns true on success or false on failure. */ + +static bool +validate_file (lto_coff_file *coff_file) +{ + size_t n, secnum; + unsigned int numsections, secheaderssize, numsyms; + off_t sectionsstart, symbolsstart, stringsstart; + unsigned int mach, charact; + + /* Read and sanity check the raw header. */ + n = read (coff_file->fd, &coff_file->coffhdr, sizeof (coff_file->coffhdr)); + if (n != sizeof (coff_file->coffhdr)) + { + error ("not a COFF object file"); + return false; + } + + mach = COFF_GET(&coff_file->coffhdr, Machine); + for (n = 0; n < NUM_COFF_KNOWN_MACHINES; n++) + if (mach == coff_machine_array[n]) + break; + if (n == NUM_COFF_KNOWN_MACHINES) + { + error ("not a recognized COFF object file"); + return false; + } + + charact = COFF_GET(&coff_file->coffhdr, Characteristics); + if (COFF_NOT_CHARACTERISTICS & charact) + { + /* DLL, EXE or SYS file. */ + error ("not a relocatable COFF object file"); + return false; + } + + if (COFF_CHARACTERISTICS != (COFF_CHARACTERISTICS & charact)) + { + /* ECOFF/XCOFF/PE+ support not implemented. */ + error ("not a 32-bit COFF object file"); + return false; + } + + /* It validated OK, so cached it if we don't already have one. */ + if (!cached_coff_hdr_valid) + { + cached_coff_hdr_valid = true; + memcpy (&cached_coff_hdr, &coff_file->coffhdr, sizeof (cached_coff_hdr)); + } + + if (mach != COFF_GET(&cached_coff_hdr, Machine)) + { + error ("inconsistent file architecture detected"); + return false; + } + + /* Read section headers and string table? */ + + numsections = COFF_GET(&coff_file->coffhdr, NumberOfSections); + secheaderssize = numsections * sizeof (Coff_section); + sectionsstart = sizeof (Coff_header) + secheaderssize; + symbolsstart = COFF_GET(&coff_file->coffhdr, PointerToSymbolTable); + numsyms = COFF_GET(&coff_file->coffhdr, NumberOfSymbols); + stringsstart = (symbolsstart + COFF_SYMBOL_SIZE * numsyms); + +#define CVOFFSETTTED(x) (coff_file->base.offset + (x)) + + if (numsections <= 0 || symbolsstart <= 0 || numsyms <= 0 + || (CVOFFSETTTED(sectionsstart) >= coff_file->file_size) + || (CVOFFSETTTED(symbolsstart) >= coff_file->file_size) + || (CVOFFSETTTED(stringsstart) >= coff_file->file_size)) + { + error ("not a valid COFF object file"); + return false; + } + +#undef CVOFFSETTTED + + /* Record start of string table. */ + coff_file->strtab_offs = stringsstart; + + /* Validate section table entries. */ + for (secnum = 0; secnum < numsections; secnum++) + { + Coff_section coffsec; + lto_coff_section *ltosec; + off_t size_raw, offs_raw, offs_relocs, offs_lines; + off_t num_relocs, num_lines; + + n = read (coff_file->fd, &coffsec, sizeof (coffsec)); + if (n != sizeof (coffsec)) + { + error ("short/missing COFF section table"); + return false; + } + + size_raw = COFF_GET(&coffsec, SizeOfRawData); + offs_raw = COFF_GET(&coffsec, PointerToRawData); + offs_relocs = COFF_GET(&coffsec, PointerToRelocations); + offs_lines = COFF_GET(&coffsec, PointerToLinenumbers); + num_relocs = COFF_GET(&coffsec, NumberOfRelocations); + num_lines = COFF_GET(&coffsec, NumberOfLinenumbers); + + if (size_raw < 0 || num_relocs < 0 || num_lines < 0 + || (size_raw + && ((COFF_GET(&coffsec, Characteristics) + & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + ? (offs_raw != 0) + : (offs_raw < sectionsstart || offs_raw >= coff_file->file_size))) + || (num_relocs + && (offs_relocs < sectionsstart + || offs_relocs >= coff_file->file_size)) + || (num_lines + && (offs_lines < sectionsstart + || offs_lines >= coff_file->file_size))) + { + error ("invalid COFF section table"); + return false; + } + + /* Looks ok, so record its details. We don't read the + string table or set up names yet; we'll do that when + we build the hash table. */ + ltosec = coff_newsection (coff_file, NULL, 0); + memcpy (<osec->coffsec, &coffsec, sizeof (ltosec->coffsec)); + } + + return true; +} + +/* Initialize COFF_FILE's executable header using cached data from previously + read files. */ + +static void +init_coffhdr (lto_coff_file *coff_file) +{ + gcc_assert (cached_coff_hdr_valid); + memset (&coff_file->coffhdr, 0, sizeof (coff_file->coffhdr)); + COFF_PUT(&coff_file->coffhdr, Machine, COFF_GET(&cached_coff_hdr, Machine)); + COFF_PUT(&coff_file->coffhdr, Characteristics, COFF_GET(&cached_coff_hdr, Characteristics)); +} + +/* Open COFF file FILENAME. If WRITABLE is true, the file is opened for write + and, if necessary, created. Otherwise, the file is opened for reading. + Returns the opened file. */ + +lto_file * +lto_obj_file_open (const char *filename, bool writable) +{ + lto_coff_file *coff_file; + lto_file *result = NULL; + off_t offset; + const char *offset_p; + char *fname; + struct stat statbuf; + + offset_p = strchr (filename, '@'); + if (!offset_p) + { + fname = xstrdup (filename); + offset = 0; + } + else + { + /* The file started with '@' is a file containing command line + options. Stop if it doesn't exist. */ + if (offset_p == filename) + fatal_error ("command line option file '%s' does not exist", + filename); + + fname = (char *) xmalloc (offset_p - filename + 1); + memcpy (fname, filename, offset_p - filename); + fname[offset_p - filename] = '\0'; + offset_p += 3; /* skip the @0x */ + offset = lto_parse_hex (offset_p); + } + + /* Set up. */ + coff_file = XCNEW (lto_coff_file); + result = (lto_file *) coff_file; + lto_file_init (result, fname, offset); + coff_file->fd = -1; + + /* Open the file. */ + coff_file->fd = open (fname, + O_BINARY | (writable ? O_WRONLY | O_CREAT | O_TRUNC : O_RDONLY), 0666); + + if (coff_file->fd == -1) + { + error ("could not open file %s", fname); + goto fail; + } + + if (stat (fname, &statbuf) < 0) + { + error ("could not stat file %s", fname); + goto fail; + } + + coff_file->file_size = statbuf.st_size; + + if (offset != 0) + { + char ar_tail[12]; + int size; + + /* Surely not? */ + gcc_assert (!writable); + + /* Seek to offset, or error. */ + if (lseek (coff_file->fd, offset, SEEK_SET) != (ssize_t) offset) + { + error ("could not find archive member @0x%lx", (long) offset); + goto fail; + } + + /* Now seek back 12 chars and read the tail of the AR header to + find the length of the member file. */ + if (lseek (coff_file->fd, -12, SEEK_CUR) < 0 + || read (coff_file->fd, ar_tail, 12) != 12 + || lseek (coff_file->fd, 0, SEEK_CUR) != (ssize_t) offset + || ar_tail[10] != '`' || ar_tail[11] != '\n') + { + error ("could not find archive header @0x%lx", (long) offset); + goto fail; + } + + ar_tail[11] = 0; + if (sscanf (ar_tail, "%d", &size) != 1) + { + error ("invalid archive header @0x%lx", (long) offset); + goto fail; + } + coff_file->file_size = size; + } + + if (writable) + { + init_coffhdr (coff_file); + coff_file->shstrtab_stream = XCNEW (struct lto_output_stream); + } + else + if (!validate_file (coff_file)) + goto fail; + + return result; + + fail: + if (result) + lto_obj_file_close (result); + return NULL; +} + + +/* Close COFF file FILE and clean up any associated data structures. If FILE + was opened for writing, the file's COFF data is written at this time, and + any cached data buffers are freed. Return TRUE if there was an error. */ + +static bool +coff_write_object_file (lto_coff_file *coff_file) +{ + lto_coff_section *cursec, *stringsec; + lto_coff_data *data; + size_t fileoffset, numsections, totalsecsize, numsyms, stringssize; + bool write_err = false; + int secnum; + + /* Infer whether this file was opened for reading or writing from the + presence or absense of an initialised stream for the string table; + do nothing if it was opened for reading. */ + if (!coff_file->shstrtab_stream) + return false; + else + { + /* Write the COFF string table into a dummy new section that + we will not write a header for. */ + lto_file *old_file = lto_set_current_out_file (&coff_file->base); + /* This recursively feeds in the data to a new section. */ + lto_coff_begin_section_with_type (".strtab", 1); + lto_write_stream (coff_file->shstrtab_stream); + lto_obj_end_section (); + lto_set_current_out_file (old_file); + free (coff_file->shstrtab_stream); + } + + /* Layout the file. Count sections (not dummy string section) and calculate + data size for all of them. */ + numsections = 0; + totalsecsize = 0; + stringssize = 0; + stringsec = NULL; + COFF_FOR_ALL_SECTIONS(coff_file, cursec) + { + lto_coff_data *data; + size_t cursecsize; + cursecsize = 0; + COFF_FOR_ALL_DATA(cursec,data) + cursecsize += data->d_size; + if (cursec->type == 0) + { + ++numsections; + totalsecsize += COFF_ALIGN(cursecsize); +#if COFF_ALIGNMENT > 1 + cursec->pad_needed = COFF_ALIGN(cursecsize) - cursecsize; +#endif + } + else + { + stringssize = cursecsize; + stringsec = cursec; + } + COFF_PUT(&cursec->coffsec, SizeOfRawData, cursecsize); + } + + /* There is a file symbol and a section symbol per section, + and each of these has a single auxiliary symbol following. */ + numsyms = 2 * (1 + numsections); + + /* Great! Now we have enough info to fill out the file header. */ + COFF_PUT(&coff_file->coffhdr, NumberOfSections, numsections); + COFF_PUT(&coff_file->coffhdr, NumberOfSymbols, numsyms); + COFF_PUT(&coff_file->coffhdr, PointerToSymbolTable, sizeof (Coff_header) + + numsections * sizeof (Coff_section) + totalsecsize); + /* The remaining members were initialised to zero or copied from + a cached header, so we leave them alone here. */ + + /* Now position all the sections, and fill out their headers. */ + fileoffset = sizeof (Coff_header) + numsections * sizeof (Coff_section); + COFF_FOR_ALL_SECTIONS(coff_file, cursec) + { + /* Skip dummy string section. */ + if (cursec->type == 1) + continue; + COFF_PUT(&cursec->coffsec, PointerToRawData, fileoffset); + fileoffset += COFF_ALIGN (COFF_GET(&cursec->coffsec, SizeOfRawData)); + COFF_PUT(&cursec->coffsec, Characteristics, COFF_SECTION_CHARACTERISTICS); + snprintf ((char *)&cursec->coffsec.Name[0], 8, "/%d", cursec->strtab_offs + 4); + } + + /* We can write the data now. As there's no way to indicate an error return + from this hook, error handling is limited to not wasting our time doing + any more writes in the event that any one fails. */ + + /* Write the COFF header. */ + write_err = (write (coff_file->fd, &coff_file->coffhdr, + sizeof (coff_file->coffhdr)) != sizeof (coff_file->coffhdr)); + + /* Write the COFF section headers. */ + COFF_FOR_ALL_SECTIONS(coff_file, cursec) + if (cursec->type == 1) /* Skip dummy string section. */ + continue; + else if (!write_err) + write_err = (write (coff_file->fd, &cursec->coffsec, + sizeof (cursec->coffsec)) != sizeof (cursec->coffsec)); + else + break; + + /* Write the COFF sections. */ + COFF_FOR_ALL_SECTIONS(coff_file, cursec) + { +#if COFF_ALIGNMENT > 1 + static const char padzeros[COFF_ALIGNMENT] = { 0 }; +#endif + /* Skip dummy string section. */ + if (cursec->type == 1) + continue; + COFF_FOR_ALL_DATA(cursec, data) + if (!write_err) + write_err = (write (coff_file->fd, data->d_buf, data->d_size) + != data->d_size); + else + break; +#if COFF_ALIGNMENT > 1 + if (!write_err && cursec->pad_needed) + write_err = (write (coff_file->fd, padzeros, cursec->pad_needed) + != cursec->pad_needed); +#endif + } + + /* Write the COFF symbol table. */ + if (!write_err) + { + union + { + Coff_symbol sym; + Coff_aux_sym_file file; + Coff_aux_sym_section sec; + } symbols[2]; + memset (&symbols[0], 0, sizeof (symbols)); + strcpy ((char *) &symbols[0].sym.Name[0], ".file"); + COFF_PUT(&symbols[0].sym, SectionNumber, IMAGE_SYM_DEBUG); + COFF_PUT(&symbols[0].sym, Type, IMAGE_SYM_TYPE); + symbols[0].sym.StorageClass[0] = IMAGE_SYM_CLASS_FILE; + symbols[0].sym.NumberOfAuxSymbols[0] = 1; + snprintf ((char *)symbols[1].file.FileName, + sizeof (symbols[1].file.FileName), + "%s", lbasename (coff_file->base.filename)); + write_err = (write (coff_file->fd, &symbols[0], sizeof (symbols)) + != (2 * COFF_SYMBOL_SIZE)); + + /* Set up constant parts for section sym loop. */ + memset (&symbols[0], 0, sizeof (symbols)); + COFF_PUT(&symbols[0].sym, Type, IMAGE_SYM_TYPE); + symbols[0].sym.StorageClass[0] = IMAGE_SYM_CLASS_STATIC; + symbols[0].sym.NumberOfAuxSymbols[0] = 1; + + secnum = 1; + if (!write_err) + COFF_FOR_ALL_SECTIONS(coff_file, cursec) + { + /* Skip dummy string section. */ + if (cursec->type == 1) + continue; + /* Reuse section name string for section symbol name. */ + COFF_PUT_NDXSZ(&symbols[0].sym, Name, 0, 0, 4); + COFF_PUT_NDXSZ(&symbols[0].sym, Name, cursec->strtab_offs + 4, 4, 4); + COFF_PUT(&symbols[0].sym, SectionNumber, secnum++); + COFF_PUT(&symbols[1].sec, Length, + COFF_GET(&cursec->coffsec, SizeOfRawData)); + if (!write_err) + write_err = (write (coff_file->fd, &symbols[0], sizeof (symbols)) + != (2 * COFF_SYMBOL_SIZE)); + else + break; + } + } + + /* Write the COFF string table. */ + if (!write_err) + { + unsigned char outlen[4]; + COFF_PUT4(outlen, stringssize + 4); + if (!write_err) + write_err = (write (coff_file->fd, outlen, 4) != 4); + if (stringsec) + COFF_FOR_ALL_DATA(stringsec, data) + if (!write_err) + write_err = (write (coff_file->fd, data->d_buf, data->d_size) + != data->d_size); + else + break; + } + + return write_err; +} + +/* Close COFF file FILE and clean up any associated data structures. If FILE + was opened for writing, the file's COFF data is written at this time, and + any cached data buffers are freed. */ + +void +lto_obj_file_close (lto_file *file) +{ + lto_coff_file *coff_file = (lto_coff_file *) file; + struct lto_char_ptr_base *cur, *tmp; + lto_coff_section *cursec, *nextsec; + bool write_err = false; + + /* Write the COFF string table into a dummy new section that + we will not write a header for. */ + if (coff_file->shstrtab_stream) + coff_write_object_file (coff_file); + + /* Close the file, we're done. */ + if (coff_file->fd != -1) + close (coff_file->fd); + + /* Free any data buffers. */ + cur = coff_file->data; + while (cur) + { + tmp = cur; + cur = (struct lto_char_ptr_base *) cur->ptr; + free (tmp); + } + + /* Free any sections and their data chains. */ + cursec = coff_file->section_chain; + while (cursec) + { + lto_coff_data *curdata, *nextdata; + nextsec = cursec->next; + curdata = cursec->data_chain; + while (curdata) + { + nextdata = curdata->next; + free (curdata); + curdata = nextdata; + } + free (cursec); + cursec = nextsec; + } + + free (file); + + /* If there was an error, mention it. */ + if (write_err) + error ("I/O error writing COFF output file"); +} + diff --git a/gcc/lto/lto-coff.h b/gcc/lto/lto-coff.h new file mode 100644 index 00000000000..f069d0cae46 --- /dev/null +++ b/gcc/lto/lto-coff.h @@ -0,0 +1,406 @@ +/* LTO routines for COFF object files. + Copyright 2009 Free Software Foundation, Inc. + Contributed by Dave Korn. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef LTO_COFF_H +#define LTO_COFF_H + +/* Rather than implementing a libcoff to match libelf, or attempting to + integrate libbfd into GCC, this file is a self-contained (and very + minimal) COFF format object file reader/writer. The generated files + will contain a COFF header, a number of COFF section headers, the + section data itself, and a trailing string table for section names. */ + +/* Alignment of sections in a COFF object file. + + The LTO writer uses zlib compression on the data that it streams into + LTO sections in the output object file. Because these streams don't + have any embedded size information, the section in the object file must + be exactly sized to the data emitted; any trailing padding bytes will + be interpreted as partial and/or corrupt compressed data. + + This is easy enough to do on COFF targets (with binutils 2.20.1 or + above) because we can specify 1-byte alignment for the LTO sections. + They are then emitted precisely-sized and byte-packed into the object + and the reader is happy when it parses them later. This is currently + implemented in the x86/windows backed in i386_pe_asm_named_section() + in config/i386/winnt.c by detecting the LTO section name prefix, + + That would be sufficient, but for one thing. At the start of the LTO + data is a header struct with (currently) a couple of version numbers and + some type info; see struct lto_header in lto-streamer.h. If the sections + are byte-packed, this header will not necessarily be correctly-aligned + when it is read back into memory. + + On x86 targets, which are currently the only LTO-COFF targets, misaligned + memory accesses aren't problematic (okay, inefficient, but not worth + worrying about two half-word memory reads per section in the context of + everything else the compiler has to do at the time!), but RISC targets may + fail on trying to access the header struct. In this case, it will be + necessary to enable (preferably in a target-dependent fashion, but a few + bytes of padding are hardly an important issue if it comes down to it) the + COFF_ALIGNMENT macros below. + + As currently implemented, this will emit padding to the necessary number + of bytes after each LTO section. These bytes will constitute 'gaps' in + the object file structure, as they won't be covered by any section header. + This hasn't yet been tested, because no such RISC LTO-COFF target yet + exists. If it causes problems further down the toolchain, it will be + necessary to adapt the code to emit additional section headers for these + padding bytes, but the odds are that it will "just work". + + */ + +#if 0 +#define COFF_ALIGNMENT (4) +#define COFF_ALIGNMENTM1 (COFF_ALIGNMENT - 1) +#define COFF_ALIGN(x) (((x) + COFF_ALIGNMENTM1) & ~COFF_ALIGNMENTM1) +#else +#define COFF_ALIGNMENT (1) +#define COFF_ALIGN(x) (x) +#endif + +/* COFF header machine codes. */ + +#define IMAGE_FILE_MACHINE_I386 (0x014c) + +/* Known header magics for validation, as an array initialiser. */ + +#define COFF_KNOWN_MACHINES \ + { IMAGE_FILE_MACHINE_I386/*, ... add more here when working. */ } + +/* COFF object file header, section and symbol flags and types. These are + currently specific to PE-COFF, which is the only LTO-COFF format at the + time of writing. Maintainers adding support for new COFF formats will + need to make these into target macros of some kind. */ + +/* COFF header characteristics. */ + +#define IMAGE_FILE_EXECUTABLE_IMAGE (1 << 1) +#define IMAGE_FILE_32BIT_MACHINE (1 << 8) +#define IMAGE_FILE_SYSTEM (1 << 12) +#define IMAGE_FILE_DLL (1 << 13) + +/* Desired characteristics (for validation). */ + +#define COFF_CHARACTERISTICS \ + (IMAGE_FILE_32BIT_MACHINE) + +/* Unwanted characteristics (for validation). */ + +#define COFF_NOT_CHARACTERISTICS \ + (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL) + +/* Section flags. LTO emits byte-aligned read-only loadable data sections. */ + +#define IMAGE_SCN_CNT_INITIALIZED_DATA (1 << 6) +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA (1 << 7) +#define IMAGE_SCN_ALIGN_1BYTES (0x1 << 20) +#define IMAGE_SCN_MEM_DISCARDABLE (1 << 25) +#define IMAGE_SCN_MEM_SHARED (1 << 28) +#define IMAGE_SCN_MEM_READ (1 << 30) + +#define COFF_SECTION_CHARACTERISTICS \ + (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES | \ + IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ) + +/* Symbol-related constants. */ + +#define IMAGE_SYM_DEBUG (-2) +#define IMAGE_SYM_TYPE_NULL (0) +#define IMAGE_SYM_DTYPE_NULL (0) +#define IMAGE_SYM_CLASS_STATIC (3) +#define IMAGE_SYM_CLASS_FILE (103) + +#define IMAGE_SYM_TYPE \ + ((IMAGE_SYM_DTYPE_NULL << 4) | IMAGE_SYM_TYPE_NULL) + +/* Size of a COFF symbol in bytes. */ + +#define COFF_SYMBOL_SIZE (18) + +/* On-disk file structures. */ + +struct Coff_header +{ + unsigned char Machine[2]; + unsigned char NumberOfSections[2]; + unsigned char TimeDateStamp[4]; + unsigned char PointerToSymbolTable[4]; + unsigned char NumberOfSymbols[4]; + unsigned char SizeOfOptionalHeader[2]; + unsigned char Characteristics[2]; +}; +typedef struct Coff_header Coff_header; + +struct Coff_section +{ + unsigned char Name[8]; + unsigned char VirtualSize[4]; + unsigned char VirtualAddress[4]; + unsigned char SizeOfRawData[4]; + unsigned char PointerToRawData[4]; + unsigned char PointerToRelocations[4]; + unsigned char PointerToLinenumbers[4]; + unsigned char NumberOfRelocations[2]; + unsigned char NumberOfLinenumbers[2]; + unsigned char Characteristics[4]; +}; +typedef struct Coff_section Coff_section; + +struct Coff_symbol +{ + unsigned char Name[8]; + unsigned char Value[4]; + unsigned char SectionNumber[2]; + unsigned char Type[2]; + unsigned char StorageClass[1]; + unsigned char NumberOfAuxSymbols[1]; +}; +typedef struct Coff_symbol Coff_symbol; + +struct Coff_aux_sym_file +{ + unsigned char FileName[18]; +}; +typedef struct Coff_aux_sym_file Coff_aux_sym_file; + +struct Coff_aux_sym_section +{ + unsigned char Length[4]; + unsigned char NumberOfRelocations[2]; + unsigned char NumberOfLineNumbers[2]; + unsigned char Checksum[4]; + unsigned char Number[2]; + unsigned char Selection[1]; + unsigned char Unused[3]; +}; +typedef struct Coff_aux_sym_section Coff_aux_sym_section; + +/* Accessor macros for the above structures. */ + +#define COFF_GET(struc,memb) \ + ((COFFENDIAN ? get_be : get_le) (&(struc)->memb[0], sizeof ((struc)->memb))) + +#define COFF_PUT(struc,memb,val) \ + ((COFFENDIAN ? put_be : put_le) (&(struc)->memb[0], sizeof ((struc)->memb), val)) + +#define COFF_PUT_NDXSZ(struc,memb,val,ndx,sz) \ + ((COFFENDIAN ? put_be : put_le) (&(struc)->memb[ndx], sz, val)) + +/* In-memory file structures. */ + +/* Forward declared structs. */ + +struct lto_coff_data; +struct lto_coff_section; +struct lto_coff_file; + +/* Section data in output files is made of these. */ + +struct lto_coff_data +{ + /* Pointer to data block. */ + void *d_buf; + + /* Size of data block. */ + ssize_t d_size; + + /* Next data block for this section. */ + struct lto_coff_data *next; +}; +typedef struct lto_coff_data lto_coff_data; + +/* This struct tracks the data for a section. */ + +struct lto_coff_section +{ + /* Singly-linked list of section's data blocks. */ + lto_coff_data *data_chain; + + /* Offset in string table of name. */ + size_t strtab_offs; + + /* Section type: 0 = real, 1 = dummy. */ + size_t type; + + /* Section name. */ + const char *name; + +#if COFF_ALIGNMENT > 1 + /* Number of trailing padding bytes needed. */ + ssize_t pad_needed; +#endif + + /* Raw section header data. */ + Coff_section coffsec; + + /* Next section for this file. */ + struct lto_coff_section *next; +}; +typedef struct lto_coff_section lto_coff_section; + +/* A COFF file. */ + +struct lto_coff_file +{ + /* The base information. */ + lto_file base; + + /* Common file members: */ + + /* The system file descriptor for the file. */ + int fd; + + /* The file's overall header. */ + Coff_header coffhdr; + + /* All sections in a singly-linked list. */ + lto_coff_section *section_chain; + + /* Readable file members: */ + + /* File total size. */ + off_t file_size; + + /* String table file offset, relative to base.offset. */ + off_t strtab_offs; + + /* Writable file members: */ + + /* The currently active section. */ + lto_coff_section *scn; + + /* The output stream for section header names. */ + struct lto_output_stream *shstrtab_stream; + + /* Linked list of data which must be freed *after* the file has been + closed. This is an annoying limitation of libelf. Which has been + faithfully reproduced here. */ + struct lto_char_ptr_base *data; +}; +typedef struct lto_coff_file lto_coff_file; + +/* Data hunk iterator. */ + +#define COFF_FOR_ALL_DATA(sec,var) \ + for (var = sec->data_chain; var; var = var->next) + +/* Section list iterator. */ + +#define COFF_FOR_ALL_SECTIONS(file,var) \ + for (var = file->section_chain; var; var = var->next) + +/* Very simple endian-ness layer. */ + +#ifndef COFFENDIAN +#define COFFENDIAN (BYTES_BIG_ENDIAN) +#endif + +static inline unsigned int +get_2_le (const unsigned char *ptr) +{ + return ptr[0] | (ptr[1] << 8); +} + +static inline unsigned int +get_4_le (const unsigned char *ptr) +{ + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); +} + +static inline unsigned int +get_2_be (const unsigned char *ptr) +{ + return ptr[1] | (ptr[0] << 8); +} + +static inline unsigned int +get_4_be (const unsigned char *ptr) +{ + return ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); +} + +static inline unsigned int +get_be (const unsigned char *ptr, size_t size) +{ + gcc_assert (size == 4 || size == 2); + return (size == 2) ? get_2_be (ptr) : get_4_be (ptr); +} + +static inline unsigned int +get_le (const unsigned char *ptr, size_t size) +{ + gcc_assert (size == 4 || size == 2); + return (size == 2) ? get_2_le (ptr) : get_4_le (ptr); +} + +static inline void +put_2_le (unsigned char *ptr, unsigned int data) +{ + ptr[0] = data & 0xff; + ptr[1] = (data >> 8) & 0xff; +} + +static inline void +put_4_le (unsigned char *ptr, unsigned int data) +{ + ptr[0] = data & 0xff; + ptr[1] = (data >> 8) & 0xff; + ptr[2] = (data >> 16) & 0xff; + ptr[3] = (data >> 24) & 0xff; +} + +static inline void +put_2_be (unsigned char *ptr, unsigned int data) +{ + ptr[1] = data & 0xff; + ptr[0] = (data >> 8) & 0xff; +} + +static inline void +put_4_be (unsigned char *ptr, unsigned int data) +{ + ptr[3] = data & 0xff; + ptr[2] = (data >> 8) & 0xff; + ptr[1] = (data >> 16) & 0xff; + ptr[0] = (data >> 24) & 0xff; +} + +static inline void +put_le (unsigned char *ptr, size_t size, unsigned int data) +{ + gcc_assert (size == 4 || size == 2); + (void) (size == 2 ? put_2_le : put_4_le) (ptr, data); +} + +static inline void +put_be (unsigned char *ptr, size_t size, unsigned int data) +{ + gcc_assert (size == 4 || size == 2); + (void) (size == 2 ? put_2_be : put_4_be) (ptr, data); +} + +/* We use this for putting the string table size. */ + +#define COFF_PUT4(ptr, data) \ + ((COFFENDIAN ? put_4_be : put_4_le) (ptr, data)) + + +#endif /* LTO_COFF_H */ diff --git a/gcc/lto/lto-elf.c b/gcc/lto/lto-elf.c index c777da70f88..1796888f4c3 100644 --- a/gcc/lto/lto-elf.c +++ b/gcc/lto/lto-elf.c @@ -179,7 +179,7 @@ eq_name (const void *p1, const void *p2) the start and size of each section in the .o file. */ htab_t -lto_elf_build_section_table (lto_file *lto_file) +lto_obj_build_section_table (lto_file *lto_file) { lto_elf_file *elf_file = (lto_elf_file *)lto_file; htab_t section_hash_table; @@ -322,7 +322,7 @@ lto_elf_begin_section_with_type (const char *name, size_t type) /* Begin a new ELF section named NAME in the current output file. */ void -lto_elf_begin_section (const char *name) +lto_obj_begin_section (const char *name) { lto_elf_begin_section_with_type (name, SHT_PROGBITS); } @@ -333,7 +333,7 @@ lto_elf_begin_section (const char *name) been written. */ void -lto_elf_append_data (const void *data, size_t len, void *block) +lto_obj_append_data (const void *data, size_t len, void *block) { lto_elf_file *file; Elf_Data *elf_data; @@ -370,7 +370,7 @@ lto_elf_append_data (const void *data, size_t len, void *block) and sets the current output file's scn member to NULL. */ void -lto_elf_end_section (void) +lto_obj_end_section (void) { lto_elf_file *file; @@ -604,7 +604,7 @@ init_ehdr (lto_elf_file *elf_file) Returns the opened file. */ lto_file * -lto_elf_file_open (const char *filename, bool writable) +lto_obj_file_open (const char *filename, bool writable) { lto_elf_file *elf_file; lto_file *result = NULL; @@ -704,7 +704,7 @@ lto_elf_file_open (const char *filename, bool writable) fail: if (result) - lto_elf_file_close (result); + lto_obj_file_close (result); return NULL; } @@ -714,7 +714,7 @@ lto_elf_file_open (const char *filename, bool writable) any cached data buffers are freed. */ void -lto_elf_file_close (lto_file *file) +lto_obj_file_close (lto_file *file) { lto_elf_file *elf_file = (lto_elf_file *) file; struct lto_char_ptr_base *cur, *tmp; @@ -750,7 +750,7 @@ lto_elf_file_close (lto_file *file) if (gelf_update_ehdr (elf_file->elf, ehdr_p) == 0) fatal_error ("gelf_update_ehdr() failed: %s", elf_errmsg (-1)); lto_write_stream (elf_file->shstrtab_stream); - lto_elf_end_section (); + lto_obj_end_section (); lto_set_current_out_file (old_file); free (elf_file->shstrtab_stream); diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index aea5ab22d35..8c4b254fc6b 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -1158,11 +1158,11 @@ static void lto_init_ts (void) #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE lto_format_attribute_table #undef LANG_HOOKS_BEGIN_SECTION -#define LANG_HOOKS_BEGIN_SECTION lto_elf_begin_section +#define LANG_HOOKS_BEGIN_SECTION lto_obj_begin_section #undef LANG_HOOKS_APPEND_DATA -#define LANG_HOOKS_APPEND_DATA lto_elf_append_data +#define LANG_HOOKS_APPEND_DATA lto_obj_append_data #undef LANG_HOOKS_END_SECTION -#define LANG_HOOKS_END_SECTION lto_elf_end_section +#define LANG_HOOKS_END_SECTION lto_obj_end_section #undef LANG_HOOKS_INIT_TS #define LANG_HOOKS_INIT_TS lto_init_ts diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 115d1cc5678..7aa1f3ecdbe 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -378,7 +378,7 @@ lto_file_read (lto_file *file, FILE *resolution_file) file_data = XCNEW (struct lto_file_decl_data); file_data->file_name = file->filename; - file_data->section_hash_table = lto_elf_build_section_table (file); + file_data->section_hash_table = lto_obj_build_section_table (file); file_data->renaming_hash_table = lto_create_renaming_table (); data = lto_get_section_data (file_data, LTO_section_decls, NULL, &len); @@ -523,6 +523,7 @@ free_section_data (struct lto_file_decl_data *file_data ATTRIBUTE_UNUSED, /* Vector of all cgraph node sets. */ static GTY (()) VEC(cgraph_node_set, gc) *lto_cgraph_node_sets; +static GTY (()) VEC(varpool_node_set, gc) *lto_varpool_node_sets; /* Group cgrah nodes by input files. This is used mainly for testing @@ -532,25 +533,21 @@ static void lto_1_to_1_map (void) { struct cgraph_node *node; + struct varpool_node *vnode; struct lto_file_decl_data *file_data; struct pointer_map_t *pmap; + struct pointer_map_t *vpmap; cgraph_node_set set; + varpool_node_set vset; void **slot; timevar_push (TV_WHOPR_WPA); lto_cgraph_node_sets = VEC_alloc (cgraph_node_set, gc, 1); - - /* If the cgraph is empty, create one cgraph node set so that there is still - an output file for any variables that need to be exported in a DSO. */ - if (!cgraph_nodes) - { - set = cgraph_node_set_new (); - VEC_safe_push (cgraph_node_set, gc, lto_cgraph_node_sets, set); - goto finish; - } + lto_varpool_node_sets = VEC_alloc (varpool_node_set, gc, 1); pmap = pointer_map_create (); + vpmap = pointer_map_create (); for (node = cgraph_nodes; node; node = node->next) { @@ -558,6 +555,9 @@ lto_1_to_1_map (void) cloned from. */ if (node->global.inlined_to || node->clone_of) continue; + /* Nodes without a body do not need partitioning. */ + if (!node->analyzed || node->same_body_alias) + continue; /* We only need to partition the nodes that we read from the gimple bytecode files. */ file_data = node->local.lto_file_data; @@ -573,14 +573,50 @@ lto_1_to_1_map (void) slot = pointer_map_insert (pmap, file_data); *slot = set; VEC_safe_push (cgraph_node_set, gc, lto_cgraph_node_sets, set); + vset = varpool_node_set_new (); + slot = pointer_map_insert (vpmap, file_data); + *slot = vset; + VEC_safe_push (varpool_node_set, gc, lto_varpool_node_sets, vset); } cgraph_node_set_add (set, node); } + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + { + if (vnode->alias) + continue; + slot = pointer_map_contains (vpmap, file_data); + if (slot) + vset = (varpool_node_set) *slot; + else + { + set = cgraph_node_set_new (); + slot = pointer_map_insert (pmap, file_data); + *slot = set; + VEC_safe_push (cgraph_node_set, gc, lto_cgraph_node_sets, set); + vset = varpool_node_set_new (); + slot = pointer_map_insert (vpmap, file_data); + *slot = vset; + VEC_safe_push (varpool_node_set, gc, lto_varpool_node_sets, vset); + } + + varpool_node_set_add (vset, vnode); + } + + /* If the cgraph is empty, create one cgraph node set so that there is still + an output file for any variables that need to be exported in a DSO. */ + if (!lto_cgraph_node_sets) + { + set = cgraph_node_set_new (); + VEC_safe_push (cgraph_node_set, gc, lto_cgraph_node_sets, set); + vset = varpool_node_set_new (); + VEC_safe_push (varpool_node_set, gc, lto_varpool_node_sets, vset); + } + pointer_map_destroy (pmap); + pointer_map_destroy (vpmap); -finish: timevar_pop (TV_WHOPR_WPA); lto_stats.num_cgraph_partitions += VEC_length (cgraph_node_set, @@ -672,174 +708,6 @@ lto_add_all_inlinees (cgraph_node_set set) lto_bitmap_free (original_decls); } -/* Owing to inlining, we may need to promote a file-scope variable - to a global variable. Consider this case: - - a.c: - static int var; - - void - foo (void) - { - var++; - } - - b.c: - - extern void foo (void); - - void - bar (void) - { - foo (); - } - - If WPA inlines FOO inside BAR, then the static variable VAR needs to - be promoted to global because BAR and VAR may be in different LTRANS - files. */ - -/* This struct keeps track of states used in globalization. */ - -typedef struct -{ - /* Current cgraph node set. */ - cgraph_node_set set; - - /* Function DECLs of cgraph nodes seen. */ - bitmap seen_node_decls; - - /* Use in walk_tree to avoid multiple visits of a node. */ - struct pointer_set_t *visited; - - /* static vars in this set. */ - bitmap static_vars_in_set; - - /* static vars in all previous set. */ - bitmap all_static_vars; - - /* all vars in all previous set. */ - bitmap all_vars; -} globalize_context_t; - -/* Callback for walk_tree. Examine the tree pointer to by TP and see if - if its a file-scope static variable of function that need to be turned - into a global. */ - -static tree -globalize_cross_file_statics (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, - void *data) -{ - globalize_context_t *context = (globalize_context_t *) data; - tree t = *tp; - - if (t == NULL_TREE) - return NULL; - - /* The logic for globalization of VAR_DECLs and FUNCTION_DECLs are - different. For functions, we can simply look at the cgraph node sets - to tell if there are references to static functions outside the set. - The cgraph node sets do not keep track of vars, we need to traverse - the trees to determine what vars need to be globalized. */ - if (TREE_CODE (t) == VAR_DECL) - { - if (!TREE_PUBLIC (t)) - { - /* This file-scope static variable is reachable from more - that one set. Make it global but with hidden visibility - so that we do not export it in dynamic linking. */ - if (bitmap_bit_p (context->all_static_vars, DECL_UID (t))) - { - TREE_PUBLIC (t) = 1; - DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; - } - bitmap_set_bit (context->static_vars_in_set, DECL_UID (t)); - } - bitmap_set_bit (context->all_vars, DECL_UID (t)); - walk_tree (&DECL_INITIAL (t), globalize_cross_file_statics, context, - context->visited); - } - else if (TREE_CODE (t) == FUNCTION_DECL && !TREE_PUBLIC (t)) - { - if (!cgraph_node_in_set_p (cgraph_node (t), context->set) - || cgraph_node (t)->address_taken) - { - /* This file-scope static function is reachable from a set - which does not contain the function DECL. Make it global - but with hidden visibility. */ - TREE_PUBLIC (t) = 1; - DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; - } - } - - return NULL; -} - -/* Helper of lto_scan_statics_in_cgraph_node below. Scan TABLE for - static decls that may be used in more than one LTRANS file. - CONTEXT is a globalize_context_t for storing scanning states. */ - -static void -lto_scan_statics_in_ref_table (struct lto_tree_ref_table *table, - globalize_context_t *context) -{ - unsigned i; - - for (i = 0; i < table->size; i++) - walk_tree (&table->trees[i], globalize_cross_file_statics, context, - context->visited); -} - -/* Promote file-scope decl reachable from NODE if necessary to global. - CONTEXT is a globalize_context_t storing scanning states. */ - -static void -lto_scan_statics_in_cgraph_node (struct cgraph_node *node, - globalize_context_t *context) -{ - struct lto_in_decl_state *state; - - /* Do nothing if NODE has no function body. */ - if (!node->analyzed) - return; - - /* Return if the DECL of nodes has been visited before. */ - if (bitmap_bit_p (context->seen_node_decls, DECL_UID (node->decl))) - return; - - bitmap_set_bit (context->seen_node_decls, DECL_UID (node->decl)); - - state = lto_get_function_in_decl_state (node->local.lto_file_data, - node->decl); - gcc_assert (state); - - lto_scan_statics_in_ref_table (&state->streams[LTO_DECL_STREAM_VAR_DECL], - context); - lto_scan_statics_in_ref_table (&state->streams[LTO_DECL_STREAM_FN_DECL], - context); -} - -/* Scan all global variables that we have not yet seen so far. CONTEXT - is a globalize_context_t storing scanning states. */ - -static void -lto_scan_statics_in_remaining_global_vars (globalize_context_t *context) -{ - tree var, var_context; - struct varpool_node *vnode; - - FOR_EACH_STATIC_VARIABLE (vnode) - { - var = vnode->decl; - var_context = DECL_CONTEXT (var); - if (TREE_STATIC (var) - && TREE_PUBLIC (var) - && (!var_context || TREE_CODE (var_context) != FUNCTION_DECL) - && !bitmap_bit_p (context->all_vars, DECL_UID (var))) - walk_tree (&var, globalize_cross_file_statics, context, - context->visited); - } -} - /* Find out all static decls that need to be promoted to global because of cross file sharing. This function must be run in the WPA mode after all inlinees are added. */ @@ -847,39 +715,61 @@ lto_scan_statics_in_remaining_global_vars (globalize_context_t *context) static void lto_promote_cross_file_statics (void) { + struct varpool_node *vnode; unsigned i, n_sets; cgraph_node_set set; cgraph_node_set_iterator csi; - globalize_context_t context; - memset (&context, 0, sizeof (context)); - context.all_vars = lto_bitmap_alloc (); - context.all_static_vars = lto_bitmap_alloc (); + gcc_assert (flag_wpa); + /* At moment we make no attempt to figure out who is refering the variables, + so all must become global. */ + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (!vnode->externally_visible && vnode->analyzed) + { + TREE_PUBLIC (vnode->decl) = 1; + DECL_VISIBILITY (vnode->decl) = VISIBILITY_HIDDEN; + } n_sets = VEC_length (cgraph_node_set, lto_cgraph_node_sets); for (i = 0; i < n_sets; i++) { set = VEC_index (cgraph_node_set, lto_cgraph_node_sets, i); - context.set = set; - context.visited = pointer_set_create (); - context.static_vars_in_set = lto_bitmap_alloc (); - context.seen_node_decls = lto_bitmap_alloc (); + /* If node has either address taken (and we have no clue from where) + or it is called from other partition, it needs to be globalized. */ for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) - lto_scan_statics_in_cgraph_node (csi_node (csi), &context); - - if (i == n_sets - 1) - lto_scan_statics_in_remaining_global_vars (&context); - - bitmap_ior_into (context.all_static_vars, context.static_vars_in_set); + { + struct cgraph_node *node = csi_node (csi); + bool globalize = node->address_taken || node->local.vtable_method; + struct cgraph_edge *e; + if (node->local.externally_visible) + continue; + for (e = node->callers; e && !globalize; e = e->next_caller) + { + struct cgraph_node *caller = e->caller; + if (caller->global.inlined_to) + caller = caller->global.inlined_to; + if (!cgraph_node_in_set_p (caller, set)) + globalize = true; + } + if (globalize) + { + TREE_PUBLIC (node->decl) = 1; + DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN; + if (node->same_body) + { + struct cgraph_node *alias; + for (alias = node->same_body; + alias; alias = alias->next) + { + TREE_PUBLIC (alias->decl) = 1; + DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN; + } + } + } + } - pointer_set_destroy (context.visited); - lto_bitmap_free (context.static_vars_in_set); - lto_bitmap_free (context.seen_node_decls); } - - lto_bitmap_free (context.all_vars); - lto_bitmap_free (context.all_static_vars); } @@ -999,6 +889,7 @@ lto_wpa_write_files (void) unsigned i, n_sets, last_out_file_ix, num_out_files; lto_file *file; cgraph_node_set set; + varpool_node_set vset; timevar_push (TV_WHOPR_WPA); @@ -1034,22 +925,23 @@ lto_wpa_write_files (void) char *temp_filename; set = VEC_index (cgraph_node_set, lto_cgraph_node_sets, i); + vset = VEC_index (varpool_node_set, lto_varpool_node_sets, i); temp_filename = get_filename_for_set (set); output_files[i] = temp_filename; if (cgraph_node_set_needs_ltrans_p (set)) { /* Write all the nodes in SET to TEMP_FILENAME. */ - file = lto_elf_file_open (temp_filename, true); + file = lto_obj_file_open (temp_filename, true); if (!file) - fatal_error ("lto_elf_file_open() failed"); + fatal_error ("lto_obj_file_open() failed"); lto_set_current_out_file (file); - ipa_write_optimization_summaries (set); + ipa_write_optimization_summaries (set, vset); lto_set_current_out_file (NULL); - lto_elf_file_close (file); + lto_obj_file_close (file); } } @@ -1422,7 +1314,13 @@ lto_fixup_type (tree t, void *data) /* Accessor is for derived node types only. */ LTO_FIXUP_SUBTREE (t->type.binfo); - LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t)); + if (TYPE_CONTEXT (t)) + { + if (TYPE_P (TYPE_CONTEXT (t))) + LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t)); + else + LTO_FIXUP_SUBTREE (TYPE_CONTEXT (t)); + } LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CANONICAL (t)); /* The following re-creates proper variant lists while fixing up @@ -1740,17 +1638,17 @@ lto_read_all_file_options (void) for (i = 0; i < num_in_fnames; i++) { struct lto_file_decl_data *file_data; - lto_file *file = lto_elf_file_open (in_fnames[i], false); + lto_file *file = lto_obj_file_open (in_fnames[i], false); if (!file) break; file_data = XCNEW (struct lto_file_decl_data); file_data->file_name = file->filename; - file_data->section_hash_table = lto_elf_build_section_table (file); + file_data->section_hash_table = lto_obj_build_section_table (file); lto_read_file_options (file_data); - lto_elf_file_close (file); + lto_obj_file_close (file); htab_delete (file_data->section_hash_table); free (file_data); } @@ -1813,7 +1711,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) fflush (stderr); } - current_lto_file = lto_elf_file_open (fnames[i], false); + current_lto_file = lto_obj_file_open (fnames[i], false); if (!current_lto_file) break; @@ -1823,7 +1721,7 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) all_file_decl_data[last_file_ix++] = file_data; - lto_elf_file_close (current_lto_file); + lto_obj_file_close (current_lto_file); current_lto_file = NULL; } diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 0c4305a1731..e55342b754a 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -38,13 +38,13 @@ extern const char *resolution_file_name; extern void lto_main (int); extern void lto_read_all_file_options (void); -/* In lto-elf.c */ -extern lto_file *lto_elf_file_open (const char *filename, bool writable); -extern void lto_elf_file_close (lto_file *file); -extern htab_t lto_elf_build_section_table (lto_file *file); -extern void lto_elf_begin_section (const char *name); -extern void lto_elf_append_data (const void *data, size_t len, void *block); -extern void lto_elf_end_section (void); +/* In lto-elf.c or lto-coff.c */ +extern lto_file *lto_obj_file_open (const char *filename, bool writable); +extern void lto_obj_file_close (lto_file *file); +extern htab_t lto_obj_build_section_table (lto_file *file); +extern void lto_obj_begin_section (const char *name); +extern void lto_obj_append_data (const void *data, size_t len, void *block); +extern void lto_obj_end_section (void); extern lto_file *lto_set_current_out_file (lto_file *file); extern lto_file *lto_get_current_out_file (void); diff --git a/gcc/opts.c b/gcc/opts.c index 0009a749dae..507b50227ee 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -858,6 +858,7 @@ decode_options (unsigned int argc, const char **argv) flag_if_conversion2 = opt1; flag_ipa_pure_const = opt1; flag_ipa_reference = opt1; + flag_ipa_profile = opt1; flag_merge_constants = opt1; flag_split_wide_types = opt1; flag_tree_ccp = opt1; diff --git a/gcc/passes.c b/gcc/passes.c index a6e5af50841..7a5d16f8a24 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -191,7 +191,11 @@ rest_of_decl_compilation (tree decl, || DECL_INITIAL (decl)) && !DECL_EXTERNAL (decl)) { - if (TREE_CODE (decl) != FUNCTION_DECL) + /* When reading LTO unit, we also read varpool, so do not + rebuild it. */ + if (in_lto_p && !at_end) + ; + else if (TREE_CODE (decl) != FUNCTION_DECL) varpool_finalize_decl (decl); else assemble_variable (decl, top_level, at_end, 0); @@ -218,7 +222,9 @@ rest_of_decl_compilation (tree decl, } /* Let cgraph know about the existence of variables. */ - if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) + if (in_lto_p && !at_end) + ; + else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) varpool_node (decl); } @@ -803,6 +809,7 @@ init_optimization_passes (void) p = &all_regular_ipa_passes; NEXT_PASS (pass_ipa_whole_program_visibility); + NEXT_PASS (pass_ipa_profile); NEXT_PASS (pass_ipa_cp); NEXT_PASS (pass_ipa_inline); NEXT_PASS (pass_ipa_reference); @@ -1361,14 +1368,17 @@ pass_init_dump_file (struct opt_pass *pass) if (dump_file && current_function_decl) { const char *dname, *aname; + struct cgraph_node *node = cgraph_node (current_function_decl); dname = lang_hooks.decl_printable_name (current_function_decl, 2); aname = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname, - cfun->function_frequency == FUNCTION_FREQUENCY_HOT + node->frequency == NODE_FREQUENCY_HOT ? " (hot)" - : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED ? " (unlikely executed)" + : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + ? " (executed once)" : ""); } return initializing_dump; @@ -1645,6 +1655,7 @@ execute_pass_list (struct opt_pass *pass) static void ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, + varpool_node_set vset, struct lto_out_decl_state *state) { while (pass) @@ -1661,7 +1672,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, if (pass->tv_id) timevar_push (pass->tv_id); - ipa_pass->write_summary (set); + ipa_pass->write_summary (set,vset); /* If a timevar is present, start it. */ if (pass->tv_id) @@ -1669,7 +1680,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, } if (pass->sub && pass->sub->type != GIMPLE_PASS) - ipa_write_summaries_2 (pass->sub, set, state); + ipa_write_summaries_2 (pass->sub, set, vset, state); pass = pass->next; } @@ -1680,14 +1691,14 @@ ipa_write_summaries_2 (struct opt_pass *pass, cgraph_node_set set, summaries. SET is the set of nodes to be written. */ static void -ipa_write_summaries_1 (cgraph_node_set set) +ipa_write_summaries_1 (cgraph_node_set set, varpool_node_set vset) { struct lto_out_decl_state *state = lto_new_out_decl_state (); lto_push_out_decl_state (state); gcc_assert (!flag_wpa); - ipa_write_summaries_2 (all_regular_ipa_passes, set, state); - ipa_write_summaries_2 (all_lto_gen_passes, set, state); + ipa_write_summaries_2 (all_regular_ipa_passes, set, vset, state); + ipa_write_summaries_2 (all_lto_gen_passes, set, vset, state); gcc_assert (lto_get_out_decl_state () == state); lto_pop_out_decl_state (); @@ -1700,7 +1711,9 @@ void ipa_write_summaries (void) { cgraph_node_set set; + varpool_node_set vset; struct cgraph_node **order; + struct varpool_node *vnode; int i, order_pos; if (!flag_generate_lto || errorcount || sorrycount) @@ -1732,13 +1745,20 @@ ipa_write_summaries (void) renumber_gimple_stmt_uids (); pop_cfun (); } - cgraph_node_set_add (set, node); + if (node->needed || node->reachable || node->address_taken) + cgraph_node_set_add (set, node); } + vset = varpool_node_set_new (); - ipa_write_summaries_1 (set); + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (vnode->needed && !vnode->alias) + varpool_node_set_add (vset, vnode); + + ipa_write_summaries_1 (set, vset); free (order); ggc_free (set); + ggc_free (vset); } /* Same as execute_pass_list but assume that subpasses of IPA passes @@ -1747,6 +1767,7 @@ ipa_write_summaries (void) static void ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, + varpool_node_set vset, struct lto_out_decl_state *state) { while (pass) @@ -1763,7 +1784,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, if (pass->tv_id) timevar_push (pass->tv_id); - ipa_pass->write_optimization_summary (set); + ipa_pass->write_optimization_summary (set, vset); /* If a timevar is present, start it. */ if (pass->tv_id) @@ -1771,7 +1792,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, } if (pass->sub && pass->sub->type != GIMPLE_PASS) - ipa_write_optimization_summaries_1 (pass->sub, set, state); + ipa_write_optimization_summaries_1 (pass->sub, set, vset, state); pass = pass->next; } @@ -1781,14 +1802,14 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, cgraph_node_set set, NULL, write out all summaries of all nodes. */ void -ipa_write_optimization_summaries (cgraph_node_set set) +ipa_write_optimization_summaries (cgraph_node_set set, varpool_node_set vset) { struct lto_out_decl_state *state = lto_new_out_decl_state (); lto_push_out_decl_state (state); gcc_assert (flag_wpa); - ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, state); - ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, state); + ipa_write_optimization_summaries_1 (all_regular_ipa_passes, set, vset, state); + ipa_write_optimization_summaries_1 (all_lto_gen_passes, set, vset, state); gcc_assert (lto_get_out_decl_state () == state); lto_pop_out_decl_state (); diff --git a/gcc/plugin.c b/gcc/plugin.c index 9e1b5f4ada1..707d2dd5f66 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -86,6 +86,8 @@ struct callback_info static struct callback_info *plugin_callbacks_init[PLUGIN_EVENT_FIRST_DYNAMIC]; static struct callback_info **plugin_callbacks = plugin_callbacks_init; +/* For invoke_plugin_callbacks(), see plugin.h. */ +bool flag_plugin_added = false; #ifdef ENABLE_PLUGIN /* Each plugin should define an initialization function with exactly @@ -137,6 +139,8 @@ add_new_plugin (const char* plugin_name) bool name_is_short; const char *pc; + flag_plugin_added = true; + /* Replace short names by their full path when relevant. */ name_is_short = !IS_ABSOLUTE_PATH (plugin_name); for (pc = plugin_name; name_is_short && *pc; pc++) @@ -483,16 +487,11 @@ unregister_callback (const char *plugin_name, int event) return PLUGEVT_NO_CALLBACK; } -/* Called from inside GCC. Invoke all plug-in callbacks registered with - the specified event. - Return PLUGEVT_SUCCESS if at least one callback was called, - PLUGEVT_NO_CALLBACK if there was no callback. - - EVENT - the event identifier - GCC_DATA - event-specific data provided by the compiler */ +/* Invoke all plugin callbacks registered with the specified event, + called from invoke_plugin_callbacks(). */ int -invoke_plugin_callbacks (int event, void *gcc_data) +invoke_plugin_callbacks_full (int event, void *gcc_data) { int retval = PLUGEVT_SUCCESS; diff --git a/gcc/plugin.h b/gcc/plugin.h index 1e1dd594937..3269641df0a 100644 --- a/gcc/plugin.h +++ b/gcc/plugin.h @@ -1,5 +1,5 @@ /* Header file for internal GCC plugin mechanism. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -26,7 +26,7 @@ struct attribute_spec; extern void add_new_plugin (const char *); extern void parse_plugin_arg_opt (const char *); -extern int invoke_plugin_callbacks (int, void *); +extern int invoke_plugin_callbacks_full (int, void *); extern void initialize_plugins (void); extern bool plugins_active_p (void); extern void dump_active_plugins (FILE *); @@ -35,6 +35,29 @@ extern void print_plugins_versions (FILE *file, const char *indent); extern void print_plugins_help (FILE *file, const char *indent); extern void finalize_plugins (void); +extern bool flag_plugin_added; + +/* Called from inside GCC. Invoke all plugin callbacks registered with + the specified event. + Return PLUGEVT_SUCCESS if at least one callback was called, + PLUGEVT_NO_CALLBACK if there was no callback. + + EVENT - the event identifier + GCC_DATA - event-specific data provided by the compiler */ + +static inline int +invoke_plugin_callbacks (int event ATTRIBUTE_UNUSED, + void *gcc_data ATTRIBUTE_UNUSED) +{ +#ifdef ENABLE_PLUGIN + /* True iff at least one plugin has been added. */ + if (flag_plugin_added) + return invoke_plugin_callbacks_full (event, gcc_data); +#endif + + return PLUGEVT_NO_CALLBACK; +} + /* In attribs.c. */ extern void register_attribute (const struct attribute_spec *attr); diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index 058c7461290..510ad66c480 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2010-04-26 Joseph Myers + + * sv.po: Update. + 2010-04-20 Joseph Myers * es.po: Update. diff --git a/gcc/po/sv.po b/gcc/po/sv.po index 93f3e0eed79..62fcd0b0ed7 100644 --- a/gcc/po/sv.po +++ b/gcc/po/sv.po @@ -8,15 +8,16 @@ # msgid "" msgstr "" -"Project-Id-Version: gcc 4.5-b20100204\n" +"Project-Id-Version: gcc 4.5.0\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2010-04-06 14:11+0000\n" -"PO-Revision-Date: 2010-02-21 17:01+0100\n" +"PO-Revision-Date: 2010-04-26 18:16+0200\n" "Last-Translator: Göran Uddeborg \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: c-decl.c:4573 c-pretty-print.c:403 c-typeck.c:5590 toplev.c:1652 #: cp/error.c:581 cp/error.c:854 @@ -641,25 +642,25 @@ msgid "collect2 version %s" msgstr "collect2 version %s" #: collect2.c:1823 -#, fuzzy, c-format +#, c-format msgid "%d constructor found\n" msgid_plural "%d constructors found\n" -msgstr[0] "%d konstruerare hittad(e)\n" -msgstr[1] "%d konstruerare hittad(e)\n" +msgstr[0] "%d konstruerare hittad\n" +msgstr[1] "%d konstruerare hittade\n" #: collect2.c:1827 -#, fuzzy, c-format +#, c-format msgid "%d destructor found\n" msgid_plural "%d destructors found\n" -msgstr[0] "%d destruerare hittad(e)\n" -msgstr[1] "%d destruerare hittad(e)\n" +msgstr[0] "%d destruerare hittad\n" +msgstr[1] "%d destruerare hittade\n" #: collect2.c:1831 -#, fuzzy, c-format +#, c-format msgid "%d frame table found\n" msgid_plural "%d frame tables found\n" -msgstr[0] "%d ramtabell(er) hittade\n" -msgstr[1] "%d ramtabell(er) hittade\n" +msgstr[0] "%d ramtabell hittad\n" +msgstr[1] "%d ramtabeller hittade\n" #: collect2.c:1985 lto-wrapper.c:175 #, c-format @@ -2528,9 +2529,8 @@ msgid "The maximum number of insns of a peeled loop that rolls only once" msgstr "Det maximala antalet instruktioner i en avskalad slinga som bara snurrar en gång" #: params.def:272 -#, fuzzy msgid "The maximum depth of a loop nest we completely peel" -msgstr "Det maximala antalet instruktioner i en helt avskalad slinga" +msgstr "Det maximala djupet av nästade slingor som vi skalar helt" #: params.def:278 msgid "The maximum number of insns of an unswitched loop" @@ -2826,13 +2826,12 @@ msgid "size of tiles for loop blocking" msgstr "storlek på bitar för slingblockning" #: params.def:752 -#, fuzzy msgid "maximum number of parameters in a SCoP" -msgstr "maximumvärde på parameter %qs är %u" +msgstr "maximalt antal parameter i en SCoP" #: params.def:759 msgid "maximum number of basic blocks per function to be analyzed by Graphite" -msgstr "" +msgstr "maximalt antal grundblock per funktion att analyseras av Graphite" #: params.def:766 msgid "Max basic blocks number in loop for loop invariant motion" @@ -2852,7 +2851,7 @@ msgstr "Minsta f #: params.def:790 msgid "Max. size of var tracking hash tables" -msgstr "" +msgstr "Max storlek på hashtabell för variabelspårning" #: params.def:797 msgid "The minimum UID to be used for a nondebug insn" @@ -4079,14 +4078,14 @@ msgid "%s:%d: instantiated from here" msgstr "%s:%d: instantierad härifrån" #: cp/error.c:2794 -#, fuzzy, c-format +#, c-format msgid "%s:%d:%d: [ skipping %d instantiation contexts ]\n" -msgstr "%s:%d:%d: instantierad från %qs\n" +msgstr "%s:%d:%d: [ hoppar över %d instantieringskontexter ]\n" #: cp/error.c:2798 #, c-format msgid "%s:%d: [ skipping %d instantiation contexts ]\n" -msgstr "" +msgstr "%s:%d: [ hoppar över %d instantieringskontexter ]\n" #: cp/g++spec.c:261 java/jvspec.c:403 #, c-format @@ -5339,9 +5338,8 @@ msgid "Allow arbitrary character line width in fixed mode" msgstr "Tillåt radlängd med godtyckligt antal tecken i fast läge" #: fortran/lang.opt:249 -#, fuzzy msgid "-ffixed-line-length-\tUse n as character line width in fixed mode" -msgstr "-ffixed-line-length-\t\tAnvänd radlängd med n tecken i fast läge" +msgstr "-ffixed-line-length-\tAnvänd radlängd med n tecken i fast läge" #: fortran/lang.opt:253 msgid "-ffpe-trap=[...]\tStop on following floating point exceptions" @@ -5356,9 +5354,8 @@ msgid "Allow arbitrary character line width in free mode" msgstr "Tillåt radlängd med godtyckligt antal tecken i fri form" #: fortran/lang.opt:265 -#, fuzzy msgid "-ffree-line-length-\tUse n as character line width in free mode" -msgstr "-ffree-line-length-\t\tAnvänd radlängd med n tecken i fri form" +msgstr "-ffree-line-length-\tAnvänd radlängd med n tecken i fri form" #: fortran/lang.opt:269 msgid "Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements" @@ -5413,9 +5410,8 @@ msgid "Try to lay out derived types as compactly as possible" msgstr "Försök placera ut härledda typer så kompakt som möjligt" #: fortran/lang.opt:329 -#, fuzzy msgid "Protect parentheses in expressions" -msgstr "föreslår parenteser runt %<>>%>-uttryck" +msgstr "Skydda parenteser i uttryck" #: fortran/lang.opt:333 msgid "Enable range checking during compilation" @@ -8968,9 +8964,8 @@ msgid "Warn for implicit type conversions that may change a value" msgstr "Varna för implicita typkonverteringar som kan ändra ett värde" #: c.opt:176 -#, fuzzy msgid "Warn for converting NULL from/to a non-pointer type" -msgstr "konvertera av NULL till icke-pekartyp" +msgstr "Varna för konvertering av NULL till icke-pekartyp" #: c.opt:180 msgid "Warn for implicit type conversions between signed and unsigned integers" @@ -9513,9 +9508,8 @@ msgid "-ftabstop=\tDistance between tab stops for column reporting" msgstr "-ftabstop=\tAvstånd mellan tabulatorstopp för kolumnvis rapportering" #: c.opt:798 -#, fuzzy msgid "-ftemplate-depth=\tSpecify maximum template instantiation depth" -msgstr "-ftemplate-depth-\tAnge maximalt instansieringsdjup för mallar" +msgstr "-ftemplate-depth=\tAnge maximalt instansieringsdjup för mallar" #: c.opt:805 msgid "-fno-threadsafe-statics\tDo not generate thread-safe code for initializing local statics" @@ -9922,7 +9916,6 @@ msgid "-dumpbase \tSet the file basename to be used for dumps" msgstr "-dumpbase \tAnge basfilnamn att användas för dumpar" #: common.opt:258 -#, fuzzy msgid "-dumpdir \tSet the directory name to be used for dumps" msgstr "-dumpdir \tAnge katalognamn att användas för dumpar" @@ -12495,9 +12488,9 @@ msgid "%qE undeclared (first use in this function)" msgstr "%qE är odeklarerad (första förekomsten i denna funktion)" #: c-decl.c:2954 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "each undeclared identifier is reported only once for each function it appears in" -msgstr "(Varje odeklarerad identifierare rapporteras bara en gång" +msgstr "varje odeklarerad identifierare rapporteras bara en gång för varje funktion den förekommer i" #: c-decl.c:3004 cp/decl.c:2446 #, gcc-internal-format @@ -15198,9 +15191,9 @@ msgid "function with qualified void return type called" msgstr "funktion med kvalificerad void-returtyp anropad" #: c-typeck.c:2820 c-typeck.c:3047 cp/typeck.c:3315 cp/typeck.c:3429 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "declared here" -msgstr "%qD är deklarerad här" +msgstr "deklarerad här" #: c-typeck.c:2855 #, gcc-internal-format @@ -16768,7 +16761,7 @@ msgstr "DW_LOC_OP %s #: dwarf2out.c:12859 #, gcc-internal-format msgid "non-delegitimized UNSPEC %d found in variable location" -msgstr "" +msgstr "odelegitimerad UNSPEC %d funnen på variabelplats" #: emit-rtl.c:2460 #, gcc-internal-format @@ -19345,12 +19338,12 @@ msgstr "Trasig v #: var-tracking.c:6051 #, gcc-internal-format msgid "variable tracking size limit exceeded with -fvar-tracking-assignments, retrying without" -msgstr "" +msgstr "storleksgräns på variabelspårning överskriden med -vfar-tracking-assignments, försöker igen utan" #: var-tracking.c:6055 #, gcc-internal-format msgid "variable tracking size limit exceeded" -msgstr "" +msgstr "storleksgräns på variabelspårning överskriden" #: varasm.c:580 #, gcc-internal-format @@ -19716,9 +19709,9 @@ msgid "bad value %qs for -mcpu switch" msgstr "felaktigt värde %qs till flaggan -mcpu" #: config/alpha/alpha.c:391 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "bad value %qs for -mtune switch" -msgstr "felaktigt värde %qs till flaggan -mcpu" +msgstr "felaktigt värde %qs till flaggan -mtune" #: config/alpha/alpha.c:398 #, gcc-internal-format @@ -23401,24 +23394,24 @@ msgid "cannot convert %qE from type %qT to type %qT" msgstr "kan inte konvertera %qE från typ %qT till typ %qT" #: cp/cvt.c:371 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of volatile reference type %q#T from rvalue of type %qT" -msgstr "ogiltig initiering av icke konstant referens av typ %qT från ett r-värde av typ %qT" +msgstr "initiering av volatile referens av typ %q#T från ett r-värde av typ %qT" #: cp/cvt.c:374 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to volatile reference type %q#T from rvalue of type %qT" -msgstr "ogiltig initiering av icke konstant referens av typ %qT från ett r-värde av typ %qT" +msgstr "konvertering till volatile referens av typ %q#T från ett r-värde av typ %qT" #: cp/cvt.c:377 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "initialization of non-const reference type %q#T from rvalue of type %qT" -msgstr "ogiltig initiering av icke konstant referens av typ %qT från ett r-värde av typ %qT" +msgstr "initiering av icke konstant referens av typ %q#T från ett r-värde av typ %qT" #: cp/cvt.c:380 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conversion to non-const reference type %q#T from rvalue of type %qT" -msgstr "ogiltig initiering av icke konstant referens av typ %qT från ett r-värde av typ %qT" +msgstr "konvertering till icke konstant referens av typ %q#T från ett r-värde av typ %qT" #: cp/cvt.c:453 #, gcc-internal-format @@ -25573,9 +25566,9 @@ msgid "%qD is already defined in %qT" msgstr "%qD är redan definierad i %qT" #: cp/decl2.c:917 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid initializer for member function %qD" -msgstr "ogiltigt startvärde för medlem %qE" +msgstr "ogiltigt initierare för medlemsfunktion %qD" #: cp/decl2.c:923 #, gcc-internal-format @@ -25706,7 +25699,7 @@ msgstr "standardargumentet saknas f #: cp/decl2.c:4017 #, gcc-internal-format msgid "converting lambda which uses %<...%> to function pointer" -msgstr "" +msgstr "konverterar lambda som använder %<...%> till funktionspekare" #: cp/decl2.c:4022 cp/search.c:1892 #, gcc-internal-format @@ -26217,7 +26210,7 @@ msgstr "det manglade namnet f #: cp/mangle.c:3071 #, gcc-internal-format msgid "-fabi-version=4 (or =0) avoids this error with a change in vector mangling" -msgstr "" +msgstr "-fabi-version=4 (eller =0) undviker detta fel med en ändring av vektormanglingen" #: cp/method.c:396 #, gcc-internal-format @@ -26275,9 +26268,9 @@ msgid "function %q+D defaulted on its first declaration must not have an excepti msgstr "funktion %q+D med standardvärde i sin första deklaration får inte a en undantagsspecifikation" #: cp/method.c:1081 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qD declared virtual cannot be defaulted in the class body" -msgstr "%qD deklarerad explicit kan inte få standardvärde i klasskroppen" +msgstr "%qD deklarerad virtuell kan inte få standardvärde i klasskroppen" #: cp/method.c:1130 #, gcc-internal-format @@ -26721,14 +26714,14 @@ msgid "typedef-name %qD used as destructor declarator" msgstr "typedef-namnet %qD använt som destruerardeklarerare" #: cp/parser.c:4552 cp/parser.c:6165 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in casts" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i typkonverteringar" #: cp/parser.c:4615 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a % expression" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i ett %-uttryck" #. Warn the user that a compound literal is not #. allowed in standard C++. @@ -26758,9 +26751,9 @@ msgid "try removing the parentheses around the type-id" msgstr "försök ta bort parenteserna runt typ-id:t" #: cp/parser.c:5852 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in a new-type-id" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i en new-type-id" #: cp/parser.c:5976 #, gcc-internal-format @@ -26813,9 +26806,9 @@ msgid "%<%T::%D%> names the constructor, not the type" msgstr "%<%T::%D%> namnger konstrueraren, inte typen" #: cp/parser.c:8113 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in conditions" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i villkor" #. Issue a warning about this use of a GNU extension. #: cp/parser.c:8462 @@ -26861,9 +26854,9 @@ msgid "templates may not be %" msgstr "mallar får inte vara %" #: cp/parser.c:9523 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in % expressions" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i %-uttryck" #: cp/parser.c:9778 #, gcc-internal-format @@ -27038,9 +27031,9 @@ msgid "invalid use of %" msgstr "ogiltigt användning av %" #: cp/parser.c:15039 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in parameter types" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i parametertyper" #: cp/parser.c:15257 #, gcc-internal-format @@ -27123,14 +27116,14 @@ msgid "keyword % not allowed in this context (the base class is impli msgstr "nyckelordet % är inte tillåtet i detta sammanhang (basklassen är implicit en typ)" #: cp/parser.c:17229 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in an exception-specification" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i en undantagsspecifikation" #: cp/parser.c:17410 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "types may not be defined in exception-declarations" -msgstr "nya typer får inte definieras i en returtyp" +msgstr "typer får inte definieras i undantagsdeklarationer" #: cp/parser.c:18303 #, gcc-internal-format @@ -27489,10 +27482,10 @@ msgid "template argument %qE involves template parameter(s)" msgstr "mallargument %qE berör mallparametrar" #: cp/pt.c:4022 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qT of template argument %qE depends on a template parameter" msgid_plural "type %qT of template argument %qE depends on template parameters" -msgstr[0] "typ %qT för mallargument %qE beror på mallparametrar" +msgstr[0] "typ %qT för mallargument %qE beror på en mallparameter" msgstr[1] "typ %qT för mallargument %qE beror på mallparametrar" #: cp/pt.c:4129 @@ -27511,29 +27504,29 @@ msgid "parameter pack %qT must be at the end of the template parameter list" msgstr "parameterpaket %qT måste vara vid slutet av mallens parameterlista" #: cp/pt.c:4190 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend re-declaration" -msgstr "standardargument är inte tillåtna i deklaration av vänmallspecialisering %qD" +msgstr "standardmallargument får inte användas i vänomdeklaration av funktionsmall" #: cp/pt.c:4193 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function template friend declarations" -msgstr "standardargument är inte tillåtna i deklaration av vänmallspecialisering %qD" +msgstr "standardmallargument får inte användas i vändeklarationer funktionsmallar" #: cp/pt.c:4196 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in function templates without -std=c++0x or -std=gnu++0x" -msgstr "standardvärda och raderade funktioner är endast tillgängliga med -std=c++0x eller -std=gnu++0x" +msgstr "standarmallargument får inte användas i funktionsmallar utan -std=c++0x eller -std=gnu++0x" #: cp/pt.c:4199 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default template arguments may not be used in partial specializations" -msgstr "mallparameter används inte i partiell specialisering:" +msgstr "standardmallargument får inte används inte i partiella specialiseringar" #: cp/pt.c:4202 cp/pt.c:4253 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "default argument for template parameter for class enclosing %qD" -msgstr "standardargumentet för parameter av typen %qT har typen %qT" +msgstr "standardargumentet för mallparameter för klass om omsluter %qD" #: cp/pt.c:4346 #, gcc-internal-format @@ -27604,17 +27597,17 @@ msgid "template specifiers not specified in declaration of %qD" msgstr "mallspecificerare inte angivna i deklarationen av %qD" #: cp/pt.c:4693 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "redeclared with %d template parameter" msgid_plural "redeclared with %d template parameters" -msgstr[0] "omdeklarerad utan %d mallparametrar" -msgstr[1] "omdeklarerad utan %d mallparametrar" +msgstr[0] "omdeklarerad med %d mallparameter" +msgstr[1] "omdeklarerad med %d mallparametrar" #: cp/pt.c:4697 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration %q+D used %d template parameter" msgid_plural "previous declaration %q+D used %d template parameters" -msgstr[0] "tidigare deklaration av %q+D använde %d mallparametrar" +msgstr[0] "tidigare deklaration av %q+D använde %d mallparameter" msgstr[1] "tidigare deklaration av %q+D använde %d mallparametrar" #: cp/pt.c:4734 @@ -27829,9 +27822,9 @@ msgid "for template declaration %q+D" msgstr "för malldeklaration %q+D" #: cp/pt.c:7060 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d (use -ftemplate-depth= to increase the maximum) instantiating %qD" -msgstr "mallinstansieringsdjupet överskrider maxvärdet på %d (använd -ftemplate-depth-NN för att öka maxvärdet) vid instansiering av %qD" +msgstr "mallinstansieringsdjupet överskrider maxvärdet på %d (använd -ftemplate-depth= för att öka maxvärdet) vid instansiering av %qD" #: cp/pt.c:8326 #, gcc-internal-format @@ -28114,9 +28107,9 @@ msgid "explicit instantiation of %qD but no definition available" msgstr "explicit instansiering av %qD men ingen definition tillgänglig" #: cp/pt.c:16910 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "template instantiation depth exceeds maximum of %d instantiating %q+D, possibly from virtual table generation (use -ftemplate-depth= to increase the maximum)" -msgstr "mallinstansieringsdjupet överskrider maxvärdet på %d vid instansiering av %qD, möjligen från generering av virtuell tabell (använd -ftemplate-depth-NN för att öka maxvärdet)" +msgstr "mallinstansieringsdjupet överskrider maxvärdet på %d vid instansiering av %q+D, möjligen från generering av virtuell tabell (använd -ftemplate-depth= för att öka maxvärdet)" #: cp/pt.c:17265 #, gcc-internal-format @@ -28129,9 +28122,9 @@ msgid "deducing from brace-enclosed initializer list requires #include " #: cp/pt.c:18315 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "variable %q#D with % type used in its own initializer" -msgstr "variabeln %D av typen % måste vara oinitierad" +msgstr "variabeln %q#D av med %-typ använd i sin egen initierare" #: cp/pt.c:18337 #, gcc-internal-format @@ -28842,10 +28835,11 @@ msgstr "man m msgid "%qE cannot be used as a function" msgstr "%qE kan inte användas som en funktion" +# Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40883 #: cp/typeck.c:3312 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too many arguments to %s %q#D" -msgstr "för många argument till %s %+#D" +msgstr "för många argument till %s %#D" #: cp/typeck.c:3318 #, gcc-internal-format @@ -28862,10 +28856,11 @@ msgstr "parameter %P till %qD har ofullst msgid "parameter %P has incomplete type %qT" msgstr "parametern %P har ofullständig typ %qT" +# Felrapporterat: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40883 #: cp/typeck.c:3426 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "too few arguments to %s %q#D" -msgstr "för få argument till %s %q+#D" +msgstr "för få argument till %s %q#D" #: cp/typeck.c:3432 #, gcc-internal-format @@ -28945,14 +28940,14 @@ msgid "invalid use of a pointer to an incomplete type in pointer arithmetic" msgstr "ogiltig användning av en pekare till en ofullständig typ i pekararitmetik" #: cp/typeck.c:4510 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "taking address of constructor %qE" -msgstr "tar adress till något temporärt" +msgstr "tar adressen till konstrueraren %qE" #: cp/typeck.c:4511 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "taking address of destructor %qE" -msgstr "tar adress till något temporärt" +msgstr "tar adressen till destrueraren %qE" #: cp/typeck.c:4525 #, gcc-internal-format @@ -29061,19 +29056,19 @@ msgid "no context to resolve type of %qE" msgstr "ingen kontext för att lösa upp typen på %qE" #: cp/typeck.c:5481 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cast from type %qT to type %qT casts away qualifiers" -msgstr "konvertering från typ %qT till typ %qT slänger bort konstanthet" +msgstr "konvertering från typ %qT till typ %qT slänger bort kvalificerare" #: cp/typeck.c:5486 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "static_cast from type %qT to type %qT casts away qualifiers" -msgstr "static_cast från typ %qT till typ %qT slänger bort konstanthet" +msgstr "static_cast från typ %qT till typ %qT slänger bort kvalificerare" #: cp/typeck.c:5491 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "reinterpret_cast from type %qT to type %qT casts away qualifiers" -msgstr "reinterpret_cast från typ %qT till typ %qT slänger bort konstanthet" +msgstr "reinterpret_cast från typ %qT till typ %qT slänger bort kvalificerare" #: cp/typeck.c:5834 #, gcc-internal-format @@ -29273,9 +29268,9 @@ msgid "type %qT is not a base type for type %qT" msgstr "typen %qT är inte en bastyp för typen %qT" #: cp/typeck2.c:106 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment of data-member %qD in read-only structure" -msgstr "privat medlem %q+#D i anonym post" +msgstr "tilldelning av datamedlem %qD i endast läsbar post" #: cp/typeck2.c:108 #, gcc-internal-format @@ -29283,39 +29278,39 @@ msgid "assignment (via 'asm' output) of data-member %qD in read-only structure" msgstr "tilldelning (via \"asm\"-utdata) av datamedlem %qD i endast läsbar post" #: cp/typeck2.c:110 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "increment of data-member %qD in read-only structure" -msgstr "ökning av pekare på okänd post" +msgstr "ökning av datamedlem %qD i endast läsbar post" #: cp/typeck2.c:112 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "decrement of data-member %qD in read-only structure" -msgstr "minskning av pekare på okänd post" +msgstr "minskning av datamedlem %qD i endast läsbar post" #: cp/typeck2.c:116 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment of read-only data-member %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning till endast läsbar datamedlem %qD" #: cp/typeck2.c:118 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment (via 'asm' output) of read-only data-member %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning (via \"asm\"-utdata) till endast läsbar datamedlem %qD" #: cp/typeck2.c:120 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "increment of read-only data-member %qD" -msgstr "ökning av endast läsbar medlem %qD" +msgstr "ökning av endast läsbar datamedlem %qD" #: cp/typeck2.c:122 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "decrement of read-only data-member %qD" -msgstr "minskning av endast läsbar medlem %qD" +msgstr "minskning av endast läsbar datamedlem %qD" #: cp/typeck2.c:131 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment of constant field %qD" -msgstr "tilldelning till endast läsbar variabel %qD" +msgstr "tilldelning till konstant fält %qD" #: cp/typeck2.c:133 #, gcc-internal-format @@ -29323,59 +29318,59 @@ msgid "assignment (via 'asm' output) of constant field %qD" msgstr "tilldelning (via \"asm\"-utdata) av konstant fält %qD" #: cp/typeck2.c:135 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "increment of constant field %qD" -msgstr "ökning av endast läsbar variabel %qD" +msgstr "ökning av konstant fält %qD" #: cp/typeck2.c:137 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "decrement of constant field %qD" -msgstr "minskning av endast läsbar variabel %qD" +msgstr "minskning av konstant fält %qD" #: cp/typeck2.c:143 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment (via 'asm' output) of read-only variable %qD" -msgstr "tilldelning till endast läsbar variabel %qD" +msgstr "tilldelning (via \"asm\"-utdata) till endast läsbar variabel %qD" #: cp/typeck2.c:153 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment of read-only parameter %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning till endast läsbar parameter %qD" #: cp/typeck2.c:155 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment (via 'asm' output) of read-only parameter %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning (via \"asm\"-utdata) till endast läsbar parameter %qD" #: cp/typeck2.c:157 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "increment of read-only parameter %qD" -msgstr "ökning av endast läsbar medlem %qD" +msgstr "ökning av endast läsbar parameter %qD" #: cp/typeck2.c:159 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "decrement of read-only parameter %qD" -msgstr "minskning av endast läsbar medlem %qD" +msgstr "minskning av endast läsbar parameter %qD" #: cp/typeck2.c:166 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment of read-only reference %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning till endast läsbar referens %qD" #: cp/typeck2.c:168 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment (via 'asm' output) of read-only reference %qD" -msgstr "tilldelning till endast läsbar medlem %qD" +msgstr "tilldelning (via \"asm\"-utdata) till endast läsbar referens %qD" #: cp/typeck2.c:170 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "increment of read-only reference %qD" -msgstr "ökning av endast läsbar medlem %qD" +msgstr "ökning av endast läsbar referens %qD" #: cp/typeck2.c:172 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "decrement of read-only reference %qD" -msgstr "minskning av endast läsbar medlem %qD" +msgstr "minskning av endast läsbar referens %qD" #: cp/typeck2.c:176 #, gcc-internal-format @@ -29418,9 +29413,9 @@ msgid "decrement of function %qD" msgstr "minskning av funktion %qD" #: cp/typeck2.c:198 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "assignment (via 'asm' output) of read-only location %qE" -msgstr "tilldelning till endast läsbar plats %qE" +msgstr "tilldelning (via \"asm\"-utdata) till endast läsbar plats %qE" #: cp/typeck2.c:384 #, gcc-internal-format @@ -29464,9 +29459,9 @@ msgid "cannot allocate an object of abstract type %qT" msgstr "det går inte att allokera ett objekt av abstrakt typ %qT" #: cp/typeck2.c:413 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid " because the following virtual functions are pure within %qT:" -msgstr "%J för följande virtuella funktioner är rena inuti %qT:" +msgstr " för följande virtuella funktioner är rena inuti %qT:" #: cp/typeck2.c:417 #, gcc-internal-format @@ -29474,34 +29469,34 @@ msgid "\t%+#D" msgstr "\t%+#D" #: cp/typeck2.c:425 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid " since type %qT has pure virtual functions" -msgstr "%J eftersom typen %qT har rent virtuella funktioner" +msgstr " eftersom typen %qT har rent virtuella funktioner" #: cp/typeck2.c:455 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%q+D has incomplete type" -msgstr "%qD har en ofullständig typ" +msgstr "%q+D har en ofullständig typ" #: cp/typeck2.c:468 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid use of incomplete type %q#T" -msgstr "ogiltig användning av ofullständig typedef %qD" +msgstr "ogiltig användning av ofullständig typ %q#T" #: cp/typeck2.c:471 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "forward declaration of %q+#T" -msgstr "deklaration av %q+#D" +msgstr "framåtdeklaration av %q+#T" #: cp/typeck2.c:474 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "declaration of %q+#T" -msgstr "deklaration av %q+#D" +msgstr "deklaration av %q+#T" #: cp/typeck2.c:479 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid use of %qT" -msgstr "ogiltigt användning av %qD" +msgstr "ogiltigt användning av %qT" #: cp/typeck2.c:495 #, gcc-internal-format @@ -29509,19 +29504,19 @@ msgid "invalid use of member (did you forget the %<&%> ?)" msgstr "ogiltig användning av medlem (glömde du %<&%>?)" #: cp/typeck2.c:504 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid use of template type parameter %qT" -msgstr "ogiltig användning av ofullständig typedef %qD" +msgstr "ogiltig användning av malltypparameter %qT" #: cp/typeck2.c:509 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid use of template template parameter %qT" -msgstr "ogiltigt standardargument för en mallmallparameter" +msgstr "ogiltigt standardargument för mallmallparameter %qT" #: cp/typeck2.c:515 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid use of dependent type %qT" -msgstr "ogiltig användning av ofullständig typedef %qD" +msgstr "ogiltig användning av beroende typ %qT" #: cp/typeck2.c:523 #, gcc-internal-format @@ -30072,9 +30067,9 @@ msgid "the '%s' and '%s' arguments of '%s' intrinsic at %L must be of the same k msgstr "\"%s\"- och \"%s\"-argumenten till inbyggd \"%s\" vid %L måste ha samma sort %d/%d" #: fortran/check.c:2289 fortran/check.c:3244 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "'%s' argument of '%s' intrinsic at %L must provide at least as many elements as there are .TRUE. values in '%s' (%ld/%d)" -msgstr "\"%s\"-argumentet till inbyggd \"%s\" vid %L ge åtminstone lika många element som det finns .TRUE.-värden i \"%s\" (%ld/%ld)" +msgstr "\"%s\"-argumentet till inbyggd \"%s\" vid %L måste ge åtminstone lika många element som det finns .TRUE.-värden i \"%s\" (%ld/%d)" #: fortran/check.c:2314 #, gcc-internal-format @@ -30628,9 +30623,9 @@ msgid "%s attribute at %L is not allowed outside of the specification part of a msgstr "%s-attribut vid %L är inte tillåtet utanför specifikationsdelen av en modul" #: fortran/decl.c:3198 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Fortran 2003: ASYNCHRONOUS attribute at %C" -msgstr "Fortran 2003: VALUE-attribut vid %C" +msgstr "Fortran 2003: ASYNCHRONOUS-attribut vid %C" #: fortran/decl.c:3244 fortran/decl.c:6119 #, gcc-internal-format @@ -31140,14 +31135,14 @@ msgid "Syntax error in VOLATILE statement at %C" msgstr "Syntaxfel i VOLATILE-sats vid %C" #: fortran/decl.c:6527 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Fortran 2003: ASYNCHRONOUS statement at %C" -msgstr "Fortran 2003: CLASS-sats vid %C" +msgstr "Fortran 2003: ASYNCHRONOUS-sats vid %C" #: fortran/decl.c:6569 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Syntax error in ASYNCHRONOUS statement at %C" -msgstr "Syntaxfel i VALUE-sats vid %C" +msgstr "Syntaxfel i ASYNCHRONOUS-sats vid %C" #: fortran/decl.c:6592 #, gcc-internal-format @@ -31422,9 +31417,9 @@ msgid "Empty FINAL at %C" msgstr "Tom FINAL vid %C" #: fortran/decl.c:7857 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Expected module procedure name at %C" -msgstr "Modulprocedurnamn förväntades vid %L" +msgstr "Modulprocedurnamn förväntades vid %C" #: fortran/decl.c:7867 #, gcc-internal-format @@ -31532,9 +31527,9 @@ msgid "Numeric operands are required in expression at %L" msgstr "Numeriska operander krävs i uttryck vid %L" #: fortran/expr.c:2076 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid initialization expression for ALLOCATABLE component '%s' in structure constructor at %L" -msgstr "Ingen initierare för komponent \"%s\" angiven i postkonstrueraren vid %C!" +msgstr "Ogiltigt initieringsuttryck för ALLOCATABLE-komponent \"%s\" i postkonstrueraren vid %L" #: fortran/expr.c:2173 #, gcc-internal-format @@ -31552,9 +31547,9 @@ msgid "Extension: Evaluation of nonstandard initialization expression at %L" msgstr "Utökning: Beräkning av ett initieringuttryck utanför standarden vid %L" #: fortran/expr.c:2318 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Function '%s' in initialization expression at %L must be an intrinsic function" -msgstr "Funktionen \"%s\" i initieringsuttrycket vid %L måste vara en inbyggd eller en specifikationsfunktion" +msgstr "Funktionen \"%s\" i initieringsuttrycket vid %L måste vara en inbyggd funktion" #: fortran/expr.c:2330 #, gcc-internal-format @@ -31847,9 +31842,9 @@ msgid "Dummy procedure '%s' at %C cannot have a generic interface" msgstr "Attrapprocedur \"%s\" vid %C kan inte ha generiskt gränssnitt" #: fortran/interface.c:254 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Fortran 2003: ABSTRACT INTERFACE at %C" -msgstr "Fortran 2003: ABSTRACT INTERFACE vid %L" +msgstr "Fortran 2003: ABSTRACT INTERFACE vid %C" #: fortran/interface.c:262 #, gcc-internal-format @@ -31957,9 +31952,9 @@ msgid "Ambiguous interfaces '%s' and '%s' in %s at %L" msgstr "Tvetydiga gränssnitt \"%s\" och \"%s\" i %s vid %L" #: fortran/interface.c:1144 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Although not referenced, '%s' has ambiguous interfaces at %L" -msgstr "Även om den inte refereras har \"%s\" vid %L tvetydiga gränssnitt" +msgstr "Fast orefererad har \"%s\" tvetydiga gränssnitt vid %L" #: fortran/interface.c:1178 #, gcc-internal-format @@ -32132,9 +32127,9 @@ msgid "Procedure '%s' called with an implicit interface at %L" msgstr "Procedur \"%s\" anropad med ett implicit gränssnitt vid %L" #: fortran/interface.c:2395 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Procedure '%s' called at %L is not explicitly declared" -msgstr "Proceduren \"%s\" i %s vid %L har inget explicit gränssnitt" +msgstr "Proceduren \"%s\" anropad vid %L är inte explicit deklarerad" #: fortran/interface.c:2407 #, gcc-internal-format @@ -32929,9 +32924,9 @@ msgid "Allocate-object at %C is not a nonprocedure pointer or an allocatable var msgstr "Allokeringsobjekt vid %C är inte en pekare på annat än procedur eller en allokerbar variabel" #: fortran/match.c:2507 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Shape specification for allocatable scalar at %C" -msgstr "Felaktig specifikation för vektor med förmodad storlek vid %C" +msgstr "Formspecifikation för allokerbar skalär vid %C" #: fortran/match.c:2524 fortran/match.c:2778 #, gcc-internal-format @@ -33353,9 +33348,9 @@ msgid "Fortran 2003: ISO_FORTRAN_ENV intrinsic module at %C" msgstr "Fortran 2003: inbyggd modul ISO_FORTRAN_ENV vid %C" #: fortran/module.c:5484 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Fortran 2003: ISO_C_BINDING module at %C" -msgstr "Fortran 2003: ISO_C_BINDING-modul vid %L" +msgstr "Fortran 2003: ISO_C_BINDING-modul vid %C" #: fortran/module.c:5494 #, gcc-internal-format @@ -33383,9 +33378,9 @@ msgid "Parse error when checking module version for file '%s' opened at %C" msgstr "Tolkningsfel vid kontroll av modulversion för filen \"%s\" öppnad vid %C" #: fortran/module.c:5539 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Wrong module version '%s' (expected '%s') for file '%s' opened at %C" -msgstr "Fel modulversion \"%s\" (\"%s\" förväntades) för fil \"%s\" öppnad vid %C" +msgstr "Fel modulversion \"%s\" (\"%s\" förväntades) för filen \"%s\" öppnad vid %C" #: fortran/module.c:5552 #, gcc-internal-format @@ -34537,9 +34532,9 @@ msgid "The element in the derived type constructor at %L, for pointer component msgstr "Elementet i den härledda typkonstrueraren vid %L, för pekarkomponent \"%s\", borde vara en POINTER eller en TARGET" #: fortran/resolve.c:930 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid expression in the derived type constructor for pointer component '%s' at %L in PURE procedure" -msgstr "Elementet i den härledda typkonstrueraren vid %L, för pekarkomponent \"%s\", är %s men borde vara %s" +msgstr "Ogiltigt uttryck i den härledda typkonstrueraren för pekarkomponent \"%s\" vidl %L i PURE-procedur" #: fortran/resolve.c:1052 #, gcc-internal-format @@ -34647,9 +34642,9 @@ msgid "The reference to function '%s' at %L either needs an explicit INTERFACE o msgstr "Referensen till funktionen \"%s\" vid %L behöver antingen ett explicit INTERFACE eller så är ordningen fel" #: fortran/resolve.c:1862 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Nonconstant character-length function '%s' at %L must have an explicit interface" -msgstr "Automatisk teckenlängdsfunktion \"%s\" vid %L måste ha explicit gränssnitt" +msgstr "Ej konstant teckenlängdsfunktion \"%s\" vid %L måste ha ett explicit gränssnitt" #: fortran/resolve.c:1964 #, gcc-internal-format @@ -34982,9 +34977,9 @@ msgid "Base object for type-bound procedure call at %L is of ABSTRACT type '%s'" msgstr "Basobjekt för typbundet proceduranrop vid %L är av ABSTRACT typ \"%s\"" #: fortran/resolve.c:4929 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Base object for NOPASS type-bound procedure call at %L must be scalar" -msgstr "Basobjekt för typbundet proceduranrop vid %L är av ABSTRACT typ \"%s\"" +msgstr "Basobjekt för typbundet NOPASS-proceduranrop vid %L måste vara skalärt" #: fortran/resolve.c:4937 #, gcc-internal-format @@ -35427,7 +35422,7 @@ msgstr "Bindning av etikett \"%s\" vid %L kolliderar med global entitet \"%s\" v #: fortran/resolve.c:8587 #, gcc-internal-format msgid "CHARACTER variable at %L has negative length %d, the length has been set to zero" -msgstr "" +msgstr "CHARACTER-variabel vid %L har negativ längd %d, längden har satts till noll" #: fortran/resolve.c:8599 #, gcc-internal-format @@ -35462,7 +35457,7 @@ msgstr "Typen \"%s\" kan inte vara v #: fortran/resolve.c:8964 #, gcc-internal-format msgid "Fortran 2008: Implied SAVE for module variable '%s' at %L, needed due to the default initialization" -msgstr "" +msgstr "Fortran 2008: Implicerad SAVE för modulvariabel \"%s\" vid %L, behövs på grund av standardinitieringar" #: fortran/resolve.c:8975 #, gcc-internal-format @@ -35793,19 +35788,19 @@ msgid "Argument '%s' of '%s' with PASS(%s) at %L must be of the derived-type '%s msgstr "Argument \"%s\" till \"%s\" med PASS(%s) vid %L måste ha den härledda typen \"%s\"" #: fortran/resolve.c:10174 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Passed-object dummy argument of '%s' at %L must be scalar" -msgstr "Skickat objekt vid %L måste vara skalär" +msgstr "Skickat objekt-attrappargument till \"%s\" vid %L måste vara skalärt" #: fortran/resolve.c:10180 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Passed-object dummy argument of '%s' at %L must not be ALLOCATABLE" -msgstr "\"%s\"-argumentet till inbyggd \"%s\" vid %L måste vara ALLOCATABLE" +msgstr "Skickat objekt-attrappargument till \"%s\" vid %L får inte vara ALLOCATABLE" #: fortran/resolve.c:10186 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Passed-object dummy argument of '%s' at %L must not be POINTER" -msgstr "\"%s\"-argumentet till inbyggd \"%s\" vid %L måste vara POINTER" +msgstr "Skickat objekt-atrappargument till \"%s\" vid %L får inte vara POINTER" #: fortran/resolve.c:10212 #, gcc-internal-format @@ -36621,9 +36616,9 @@ msgid "Duplicate VOLATILE attribute specified at %L" msgstr "Dubblerat VOLATILE-attribut angivet vid %L" #: fortran/symbol.c:1122 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Duplicate ASYNCHRONOUS attribute specified at %L" -msgstr "Dubblerat VALUE-attribut angivet vid %L" +msgstr "Dubblerat ASYNCHRONOUS-attribut angivet vid %L" #: fortran/symbol.c:1413 #, gcc-internal-format @@ -37012,9 +37007,9 @@ msgid "Bad IO basetype (%d)" msgstr "Felaktig IO-bastyp (%d)" #: fortran/trans-openmp.c:1643 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "gfc_trans_omp_workshare(): Bad statement code" -msgstr "gfc_trans_code(): Felaktig satskod" +msgstr "gfc_trans_omp_workshare(): Felaktig satskod" #: fortran/trans-stmt.c:513 #, gcc-internal-format @@ -37067,9 +37062,9 @@ msgid "ConstantValue attribute of field '%s' has wrong type" msgstr "attributet ConstantValue på fältet \"%s\" har fel typ" #: java/class.c:1613 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "abstract method in non-abstract class" -msgstr "%Jabstrakt metod i icke-abstrakt klass" +msgstr "abstrakt metod i icke-abstrakt klass" #: java/class.c:2689 #, gcc-internal-format @@ -37244,9 +37239,9 @@ msgid "error while parsing final attributes" msgstr "fel vid tolkning av slutliga attribut" #: java/jcf-parse.c:1509 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "duplicate class will only be compiled once" -msgstr "%Hdubblerad klass kommer endast att kompileras en gång" +msgstr "dubblerad klass kommer endast att kompileras en gång" #: java/jcf-parse.c:1604 #, gcc-internal-format @@ -37329,14 +37324,14 @@ msgid "bad pc in exception_table" msgstr "felaktig pc i exception_table" #: lto/lto-elf.c:114 lto/lto-elf.c:135 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not read section header: %s" -msgstr "kunde inte hitta specs-filen %s\n" +msgstr "det gick inte att läsa sektionshuvud %s" #: lto/lto-elf.c:234 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "two or more sections for %s:" -msgstr "två eller fler datatyper i deklaration av %qs" +msgstr "två eller flera sektioner för %s" #. Initialize the section header of section SCN. SH_NAME is the section name #. as an index into the section header string table. SH_TYPE is the section @@ -37352,14 +37347,14 @@ msgid "elf64_getshdr() failed: %s" msgstr "elf64_getshdr() misslyckades: %s" #: lto/lto-elf.c:295 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not create a new ELF section: %s" -msgstr "kunde inte konvertera mallargument %qE till %qT" +msgstr "det gick inte att skapa en ny ELF-sektion: %s" #: lto/lto-elf.c:349 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not append data to ELF section: %s" -msgstr "kunde inte öppna dump-fil %qs: %s" +msgstr "det gick inte att lägga till data till ELF-sektion: %s" #. Validate's ELF_FILE's executable header and, if cached_file_attrs is #. uninitialized, caches the architecture. @@ -37389,9 +37384,9 @@ msgid "unsupported ELF file class" msgstr "ej stödd ELF-filklass" #: lto/lto-elf.c:525 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not locate ELF string table: %s" -msgstr "det gick inte att stänga svarsfilen %s" +msgstr "det gick inte att hitta ELF-strängtabellen: %s" #. Helper functions used by init_ehdr. Initialize ELF_FILE's executable #. header using cached data from previously read files. @@ -37406,9 +37401,9 @@ msgid "elf64_newehdr() failed: %s" msgstr "elf64_newehdr() misslyckades: %s" #: lto/lto-elf.c:635 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not open file %s" -msgstr "det gick inte att öppna svarsfilen %s" +msgstr "det gick inte att öppna filen %s" #: lto/lto-elf.c:642 #, gcc-internal-format @@ -37416,19 +37411,19 @@ msgid "ELF library is older than that used when building GCC" msgstr "ELF-biblioteket är äldre än det som användes när GCC byggdes" #: lto/lto-elf.c:651 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not open ELF file: %s" -msgstr "kunde inte öppna dump-fil %qs: %s" +msgstr "det gick inte att öppna ELF-filen: %s" #: lto/lto-elf.c:661 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not seek in archive" -msgstr "gick inte att dela instruktion" +msgstr "det gick inte att söka i arkivet" #: lto/lto-elf.c:668 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not find archive member" -msgstr "kunde inte hitta något spillregister" +msgstr "det gick inte att hitta arkivmedlem" #: lto/lto-elf.c:716 #, gcc-internal-format @@ -37436,9 +37431,9 @@ msgid "gelf_getehdr() failed: %s" msgstr "gelf_getehdr() misslyckades: %s" #: lto/lto-elf.c:725 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "elf_getscn() failed: %s" -msgstr "verifiering misslyckades: %s" +msgstr "elf_getscn() misslyckades: %s" #: lto/lto-elf.c:728 #, gcc-internal-format @@ -37456,9 +37451,9 @@ msgid "gelf_update_ehdr() failed: %s" msgstr "gelf_update_ehdr() misslyckades: %s" #: lto/lto-elf.c:743 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "elf_update() failed: %s" -msgstr "verifiering misslyckades: %s" +msgstr "elf_update() misslyckades: %s" #: lto/lto-lang.c:659 #, gcc-internal-format @@ -37476,29 +37471,29 @@ msgid "could not parse hex number" msgstr "kunde inte tolka hexadecimalt tal" #: lto/lto.c:308 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "unexpected file name %s in linker resolution file. Expected %s" -msgstr "kvalificerat namn förväntades i vändeklaration för destruerare %qD" +msgstr "oväntat filnamn %s i länkupplösningsfilen. %s förväntades" #: lto/lto.c:317 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not parse file offset" -msgstr "det gick inte att öppna svarsfilen %s" +msgstr "det gick inte tolka filavstånd" #: lto/lto.c:320 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "unexpected offset" -msgstr "oväntad operand" +msgstr "oväntat avstånd" #: lto/lto.c:339 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid line in the resolution file." -msgstr "ogiltigt register i instruktionen" +msgstr "Ogiltig rad i upplösningsfilen." #: lto/lto.c:352 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "Invalid resolution in the resolution file." -msgstr "ogiltigt register i instruktionen" +msgstr "Ogiltig upplösning i upplösningsfilen." #: lto/lto.c:1049 #, gcc-internal-format @@ -37506,14 +37501,14 @@ msgid "lto_elf_file_open() failed" msgstr "lto_elf_file_open() misslyckades" #: lto/lto.c:1109 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "environment variable COLLECT_GCC must be set" -msgstr "omgivningsvariabeln DJGPP är inte definierad" +msgstr "miljövariabeln COLLECT_GCC måste vara satt" #: lto/lto.c:1114 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "environment variable COLLECT_GCC_OPTIONS must be set" -msgstr "omgivningsvariabeln DJGPP är inte definierad" +msgstr "miljövariabeln COLLECT_GCC_OPTIONS måste vara satt" #: lto/lto.c:1123 #, gcc-internal-format @@ -37521,44 +37516,44 @@ msgid "malformed COLLECT_GCC_OPTIONS" msgstr "felformaterad COLLECT_GCC_OPTIONS" #: lto/lto.c:1169 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "opening LTRANS output list %s: %m" -msgstr "vid öppnandet av utdatafil %s: %m" +msgstr "när LTRANS-utdatafil %s öppnades: %m" #: lto/lto.c:1187 lto/lto.c:1209 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "writing to LTRANS output list %s: %m" -msgstr "när utdata skrevs till %s: %m" +msgstr "när utdata skrevs till LTRANS-utdatalista %s: %m" #: lto/lto.c:1226 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "pex_init failed: %s" -msgstr "pex_init misslyckades" +msgstr "pex_init misslyckades: %s" #: lto/lto.c:1234 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "can't get program status: %s" -msgstr "kan inte ta programstatus" +msgstr "kan inte ta programstatus: %s" #: lto/lto.c:1246 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%s terminated with status %d" -msgstr "%s: %s avslutade med status %d\n" +msgstr "%s avslutade med status %d" #: lto/lto.c:1255 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "closing LTRANS output list %s: %m" -msgstr "vid öppnandet av utdatafil %s: %m" +msgstr "när LTRANS-utdatalista %s stängdes: %m" #: lto/lto.c:1747 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "deleting LTRANS input file %s: %m" -msgstr "vid öppnandet av utdatafil %s: %m" +msgstr "när LTRANS-indatafil %s raderades: %m" #: lto/lto.c:1828 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "could not open symbol resolution file: %s" -msgstr "det gick inte att öppna svarsfilen %s" +msgstr "det gick inte att öppna symbolupplösningsfilen: %s" #: objc/objc-act.c:729 #, gcc-internal-format @@ -37576,14 +37571,14 @@ msgid "method definition not in @implementation context" msgstr "metoddefinition som inte är i @implementation-kontext" #: objc/objc-act.c:1026 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "class %qs does not implement the %qE protocol" -msgstr "%s %qs implementerar inte helt protokollet %qs" +msgstr "klass %qs implementerar inte protokollet %qE" #: objc/objc-act.c:1029 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qs does not conform to the %qE protocol" -msgstr "%s %qs implementerar inte helt protokollet %qs" +msgstr "typ %qs följer inte protokollet %qE" #: objc/objc-act.c:1206 #, gcc-internal-format @@ -37611,45 +37606,45 @@ msgid "passing argument %d of %qE from distinct Objective-C type" msgstr "skickar argument %d till %qE från distinkt Objective-C-typ" #: objc/objc-act.c:1378 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "statically allocated instance of Objective-C class %qE" -msgstr "statiskt allokerade instans av Objective-C-klass %qs" +msgstr "statiskt allokerade instans av Objective-C-klass %qE" #: objc/objc-act.c:1455 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "protocol %qE has circular dependency" -msgstr "protokollet %qs har cirkulärt beroende" +msgstr "protokollet %qE har cirkulärt beroende" #: objc/objc-act.c:1480 objc/objc-act.c:6680 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot find protocol declaration for %qE" -msgstr "kan inte hitta protokolldeklaration för %qs" +msgstr "det går inte att hitta en protokolldeklaration för %qE" #: objc/objc-act.c:1954 objc/objc-act.c:3408 objc/objc-act.c:7297 #: objc/objc-act.c:7631 objc/objc-act.c:7686 objc/objc-act.c:7711 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot find interface declaration for %qE" -msgstr "kan inte hitta gränssnittsdeklaration för %qs" +msgstr "det går inte att hitta en gränssnittsdeklaration för %qE" #: objc/objc-act.c:1958 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "interface %qE does not have valid constant string layout" -msgstr "gränssnitt %qs har inte giltig konstantsträngslayout" +msgstr "gränssnitt %qE har inte giltig konstantsträngslayout" #: objc/objc-act.c:1963 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot find reference tag for class %qE" -msgstr "kan inte hitta referenstagg klass %qs" +msgstr "det går inte att hitta en referenstagg för klass %qE" #: objc/objc-act.c:2600 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "creating selector for nonexistent method %qE" -msgstr "%Hskapar selektor för icke existerande metod %qE" +msgstr "skapar selektor för icke existerande metod %qE" #: objc/objc-act.c:2803 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qE is not an Objective-C class name or alias" -msgstr "%qs är inte ett Objective-C-klassnamn eller alias" +msgstr "%qE är inte ett Objective-C-klassnamn eller alias" #: objc/objc-act.c:2932 objc/objc-act.c:2964 objc/objc-act.c:7559 #: objc/objc-act.c:7861 objc/objc-act.c:7891 @@ -37658,19 +37653,19 @@ msgid "Objective-C declarations may only appear in global scope" msgstr "Objective-C-deklarationer får bara förekomma på global nivå" #: objc/objc-act.c:2937 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot find class %qE" -msgstr "kan inte hitta klass %qs" +msgstr "det går inte att hitta klass %qE" #: objc/objc-act.c:2939 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "class %qE already exists" -msgstr "klass %qs finns redan" +msgstr "klass %qE finns redan" #: objc/objc-act.c:2984 objc/objc-act.c:7600 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qE redeclared as different kind of symbol" -msgstr "%qs omdeklarerad som en annan sorts symbol" +msgstr "%qE omdeklarerad som en annan sorts symbol" #: objc/objc-act.c:3262 #, gcc-internal-format @@ -37713,9 +37708,9 @@ msgid "exception of type %<%T%> will be caught" msgstr "undantag av typ %<%T%> kommer att fångas" #: objc/objc-act.c:3884 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid " by earlier handler for %<%T%>" -msgstr "%H av tidigare hanterare för %<%T%>" +msgstr " av tidigare hanterare för %<%T%>" #: objc/objc-act.c:3937 #, gcc-internal-format @@ -37733,9 +37728,9 @@ msgid "type %q+D does not have a known size" msgstr "typ %q+D har inte någon känd storlek" #: objc/objc-act.c:5029 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%s %qs" -msgstr "%J%s %qs" +msgstr "%s %qs" #: objc/objc-act.c:5052 objc/objc-act.c:5071 #, gcc-internal-format @@ -37753,9 +37748,9 @@ msgid "multiple methods named %<%c%E%> found" msgstr "multipla metoder med namnet %<%c%E%> funna" #: objc/objc-act.c:6165 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "using %<%c%s%>" -msgstr "%J%s %<%c%s%>" +msgstr "använder %<%c%s%>" #: objc/objc-act.c:6174 #, gcc-internal-format @@ -37763,24 +37758,24 @@ msgid "multiple selectors named %<%c%E%> found" msgstr "multipla selektorer med namnet %<%c%E%> funna" #: objc/objc-act.c:6177 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "found %<%c%s%>" -msgstr "%J%s %<%c%s%>" +msgstr "hittade %<%c%s%>" #: objc/objc-act.c:6186 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "also found %<%c%s%>" -msgstr "%J%s %<%c%s%>" +msgstr "hittade också %<%c%s%>" #: objc/objc-act.c:6400 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "no super class declared in @interface for %qE" -msgstr "ingen superklass deklarerad i @interface för %qs" +msgstr "ingen superklass deklarerad i @interface för %qE" #: objc/objc-act.c:6438 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "found %<-%E%> instead of %<+%E%> in protocol(s)" -msgstr "hittade %<-%s%> istället för %<+%s%> i protokoll" +msgstr "hittade %<-%E%> istället för %<+%E%> i protokoll" #: objc/objc-act.c:6495 #, gcc-internal-format @@ -37788,19 +37783,19 @@ msgid "invalid receiver type %qs" msgstr "ogiltig mottagartyp %qs" #: objc/objc-act.c:6510 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%<%c%E%> not found in protocol(s)" -msgstr "%<%c%s%> finns inte bland protokoll" +msgstr "%<%c%E%> finns inte bland protokoll" #: objc/objc-act.c:6524 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qE may not respond to %<%c%E%>" -msgstr "%qs svarar kanske inte på %<%c%s%>" +msgstr "%qE svarar kanske inte på %<%c%E%>" #: objc/objc-act.c:6532 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "no %<%c%E%> method found" -msgstr "ingen metod %<%c%s%> funnen" +msgstr "ingen metod %<%c%E%> funnen" #: objc/objc-act.c:6539 #, gcc-internal-format @@ -37818,9 +37813,9 @@ msgid "%<...%> as arguments.)" msgstr "%<...%> som argument.)" #: objc/objc-act.c:6781 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "undeclared selector %qE" -msgstr "odeklarerad selektor %qs" +msgstr "odeklarerad selektor %qE" #. Historically, a class method that produced objects (factory #. method) would assign `self' to the instance that it @@ -37832,19 +37827,19 @@ msgstr "odeklarerad selektor %qs" #. where this is done unknowingly than to support the above #. paradigm. #: objc/objc-act.c:6823 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "instance variable %qE accessed in class method" -msgstr "instansvariabel %qs använd i klassmetod" +msgstr "instansvariabel %qE använd i klassmetod" #: objc/objc-act.c:7058 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "duplicate declaration of method %<%c%E%>" -msgstr "duplicerad deklaration av metoden %<%c%s%>" +msgstr "duplicerad deklaration av metoden %<%c%E%>" #: objc/objc-act.c:7119 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "duplicate interface declaration for category %<%E(%E)%>" -msgstr "dubbel gränssnittsdeklaration för kategorin %<%s(%s)%>" +msgstr "dubbel gränssnittsdeklaration för kategorin %<%E(%E)%>" #: objc/objc-act.c:7146 #, gcc-internal-format @@ -37857,36 +37852,36 @@ msgid "instance variable %qs has unknown size" msgstr "instansvariabeln %qs har okänd storlek" #: objc/objc-act.c:7182 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qE has no default constructor to call" -msgstr "typ %qs har ingen standardkonstruerare att anropa" +msgstr "typen %qE har ingen standardkonstruerare att anropa" #: objc/objc-act.c:7188 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "destructor for %qE shall not be run either" -msgstr "destruerare för %qs skall inte heller köras" +msgstr "destruerare för %qE skall inte heller köras" #. Vtable pointers are Real Bad(tm), since Obj-C cannot #. initialize them. #: objc/objc-act.c:7200 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qE has virtual member functions" -msgstr "typen %qs har virtuella medlemsfunktioner" +msgstr "typen %qE har virtuella medlemsfunktioner" #: objc/objc-act.c:7201 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "illegal aggregate type %qE specified for instance variable %qs" -msgstr "ogiltig aggregattyp %qs angiven för instansvariabel %qs" +msgstr "ogiltig aggregattyp %qE angiven för instansvariabel %qs" #: objc/objc-act.c:7211 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qE has a user-defined constructor" -msgstr "typ %qs har en användardefinierad konstruerare" +msgstr "typen %qE har en användardefinierad konstruerare" #: objc/objc-act.c:7213 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "type %qE has a user-defined destructor" -msgstr "typ %qs har en användardefinierad destruerare" +msgstr "typen %qE har en användardefinierad destruerare" #: objc/objc-act.c:7217 #, gcc-internal-format @@ -37894,39 +37889,39 @@ msgid "C++ constructors and destructors will not be invoked for Objective-C fiel msgstr "C++-konstruerare och -destruerare kommer inte att anropas för Objective-C-fält" #: objc/objc-act.c:7326 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "instance variable %qE is declared private" -msgstr "instansvariabel %qs är deklarerad privat" +msgstr "instansvariabeln %qE är deklarerad privat" #: objc/objc-act.c:7337 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "instance variable %qE is %s; this will be a hard error in the future" -msgstr "instansvariabel %qs är %s, detta kommer bli ett fel i framtiden" +msgstr "instansvariabeln %qE är %s, detta kommer bli ett fel i framtiden" #: objc/objc-act.c:7344 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "instance variable %qE is declared %s" -msgstr "instansvariabel %qs är deklarerad %s" +msgstr "instansvariabeln %qE är deklarerad %s" #: objc/objc-act.c:7370 objc/objc-act.c:7458 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "incomplete implementation of class %qE" -msgstr "ofullständig implementation av klassen %qs" +msgstr "ofullständig implementation av klassen %qE" #: objc/objc-act.c:7374 objc/objc-act.c:7462 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "incomplete implementation of category %qE" -msgstr "ofullständig implementation av kategorin %qs" +msgstr "ofullständig implementation av kategorin %qE" #: objc/objc-act.c:7379 objc/objc-act.c:7466 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "method definition for %<%c%E%> not found" -msgstr "metoddefinition för %<%c%s%> finns inte" +msgstr "metoddefinition för %<%c%E%> finns inte" #: objc/objc-act.c:7507 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%s %qE does not fully implement the %qE protocol" -msgstr "%s %qs implementerar inte helt protokollet %qs" +msgstr "%s %qE implementerar inte helt protokollet %qE" #: objc/objc-act.c:7565 objc/objc-act.c:9252 #, gcc-internal-format @@ -37934,54 +37929,54 @@ msgid "%<@end%> missing in implementation context" msgstr "%<@end%> saknas i implementationskontext" #: objc/objc-act.c:7584 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "cannot find interface declaration for %qE, superclass of %qE" -msgstr "hittar inte gränssnittsdeklaration av %qs, superklass till %qs" +msgstr "hittar inte gränssnittsdeklaration för %qE, superklass till %qE" #: objc/objc-act.c:7614 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "reimplementation of class %qE" -msgstr "omimplementation av klassen %qs" +msgstr "omimplementation av klassen %qE" #: objc/objc-act.c:7644 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conflicting super class name %qE" -msgstr "motstridande superklassnamn %qs" +msgstr "motstridande superklassnamn %qE" #: objc/objc-act.c:7647 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration of %qE" -msgstr "tidigare deklaration av %qs" +msgstr "tidigare deklaration av %qE" #: objc/objc-act.c:7649 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration" -msgstr "tidigare deklaration %q+D" +msgstr "tidigare deklaration" #: objc/objc-act.c:7665 objc/objc-act.c:7663 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "duplicate interface declaration for class %qE" -msgstr "dubblerad gränssnittsdeklaration av klass %qs" +msgstr "dubblerad gränssnittsdeklaration av klass %qE" #: objc/objc-act.c:7919 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "duplicate declaration for protocol %qE" -msgstr "dubblerad deklaration av protokoll %qs" +msgstr "dubblerad deklaration av protokoll %qE" #: objc/objc-act.c:8736 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "conflicting types for %<%c%s%>" -msgstr "motstridiga typer på %q+D" +msgstr "motstridiga typer på %<%c%s%>" #: objc/objc-act.c:8740 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "previous declaration of %<%c%s%>" -msgstr "tidigare deklaration av %qs" +msgstr "tidigare deklaration av %<%c%s%>" #: objc/objc-act.c:8830 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "no super class declared in interface for %qE" -msgstr "ingen superklass deklarerad i gränssnittet för %qs" +msgstr "ingen superklass deklarerad i gränssnittet för %qE" #: objc/objc-act.c:8889 #, gcc-internal-format @@ -37994,9 +37989,9 @@ msgid "method possibly missing a [super dealloc] call" msgstr "metod saknar kanske ett [super dealloc]-anrop" #: objc/objc-act.c:9545 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "local declaration of %qE hides instance variable" -msgstr "lokal deklaration av %qs döljer instansvariabel" +msgstr "lokal deklaration av %qE döljer instansvariabel" #: ada/gcc-interface/misc.c:196 #, gcc-internal-format @@ -38015,932 +38010,26 @@ msgid "-fexcess-precision=standard for Ada" msgstr "-fexcess-precision=standard för Ada" #: ada/gcc-interface/utils.c:5299 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs attribute requires prototypes with named arguments" -msgstr "attributet %qE kräver prototyper med namngivna argument" +msgstr "attributet %qs kräver prototyper med namngivna argument" #: ada/gcc-interface/utils.c:5311 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "%qs attribute only applies to variadic functions" -msgstr "attributet %qE fungerar bara på funktioner med variabelt antal argument" +msgstr "attributet %qs fungerar bara på funktioner med variabelt antal argument" #: ada/gcc-interface/utils.c:5474 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid vector type for attribute %qs" -msgstr "ogiltig vektortyp för attributet %qE" +msgstr "ogiltig vektortyp för attributet %qs" #: ada/gcc-interface/utils.c:5537 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "attribute %qs applies to array types only" -msgstr "attributet %qs är bara tillämpbart på variabler" +msgstr "attributet %qs är bara tillämpbart på vektortyper" #: ada/gcc-interface/utils.c:5564 -#, fuzzy, gcc-internal-format +#, gcc-internal-format msgid "invalid element type for attribute %qs" -msgstr "ogiltig vektortyp för attributet %qE" - -#~ msgid "If scheduling post reload, do trace scheduling" -#~ msgstr "Om schemaläggning efter omläsning, gör spårningsschemaläggning" - -#~ msgid "for each function it appears in.)" -#~ msgstr "för varje funktion den finns i.)" - -#~ msgid "lambda expression with no captures declared mutable" -#~ msgstr "muterbart lambdauttryck utan några deklarerade infånganden" - -#~ msgid "at this point in file" -#~ msgstr "på den här platsen i filen" - -#~ msgid "Vector assignment to assumed-size Cray Pointee at %L is illegal" -#~ msgstr "Vektortilldelning till Cray-utpekad med förmodad storlek vid %L är otillåten" - -#~ msgid "CHARACTER variable has zero length at %L" -#~ msgstr "CHARACTER-variabel har längd noll vid %L" - -#~ msgid "Object '%s' at %L must have the SAVE attribute for default initialization of a component" -#~ msgstr "Objekt \"%s\" vid %L måste ha attributet SAVE för standardinitiering av en komponent" - -#, fuzzy -#~ msgid "command line option file '%s' does not exist" -#~ msgstr "kommandoradsflaggan \"%s\" är giltig för %s men inte för %s" - -#~ msgid "GMP version %s, MPFR version %s\n" -#~ msgstr "GMP-version %s, MPFR-version %s\n" - -#~ msgid "Initialization expression didn't reduce %C" -#~ msgstr "Initieringsuttryck kunde inte reduceras %C" - -#~ msgid "All components of '%s' are PRIVATE in structure constructor at %C" -#~ msgstr "Alla komponenter i \"%s\" är PRIVATE i postkonstruerare vid %C" - -#~ msgid "Set class path" -#~ msgstr "Ange klassökväg" - -#~ msgid "Warn about code that will never be executed" -#~ msgstr "Varna för kod som aldrig kommer köras" - -#~ msgid "Set the default symbol visibility" -#~ msgstr "Ange normalsynlighet för symboler" - -#~ msgid "will never be executed" -#~ msgstr "kommer aldrig utföras" - -#~ msgid "function %q+F can never be copied because it uses variable sized variables" -#~ msgstr "funktion %q+F kan aldrig kopieras eftersom den använder variabler med variabel storlek" - -#~ msgid "jump bypassing disabled" -#~ msgstr "passage av hopp avslaget" - -#~ msgid "%s: error writing file '%s': %s\n" -#~ msgstr "%s: fel vid skrivning till fil \"%s\": %s\n" - -#~ msgid "%s: usage '%s [ -VqfnkN ] [ -i ] [ filename ... ]'\n" -#~ msgstr "%s: användning '%s [ -VqfnkN ] [ -i ] [ filnamn ... ]'\n" - -#~ msgid "%s: usage '%s [ -VqfnkNlgC ] [ -B ] [ filename ... ]'\n" -#~ msgstr "%s: användning '%s [ -VqfnkNlgC ] [ -B ] [ filnamn ... ]'\n" - -#~ msgid "%s: warning: no read access for file '%s'\n" -#~ msgstr "%s: varning: ingen läsrättighet för fil \"%s\"\n" - -#~ msgid "%s: warning: no write access for file '%s'\n" -#~ msgstr "%s: varning: ingen skrivrättighet för fil \"%s\"\n" - -#~ msgid "%s: warning: no write access for dir containing '%s'\n" -#~ msgstr "%s: varning: ingen skrivrättighet för katalog som innehåller \"%s\"\n" - -#~ msgid "%s: invalid file name: %s\n" -#~ msgstr "%s: ogiltigt filnamn: %s\n" - -#~ msgid "%s: %s: can't get status: %s\n" -#~ msgstr "%s: %s: kan inte få status: %s\n" - -#~ msgid "" -#~ "\n" -#~ "%s: fatal error: aux info file corrupted at line %d\n" -#~ msgstr "" -#~ "\n" -#~ "%s: ödesdigert fel: fil med extra information trasig vid rad %d\n" - -#~ msgid "%s:%d: declaration of function '%s' takes different forms\n" -#~ msgstr "%s:%d: deklarationen av funktionen \"%s\" tar olika former\n" - -#~ msgid "%s: compiling '%s'\n" -#~ msgstr "%s: kompilerar \"%s\"\n" - -#~ msgid "%s: wait: %s\n" -#~ msgstr "%s: vänta: %s\n" - -#~ msgid "%s: subprocess got fatal signal %d\n" -#~ msgstr "%s: subprocess fick dödlig signal %d\n" - -#~ msgid "%s: warning: missing SYSCALLS file '%s'\n" -#~ msgstr "%s: varning: ingen SYSCALLS-fil \"%s\"\n" - -#~ msgid "%s: can't read aux info file '%s': %s\n" -#~ msgstr "%s: kan inte läsa fil med övrig info \"%s\": %s\n" - -#~ msgid "%s: can't get status of aux info file '%s': %s\n" -#~ msgstr "%s: kan inte ta status på fil med övrig info \"%s\": %s\n" - -#~ msgid "%s: can't open aux info file '%s' for reading: %s\n" -#~ msgstr "%s: kan inte öppna fil med övrig info \"%s\" för läsning: %s\n" - -#~ msgid "%s: error reading aux info file '%s': %s\n" -#~ msgstr "%s: fel när fil med övrig info lästes \"%s\": %s\n" - -#~ msgid "%s: error closing aux info file '%s': %s\n" -#~ msgstr "%s: fel när fil med övrig info stängdes \"%s\": %s\n" - -#~ msgid "%s: can't delete aux info file '%s': %s\n" -#~ msgstr "%s: kan inte radera fil med övrig info \"%s\": %s\n" - -#~ msgid "%s: can't delete file '%s': %s\n" -#~ msgstr "%s: kan inte radera fil \"%s\": %s\n" - -#~ msgid "%s: warning: can't rename file '%s' to '%s': %s\n" -#~ msgstr "%s: varning: kan inte ändra namn på filen \"%s\" till \"%s\": %s\n" - -#~ msgid "%s: conflicting extern definitions of '%s'\n" -#~ msgstr "%s: motstridiga externdefinitioner av \"%s\"\n" - -#~ msgid "%s: declarations of '%s' will not be converted\n" -#~ msgstr "%s: deklarationer av \"%s\" kommer inte konverteras\n" - -#~ msgid "%s: conflict list for '%s' follows:\n" -#~ msgstr "%s: konfliktlista för \"%s\" följer:\n" - -#~ msgid "%s: warning: using formals list from %s(%d) for function '%s'\n" -#~ msgstr "%s: varning: använder formella listor från %s(%d) för funktionen \"%s\"\n" - -#~ msgid "%s: %d: '%s' used but missing from SYSCALLS\n" -#~ msgstr "%s: %d: \"%s\" används men saknas i SYSCALLS\n" - -#~ msgid "%s: %d: warning: no extern definition for '%s'\n" -#~ msgstr "%s: %d: varning: ingen externdefinition för \"%s\"\n" - -#~ msgid "%s: warning: no static definition for '%s' in file '%s'\n" -#~ msgstr "%s: varning: ingen statisk definition för \"%s\" i filen \"%s\"\n" - -#~ msgid "%s: multiple static defs of '%s' in file '%s'\n" -#~ msgstr "%s: multipla statiska definitioner av \"%s\" i filen \"%s\"\n" - -#~ msgid "%s: %d: warning: source too confusing\n" -#~ msgstr "%s: %d: varning: källkoden alltför förvirrande\n" - -#~ msgid "%s: %d: warning: varargs function declaration not converted\n" -#~ msgstr "%s: %d: varning: varargs-funktionsdeklaration konverterades inte\n" - -#~ msgid "%s: declaration of function '%s' not converted\n" -#~ msgstr "%s: deklarationen av funktionen \"%s\" inte konverterad\n" - -#~ msgid "%s: warning: too many parameter lists in declaration of '%s'\n" -#~ msgstr "%s: varning: för många parameterlistor i deklarationen av \"%s\"\n" - -#~ msgid "" -#~ "\n" -#~ "%s: warning: too few parameter lists in declaration of '%s'\n" -#~ msgstr "" -#~ "\n" -#~ "%s: varning: för få parameterlistor i deklarationen av \"%s\"\n" - -#~ msgid "%s: %d: warning: found '%s' but expected '%s'\n" -#~ msgstr "%s: %d: varning: fann \"%s\" men förväntade \"%s\"\n" - -#~ msgid "%s: local declaration for function '%s' not inserted\n" -#~ msgstr "%s: lokal deklaration för funktionen \"%s\" inte infogad\n" - -#~ msgid "" -#~ "\n" -#~ "%s: %d: warning: can't add declaration of '%s' into macro call\n" -#~ msgstr "" -#~ "\n" -#~ "%s: %d: varning: kan inte lägga till deklaration av \"%s\" i makroanrop\n" - -#~ msgid "%s: global declarations for file '%s' not inserted\n" -#~ msgstr "%s: globala deklarationer för filen \"%s\" inte infogade\n" - -#~ msgid "%s: definition of function '%s' not converted\n" -#~ msgstr "%s: definitionen av funktionen \"%s\" inte konverterad\n" - -#~ msgid "%s: %d: warning: definition of %s not converted\n" -#~ msgstr "%s: %d: varning: definition av %s konverterades inte\n" - -#~ msgid "%s: found definition of '%s' at %s(%d)\n" -#~ msgstr "%s: fann definition av \"%s\" vid %s(%d)\n" - -#~ msgid "%s: %d: warning: '%s' excluded by preprocessing\n" -#~ msgstr "%s: %d: varning: \"%s\" uteslöts av preprocessningen\n" - -#~ msgid "%s: function definition not converted\n" -#~ msgstr "%s: funktionsdefinition inte konverterad\n" - -#~ msgid "%s: '%s' not converted\n" -#~ msgstr "%s: \"%s\" inte konverterad\n" - -#~ msgid "%s: would convert file '%s'\n" -#~ msgstr "%s: skulle konvertera filen \"%s\"\n" - -#~ msgid "%s: converting file '%s'\n" -#~ msgstr "%s: konverterar filen \"%s\"\n" - -#~ msgid "%s: can't get status for file '%s': %s\n" -#~ msgstr "%s: kan inte ta status på filen \"%s\": %s\n" - -#~ msgid "%s: can't open file '%s' for reading: %s\n" -#~ msgstr "%s: kan inte öppna filen \"%s\" för läsning: %s\n" - -#~ msgid "" -#~ "\n" -#~ "%s: error reading input file '%s': %s\n" -#~ msgstr "" -#~ "\n" -#~ "%s: fel när infilen \"%s\" lästes: %s\n" - -#~ msgid "%s: can't create/open clean file '%s': %s\n" -#~ msgstr "%s: kan inte skapa/öppna en tom fil \"%s\": %s\n" - -#~ msgid "%s: warning: file '%s' already saved in '%s'\n" -#~ msgstr "%s: varning: filen \"%s\" redan sparad i \"%s\"\n" - -#~ msgid "%s: can't link file '%s' to '%s': %s\n" -#~ msgstr "%s: kan inte länka filen \"%s\" till \"%s\": %s\n" - -#~ msgid "%s: can't create/open output file '%s': %s\n" -#~ msgstr "%s: kan inte skapa/öppna utdatafil \"%s\": %s\n" - -#~ msgid "%s: can't change mode of file '%s': %s\n" -#~ msgstr "%s: kan inte ändra rättigheterna på filen \"%s\": %s\n" - -#~ msgid "%s: cannot get working directory: %s\n" -#~ msgstr "%s: kan inte bestämma aktuell katalog: %s\n" - -#~ msgid "%s: input file names must have .c suffixes: %s\n" -#~ msgstr "%s: indatafilnamn måste ha ändelsen .c: %s\n" - -#~ msgid "The maximum structure size (in bytes) for which GCC will use by-element copies" -#~ msgstr "Den maximala poststorlek (i byte) vid vilken GCC använder elementvis kopiering" - -#~ msgid "The maximum number of structure fields for which GCC will use by-element copies" -#~ msgstr "Den maximala antalet postfält (i byte) vid vilken GCC använder elementvis kopiering" - -#~ msgid "The threshold ratio between instantiated fields and the total structure size" -#~ msgstr "Tröskelförhållandet mellan instansierade fält och den totala poststorleken" - -#~ msgid "The maximum number of passes to make when doing GCSE" -#~ msgstr "Det maximala antalet pass som görs under GCSE" - -#~ msgid "The maximum number of virtual operators that a function is allowed to have before triggering memory partitioning heuristics" -#~ msgstr "Det maximala antalet virtuella operatorer som en funktion tillåts ha före heuristik för minnesuppdelning utlöses" - -#~ msgid "The average number of virtual operators that memory statements are allowed to have before triggering memory partitioning heuristics" -#~ msgstr "Det genomsnittliga antalet virtuella operatorer som minnessatser tillåts ha före heuristik för minnesuppdelning utlöses" - -#~ msgid "SHIFT argument at %L of CSHIFT must have rank %d or be a scalar" -#~ msgstr "SHIFT-argument vid %L till CSHIFT måste ha ordning %d eller vara en skalär" - -#~ msgid "SHIFT argument at %L of EOSHIFT must have rank %d or be a scalar" -#~ msgstr "SHIFT-argument vid %L till EOSHIFT måste ha ordning %d eller vara en skalär" - -#~ msgid "BOUNDARY argument at %L of EOSHIFT must have rank %d or be a scalar" -#~ msgstr "BOUNDARY-argument vid %L till EOSHIFT måste ha ordning %d eller vara en skalär" - -#~ msgid "Different shape in dimension %d for SHIFT and BOUNDARY arguments of EOSHIFT at %L" -#~ msgstr "Olika form i dimension %d för argumenten SHIFT och BOUNDARY till EOSHIFT vid %L" - -#~ msgid "FIELD argument at %L of UNPACK must have the same rank as MASK or be a scalar" -#~ msgstr "FIELD-argumentet vid %L till UNPACK måste ha samma ordning som MASK eller vara en skalär" - -#~ msgid "Different shape in dimension %d for MASK and FIELD arguments of UNPACK at %L" -#~ msgstr "Olika form i dimension %d för argumenten MASK och FIELD till UNPACK vid %L" - -#~ msgid "Allocatable component at %C must be an array" -#~ msgstr "Allokerbar komponent vid %C måste vara en vektor" - -#~ msgid "Fortran 2003: Procedure components at %C are not yet implemented in gfortran" -#~ msgstr "Fortran 2003: Procedurkomponenter vid %C är inte implementerade ännu i gfortran" - -#~ msgid "DEFERRED not yet implemented at %C" -#~ msgstr "DEFERRED inte implementerad ännu vid %C" - -#~ msgid "Type/rank mismatch in argument '%s' at %L" -#~ msgstr "Typ/ordning stämmer inte i argument \"%s\" vid %L" - -#~ msgid "Function '%s' called in lieu of an operator at %L must be PURE" -#~ msgstr "Funktionen \"%s\" anropad istället för en operator vid %L måste vara PURE" - -#~ msgid "Repeat count cannot follow P descriptor" -#~ msgstr "Upprepningsantal får inte följa efter P-deskriptor" - -#~ msgid "Fortran F2003: ROUND= specifier at %C not implemented" -#~ msgstr "Fortran F2003: ROUND=-specificerare vid %C är inte implementerad" - -#~ msgid "F2003 Feature: ROUND= specifier at %C not implemented" -#~ msgstr "F2003-funktion: specificerare ROUND= vid %C är inte implementerad" - -#~ msgid "Illegal deallocate-expression in DEALLOCATE at %C for a PURE procedure" -#~ msgstr "Otillåtet avallokeringsuttryck i DEALLOCATE vid %C för en PURE-procedur" - -#~ msgid "Expected case name of '%s' at %C" -#~ msgstr "Case-namnet \"%s\" förväntades vid %C" - -#~ msgid "Option -fwhole-program is not supported for Fortran" -#~ msgstr "Flaggan -fwhole-program stöds inte för Fortran" - -#~ msgid "PROCEDURE binding at %C must be inside CONTAINS" -#~ msgstr "PROCEDURE-bindning vid %C måste vara inuti CONTAINS" - -#~ msgid "Intrinsic subroutine '%s' used as a function at %L" -#~ msgstr "Inbyggd subrutin \"%s\" använd som en funktion vid %L" - -#~ msgid "Expression in DEALLOCATE statement at %L must be ALLOCATABLE or a POINTER" -#~ msgstr "Uttryck i DEALLOCATE-sats vid %L måste vara ALLOCATABLE eller en POINTER" - -#~ msgid "The STAT variable '%s' in an ALLOCATE statement must not be allocated in the same statement at %L" -#~ msgstr "STAT-variabeln \"%s\" i en ALLOCATE-sats får inte allokeras i samma sats vid %L" - -#~ msgid "STAT variable '%s' of %s statement at %C cannot be INTENT(IN)" -#~ msgstr "STAT-variabel \"%s\" i %s-sats vid %C får inte vara INTENT(IN)" - -#~ msgid "Illegal STAT variable in %s statement at %C for a PURE procedure" -#~ msgstr "Otillåten STAT-variabel i %s-sats vid %C för en PURE-procedur" - -#~ msgid "Deleted feature: GOTO at %L jumps to END of construct at %L" -#~ msgstr "Borttagen funktion: GOTO vid %L hoppar till END av konstruktion vid %L" - -#~ msgid "Subroutine '%s' called instead of assignment at %L must be PURE" -#~ msgstr "Subrutin \"%s\" anropad stället för tilldelning vid %L måste vara PURE" - -#~ msgid "CHARACTER(*) function '%s' at %L is obsolescent in fortran 95" -#~ msgstr "CHARACTER(*)-funktion \"%s\" vid %L är föråldrad i fortran 95" - -#~ msgid "non-constant DATA value at %L" -#~ msgstr "ickekonstant DATA-värde vid %L" - -#~ msgid "Integer too large in shape specification at %L" -#~ msgstr "För stort heltal i formspecifikation vid %L" - -#~ msgid "Too many dimensions in shape specification for RESHAPE at %L" -#~ msgstr "För många dimensioner i formspecifikation till RESHAPE vid %L" - -#~ msgid "Shape specification at %L cannot be negative" -#~ msgstr "Formspecifikation vid %L kan inte vara negativ" - -#~ msgid "Shape specification at %L cannot be the null array" -#~ msgstr "Formspecifikation vid %L får inte vara den tomma vektorn" - -#~ msgid "ORDER parameter of RESHAPE at %L is not the same size as SHAPE parameter" -#~ msgstr "ORDER-parameter till RESHAPE vid %L har inte samma storlek som SHAPE-parametern" - -#~ msgid "Error in ORDER parameter of RESHAPE at %L" -#~ msgstr "Fel i ORDER-parameter till RESHAPE vid %L" - -#~ msgid "ORDER parameter of RESHAPE at %L is out of range" -#~ msgstr "ORDER-parameter till RESHAPE vid %L är utanför gränsen" - -#~ msgid "Invalid permutation in ORDER parameter at %L" -#~ msgstr "Ogiltig permutation i ORDER-parameter vid %L" - -#~ msgid "PAD parameter required for short SOURCE parameter at %L" -#~ msgstr "PAD-parameter krävs för kort SOURCE-parameter vid %L" - -#~ msgid "Support SSE5 built-in functions and code generation" -#~ msgstr "Stöd inbyggda SSE5-funktioner och -kodgenerering" - -#~ msgid "Do not generate tablejump insns" -#~ msgstr "Generera inte tabellhoppinstruktioner" - -#~ msgid "Output instruction sizes to the asm file" -#~ msgstr "Mata ut instruktionsstorlekar till asm-filen" - -#~ msgid "Do not generate fused multiply/add instructions" -#~ msgstr "Generera inte sammansmälta multiplikations/additions-instruktioner" - -#~ msgid "Generate SH2a code" -#~ msgstr "Generera SH2a-kod" - -#~ msgid "Expand cbranchdi4 pattern early into separate comparisons and branches." -#~ msgstr "Expandera cbranchdi4-mönster tidigt i separata jämförelser och grenar." - -#~ msgid "When running CSE, follow conditional jumps" -#~ msgstr "När CSE körs, följ villkorliga hopp" - -#~ msgid "Perform sequence abstraction optimization on RTL" -#~ msgstr "Utför sekvensabstraktionsoptimeringar på RTL" - -#~ msgid "Eliminate redundant sign extensions using LCM." -#~ msgstr "Eliminera överflödiga teckenutvidgningar med LCM." - -#~ msgid "logical %<%s%> with non-zero constant will always evaluate as true" -#~ msgstr "logisk %<%s%> men konstant skild från noll kommer alltid beräknas till sant" - -#~ msgid "%Hduplicate label %qD" -#~ msgstr "%Hdubblerad etikett %qD" - -#~ msgid "%Jjump into statement expression" -#~ msgstr "%Jhopp in i satsuttryck" - -#~ msgid "%Jjump into scope of identifier with variably modified type" -#~ msgstr "%Jhopp in i räckvidd för identifierare med variabel typ" - -#~ msgid "variable or field %qs declared void" -#~ msgstr "variabel eller fält %qs deklarerad void" - -#~ msgid "%Jinvalid use of structure with flexible array member" -#~ msgstr "%Jogiltig användning av post flexibel vektormedlem" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Bool%> in declaration specifiers" -#~ msgstr "både % och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Bool%> in declaration specifiers" -#~ msgstr "både % och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Bool%> in declaration specifiers" -#~ msgstr "både % och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Bool%> in declaration specifiers" -#~ msgstr "både % och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both % and % in declaration specifiers" -#~ msgstr "både % och % i deklarationsspecificerare" - -#~ msgid "both % and %<_Bool%> in declaration specifiers" -#~ msgstr "både % och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både % och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Fract%> in declaration specifiers" -#~ msgstr "både % och %<_Fract%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Accum%> in declaration specifiers" -#~ msgstr "både % och %<_Accum%> i deklarationsspecificerare" - -#~ msgid "both % and %<_Sat%> in declaration specifiers" -#~ msgstr "både % och %<_Sat%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and %<_Bool%> in declaration specifiers" -#~ msgstr "både %<_Sat%> och %<_Bool%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and %<_Decimal32%> in declaration specifiers" -#~ msgstr "både %<_Sat%> och %<_Decimal32%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and %<_Decimal64%> in declaration specifiers" -#~ msgstr "både %<_Sat%> och %<_Decimal64%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and %<_Decimal128%> in declaration specifiers" -#~ msgstr "både %<_Sat%> och %<_Decimal128%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and % in declaration specifiers" -#~ msgstr "både %<_Sat%> och % i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both % and %<%s%> in declaration specifiers" -#~ msgstr "både % och %<%s%> i deklarationsspecificerare" - -#~ msgid "both %<_Sat%> and %<%s%> in declaration specifiers" -#~ msgstr "både %<_Sat%> och %<%s%> i deklarationsspecificerare" - -#~ msgid "decimal floating point not supported for this target" -#~ msgstr "decimala flyttal stöds inte för denna målarkitektur" - -#~ msgid "missing %<(%> after %<#pragma push_macro%> - ignored" -#~ msgstr "%<(%> saknas efter %<#pragma pack_macro%> - ignoreras" - -#~ msgid "invalid constant in %<#pragma push_macro%> - ignored" -#~ msgstr "ogiltig konstant i %<#pragma push_macro%> - ignoreras" - -#~ msgid "missing %<)%> after %<#pragma push_macro%> - ignored" -#~ msgstr "%<)%> saknas efter %<#pragma push_macro%> - ignoreras" - -#~ msgid "junk at end of %<#pragma push_macro%>" -#~ msgstr "skräp vid slutet av %<#pragma push_macro%>" - -#~ msgid "missing %<(%> after %<#pragma pop_macro%> - ignored" -#~ msgstr "%<(%> saknas efter %<#pragma pop_macro%> - ignoreras" - -#~ msgid "invalid constant in %<#pragma pop_macro%> - ignored" -#~ msgstr "ogiltig konstant i %<#pragma pop_macro%> - ignoreras" - -#~ msgid "missing %<)%> after %<#pragma pop_macro%> - ignored" -#~ msgstr "%<)%> saknas efter %<#pragma pop_macro%> - ignoreras" - -#~ msgid "junk at end of %<#pragma pop_macro%>" -#~ msgstr "skräp vid slutet av %<#pragma pop_macro%>" - -#~ msgid "#pragma redefine_extname not supported on this target" -#~ msgstr "#pragma redefine_extname stöds inte på denna målarkitektur" - -#~ msgid "signed and unsigned type in conditional expression" -#~ msgstr "typ signed och unsigned i villkorsuttryck" - -#~ msgid "case label in statement expression not containing enclosing switch statement" -#~ msgstr "case-etikett i satsuttryck som inte innehåller en omslutande switch-sats" - -#~ msgid "% label in statement expression not containing enclosing switch statement" -#~ msgstr "%-etikett i satsuttryck som inte innehåller en omslutande switch-sats" - -#~ msgid "case label in scope of identifier with variably modified type not containing enclosing switch statement" -#~ msgstr "case-etikett i räckvidden för en identifierare med variabel typ som inte innehåller en omslutande switch-sats" - -#~ msgid "% label in scope of identifier with variably modified type not containing enclosing switch statement" -#~ msgstr "%-etikett i räckvidden för en identifierare med variabel typ som inte innehåller en omslutande switch-sats" - -#~ msgid "%Hstatement with no effect" -#~ msgstr "%Hsats utan effekt" - -#~ msgid "Unrecognized GIMPLE statement during RTL expansion" -#~ msgstr "Okänd GIMPLE-sats under RTL-expansion" - -#~ msgid "region %i may contain throw and is contained in region that may not" -#~ msgstr "region %i kan innehålla throw och ligger inne i en region som inte kan det" - -#~ msgid "%H%s" -#~ msgstr "%H%s" - -#~ msgid "iteration variable %qs should not be firstprivate" -#~ msgstr "iterationsvariabel %qs får inte vara firstprivate" - -#~ msgid "-freorder-blocks-and-partition does not work with exceptions" -#~ msgstr "-freorder-blocks-and-partition fungerar inte med undantag" - -#~ msgid "-freorder-blocks-and-partition does not support unwind info" -#~ msgstr "-freorder-blocks-and-partition stödjer inte unwind-info" - -#~ msgid "%Hvalue computed is not used" -#~ msgstr "%Hberäknat värde används inte" - -#~ msgid "%qs is deprecated (declared at %s:%d)" -#~ msgstr "%qs bör undvikas (deklarerad vid %s:%d)" - -#~ msgid "EH edge %i->%i is missing" -#~ msgstr "EH-båge %i->%i saknas" - -#~ msgid "EH edge %i->%i miss EH flag" -#~ msgstr "EH-bågen %i->%i saknar EH-flagga" - -#~ msgid "EH edge %i->%i has duplicated regions" -#~ msgstr "EH-bågen %i->%i har dubblerade regioner" - -#~ msgid " Pending stmts not issued on PRED edge (%d, %d)\n" -#~ msgstr " Väntande satser inte utmatade på PRED-båge (%d, %d)\n" - -#~ msgid " Pending stmts not issued on SUCC edge (%d, %d)\n" -#~ msgstr " Väntande satser inte utmatade på SUCC-båge (%d, %d)\n" - -#~ msgid " Pending stmts not issued on ENTRY edge (%d, %d)\n" -#~ msgstr " Väntande satser inte utmatade på ENTRY-båge (%d, %d)\n" - -#~ msgid " Pending stmts not issued on EXIT edge (%d, %d)\n" -#~ msgstr " Väntande satser inte utmatade på EXIT-båge (%d, %d)\n" - -#~ msgid "initialized from %qE" -#~ msgstr "initierade från %qE" - -#~ msgid "dereferencing pointer %qD does break strict-aliasing rules" -#~ msgstr "att dereferera pekare %qD bryter regler för strikt aliasing" - -#~ msgid "non-addressable variable inside an alias set" -#~ msgstr "oadresserbar variabel inuti en aliasmängd" - -#~ msgid "verify_flow_insensitive_alias_info failed" -#~ msgstr "verify_flow_insensitive_alias_info misslyckades" - -#~ msgid "dereferenced pointers should have a name or a symbol tag" -#~ msgstr "derefererade pekare skall ha ett namn eller en symboltagg" - -#~ msgid "pointers with a memory tag, should have points-to sets" -#~ msgstr "pekare med en minnestagg, skulle ha pekar-på-mängder" - -#~ msgid "pointer escapes but its name tag is not call-clobbered" -#~ msgstr "pekare utgår, men dess namntagg är inte anropsöverskriven" - -#~ msgid "verify_flow_sensitive_alias_info failed" -#~ msgstr "verify_flow_sensitive_alias_info misslyckades" - -#~ msgid "variable in call_clobbered_vars but not marked call_clobbered" -#~ msgstr "variabel i call_clobbered_vars men inte markerad call_clobbered" - -#~ msgid "variable marked call_clobbered but not in call_clobbered_vars bitmap." -#~ msgstr "variabel markerad call_clobbered men inte i bitkartan call_clobbered_vars." - -#~ msgid "verify_call_clobbering failed" -#~ msgstr "verify_call_clobbering misslyckades" - -#~ msgid "Memory partitions should have at least one symbol" -#~ msgstr "Minnespartitioner skall ha åtminstone en symbol" - -#~ msgid "Partitioned symbols should belong to exactly one partition" -#~ msgstr "Partitionerade symboler skall tillhöra exakt en partition" - -#~ msgid "verify_memory_partitions failed" -#~ msgstr "verify_memory_partitions misslyckades" - -#~ msgid "%Jonly weak aliases are supported in this configuration" -#~ msgstr "%Jendast svaga alias stöds i denna konfiguration" - -#~ msgid "the -mno-tablejump switch is deprecated" -#~ msgstr "flaggan -mno-tablejump bör undvikas" - -#~ msgid "GCC 4.4 is the last release with this switch" -#~ msgstr "GCC 4.4 är den sista utgåvan med denna flagga" - -#~ msgid "use the -fno-jump-tables switch instead" -#~ msgstr "använd flaggan -fno-jump-tables istället" - -#~ msgid "trampolines not supported" -#~ msgstr "trampoliner stöds ej" - -#~ msgid "`%s' attribute only applies to functions" -#~ msgstr "attributet \"%s\" är bara tillämpbart på funktioner" - -#~ msgid "`%s' attribute only applies to variables" -#~ msgstr "attributet \"%s\" är bara tillämpbart på variabler" - -#~ msgid "Trampoline support for CRX" -#~ msgstr "Trampolinstöd för CRX" - -#~ msgid "nested functions are limited to 2 register parameters" -#~ msgstr "nästade funktioner begränsas till 2 registerparametrar" - -#~ msgid "value %<%s%> for -mtune= switch is deprecated" -#~ msgstr "värde %<%s%> till flaggan -mtune= bör undvikas" - -#~ msgid "GCC 4.4 is the last release with Itanium1 tuning support" -#~ msgstr "GCC 4.4 är den sista utgåvan med stöd för trimning av Itanium1" - -#~ msgid "not yet implemented: latency-optimized inline square root" -#~ msgstr "ännu inte implementerat: latensoptimerad inline:ad kvadratrot" - -#~ msgid "`%s' attribute applies only to functions" -#~ msgstr "attributet \"%s\" fungerar bara på funktioner" - -#~ msgid "`%s' attribute argument not an integer constant" -#~ msgstr "attributargument \"%s\" är inte en heltalskonstant" - -#~ msgid "`%s' attribute ignored" -#~ msgstr "attributet \"%s\" ignoreras" - -#~ msgid "%H from here" -#~ msgstr "%H härifrån" - -#~ msgid " enters scope of non-POD %q+#D" -#~ msgstr " går in i räckvid för icke-POD %q+#D" - -#~ msgid "%J enters catch block" -#~ msgstr "%J går in i catch-block" - -#~ msgid "ISO C++ forbids use of initializer list to initialize reference %qD" -#~ msgstr "ISO C++ förbjuder användning av initierarlistor för att initiera referensen %qD" - -#~ msgid "creating %s" -#~ msgstr "skapar %s" - -# Detta är en exakt kopia från koden. Skall nog knappast översättas. -#~ msgid "XXX is_class_level != (current_scope == class_scope)\n" -#~ msgstr "XXX is_class_level != (current_scope == class_scope)\n" - -#~ msgid "%q+D is not a function," -#~ msgstr "%q+D är inte en funktion," - -#~ msgid " conflict with %q+D" -#~ msgstr " står i konflikt med %q+D" - -#~ msgid "%H% is too long for GCC" -#~ msgstr "%H% är för långt för GCC" - -#~ msgid "%H%qT is not a template" -#~ msgstr "%H%qT är inte en mall" - -#~ msgid "%Hunsupported non-standard concatenation of string literals" -#~ msgstr "%Hicke-standardsuffix på flyttalskonstant stöds inte" - -#~ msgid "%H%qD used without template parameters" -#~ msgstr "%H%qD använd utan mallparametrar" - -#~ msgid "%Hreference to %qD is ambiguous" -#~ msgstr "%Hreferens till %qD är tvetydig" - -#~ msgid "%Hinvalid use of %qD" -#~ msgstr "%Hogiltig användning av %qD" - -#~ msgid "%Hcase label not within a switch statement" -#~ msgstr "%Hcase-etikett är inte i en switch-sats" - -#~ msgid "%H% without a previous %" -#~ msgstr "%H% utan ett föregående %" - -#~ msgid "%Hbreak statement not within loop or switch" -#~ msgstr "%Hbreak-sats som inte är i en slinga eller switch" - -#~ msgid "%Hinvalid exit from OpenMP structured block" -#~ msgstr "%Hogiltig utgång från OpenMP strukturerat block" - -#~ msgid "%Hbreak statement used with OpenMP for loop" -#~ msgstr "%Hbreak-sats använd med OpenMP-for-slinga" - -#~ msgid "%Hcontinue statement not within a loop" -#~ msgstr "%Hcontinue-sats som inte är i en slinga" - -#~ msgid "using % outside of template" -#~ msgstr "användning av % utanför mall" - -#~ msgid "%Harray bound is not an integer constant" -#~ msgstr "%Hvektorgräns är inte en heltalskonstant" - -#~ msgid "%Hredefinition of %q#T" -#~ msgstr "%Homdefinition av %q#T" - -#~ msgid "%Htemplate declaration of %qs" -#~ msgstr "%Hmalldeklaration av %qs" - -#~ msgid "%Htoo many %qs clauses" -#~ msgstr "%Hför många %qs-klausuler" - -#~ msgid "%Hcollapse argument needs positive constant integer expression" -#~ msgstr "%Hcollapse-argument behöver ett positivt konstant heltalsuttryck" - -#~ msgid "%Hschedule % does not take a % parameter" -#~ msgstr "%H%-schemaläggning tar ingen %-parameter" - -#~ msgid "%Hschedule % does not take a % parameter" -#~ msgstr "%H%-schemaläggning tar ingen %-parameter" - -#~ msgid "%H%qs is not valid for %qs" -#~ msgstr "%H%qs är inte giltigt för %qs" - -#~ msgid "%Hiteration variable %qD should not be firstprivate" -#~ msgstr "%Hiterationsvariabel %qD får inte vara firstprivate" - -#~ msgid "%Hiteration variable %qD should not be reduction" -#~ msgstr "%Hiterationsvariabel %qD skall inte vara reduktion" - -#~ msgid "%Hcollapsed loops not perfectly nested" -#~ msgstr "%Hkollapsade slingor inte perfäkt nästade" - -#~ msgid "%Hexpected string literal" -#~ msgstr "%Hsträngkonstant förväntades" - -#~ msgid "%H%<#pragma GCC pch_preprocess%> must be first" -#~ msgstr "%H%<#pragma GCC pch_preprocess%> måste komma först" - -#~ msgid "%H%<#pragma omp barrier%> may only be used in compound statements" -#~ msgstr "%H%<#pragma omp barrier%> får bara användas i sammansatta satser" - -#~ msgid "%H%<#pragma omp flush%> may only be used in compound statements" -#~ msgstr "%H%<#pragma omp flush%> får bara användas i sammansatta satser" - -#~ msgid "%H%<#pragma omp taskwait%> may only be used in compound statements" -#~ msgstr "%H%<#pragma omp barrier%> får bara användas i sammansatta satser" - -#~ msgid "%H%<#pragma omp section%> may only be used in %<#pragma omp sections%> construct" -#~ msgstr "%H%<#pragma omp section%> får bara användas i %<#pragma omp sections%>-konstruktion" - -#~ msgid "%H%qD is not a member of %qT" -#~ msgstr "%H%qD är inte en medlem av %qT" - -#~ msgid "%Hinvalid controlling predicate" -#~ msgstr "%Hogiltigt styrpredikat" - -#~ msgid "%Hinvalid increment expression" -#~ msgstr "%Hogiltigt ökningsuttryck" - -#~ msgid "%Hexpected iteration declaration or initialization" -#~ msgstr "%Hiterationsdeklaration eller initiering förväntades" - -#~ msgid "%Hmissing controlling predicate" -#~ msgstr "%Hstyrpredikat saknas" - -#~ msgid "%Hmissing increment expression" -#~ msgstr "%Hutelämnat ökningsuttryck" - -#~ msgid "global register variable %qs used in nested function" -#~ msgstr "global registervariabel %qs använd i nästad funktion" - -#~ msgid "register variable %qs used in nested function" -#~ msgstr "registervariabel %qs använd i nästad funktion" - -#~ msgid "address of global register variable %qs requested" -#~ msgstr "adress till global registervariabel %qs efterfrågad" - -#~ msgid "address of register variable %qs requested" -#~ msgstr "adress till registervariabeln %qs efterfrågad" +msgstr "ogiltig elementtyp för attributet %qs" diff --git a/gcc/predict.c b/gcc/predict.c index eb5ddef2e38..29e0e2fcd99 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -113,15 +113,19 @@ static const struct predictor_info predictor_info[]= { static inline bool maybe_hot_frequency_p (int freq) { + struct cgraph_node *node = cgraph_node (current_function_decl); if (!profile_info || !flag_branch_probabilities) { - if (cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) return false; - if (cfun->function_frequency == FUNCTION_FREQUENCY_HOT) + if (node->frequency == NODE_FREQUENCY_HOT) return true; } if (profile_status == PROFILE_ABSENT) return true; + if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + && freq <= (ENTRY_BLOCK_PTR->frequency * 2 / 3)) + return false; if (freq < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)) return false; return true; @@ -161,11 +165,16 @@ cgraph_maybe_hot_edge_p (struct cgraph_edge *edge) && (edge->count <= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION))) return false; - if (lookup_attribute ("cold", DECL_ATTRIBUTES (edge->callee->decl)) - || lookup_attribute ("cold", DECL_ATTRIBUTES (edge->caller->decl))) + if (edge->caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED + || edge->callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) + return false; + if (optimize_size) return false; - if (lookup_attribute ("hot", DECL_ATTRIBUTES (edge->caller->decl))) + if (edge->caller->frequency == NODE_FREQUENCY_HOT) return true; + if (edge->caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE + && edge->frequency < CGRAPH_FREQ_BASE * 3 / 2) + return false; if (flag_guess_branch_prob && edge->frequency <= (CGRAPH_FREQ_BASE / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))) @@ -191,7 +200,7 @@ probably_never_executed_bb_p (const_basic_block bb) if (profile_info && flag_branch_probabilities) return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0; if ((!profile_info || !flag_branch_probabilities) - && cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + && cgraph_node (current_function_decl)->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) return true; return false; } @@ -202,8 +211,9 @@ bool optimize_function_for_size_p (struct function *fun) { return (optimize_size - || (fun && (fun->function_frequency - == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED))); + || (fun && fun->decl + && (cgraph_node (fun->decl)->frequency + == NODE_FREQUENCY_UNLIKELY_EXECUTED))); } /* Return true when current function should always be optimized for speed. */ @@ -2148,27 +2158,36 @@ void compute_function_frequency (void) { basic_block bb; + struct cgraph_node *node = cgraph_node (current_function_decl); if (!profile_info || !flag_branch_probabilities) { + int flags = flags_from_decl_or_type (current_function_decl); if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl)) != NULL) - cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED; + node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl)) != NULL) - cfun->function_frequency = FUNCTION_FREQUENCY_HOT; + node->frequency = NODE_FREQUENCY_HOT; + else if (flags & ECF_NORETURN) + node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; + else if (MAIN_NAME_P (DECL_NAME (current_function_decl))) + node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; + else if (DECL_STATIC_CONSTRUCTOR (current_function_decl) + || DECL_STATIC_DESTRUCTOR (current_function_decl)) + node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; return; } - cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED; + node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; FOR_EACH_BB (bb) { if (maybe_hot_bb_p (bb)) { - cfun->function_frequency = FUNCTION_FREQUENCY_HOT; + node->frequency = NODE_FREQUENCY_HOT; return; } if (!probably_never_executed_bb_p (bb)) - cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL; + node->frequency = NODE_FREQUENCY_NORMAL; } } @@ -2176,6 +2195,7 @@ compute_function_frequency (void) static void choose_function_section (void) { + struct cgraph_node *node = cgraph_node (current_function_decl); if (DECL_SECTION_NAME (current_function_decl) || !targetm.have_named_sections /* Theoretically we can split the gnu.linkonce text section too, @@ -2191,10 +2211,10 @@ choose_function_section (void) if (flag_reorder_blocks_and_partition) return; - if (cfun->function_frequency == FUNCTION_FREQUENCY_HOT) + if (node->frequency == NODE_FREQUENCY_HOT) DECL_SECTION_NAME (current_function_decl) = build_string (strlen (HOT_TEXT_SECTION_NAME), HOT_TEXT_SECTION_NAME); - if (cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) DECL_SECTION_NAME (current_function_decl) = build_string (strlen (UNLIKELY_EXECUTED_TEXT_SECTION_NAME), UNLIKELY_EXECUTED_TEXT_SECTION_NAME); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6afd75b1c43..07e7e503609 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,294 @@ +2010-04-28 Mike Stump + + * g++.dg/uninit-pred-1_b.C: Use dg-message instead of + dg-excess-errors. + * g++.dg/uninit-pred-2_b.C: Likewise. + +2010-04-28 Tobias Burnus + + PR fortran/18918 + PR fortran/43919 + * gfortran.dg/coarray_11.f90: Add scalar-coarrays test case. + +2010-04-28 Matthias Klose + + * gcc.dg/plugin/plugin.exp: Run the plugindir tests. + * gcc.dg/plugindir1.c: Move to gcc.dg/plugin/plugindir1.c. + * gcc.dg/plugindir2.c: Move to gcc.dg/plugin/plugindir2.c. + * gcc.dg/plugindir3.c: Move to gcc.dg/plugin/plugindir3.c. + * gcc.dg/plugindir4.c: Move to gcc.dg/plugin/plugindir4.c. + +2010-04-28 Eric Botcazou + + * gcc.dg/const-uniq-1.c: New test. + * gcc.dg/lto/const-uniq_[01].c: Likewise. + +2010-04-28 Xinliang David Li + + * gcc.dg/uninit-pred-2_b.c: New test. + * gcc.dg/uninit-pred-4_b.c: New test. + * gcc.dg/uninit-pred-3_d.c: New test. + * gcc.dg/uninit-pred-6_b.c: New test. + * gcc.dg/uninit-pred-8_b.c: New test. + * gcc.dg/uninit-pred-3_a.c: New test. + * gcc.dg/uninit-pred-2_c.c: New test. + * gcc.dg/uninit-pred-5_a.c: New test. + * gcc.dg/uninit-pred-3_e.c: New test. + * gcc.dg/uninit-pred-7_a.c: New test. + * gcc.dg/uninit-pred-6_c.c: New test. + * gcc.dg/uninit-pred-9_a.c: New test. + * gcc.dg/uninit-pred-8_c.c: New test. + * gcc.dg/uninit-pred-3_b.c: New test. + * gcc.dg/uninit-pred-5_b.c: New test. + * gcc.dg/uninit-pred-7_b.c: New test. + * gcc.dg/uninit-pred-6_d.c: New test. + * gcc.dg/uninit-pred-9_b.c: New test. + * gcc.dg/uninit-pred-2_a.c: New test. + * gcc.dg/uninit-pred-4_a.c: New test. + * gcc.dg/uninit-pred-3_c.c: New test. + * gcc.dg/uninit-pred-6_a.c: New test. + * gcc.dg/uninit-pred-8_a.c: New test. + * gcc.dg/uninit-pred-7_c.c: New test. + * gcc.dg/uninit-pred-6_e.c: New test. + * g++.dg/uninit-pred-loop-1_b.cc: New test. + * g++.dg/uninit-pred-1_a.C: New test. + * g++.dg/uninit-pred-1_b.C: New test. + * g++.dg/uninit-pred-2_a.C: New test. + * g++.dg/uninit-pred-2_b.C: New test. + * g++.dg/uninit-pred-loop-1_a.cc: New test. + * g++.dg/uninit-pred-loop-1_c.cc: New test. + * g++.dg/uninit-pred-loop_1.cc: New test. + +2010-04-28 Martin Jambor + + * gcc.dg/lto/20091209-1_0.c: New testcase. + +2010-04-28 Richard Guenther + + PR tree-optimization/43879 + PR tree-optimization/43909 + * gcc.dg/ipa/ipa-pta-14.c: Adjust. + +2010-04-28 Richard Guenther + + PR c++/43880 + * g++.dg/torture/pr43880.C: New testcase. + +2010-04-28 Manuel López-Ibáñez + + PR c++/9335 + * g++.dg/template/recurse2.C: Update + * g++.dg/template/recurse.C: Update. + * g++.dg/template/pr23510.C: Update. + * lib/prune.exp: Filter out 'recursively instantiated'. + +2010-04-27 Fabien Chêne + + PR c++/29043 + * g++.dg/init/pr29043.C: New. + +2010-04-27 Jason Merrill + + * g++.dg/lookup/scoped5.C: Adjust. + * g++.dg/lookup/scoped8.C: Adjust. + * g++.dg/template/dependent-expr5.C: Adjust. + * g++.old-deja/g++.brendan/nest1.C: Adjust. + + PR c++/43856 + * g++.dg/cpp0x/lambda/lambda-this2.C: New. + + PR c++/43875 + * g++.dg/cpp0x/lambda/lambda-deduce2.C: New. + +2010-04-27 Manuel López-Ibáñez + Jan Hubicka + + * gcc.dg/pure-2.c: New testcase. + * gcc.dg/const-1.c: New testcase. + +2010-04-27 Jason Merrill + + * g++.dg/cpp0x/lambda/lambda-ice1.C: New. + + PR c++/41468 + * g++.dg/template/sfinae17.C: New. + * g++.dg/template/sfinae18.C: New. + +2010-04-27 Fabien Chêne + + * g++.dg/init/pr42844.C: New. + * g++.dg/cpp0x/pr42844-2.C: New. + * g++.dg/cpp0x/defaulted2.C: Adjust. + * g++.dg/tree-ssa/pr27549.C: Likewise. + * g++.old-deja/g++.mike/dyncast8.C: Likewise. + +2010-04-27 Tobias Burnus + + PR fortran/18918 + * gfortran.dg/coarray_12.f90: Fix dump parsing. + +2010-04-27 Richard Guenther + + PR middle-end/40561 + * g++.dg/other/pr40561.C: New testcase. + +2010-04-27 Martin Jambor + + PR middle-end/43812 + * g++.dg/ipa/pr43812.C: New test. + +2010-04-27 Jan Hubicka + + * gcc.dg/ipa/iinline-1.c (main): Rename to... + (test): ... this one. + +2010-04-27 Bernd Schmidt + + PR target/40657 + * gcc.target/arm/thumb-stackframe.c: New test. + +2010-04-27 Shujing Zhao + + * gcc.dg/pr32207.c: Fix typo in expected warning messages. + * gcc.dg/misc-column.c: Likewise. + * gcc.dg/Walways-true-1.c: Likewise. + * gcc.dg/Walways-true-2.c: Likewise. + * gcc.dg/warn-addr-cmp.c: Likewise. + +2010-04-27 Tobias Burnus + + PR fortran/18918 + * gfortran.dg/coarray_7.f90: Modified and removed obsolete tests. + * gfortran.dg/coarray_12.f90: New. + +2010-04-27 Shujing Zhao + + PR c/32207 + * gcc.dg/pr32207.c: New test. + * gcc.dg/misc-column.c: Adjust expected warning. + * gcc.dg/Walways-true-1.c: Likewise. + * gcc.dg/Walways-true-2.c: Likewise. + * gcc.dg/warn-addr-cmp.c: Likewise. + +2010-04-27 Dave Korn + + PR lto/42776 + * lib/lto.exp (lto_prune_vis_warns): New function. + (lto-link-and-maybe-run): Call it. + +2010-04-26 H.J. Lu + + PR tree-optimization/43904 + * gcc.dg/tree-ssa/tailcall-6.c: New. + +2010-04-26 Iain Sandoe + + PR testsuite/35165 + * obj-c++.dg/stubify-2.mm: Restrict to ilp32 targets. Require + Darwin8/OSX10.4 - compatible code generation. + Use scan-rtl-dump. + * obj-c++.dg/stubify-1.mm: Ditto. + * lib/objc-torture.exp: Do not require link success for + "trivial.m" in the runtime checks when dowhat = 'compile'. + * lib/dg-pch.exp: (dg-flags-pch): New Proc. + * objc.dg/stubify-1.m: Restrict to ilp32 targets. Require + Darwin8/OSX10.4 - compatible code generation. + * objc.dg/stubify-2.m: Ditto. + * objc.dg/symtab-1.m: Match '.quad' for m64 code. + * objc.dg/next-runtime-1.m: Ditto. + * objc.dg/stret-2.m: Restrict to ilp32 targets. + * objc.dg/pch/pch.exp: Apply tests to both Gnu and NeXT + runtimes on Darwin. + +2010-04-26 Jack Howarth + + PR 43715 + * testsuite/lib/plugin-support.exp: Use "-undefined + dynamic_lookup" on darwin. + +2010-04-26 Richard Guenther + + * gcc.dg/lto/20100426_0.c: New testcase. + +2010-04-26 Jie Zhang + + PR tree-optimization/43833 + gcc.dg/Warray-bounds-8.c: New test case. + +2010-04-26 Richard Guenther + + PR lto/43080 + * g++.dg/lto/20100423-3_0.C: New testcase. + +2010-04-26 Richard Guenther + + PR lto/42425 + * g++.dg/lto/20100423-2_0.C: New testcase. + +2010-04-26 Ira Rosen + + * gcc.dg/vect/bb-slp-23.c: New test. + +2010-04-25 Joseph Myers + + * gcc.dg/c90-float-1.c: Also test that C1X macros are not defined. + * gcc.dg/c99-float-1.c: Also test that C1X macros are not defined. + * gcc.dg/c1x-float-1.c: New test. + +2010-04-25 H.J. Lu + + * gcc.target/i386/pr43766.c: Scan "lea\[lq\]?\[ \t\]" instead + of "lea\[ \t\]". + +2010-04-25 Steven G. Kargl + + * gfortran.dg/default_format_denormal_2.f90: Remove XFAIL for + FreeBSD. + * gfortran.dg/default_format_denormal_1.f90: Ditto. + * gfortran.dg/default_format_2.f90: Ditto. + +2010-04-25 Steven G. Kargl + + * gfortran.dg/pr43505.f90: Clean up .mod file. + * gfortran.dg/host_assoc_blockdata_1.f90: Ditto. + * gfortran.dg/pr41347.f90: Ditto. + * gfortran.dg/internal_pack_4.f90: Ditto. + * gfortran.dg/proc_decl_23.f90: Ditto. + * gfortran.dg/recursive_check_3.f90: Ditto. + * gfortran.dg/intent_out_3.f90: Ditto. + * gfortran.dg/assignment_2.f90: Ditto. + * gfortran.dg/pr41928.f90: Ditto. + * gfortran.dg/pr42166.f90: Ditto. + * gfortran.dg/private_type_12.f90: Ditto. + * gfortran.dg/graphite/pr42185.f90: Ditto. + * gfortran.dg/graphite/pr42186.f90: Ditto. + * gfortran.dg/graphite/pr40982.f90: Ditto. + * gfortran.dg/graphite/id-2.f90: Ditto. + * gfortran.dg/graphite/id-4.f90: Ditto. + * gfortran.dg/graphite/pr42050.f90: Ditto. + * gfortran.dg/graphite/id-18.f90: Ditto. + * gfortran.dg/graphite/pr42393-1.f90: Ditto. + * gfortran.dg/graphite/pr41924.f90: Ditto. + * gfortran.dg/graphite/pr42393.f90: Ditto. + * gfortran.dg/graphite/pr37980.f90: Ditto. + * gfortran.dg/graphite/pr38953.f90: Ditto. + * gfortran.dg/graphite/pr42180.f90: Ditto. + * gfortran.dg/graphite/pr42181.f90: Ditto. + * gfortran.dg/where_operator_assign_4.f90: Ditto. + * gfortran.dg/select_type_4.f90: Ditto. + * gfortran.dg/redefined_intrinsic_assignment.f90: Ditto. + * gfortran.dg/host_assoc_blockdata_2.f90: Ditto. + * gfortran.dg/lto/pr40725_0.f03: Ditto. + * gfortran.dg/elemental_args_check_2.f90: Ditto. + * gfortran.dg/whole_file_11.f90: Ditto. + * gfortran.dg/private_type_11.f90: Ditto. + * gfortran.dg/vect/vect-gems.f90: Ditto. + * gfortran.dg/vect/fast-math-real8-pr40801.f90: Ditto. + +2010-04-25 H.J. Lu + + * gcc.target/i386/pr43766.c: Scan "lea\[ \t\]" instead of "lea". + 2010-04-25 Eric Botcazou * gnat.dg/pack15.ad[sb]: New test. diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C index ea06d92530f..ad3274a2ea9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C +++ b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C @@ -15,9 +15,9 @@ A::A() = default; // { dg-error "redefinition" } void g() {} // { dg-error "previous" } void g() = delete; // { dg-error "redefinition" } -struct B +struct B // { dg-message "user-provided default constructor" } { - B() = default; + B() = default; // { dg-message "not user-provided" } }; const B b; // { dg-error "uninitialized const" } diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C new file mode 100644 index 00000000000..718d49cd9bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce2.C @@ -0,0 +1,7 @@ +// PR c++/43875 +// { dg-options "-std=c++0x" } + +int main() +{ + auto x2 = []{ return { 1, 2 }; }; // { dg-message "return" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C new file mode 100644 index 00000000000..1ea8f4d7b58 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice1.C @@ -0,0 +1,13 @@ +// PR c++/43790 +// { dg-options "-std=c++0x" } + +struct A +{ + int f(); +}; + +int main() +{ + A a; + auto l = [] () { return a.f(); }; // { dg-error "not captured|return" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C new file mode 100644 index 00000000000..04fe474c733 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this2.C @@ -0,0 +1,17 @@ +// PR c++/43856 +// Test for implicit 'this' capture via rewriting. +// { dg-options "-std=c++0x" } + +struct S1 { + int operator()(int); + int i; + void g(); + void f() { + [=]() { + i; + g(); + S1::g(); + operator()(42); + }; + } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr42844-2.C b/gcc/testsuite/g++.dg/cpp0x/pr42844-2.C new file mode 100644 index 00000000000..5af4ff217f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr42844-2.C @@ -0,0 +1,38 @@ +// PR c++/42844 +// { dg-do compile } +// { dg-options "-std=c++0x" } + +struct A // { dg-message "user-provided default constructor" } +{ + A() = default; // { dg-message "not user-provided" } +}; + +struct Base +{ + Base() {} +}; + +struct Derived : Base // { dg-message "user-provided default constructor" } +{ + Derived() = default; // { dg-message "not user-provided" } +}; + +struct Derived2 : Base // { dg-message "user-provided default constructor" } +{ + Derived2() = default; // { dg-message "not user-provided" } + Derived2( Derived2 const& ) = default; +}; + +struct Derived3 : Base // { dg-message "user-provided default constructor" } +{ + Derived3( Derived3 const& ) = default; + Derived3() = default; // { dg-message "not user-provided" } +}; + +void f() +{ + const A a; // { dg-error "uninitialized const" } + const Derived d; // { dg-error "uninitialized const" } + const Derived2 d2; // { dg-error "uninitialized const" } + const Derived3 d3; // { dg-error "uninitialized const" } +} diff --git a/gcc/testsuite/g++.dg/init/pr29043.C b/gcc/testsuite/g++.dg/init/pr29043.C new file mode 100644 index 00000000000..6ed31b5d6b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr29043.C @@ -0,0 +1,52 @@ +// PR c++/29043 +// { dg-do compile } + +struct S +{ + int const i; // { dg-message "should be initialized" } +}; + +class C +{ +public: + C() {} // { dg-error "uninitialized const member" } + S s; +}; + +struct S2 +{ + int& ref; // { dg-message "should be initialized" } +}; + +class C2 +{ +public: + C2() {} // { dg-error "uninitialized reference member" } + S2 s; +}; + +class C3 +{ + C3() { } + struct s { + const int i; + }; +}; + +struct S4 +{ + int const i; // { dg-message "should be initialized" } +}; + +struct C4 +{ + C4() {} // { dg-error "uninitialized const member" } + S4 s4[ 1 ]; +}; + +struct C5 +{ + C5() {} // { dg-message "uninitialized" } + int const iit[ 1 ]; +}; + diff --git a/gcc/testsuite/g++.dg/init/pr42844.C b/gcc/testsuite/g++.dg/init/pr42844.C new file mode 100644 index 00000000000..7b423ccb64b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/pr42844.C @@ -0,0 +1,56 @@ +// PR c++/42844 +// { dg-do compile } + +struct A +{ + A(){} +}; + +struct B : A {}; // { dg-message "user-provided default constructor" } + +struct C : A {}; // { dg-message "user-provided default constructor" } + +struct D : B { D() {} }; + +struct E {}; // { dg-message "user-provided default constructor" } + +template +struct F : A {}; // { dg-message "user-provided default constructor" } + +template +struct G {}; // { dg-message "user-provided default constructor" } + +void f () +{ + B const b; // { dg-error "uninitialized const" } + extern B const bext; + + C const c[ 1 ]; // { dg-error "uninitialized const" } + extern C const cext[ 1 ]; + + D const d; + extern D const dext; + + E const e; // { dg-error "uninitialized const" } + extern E const eext; + + F const f; // { dg-error "uninitialized const" } + extern F const fext; + + G const g; // { dg-error "uninitialized const" } + extern G const gext; +} + +struct H {}; // { dg-message "user-provided default constructor" } + +struct I : A {}; // { dg-message "user-provided default constructor" } + +template +void g () +{ + T const t; // { dg-error "uninitialized const" } + extern T const text; +} + +template void g (); +template void g (); diff --git a/gcc/testsuite/g++.dg/ipa/pr43812.C b/gcc/testsuite/g++.dg/ipa/pr43812.C new file mode 100644 index 00000000000..cc46eed6501 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr43812.C @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fwhole-program -fipa-cp" } */ + +typedef float scoord_t; +typedef scoord_t sdist_t; +typedef sdist_t dist_t; +template class TRay { }; +typedef TRay Ray; +class BBox { }; +class RenderContext { }; +class RefCounted { +public: + void deref () const { + if (--ref_count <= 0) { + delete this; + } + } + mutable int ref_count; +}; +template class Ref { +public: + ~Ref () { + if (obj) obj->deref (); + } + T *obj; +}; +class Material : public RefCounted { }; +class Surface { +public: + virtual ~Surface () { } + class IsecInfo { }; + virtual const IsecInfo *intersect (Ray &ray, RenderContext &context) const; + Ref material; +}; +class LocalSurface : public Surface { + virtual BBox bbox () const; +}; +BBox LocalSurface::bbox () const { } diff --git a/gcc/testsuite/g++.dg/lookup/scoped5.C b/gcc/testsuite/g++.dg/lookup/scoped5.C index 37ac16423e1..a4aa7298f2c 100644 --- a/gcc/testsuite/g++.dg/lookup/scoped5.C +++ b/gcc/testsuite/g++.dg/lookup/scoped5.C @@ -9,11 +9,11 @@ class A { public: class B { public: - int a; // { dg-error "object missing" } + int a; }; }; class C { public: - void f(void) { sizeof(A::B::a); } // { dg-error "this location" } + void f(void) { sizeof(A::B::a); } }; diff --git a/gcc/testsuite/g++.dg/lookup/scoped8.C b/gcc/testsuite/g++.dg/lookup/scoped8.C index 2ba28a6941b..2764f75c135 100644 --- a/gcc/testsuite/g++.dg/lookup/scoped8.C +++ b/gcc/testsuite/g++.dg/lookup/scoped8.C @@ -7,7 +7,7 @@ struct A { - int i; // { dg-error "object missing" } + int i; // { dg-error "non-static" } }; template struct B diff --git a/gcc/testsuite/g++.dg/lto/20100423-2_0.C b/gcc/testsuite/g++.dg/lto/20100423-2_0.C new file mode 100644 index 00000000000..2ab6bdc56ef --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/20100423-2_0.C @@ -0,0 +1,14 @@ +// { dg-lto-do assemble } +// { dg-lto-options {{-flto -g}} } + +struct A +{ + virtual ~A(); +}; + +void foo() +{ + struct B : A {}; + B b; +} + diff --git a/gcc/testsuite/g++.dg/lto/20100423-3_0.C b/gcc/testsuite/g++.dg/lto/20100423-3_0.C new file mode 100644 index 00000000000..49564a586b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/20100423-3_0.C @@ -0,0 +1,14 @@ +// { dg-lto-do assemble } +// { dg-lto-options {{-flto -g}} } + +inline int foo() +{ + static union { int i; }; + return i; +} + +void bar() +{ + foo(); +} + diff --git a/gcc/testsuite/g++.dg/other/pr40561.C b/gcc/testsuite/g++.dg/other/pr40561.C new file mode 100644 index 00000000000..c94dfa4bd62 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr40561.C @@ -0,0 +1,38 @@ +// { dg-do compile } + +#include + +class SyAccess; +class VamsBase +{ + public: + virtual ~VamsBase(void); +}; + +class VamsFnct : public VamsBase +{ + public: + ~VamsFnct(void); + std::set getNullDependencies(void) const + { return std::set(); + } +}; + +class VamsFnctSystem:public VamsFnct +{ public: + VamsFnctSystem( + const bool _bPassDependencies); +}; + +template< std::set (VamsFnct::*__GET_DEP__)(void) const > +class VamsSystemFunction:public VamsFnctSystem +{ public: + VamsSystemFunction() + :VamsFnctSystem( + __GET_DEP__ != &VamsFnct::getNullDependencies + ) + { + } +}; + +VamsSystemFunction<&VamsFnct::getNullDependencies> s; diff --git a/gcc/testsuite/g++.dg/template/dependent-expr5.C b/gcc/testsuite/g++.dg/template/dependent-expr5.C index 64e86c7289f..db67273b362 100644 --- a/gcc/testsuite/g++.dg/template/dependent-expr5.C +++ b/gcc/testsuite/g++.dg/template/dependent-expr5.C @@ -18,7 +18,7 @@ template void bindb(F (T::*f)(void)) {} // { dg-message "note" struct foo { static int baist; - int bait; + int bait; // { dg-error "non-static data member" } void barf (); static void barf (int); @@ -31,7 +31,7 @@ struct foo { bar() { bind (&baist); bind (&foo::baist); - bind (&bait); // { dg-error "nonstatic data member" } + bind (&bait); // { dg-error "from this location" } bind (&foo::bait); bind (&baikst); @@ -75,7 +75,7 @@ struct foo { barT() { bind (&baist); bind (&foo::baist); - bind (&bait); // { dg-error "nonstatic data member" } + bind (&bait); // { dg-error "from this location" } bind (&foo::bait); bind (&baikst); diff --git a/gcc/testsuite/g++.dg/template/pr23510.C b/gcc/testsuite/g++.dg/template/pr23510.C index a0806e245c5..b9e9889e9c0 100644 --- a/gcc/testsuite/g++.dg/template/pr23510.C +++ b/gcc/testsuite/g++.dg/template/pr23510.C @@ -4,7 +4,7 @@ template struct Factorial { enum { nValue = nFactor * Factorial::nValue }; // { dg-error "depth exceeds maximum" } - // { dg-message "skipping 5 instantiation contexts" "" { target *-*-* } 6 } + // { dg-message "recursively instantiated" "" { target *-*-* } 6 } // { dg-error "incomplete type" "" { target *-*-* } 6 } } diff --git a/gcc/testsuite/g++.dg/template/recurse.C b/gcc/testsuite/g++.dg/template/recurse.C index 17fe1866eb2..448c34721c2 100644 --- a/gcc/testsuite/g++.dg/template/recurse.C +++ b/gcc/testsuite/g++.dg/template/recurse.C @@ -8,8 +8,7 @@ template struct F F f; // { dg-error "incomplete type" "incomplete" } // { dg-bogus "exceeds maximum.*exceeds maximum" "exceeds" { xfail *-*-* } 8 } // { dg-error "exceeds maximum" "exceeds" { xfail *-*-* } 8 } - return f()*I; // { dg-message "instantiated" "recurse" } - // { dg-message "skipping 40 instantiation contexts" "" { target *-*-* } 11 } + return f()*I; // { dg-message "recursively instantiated" "recurse" } } }; diff --git a/gcc/testsuite/g++.dg/template/recurse2.C b/gcc/testsuite/g++.dg/template/recurse2.C index cf085e0d553..b9767dfb600 100644 --- a/gcc/testsuite/g++.dg/template/recurse2.C +++ b/gcc/testsuite/g++.dg/template/recurse2.C @@ -3,5 +3,6 @@ template struct X { static const int value = X::value; // { dg-error "instantiation|incomplete" } + // { dg-message "recursively instantiated" "" { target *-*-* } 5 } }; template struct X<1000>; diff --git a/gcc/testsuite/g++.dg/template/sfinae17.C b/gcc/testsuite/g++.dg/template/sfinae17.C new file mode 100644 index 00000000000..eb043cbddfb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae17.C @@ -0,0 +1,28 @@ +// The conversion from D* to B* is ambiguous, but that should not produce +// an error, it should remove the first f overload by SFINAE. + +#define static_assert(TEST,STR) \ + do { int ar[(TEST)?1:-1]; } while (0); + +struct B {}; + +struct B1 : B {}; +struct B2 : B {}; + +struct D : B1, B2 {}; + +template T create(); + +typedef char one[1]; +typedef char two[2]; + +template + one &f(char (*)[sizeof static_cast(create())]); +template + two &f(...); + +int main() +{ + static_assert(sizeof f(0) == sizeof(two), ""); + static_assert(sizeof f(0) == sizeof(two), ""); +} diff --git a/gcc/testsuite/g++.dg/template/sfinae18.C b/gcc/testsuite/g++.dg/template/sfinae18.C new file mode 100644 index 00000000000..bbc39cb3ac0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae18.C @@ -0,0 +1,10 @@ +// PR c++/41468 + +typedef int Ft(int); +struct A { operator Ft*(); }; +struct B { operator Ft*(); }; +struct C : A, B { }; + +template void f(int (*a)[sizeof(C()(0))]); +template void f(...); +int main() { f(0); } diff --git a/gcc/testsuite/g++.dg/torture/pr43880.C b/gcc/testsuite/g++.dg/torture/pr43880.C new file mode 100644 index 00000000000..bf82bc54bc6 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr43880.C @@ -0,0 +1,16 @@ +// { dg-do compile } + +extern void xread(void *); +class test +{ +public: + test(void); +}; +test::test(void) +{ + union { + char pngpal[1]; + }; + xread(pngpal); +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27549.C b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C index 2dc98a22019..cd5944d2439 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr27549.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C @@ -13,6 +13,7 @@ struct E struct F : public E { + F () {} virtual ~F () {} virtual size_t e () const { return 0; } virtual void f (char *x) const { *x = '\0'; } diff --git a/gcc/testsuite/g++.dg/uninit-pred-1_a.C b/gcc/testsuite/g++.dg/uninit-pred-1_a.C new file mode 100644 index 00000000000..58bb9c5d45a --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-1_a.C @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +typedef long long int64; +void incr (); +bool is_valid (int); +int get_time (); + +class A +{ +public: + A (); + ~A () { + if (I) delete I; + } + +private: + int* I; +}; + +bool get_url (A *); + +class M { + + public: +__attribute__ ((always_inline)) int GetC (int *c) { + + A details_str; + if (!get_url (&details_str)) + { + incr (); + return 1; + } + + *c = get_time (); + return -1; + } + + void do_sth(); + void do_sth2(); + + void P (int64 t) + { + int cc; /* { dg-bogus "uninitialized" "uninitialized variable warning" } */ + if (GetC (&cc) >= 0 ) + return; + + if (t && cc <= 0 ) /* { dg-bogus "uninitialized" "uninitialized variable warning" } */ + { + this->do_sth(); + return; + } + + do_sth2(); + } +}; + +M* m; +void foo(int x) +{ + m = new M; + m->P(x); +} diff --git a/gcc/testsuite/g++.dg/uninit-pred-1_b.C b/gcc/testsuite/g++.dg/uninit-pred-1_b.C new file mode 100644 index 00000000000..94a444d21ef --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-1_b.C @@ -0,0 +1,63 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +typedef long long int64; +void incr (); +bool is_valid (int); +int get_time (); + +class A +{ +public: + A (); + ~A () { + if (I) delete I; + } + +private: + int* I; +}; + +bool get_url (A *); + +class M { + + public: +__attribute__ ((always_inline)) int GetC (int *c) { + + A details_str; + if (!get_url (&details_str)) + { + incr (); + return 1; + } + + *c = get_time (); + return -1; + } + + void do_sth(); + void do_sth2(); + + void P (int64 t) + { + int cc; /* { dg-message "note: 'cc' was declared here" } */ + if (GetC (&cc) <= 0 ) /* return flag checked wrongly */ + return; + + if (t && cc <= 0 ) /* { dg-warning "uninitialized" "uninitialized variable warning" } */ + { + this->do_sth(); + return; + } + + do_sth2(); + } +}; + +M* m; +void foo(int x) +{ + m = new M; + m->P(x); +} diff --git a/gcc/testsuite/g++.dg/uninit-pred-2_a.C b/gcc/testsuite/g++.dg/uninit-pred-2_a.C new file mode 100644 index 00000000000..918c94375c2 --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-2_a.C @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +typedef long long int64; +void incr (); +bool is_valid (int); +int get_time (); + +class A +{ +public: + A (); + ~A () { + if (I) delete I; + } + +private: + int* I; +}; + +bool get_url (A *); + +class M { + + public: +__attribute__ ((always_inline)) bool GetC (int *c) { + + A details_str; + if (get_url (&details_str)) + { + *c = get_time (); + return true; + } + + return false; + } + + void do_sth(); + void do_sth2(); + + void P (int64 t) + { + int cc; + if (!GetC (&cc)) /* return flag checked properly */ + return; + + if (cc <= 0) /* { dg-bogus "uninitialized" "uninitialized variable warning" } */ + { + this->do_sth(); + return; + } + + do_sth2(); + } +}; + +M* m; +void foo(int x) +{ + m = new M; + m->P(x); +} diff --git a/gcc/testsuite/g++.dg/uninit-pred-2_b.C b/gcc/testsuite/g++.dg/uninit-pred-2_b.C new file mode 100644 index 00000000000..5023fc50b6b --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-2_b.C @@ -0,0 +1,62 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +typedef long long int64; +void incr (); +bool is_valid (int); +int get_time (); + +class A +{ +public: + A (); + ~A () { + if (I) delete I; + } + +private: + int* I; +}; + +bool get_url (A *); + +class M { + + public: +__attribute__ ((always_inline)) bool GetC (int *c) { + + A details_str; + if (get_url (&details_str)) + { + *c = get_time (); + return true; + } + + return false; + } + + void do_sth(); + void do_sth2(); + + void P (int64 t) + { + int cc; /* { dg-message "note: 'cc' was declared here" } */ + if (GetC (&cc)) /* return flag checked wrongly */ + return; + + if (cc <= 0) /* { dg-warning "uninitialized" "uninitialized variable warning" } */ + { + this->do_sth(); + return; + } + + do_sth2(); + } +}; + +M* m; +void foo(int x) +{ + m = new M; + m->P(x); +} diff --git a/gcc/testsuite/g++.dg/uninit-pred-loop-1_a.cc b/gcc/testsuite/g++.dg/uninit-pred-loop-1_a.cc new file mode 100644 index 00000000000..835cdbae320 --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-loop-1_a.cc @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +extern int bar(); +int foo(void) +{ + for (;;) { + int err = ({int _err; /* { dg-bogus "uninitialized" "false warning" } */ + for (int i = 0; i < 16; ++i) { + _err = 17; + _err = bar(); + } + _err; /* { dg-bogus "uninitialized" "false warning" } */ + }); + + if (err == 0) return 17; + } + + return 18; +} + diff --git a/gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc b/gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc new file mode 100644 index 00000000000..e4ef3d22c06 --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-loop-1_b.cc @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +extern int bar(); +int foo(int n) +{ + for (;;) { + int err = ({int _err; + for (int i = 0; i < n; ++i) { + _err = 17; + _err = bar(); + } + _err; + }); /* { dg-warning "uninitialized" "warn on _err" } */ + + if (err == 0) return 17; + } + + return 18; +} + diff --git a/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc b/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc new file mode 100644 index 00000000000..7f6b41d31ff --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-loop-1_c.cc @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +extern int bar(); +int foo(int n, int m) +{ + for (;;) { + int err = ({int _err; + for (int i = 0; i < 16; ++i) { + if (m+i > n) + break; + _err = 17; + _err = bar(); + } + _err; + }); + + if (err == 0) return 17; }); /* { dg-warning "uninitialized" "warn on _err" } */ + } + + return 18; +} + diff --git a/gcc/testsuite/g++.dg/uninit-pred-loop_1.cc b/gcc/testsuite/g++.dg/uninit-pred-loop_1.cc new file mode 100644 index 00000000000..835cdbae320 --- /dev/null +++ b/gcc/testsuite/g++.dg/uninit-pred-loop_1.cc @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +extern int bar(); +int foo(void) +{ + for (;;) { + int err = ({int _err; /* { dg-bogus "uninitialized" "false warning" } */ + for (int i = 0; i < 16; ++i) { + _err = 17; + _err = bar(); + } + _err; /* { dg-bogus "uninitialized" "false warning" } */ + }); + + if (err == 0) return 17; + } + + return 18; +} + diff --git a/gcc/testsuite/g++.dg/warn/string1.C b/gcc/testsuite/g++.dg/warn/string1.C index 302772795cd..2670f63d931 100644 --- a/gcc/testsuite/g++.dg/warn/string1.C +++ b/gcc/testsuite/g++.dg/warn/string1.C @@ -2,7 +2,7 @@ // { dg-options "-O" } #include -int main() { +int test() { // blank line padding, could also be code... // // diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/nest1.C b/gcc/testsuite/g++.old-deja/g++.brendan/nest1.C index 7763538d50b..842b2f692e6 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/nest1.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/nest1.C @@ -3,7 +3,7 @@ int x; class enclose { public: - int x; + int x; // { dg-error "non-static" } class inner { public: diff --git a/gcc/testsuite/g++.old-deja/g++.mike/dyncast8.C b/gcc/testsuite/g++.old-deja/g++.mike/dyncast8.C index 65542b89535..e2c5a2df9a6 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/dyncast8.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/dyncast8.C @@ -7,7 +7,11 @@ public: virtual ~Base() { } }; -class Derived : public Base { }; +class Derived : public Base +{ +public: + Derived() {} +}; int main() { diff --git a/gcc/testsuite/gcc.dg/Walways-true-1.c b/gcc/testsuite/gcc.dg/Walways-true-1.c index 32b921c3fa7..e4e4596cb44 100644 --- a/gcc/testsuite/gcc.dg/Walways-true-1.c +++ b/gcc/testsuite/gcc.dg/Walways-true-1.c @@ -26,32 +26,32 @@ bar (int a) foo (5); if (&&lab) /* { dg-warning "7:always evaluate as" "correct warning" } */ foo (6); - if (foo == 0) /* { dg-warning "11:never be NULL" "correct warning" } */ + if (foo == 0) /* { dg-warning "11:the comparison will always evaluate as 'false'" "correct warning" } */ foo (7); if (foo (1) == 0) foo (8); - if (&i == 0) /* { dg-warning "10:never be NULL" "correct warning" } */ + if (&i == 0) /* { dg-warning "10:the comparison will always evaluate as 'false'" "correct warning" } */ foo (9); if (i == 0) foo (10); - if (&a == 0) /* { dg-warning "10:never be NULL" "correct warning" } */ + if (&a == 0) /* { dg-warning "10:the comparison will always evaluate as 'false'" "correct warning" } */ foo (11); if (a == 0) foo (12); - if (&&lab == 0) /* { dg-warning "13:never be NULL" "correct warning" } */ + if (&&lab == 0) /* { dg-warning "13:the comparison will always evaluate as 'false'" "correct warning" } */ foo (13); - if (0 == foo) /* { dg-warning "9:never be NULL" "correct warning" } */ + if (0 == foo) /* { dg-warning "9:the comparison will always evaluate as 'false'" "correct warning" } */ foo (14); if (0 == foo (1)) foo (15); - if (0 == &i) /* { dg-warning "9:never be NULL" "correct warning" } */ + if (0 == &i) /* { dg-warning "9:the comparison will always evaluate as 'false'" "correct warning" } */ foo (16); if (0 == i) foo (17); - if (0 == &a) /* { dg-warning "9:never be NULL" "correct warning" } */ + if (0 == &a) /* { dg-warning "9:the comparison will always evaluate as 'false'" "correct warning" } */ foo (18); if (0 == a) foo (19); - if (0 == &&lab) /* { dg-warning "9:never be NULL" "correct warning" } */ + if (0 == &&lab) /* { dg-warning "9:the comparison will always evaluate as 'false'" "correct warning" } */ foo (20); } diff --git a/gcc/testsuite/gcc.dg/Walways-true-2.c b/gcc/testsuite/gcc.dg/Walways-true-2.c index c14857eaee6..af40ba65a5a 100644 --- a/gcc/testsuite/gcc.dg/Walways-true-2.c +++ b/gcc/testsuite/gcc.dg/Walways-true-2.c @@ -37,11 +37,11 @@ bar (int a) foo (9); if (i == 0) foo (10); - if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */ + if (&a == 0) /* { dg-warning "the comparison will always evaluate as 'false'" "correct warning" } */ foo (11); if (a == 0) foo (12); - if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */ + if (&&lab == 0) /* { dg-warning "the comparison will always evaluate as 'false'" "correct warning" } */ foo (13); if (0 == foo) foo (14); @@ -51,10 +51,10 @@ bar (int a) foo (16); if (0 == i) foo (17); - if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */ + if (0 == &a) /* { dg-warning "the comparison will always evaluate as 'false'" "correct warning" } */ foo (18); if (0 == a) foo (19); - if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */ + if (0 == &&lab) /* { dg-warning "the comparison will always evaluate as 'false'" "correct warning" } */ foo (20); } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-8.c b/gcc/testsuite/gcc.dg/Warray-bounds-8.c new file mode 100644 index 00000000000..85839f3f07e --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-8.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Wall" } */ +/* based on PR 43833 */ + +extern unsigned char data[5]; + +unsigned char +foo (char *str) +{ + int i, j; + unsigned char c = 0; + + for (i = 0; i < 8; i++) + { + j = i * 5; + if ((j % 8) > 3) + c |= data[(j / 8) + 1]; + } + return c; +} diff --git a/gcc/testsuite/gcc.dg/c99-float-1.c b/gcc/testsuite/gcc.dg/c1x-float-1.c similarity index 71% copy from gcc/testsuite/gcc.dg/c99-float-1.c copy to gcc/testsuite/gcc.dg/c1x-float-1.c index 07fb9ee8bfb..75233ac8227 100644 --- a/gcc/testsuite/gcc.dg/c99-float-1.c +++ b/gcc/testsuite/gcc.dg/c1x-float-1.c @@ -1,9 +1,9 @@ -/* Test for C99 macros. */ -/* Origin: Joseph Myers */ +/* Test for C1X macros. */ +/* Origin: Joseph Myers */ /* { dg-do preprocess } */ -/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ +/* { dg-options "-std=c1x -pedantic-errors" } */ -/* This test checks that the C99 macros are defined; +/* This test checks that the C1X macros are defined; it does not check the correctness of their values. */ #include @@ -131,3 +131,39 @@ #ifndef DECIMAL_DIG #error "DECIMAL_DIG undefined" #endif + +#ifndef FLT_DECIMAL_DIG +#error "FLT_DECIMAL_DIG undefined" +#endif + +#ifndef DBL_DECIMAL_DIG +#error "DBL_DECIMAL_DIG undefined" +#endif + +#ifndef LDBL_DECIMAL_DIG +#error "LDBL_DECIMAL_DIG undefined" +#endif + +#ifndef FLT_HAS_SUBNORM +#error "FLT_HAS_SUBNORM undefined" +#endif + +#ifndef DBL_HAS_SUBNORM +#error "DBL_HAS_SUBNORM undefined" +#endif + +#ifndef LDBL_HAS_SUBNORM +#error "LDBL_HAS_SUBNORM undefined" +#endif + +#ifndef FLT_TRUE_MIN +#error "FLT_TRUE_MIN undefined" +#endif + +#ifndef DBL_TRUE_MIN +#error "DBL_TRUE_MIN undefined" +#endif + +#ifndef LDBL_TRUE_MIN +#error "LDBL_TRUE_MIN undefined" +#endif diff --git a/gcc/testsuite/gcc.dg/c90-float-1.c b/gcc/testsuite/gcc.dg/c90-float-1.c index 39a585bcd09..5a2cab657a3 100644 --- a/gcc/testsuite/gcc.dg/c90-float-1.c +++ b/gcc/testsuite/gcc.dg/c90-float-1.c @@ -3,8 +3,8 @@ /* { dg-do preprocess } */ /* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ -/* This test checks that the C90 macros (but not the C99 ones) are defined; - it does not check the correctness of their values. */ +/* This test checks that the C90 macros (but not the C99 or C1X ones) + are defined; it does not check the correctness of their values. */ #include @@ -131,3 +131,39 @@ #ifdef DECIMAL_DIG #error "DECIMAL_DIG defined" #endif + +#ifdef FLT_DECIMAL_DIG +#error "FLT_DECIMAL_DIG defined" +#endif + +#ifdef DBL_DECIMAL_DIG +#error "DBL_DECIMAL_DIG defined" +#endif + +#ifdef LDBL_DECIMAL_DIG +#error "LDBL_DECIMAL_DIG defined" +#endif + +#ifdef FLT_HAS_SUBNORM +#error "FLT_HAS_SUBNORM defined" +#endif + +#ifdef DBL_HAS_SUBNORM +#error "DBL_HAS_SUBNORM defined" +#endif + +#ifdef LDBL_HAS_SUBNORM +#error "LDBL_HAS_SUBNORM defined" +#endif + +#ifdef FLT_TRUE_MIN +#error "FLT_TRUE_MIN defined" +#endif + +#ifdef DBL_TRUE_MIN +#error "DBL_TRUE_MIN defined" +#endif + +#ifdef LDBL_TRUE_MIN +#error "LDBL_TRUE_MIN defined" +#endif diff --git a/gcc/testsuite/gcc.dg/c99-float-1.c b/gcc/testsuite/gcc.dg/c99-float-1.c index 07fb9ee8bfb..f0dc39136e9 100644 --- a/gcc/testsuite/gcc.dg/c99-float-1.c +++ b/gcc/testsuite/gcc.dg/c99-float-1.c @@ -3,7 +3,7 @@ /* { dg-do preprocess } */ /* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ -/* This test checks that the C99 macros are defined; +/* This test checks that the C99 macros (but not the C1X ones) are defined; it does not check the correctness of their values. */ #include @@ -131,3 +131,39 @@ #ifndef DECIMAL_DIG #error "DECIMAL_DIG undefined" #endif + +#ifdef FLT_DECIMAL_DIG +#error "FLT_DECIMAL_DIG defined" +#endif + +#ifdef DBL_DECIMAL_DIG +#error "DBL_DECIMAL_DIG defined" +#endif + +#ifdef LDBL_DECIMAL_DIG +#error "LDBL_DECIMAL_DIG defined" +#endif + +#ifdef FLT_HAS_SUBNORM +#error "FLT_HAS_SUBNORM defined" +#endif + +#ifdef DBL_HAS_SUBNORM +#error "DBL_HAS_SUBNORM defined" +#endif + +#ifdef LDBL_HAS_SUBNORM +#error "LDBL_HAS_SUBNORM defined" +#endif + +#ifdef FLT_TRUE_MIN +#error "FLT_TRUE_MIN defined" +#endif + +#ifdef DBL_TRUE_MIN +#error "DBL_TRUE_MIN defined" +#endif + +#ifdef LDBL_TRUE_MIN +#error "LDBL_TRUE_MIN defined" +#endif diff --git a/gcc/testsuite/gcc.dg/const-1.c b/gcc/testsuite/gcc.dg/const-1.c new file mode 100644 index 00000000000..2657c9b5738 --- /dev/null +++ b/gcc/testsuite/gcc.dg/const-1.c @@ -0,0 +1,57 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wsuggest-attribute=const" } */ + +extern int extern_const(int a) __attribute__ ((const)); + +/* Trivial. */ +int +foo1(int a) /* { dg-bogus "normally" "detect const candidate" } */ +{ /* { dg-warning "const" "detect const candidate" { target *-*-* } "8" } */ + return extern_const (a); +} + +/* Loops known to be normally and extern const calls should be safe. */ + +int __attribute__ ((noinline)) +foo2(int n) /* { dg-bogus "normally" "detect const candidate" } */ +{ /* { dg-warning "const" "detect const candidate" { target *-*-* } "16" } */ + int ret = 0; + int i; + for (i=0; ip = (void *)0; if (a.p != (void *)0) abort (); diff --git a/gcc/testsuite/gcc.dg/lto/20091209-1_0.c b/gcc/testsuite/gcc.dg/lto/20091209-1_0.c new file mode 100644 index 00000000000..5aa2fe0b058 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091209-1_0.c @@ -0,0 +1,23 @@ +/* Stream an indirect edge in and out. */ + +/* { dg-lto-do link } */ +/* { dg-lto-options {{ -O3 -fno-early-inlining -flto }} } */ + +volatile int something; + +static void hooray () +{ + something = 1; +} + +static void hiphip (void (*f)()) +{ + something = 2; + f (); +} + +int main (int argc, int *argv[]) +{ + hiphip (hooray); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/20100426_0.c b/gcc/testsuite/gcc.dg/lto/20100426_0.c new file mode 100644 index 00000000000..e1dc06f960b --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20100426_0.c @@ -0,0 +1,7 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options {{-r -nostdlib -flto -g}} } */ + +long Perl_my_htonl (long l) +{ + union { } u; +} diff --git a/gcc/testsuite/gcc.dg/lto/const-uniq_0.c b/gcc/testsuite/gcc.dg/lto/const-uniq_0.c new file mode 100644 index 00000000000..746167c6517 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/const-uniq_0.c @@ -0,0 +1,16 @@ +/* The 3 constant initializers should be uniquized. */ + +/* { dg-lto-do run } */ +/* { dg-lto-options {{-Os -flto} {-Os -fwhopr} } } */ + +int lookup1 (int i) +{ + int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + return a[i]; +} + +int lookup2 (int i) +{ + int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + return a[i+1]; +} diff --git a/gcc/testsuite/gcc.dg/lto/const-uniq_1.c b/gcc/testsuite/gcc.dg/lto/const-uniq_1.c new file mode 100644 index 00000000000..ee1505cc9a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/const-uniq_1.c @@ -0,0 +1,23 @@ +extern int lookup1 (int i); +extern int lookup2 (int i); +extern void abort (void); + +int lookup3 (int i) +{ + int a[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + return a[i+2]; +} + +int main (void) +{ + if (lookup1(2) != 2) + abort (); + + if (lookup2(2) != 3) + abort (); + + if (lookup3(2) != 4) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/misc-column.c b/gcc/testsuite/gcc.dg/misc-column.c index a24427e4baa..e68300bfc29 100644 --- a/gcc/testsuite/gcc.dg/misc-column.c +++ b/gcc/testsuite/gcc.dg/misc-column.c @@ -19,7 +19,7 @@ void foo (void) if (p < q) /* { dg-warning "9:comparison of distinct pointer types" } */ bar (); - if (&p == 0) /* { dg-warning "10:will never be NULL" } */ + if (&p == 0) /* { dg-warning "10:comparison will always evaluate as 'false'" } */ bar(); if (p == 4) /* { dg-warning "9:comparison between pointer and integer" } */ diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 872a0ea8c3c..a5221b92237 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -68,3 +68,15 @@ foreach plugin_test $plugin_test_list { set plugin_input_tests [lreplace $plugin_test 0 0] plugin-test-execute $plugin_src $plugin_input_tests } + +# run the plugindir tests + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/plugindir*.\[cSi\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/plugindir1.c b/gcc/testsuite/gcc.dg/plugin/plugindir1.c similarity index 100% rename from gcc/testsuite/gcc.dg/plugindir1.c rename to gcc/testsuite/gcc.dg/plugin/plugindir1.c diff --git a/gcc/testsuite/gcc.dg/plugindir2.c b/gcc/testsuite/gcc.dg/plugin/plugindir2.c similarity index 100% rename from gcc/testsuite/gcc.dg/plugindir2.c rename to gcc/testsuite/gcc.dg/plugin/plugindir2.c diff --git a/gcc/testsuite/gcc.dg/plugindir3.c b/gcc/testsuite/gcc.dg/plugin/plugindir3.c similarity index 100% rename from gcc/testsuite/gcc.dg/plugindir3.c rename to gcc/testsuite/gcc.dg/plugin/plugindir3.c diff --git a/gcc/testsuite/gcc.dg/plugindir4.c b/gcc/testsuite/gcc.dg/plugin/plugindir4.c similarity index 100% rename from gcc/testsuite/gcc.dg/plugindir4.c rename to gcc/testsuite/gcc.dg/plugin/plugindir4.c diff --git a/gcc/testsuite/gcc.dg/pr32207.c b/gcc/testsuite/gcc.dg/pr32207.c new file mode 100644 index 00000000000..cf9bef8099a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr32207.c @@ -0,0 +1,9 @@ +/* Test warning for comparison non-null address with null pointer constant. */ +/* Origin: Pawel Sikora */ +/* { dg-do compile } */ +/* { dg-options "-Waddress" } */ +extern void z(); + +void f() { if ( z ) z(); } /* { dg-warning "always evaluate as" } */ +void g() { if ( z != 0 ) z(); } /* { dg-warning "the comparison will always evaluate as 'true'" } */ +void h() { if ( z != (void*)0 ) z(); } /* { dg-warning "the comparison will always evaluate as 'true'" } */ diff --git a/gcc/testsuite/gcc.dg/pure-2.c b/gcc/testsuite/gcc.dg/pure-2.c new file mode 100644 index 00000000000..97ba31f0261 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pure-2.c @@ -0,0 +1,57 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wsuggest-attribute=pure" } */ + +extern int extern_const(int a) __attribute__ ((pure)); +extern int v; + +/* Trivial. */ +int +foo1(int a) /* { dg-bogus "normally" "detect pure candidate" } */ +{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "9" } */ + return v; +} + +/* Loops known to be normally and extern const calls should be safe. */ +int __attribute__ ((noinline)) +foo2(int n) /* { dg-bogus "normally" "detect pure candidate" } */ +{ /* { dg-warning "pure" "detect pure candidate" { target *-*-* } "16" } */ + int ret = 0; + int i; + for (i=0; i 0) + if (flag) + blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-3_b.c b/gcc/testsuite/gcc.dg/uninit-pred-3_b.c new file mode 100644 index 00000000000..978210d5079 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-3_b.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int m, int r) +{ + int flag = 0; + int v; + + if (n) + { + v = r; + flag = 1; + } + + if (m) + g++; + else + bar(); + + if (r > 0) + goto use; + if (flag) + { +use: + blah(v); /* { dg-warning "uninitialized" "real warning" } */ + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-3_c.c b/gcc/testsuite/gcc.dg/uninit-pred-3_c.c new file mode 100644 index 00000000000..1309790786c --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-3_c.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int m, int r) +{ + int flag = 0; + int v; + + if (n) + { + v = r; + flag = -1; + } + + if (m) + g++; + else + bar(); + + if (r > 0) + if (flag < 0) + blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-3_d.c b/gcc/testsuite/gcc.dg/uninit-pred-3_d.c new file mode 100644 index 00000000000..9f938763caa --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-3_d.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int m, int r) +{ + int flag = 0; + int v; + + if (n) + { + v = r; + flag = -1; + } + + if (m) + g++; + else + bar(); + + if (r > 0) + if (flag == -1) + blah(v); /* {dg-bogus "uninitialized" "bogus warning" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-3_e.c b/gcc/testsuite/gcc.dg/uninit-pred-3_e.c new file mode 100644 index 00000000000..66e2a3a9316 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-3_e.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int m, int r) +{ + int flag = 0; + int v; + + if (n) + { + v = r; + flag = -1; + } + + if (m) + g++; + else + bar(); + + if (r > 0) + if (flag <= 0 ) + blah(v); /* { dg-warning "uninitialized" "real warning" } */ + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-4_a.c b/gcc/testsuite/gcc.dg/uninit-pred-4_a.c new file mode 100644 index 00000000000..7b2d291a66f --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-4_a.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); +int foo (int n, int m, int r, int t) +{ + int flag = 0; + int v; + + if (t) + { + if (n) + { + v = r; /* init path 1 */ + flag = 1; + } + + if (m) + g++; + else + bar(); + + if (flag) /* properly guarded */ + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + } + else + { + v = r+1; /* init path 2 */ + flag = 2; + } + + if (m) + g++; + else + bar(); + + if (flag) /* properly guarded */ + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-4_b.c b/gcc/testsuite/gcc.dg/uninit-pred-4_b.c new file mode 100644 index 00000000000..3766395889d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-4_b.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); +int foo (int n, int m, int r, int t) +{ + int flag = 0; + int v; + + if (t) + { + if (n) + { + v = r; /* init path 1 */ + flag = 1; + } + + if (m) g++; + else bar(); + + if (flag) /* properly guarded */ + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + } + else + { + v = r+1; /* init path 2 */ + flag = 2; + } + + if (m) g++; + else bar(); + + if (g) /* guard can not be determined statically to be safe */ + blah(v); /* { dg-warning "uninitialized" "real warning" } */ + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-5_a.c b/gcc/testsuite/gcc.dg/uninit-pred-5_a.c new file mode 100644 index 00000000000..845f3c46124 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-5_a.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +int bar(); +int blah(int); +void t(int); + +__attribute__((always_inline)) +int foo (int n, int* v, int r) +{ + int flag = 0; + if (r > n) + { + *v = bar(); + flag = 1; + } + + if (n > g) + g++; + else + bar(); + + return flag; +} + +int a[100]; +int b[100]; +int blah(int n) +{ + int i; + for (i = 0 ; i < n; i++) + { + int v; + if (!foo (n, &v, b[i])) + return 0; + t (v); /* { dg-bogus "uninitialized" "bogus warning" } */ + } + return 1; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-5_b.c b/gcc/testsuite/gcc.dg/uninit-pred-5_b.c new file mode 100644 index 00000000000..13f1e31f805 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-5_b.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +int bar(); +int blah(int); +void t(int); + +__attribute__((always_inline)) +int foo (int n, int* v, int r) +{ + int flag = 0; + if (r > n) + { + *v = bar(); + flag = 1; + } + + if (n > g) + g++; + else + bar(); + + return flag; +} + +int a[100]; +int b[100]; +int blah(int n) +{ + int i; + for (i = 0 ; i < n; i++) + { + int v; + if (foo (n, &v, b[i])) + return 0; + t (v); /* { dg-warning "uninitialized" "real warning" } */ + } + return 1; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-6_a.c b/gcc/testsuite/gcc.dg/uninit-pred-6_a.c new file mode 100644 index 00000000000..aa44f76160d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-6_a.c @@ -0,0 +1,40 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n && l) + v = r; + + if (m) g++; + else bar(); + + if ( n && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n && l) + v = r; + + if (m) g++; + else bar(); + + if (n) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-6_b.c b/gcc/testsuite/gcc.dg/uninit-pred-6_b.c new file mode 100644 index 00000000000..dcc9a14a3c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-6_b.c @@ -0,0 +1,46 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n) + if (l) + v = r; + + if (m) g++; + else bar(); + + if ( n && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if (l) + if (n) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n) + if (l) + v = r; + + if (m) g++; + else bar(); + + if (n || l) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-6_c.c b/gcc/testsuite/gcc.dg/uninit-pred-6_c.c new file mode 100644 index 00000000000..f60868dad23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-6_c.c @@ -0,0 +1,46 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n > 10) + if (l) + v = r; + + if (m) g++; + else bar(); + + if ( (n > 10) && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if (l) + if (n > 12) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n > 10) + if (l) + v = r; + + if (m) g++; + else bar(); + + if (n > 8 ) + if (l) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-6_d.c b/gcc/testsuite/gcc.dg/uninit-pred-6_d.c new file mode 100644 index 00000000000..704c3e6e1d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-6_d.c @@ -0,0 +1,24 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n) + v = r; + + if (m) g++; + else bar(); + + if ( n && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/uninit-pred-6_e.c b/gcc/testsuite/gcc.dg/uninit-pred-6_e.c new file mode 100644 index 00000000000..21f429daf4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-6_e.c @@ -0,0 +1,43 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n > 10) + v = r; + + if (m) g++; + else bar(); + + if ( (n > 10) && (l < 100)) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n > 100 ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n > 10) + v = r; + + if (m) g++; + else bar(); + + if ( n < 10) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-7_a.c b/gcc/testsuite/gcc.dg/uninit-pred-7_a.c new file mode 100644 index 00000000000..c2ba2a4248d --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-7_a.c @@ -0,0 +1,54 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n || l) + v = r; + + if (m) g++; + else bar(); + + if ( n && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( l ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n || l) + v = r; + + if (m) g++; + else bar(); + + if ( n && l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if (m || l) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + if ( l ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-7_b.c b/gcc/testsuite/gcc.dg/uninit-pred-7_b.c new file mode 100644 index 00000000000..338d18c95e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-7_b.c @@ -0,0 +1,23 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n > 10) + v = r; + + if (m) g++; + else bar(); + + if (( n > 10) || (l != 100)) + blah (v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-7_c.c b/gcc/testsuite/gcc.dg/uninit-pred-7_c.c new file mode 100644 index 00000000000..1bbe5014dec --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-7_c.c @@ -0,0 +1,33 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n) + v = r; + + if (m) g++; + else bar(); + + if (n ) + { + if (l) + g++; + else + goto l; + } + else + { +l: + blah (v); /* { dg-warning "uninitialized" "warning" } */ + } + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-8_a.c b/gcc/testsuite/gcc.dg/uninit-pred-8_a.c new file mode 100644 index 00000000000..1b7c472420c --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-8_a.c @@ -0,0 +1,45 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n || m || r || l) + v = r; + + if (m) g++; + else bar(); + + if ( n || m || r || l) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( l ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n || m || r ) + v = r; + + if (m) g++; + else bar(); + + if ( n || m || r || l) + blah(v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-8_b.c b/gcc/testsuite/gcc.dg/uninit-pred-8_b.c new file mode 100644 index 00000000000..06e2eba27d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-8_b.c @@ -0,0 +1,45 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n < 10 || m > 100 || r < 20 || l) + v = r; + + if (m) g++; + else bar(); + + if ( n < 10 || m > 100 || r < 20 ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n < 10 || m > 100 || r < 10 ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n < 10 || m > 100 || r < 20 || l) + v = r; + + if (m) g++; + else bar(); + + if ( n < 10 || m > 100 || r < 20 ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( n < 10 || m > 100 || r < 30 ) + blah(v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-8_c.c b/gcc/testsuite/gcc.dg/uninit-pred-8_c.c new file mode 100644 index 00000000000..39d1bcd9346 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-8_c.c @@ -0,0 +1,39 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if (n < 10 && m > 100 && r < 20 ) + v = r; + + if (m) g++; + else bar(); + + if ( n <= 8 && m > 101 && r < 19 ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if (n < 10 && m > 100 && r < 20 ) + v = r; + + if (m) g++; + else bar(); + + if ( n <= 8 && m > 99 && r < 19 ) + blah(v); /* { dg-warning "uninitialized" "warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_a.c b/gcc/testsuite/gcc.dg/uninit-pred-9_a.c new file mode 100644 index 00000000000..67fb8ab9778 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_a.c @@ -0,0 +1,23 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if ( (n < 10) && (m == l) && (r < 20) ) + v = r; + + if (m) g++; + else bar(); + + if ( (n <= 8) && (m == l) && (r < 19) ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/uninit-pred-9_b.c b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c new file mode 100644 index 00000000000..d9ae75e0765 --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pred-9_b.c @@ -0,0 +1,44 @@ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -O2" } */ + +int g; +void bar(); +void blah(int); + +int foo (int n, int l, int m, int r) +{ + int v; + + if ( (n < 10) && (m != 100) && (r < 20) ) + v = r; + + if (m) g++; + else bar(); + + if (l > 100) + if ( (n <= 9) && (m < 100) && (r < 19) ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + if ( (n <= 8) && (m < 99) && (r < 19) ) + blah(v); /* { dg-bogus "uninitialized" "bogus warning" } */ + + return 0; +} + +int foo_2 (int n, int l, int m, int r) +{ + int v; + + if ( (n < 10) && (m != 100) && (r < 20) ) + v = r; + + if (m) g++; + else bar(); + + if (l > 100) + if ( (n <= 8) && (m < 101) && (r < 19) ) + blah(v); /* { dg-warning "uninitialized" "real warning" } */ + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c new file mode 100644 index 00000000000..640d81a2560 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include +#include +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int a[N], b[N]; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* This statement is ignored in vectorization of this basic block. */ + a[x] = b [y]; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/warn-addr-cmp.c b/gcc/testsuite/gcc.dg/warn-addr-cmp.c index 6ad94731aff..07491d1bb98 100644 --- a/gcc/testsuite/gcc.dg/warn-addr-cmp.c +++ b/gcc/testsuite/gcc.dg/warn-addr-cmp.c @@ -36,13 +36,13 @@ test_func_cmp (void) int test_func_cmp_rhs_zero (void) { - if (func == 0) /* { dg-warning "the address of 'func'" } */ + if (func == 0) /* { dg-warning "the comparison will always evaluate as 'false'" } */ return 1; - if (func != 0) /* { dg-warning "the address of 'func'" } */ + if (func != 0) /* { dg-warning "the comparison will always evaluate as 'true'" } */ return 1; - if (&var == 0) /* { dg-warning "the address of 'var'" } */ + if (&var == 0) /* { dg-warning "the comparison will always evaluate as 'false'" } */ return 1; - if (&var != 0) /* { dg-warning "the address of 'var'" } */ + if (&var != 0) /* { dg-warning "the comparison will always evaluate as 'true'" } */ return 1; if (weak_func == 0) return 1; @@ -59,13 +59,13 @@ test_func_cmp_rhs_zero (void) int test_func_cmp_lhs_zero (void) { - if (0 == func) /* { dg-warning "the address of 'func'" } */ + if (0 == func) /* { dg-warning "the comparison will always evaluate as 'false'" } */ return 1; - if (0 != func) /* { dg-warning "the address of 'func'" } */ + if (0 != func) /* { dg-warning "the comparison will always evaluate as 'true'" } */ return 1; - if (0 == &var) /* { dg-warning "the address of 'var'" } */ + if (0 == &var) /* { dg-warning "the comparison will always evaluate as 'false'" } */ return 1; - if (0 != &var) /* { dg-warning "the address of 'var'" } */ + if (0 != &var) /* { dg-warning "the comparison will always evaluate as 'true'" } */ return 1; if (0 == weak_func) return 1; diff --git a/gcc/testsuite/gcc.target/arm/thumb-stackframe.c b/gcc/testsuite/gcc.target/arm/thumb-stackframe.c new file mode 100644 index 00000000000..f6c78804e91 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/thumb-stackframe.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-mthumb -Os" } */ +/* { dg-require-effective-target arm_thumb1_ok } */ + +extern void bar(int*); +int foo() +{ + int x; + bar(&x); + return x; +} + +/* { dg-final { scan-assembler-not "sub\[\\t \]*sp,\[\\t \]*sp," } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr43766.c b/gcc/testsuite/gcc.target/i386/pr43766.c index 701be6ef6f8..731b780ba6d 100644 --- a/gcc/testsuite/gcc.target/i386/pr43766.c +++ b/gcc/testsuite/gcc.target/i386/pr43766.c @@ -7,4 +7,4 @@ void p (int *a, int i) __builtin_prefetch (&a[i]); } -/* { dg-final { scan-assembler-not "lea" } } */ +/* { dg-final { scan-assembler-not "lea\[lq\]?\[ \t\]" } } */ diff --git a/gcc/testsuite/gfortran.dg/assignment_2.f90 b/gcc/testsuite/gfortran.dg/assignment_2.f90 index 47e400962cb..18f303b368d 100644 --- a/gcc/testsuite/gfortran.dg/assignment_2.f90 +++ b/gcc/testsuite/gfortran.dg/assignment_2.f90 @@ -47,3 +47,4 @@ contains END SUBROUTINE end module m3 +! { dg-final { cleanup-modules "m1 m2 m3" } } diff --git a/gcc/testsuite/gfortran.dg/coarray_11.f90 b/gcc/testsuite/gfortran.dg/coarray_11.f90 index 969d4911caa..7ec73535732 100644 --- a/gcc/testsuite/gfortran.dg/coarray_11.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_11.f90 @@ -2,6 +2,7 @@ ! { dg-options "-fcoarray=single -fdump-tree-original" } ! ! PR fortran/18918 +! PR fortran/43919 for boundsTest() ! ! Coarray intrinsics ! @@ -52,5 +53,12 @@ if (lcobound(a,dim=3,kind=8) /= -3_8) call not_existing() if (ucobound(a,dim=1,kind=2) /= 9_2) call not_existing() end subroutine andanother +subroutine boundsTest() + implicit none + integer :: a[*] = 7 + if (any (lcobound(a) /= [1])) call not_existing() + if (any (ucobound(a) /= [1])) call not_existing() +end subroutine boundsTest + ! { dg-final { scan-tree-dump-times "not_existing" 0 "original" } } ! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/coarray_12.f90 b/gcc/testsuite/gfortran.dg/coarray_12.f90 new file mode 100644 index 00000000000..c1b7342129d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray_12.f90 @@ -0,0 +1,77 @@ +! { dg-do compile } +! { dg-options "-fcoarray=single -fdump-tree-original" } +! +! Coarray support -- allocatable array coarrays +! PR fortran/18918 +! +integer,allocatable :: a(:)[:,:] +nn = 5 +mm = 7 +allocate(a(nn)[mm,*]) +end + +subroutine testAlloc3 + implicit none + integer, allocatable :: ab(:,:,:)[:,:] + integer, allocatable, dimension(:),codimension[:] :: b(:,:,:)[:,:] + integer, allocatable, dimension(:,:),codimension[:,:,:] :: c + integer, allocatable, dimension(:,:),codimension[:,:,:] :: d[:,:] + integer, allocatable, dimension(:,:,:),codimension[:,:,:] :: e(:,:) + integer, allocatable, dimension(:,:,:),codimension[:,:,:] :: f(:,:)[:,:] + + allocate(ab(1,2,3)[4,*]) + allocate(b(1,2,3)[4,*]) + allocate(c(1,2)[3,4,*]) + allocate(d(1,2)[3,*]) + allocate(e(1,2)[3,4,*]) + allocate(f(1,2)[3,*]) +end subroutine testAlloc3 + +subroutine testAlloc4() + implicit none + integer, allocatable :: xxx(:)[:,:,:,:] + integer :: mmm + mmm=88 + allocate(xxx(1)[7,-5:8,mmm:2,*]) +end subroutine testAlloc4 + +subroutine testAlloc5() + implicit none + integer, allocatable :: yyy(:)[:,:,:,:] + integer :: ooo, ppp + ooo=88 + ppp=42 + allocate(yyy(1)[7,-5:ppp,1,ooo:*]) +end subroutine testAlloc5 + + +! { dg-final { scan-tree-dump-times "a.dim.0..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "a.dim.0..ubound = .*nn;" 1 "original" } } +! { dg-final { scan-tree-dump-times "a.dim.1..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "a.dim.1..ubound = .*mm;" 1 "original" } } +! { dg-final { scan-tree-dump-times "a.dim.2..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "a.dim.2..ubound" 0 "original" } } + +! { dg-final { scan-tree-dump-times "xxx.dim.0..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.0..ubound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.1..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.1..ubound = 7;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.2..lbound = -5;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.2..ubound = 8;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.3..lbound = .*mmm;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.3..ubound = 2;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.4..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "xxx.dim.4..ubound" 0 "original" } } + +! { dg-final { scan-tree-dump-times "yyy.dim.0..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.0..ubound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.1..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.1..ubound = 7;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.2..lbound = -5;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.2..ubound = .*ppp;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.3..lbound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.3..ubound = 1;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.4..lbound = .*ooo;" 1 "original" } } +! { dg-final { scan-tree-dump-times "yyy.dim.4..ubound" 0 "original" } } + +! { dg-final { cleanup-tree-dump "original" } } diff --git a/gcc/testsuite/gfortran.dg/coarray_7.f90 b/gcc/testsuite/gfortran.dg/coarray_7.f90 index 8cd295d38b3..29af0d19195 100644 --- a/gcc/testsuite/gfortran.dg/coarray_7.f90 +++ b/gcc/testsuite/gfortran.dg/coarray_7.f90 @@ -91,7 +91,6 @@ type(t), allocatable :: b(:)[:], C[:] allocate(b(1)) ! { dg-error "Coarray specification" } allocate(a[3]%a(5)) ! { dg-error "Coindexed allocatable" } allocate(c[*]) ! { dg-error "Sorry" } -allocate(b(3)[5:*]) ! { dg-error "Sorry" } allocate(a%a(5)) ! OK end subroutine alloc @@ -148,34 +147,16 @@ end subroutine test4 subroutine allocateTest() implicit none - real, allocatable,dimension(:,:), codimension[:,:] :: a,b,c + real, allocatable, codimension[:,:] :: a,b,c integer :: n, q n = 1 q = 1 - allocate(a(n,n)[q,*]) ! { dg-error "Sorry" } - allocate(b(n,n)[q,*]) ! { dg-error "Sorry" } - allocate(c(n,n)[q,*]) ! { dg-error "Sorry" } + allocate(a[q,*]) ! { dg-error "Sorry" } + allocate(b[q,*]) ! { dg-error "Sorry" } + allocate(c[q,*]) ! { dg-error "Sorry" } end subroutine allocateTest -subroutine testAlloc3 -implicit none -integer, allocatable :: a(:,:,:)[:,:] -integer, allocatable, dimension(:),codimension[:] :: b(:,:,:)[:,:] -integer, allocatable, dimension(:,:),codimension[:,:,:] :: c -integer, allocatable, dimension(:,:),codimension[:,:,:] :: d[:,:] -integer, allocatable, dimension(:,:,:),codimension[:,:,:] :: e(:,:) -integer, allocatable, dimension(:,:,:),codimension[:,:,:] :: f(:,:)[:,:] - -allocate(a(1,2,3)[4,*]) ! { dg-error "Sorry" } -allocate(b(1,2,3)[4,*]) ! { dg-error "Sorry" } -allocate(c(1,2)[3,4,*]) ! { dg-error "Sorry" } -allocate(d(1,2)[3,*]) ! { dg-error "Sorry" } -allocate(e(1,2)[3,4,*]) ! { dg-error "Sorry" } -allocate(f(1,2)[3,*]) ! { dg-error "Sorry" } -end subroutine testAlloc3 - - subroutine testAlloc4() implicit none type co_double_3 diff --git a/gcc/testsuite/gfortran.dg/default_format_2.f90 b/gcc/testsuite/gfortran.dg/default_format_2.f90 index 9442242f143..26424673220 100644 --- a/gcc/testsuite/gfortran.dg/default_format_2.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_2.f90 @@ -1,5 +1,5 @@ ! { dg-require-effective-target fortran_large_real } -! { dg-do run { xfail powerpc*-apple-darwin* *-*-freebsd* powerpc*-*-linux* } } +! { dg-do run { xfail powerpc*-apple-darwin* powerpc*-*-linux* } } ! Test XFAILed on these platforms because the system's printf() lacks ! proper support for denormalized long doubles. See PR24685 ! diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 index a93bf9da37f..7c960538376 100644 --- a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 @@ -1,4 +1,4 @@ -! { dg-do run { xfail *-*-darwin[89]* *-*-freebsd* *-*-cygwin* spu-*-* } } +! { dg-do run { xfail *-*-darwin[89]* *-*-cygwin* spu-*-* } } ! Test XFAILed on these platforms because the system's printf() lacks ! proper support for denormals. ! diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 index ae2f71f42e7..36697067c7f 100644 --- a/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 +++ b/gcc/testsuite/gfortran.dg/default_format_denormal_2.f90 @@ -1,5 +1,5 @@ ! { dg-require-effective-target fortran_large_real } -! { dg-do run { xfail powerpc*-apple-darwin* *-*-freebsd* powerpc*-*-linux* } } +! { dg-do run { xfail powerpc*-apple-darwin* powerpc*-*-linux* } } ! Test XFAILed on these platforms because the system's printf() lacks ! proper support for denormalized long doubles. See PR24685 ! diff --git a/gcc/testsuite/gfortran.dg/elemental_args_check_2.f90 b/gcc/testsuite/gfortran.dg/elemental_args_check_2.f90 index 51e69a49ee4..e8b429305e8 100644 --- a/gcc/testsuite/gfortran.dg/elemental_args_check_2.f90 +++ b/gcc/testsuite/gfortran.dg/elemental_args_check_2.f90 @@ -17,3 +17,4 @@ CONTAINS END INTERFACE END SUBROUTINE S1 END MODULE M1 +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/id-18.f90 b/gcc/testsuite/gfortran.dg/graphite/id-18.f90 index 273e670fcee..ed780673655 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-18.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-18.f90 @@ -23,3 +23,4 @@ CONTAINS END SELECT END FUNCTION dlegendre END MODULE spherical_harmonics +! { dg-final { cleanup-modules "spherical_harmonics" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/id-2.f90 b/gcc/testsuite/gfortran.dg/graphite/id-2.f90 index 720fff8dd02..2f9f9dbec37 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-2.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-2.f90 @@ -11,3 +11,4 @@ contains subroutine fourir(A,ntot,kconjg, E,useold) end subroutine fourir end module solv_cap +! { dg-final { cleanup-modules "solv_cap" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/id-4.f90 b/gcc/testsuite/gfortran.dg/graphite/id-4.f90 index b2c6cb04edc..83899445de4 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-4.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/id-4.f90 @@ -30,3 +30,4 @@ CONTAINS END IF END SUBROUTINE QSORT END SUBROUTINE READIN +! { dg-final { cleanup-modules "vimage vcimage" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 b/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 index 62eccf35ff1..e964adec1b8 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr37980.f90 @@ -9,3 +9,4 @@ contains mat0 = 0.0d0 end function spher_cartesians end module INT_MODULE +! { dg-final { cleanup-modules "int_module" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 b/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 index 73224764f16..391549e3cd0 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr38953.f90 @@ -113,3 +113,4 @@ ENDIF 999 CONTINUE END +! { dg-final { cleanup-modules "main1" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr40982.f90 b/gcc/testsuite/gfortran.dg/graphite/pr40982.f90 index b9641aef031..c49def850bf 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr40982.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr40982.f90 @@ -67,3 +67,5 @@ contains end subroutine mutual_ind_quad_cir_coil end module mqc_m +! { dg-final { cleanup-modules "mqc_m" } } + diff --git a/gcc/testsuite/gfortran.dg/graphite/pr41924.f90 b/gcc/testsuite/gfortran.dg/graphite/pr41924.f90 index f8dc8078e5c..2f248d0b892 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr41924.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr41924.f90 @@ -13,3 +13,4 @@ SUBROUTINE VOLCALC() IF ( WETSCIM ) HRVALD(ITYP) = 0.0 ENDDO END SUBROUTINE VOLCALC +! { dg-final { cleanup-modules "main1" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42050.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42050.f90 index 09cab6f0f1c..e019917414c 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42050.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42050.f90 @@ -23,3 +23,4 @@ CONTAINS CALL test() END SUBROUTINE sic_explicit_orbitals END MODULE qs_ks_methods +! { dg-final { cleanup-modules "qs_ks_methods" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42180.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42180.f90 index 523c479e215..bb5bc0c58db 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42180.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42180.f90 @@ -20,3 +20,4 @@ contains l12 = coefficient * l12 end subroutine mutual_ind_cir_cir_coils end module mcc_m +! { dg-final { cleanup-modules "mcc_m" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42181.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42181.f90 index dafb63fdc8b..06ce47d9e7f 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42181.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42181.f90 @@ -17,3 +17,4 @@ CONTAINS END IF END SUBROUTINE newuob END MODULE powell +! { dg-final { cleanup-modules "powell" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42185.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42185.f90 index 0918f72874c..d0e1b017879 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42185.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42185.f90 @@ -25,3 +25,4 @@ CONTAINS END DO mainloop END SUBROUTINE trsapp END MODULE powell +! { dg-final { cleanup-modules "powell" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42186.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42186.f90 index 9e488f4f189..0e3669bf5e7 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42186.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42186.f90 @@ -12,3 +12,4 @@ CONTAINS END IF END SUBROUTINE CALERF END MODULE erf_fn +! { dg-final { cleanup-modules "erf_fn" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42393-1.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42393-1.f90 index fb62e20f45c..45c635b761d 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42393-1.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42393-1.f90 @@ -22,3 +22,4 @@ CONTAINS fn_val = sum END FUNCTION basym END MODULE beta_gamma_psi +! { dg-final { cleanup-modules "beta_gamma_psi" } } diff --git a/gcc/testsuite/gfortran.dg/graphite/pr42393.f90 b/gcc/testsuite/gfortran.dg/graphite/pr42393.f90 index 1fc708ef967..da9a348dd44 100644 --- a/gcc/testsuite/gfortran.dg/graphite/pr42393.f90 +++ b/gcc/testsuite/gfortran.dg/graphite/pr42393.f90 @@ -28,3 +28,4 @@ CONTAINS fn_val = e0*t*u*sum END FUNCTION basym END MODULE beta_gamma_psi +! { dg-final { cleanup-modules "beta_gamma_psi" } } diff --git a/gcc/testsuite/gfortran.dg/host_assoc_blockdata_1.f90 b/gcc/testsuite/gfortran.dg/host_assoc_blockdata_1.f90 index 7f24fecb0e0..07f9ed478b2 100644 --- a/gcc/testsuite/gfortran.dg/host_assoc_blockdata_1.f90 +++ b/gcc/testsuite/gfortran.dg/host_assoc_blockdata_1.f90 @@ -9,3 +9,4 @@ END module globals BLOCK DATA use globals END BLOCK DATA +! { dg-final { cleanup-modules "globals" } } diff --git a/gcc/testsuite/gfortran.dg/host_assoc_blockdata_2.f90 b/gcc/testsuite/gfortran.dg/host_assoc_blockdata_2.f90 index 3cb4abaedd2..40e3ac4d5d4 100644 --- a/gcc/testsuite/gfortran.dg/host_assoc_blockdata_2.f90 +++ b/gcc/testsuite/gfortran.dg/host_assoc_blockdata_2.f90 @@ -15,3 +15,4 @@ program main use globals common /co/ pdm_bps ! { dg-error "already in a COMMON block" } end program main +! { dg-final { cleanup-modules "globals" } } diff --git a/gcc/testsuite/gfortran.dg/intent_out_3.f90 b/gcc/testsuite/gfortran.dg/intent_out_3.f90 index 7b68a352246..7346fd04668 100644 --- a/gcc/testsuite/gfortran.dg/intent_out_3.f90 +++ b/gcc/testsuite/gfortran.dg/intent_out_3.f90 @@ -17,3 +17,4 @@ END MODULE M1 USE M1 CALL S1(D1%I(3)) ! { dg-error "must be definable" } END +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/internal_pack_4.f90 b/gcc/testsuite/gfortran.dg/internal_pack_4.f90 index 0bcfc799a8e..5ddc035e9c4 100644 --- a/gcc/testsuite/gfortran.dg/internal_pack_4.f90 +++ b/gcc/testsuite/gfortran.dg/internal_pack_4.f90 @@ -29,3 +29,4 @@ END ! { dg-final { scan-tree-dump-times "a != 0B \\? \\\(.*\\\) _gfortran_internal_pack" 1 "original" } } ! { dg-final { scan-tree-dump-times "if \\(a != 0B &&" 1 "original" } } ! { dg-final { cleanup-tree-dump "original" } } +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 b/gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 index 2f33a0f5bf4..db783159a24 100644 --- a/gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 +++ b/gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 @@ -14,3 +14,4 @@ contains end subroutine sub0 end module bind_c_dts_2 +! { dg-final { cleanup-modules "bind_c_dts_2" } } diff --git a/gcc/testsuite/gfortran.dg/pr41347.f90 b/gcc/testsuite/gfortran.dg/pr41347.f90 index ae48857d507..e8ceef5f7d9 100644 --- a/gcc/testsuite/gfortran.dg/pr41347.f90 +++ b/gcc/testsuite/gfortran.dg/pr41347.f90 @@ -30,3 +30,4 @@ module hsl_ma41_m end subroutine prininfo end module hsl_ma41_m +! { dg-final { cleanup-modules "hsl_ma41_m" } } diff --git a/gcc/testsuite/gfortran.dg/pr41928.f90 b/gcc/testsuite/gfortran.dg/pr41928.f90 index 1438b0c122d..2805c2d7dab 100644 --- a/gcc/testsuite/gfortran.dg/pr41928.f90 +++ b/gcc/testsuite/gfortran.dg/pr41928.f90 @@ -261,3 +261,4 @@ CONTAINS END DO END SUBROUTINE diff_momop END MODULE ai_moments +! { dg-final { cleanup-modules "ai_moments" } } diff --git a/gcc/testsuite/gfortran.dg/pr42166.f90 b/gcc/testsuite/gfortran.dg/pr42166.f90 index 5b978153a45..910a08c36fc 100644 --- a/gcc/testsuite/gfortran.dg/pr42166.f90 +++ b/gcc/testsuite/gfortran.dg/pr42166.f90 @@ -18,3 +18,4 @@ CONTAINS END SUBROUTINE newuob END MODULE powell +! { dg-final { cleanup-modules "powell" } } diff --git a/gcc/testsuite/gfortran.dg/pr43505.f90 b/gcc/testsuite/gfortran.dg/pr43505.f90 index bdeb6c538c2..b912c9ff0dd 100644 --- a/gcc/testsuite/gfortran.dg/pr43505.f90 +++ b/gcc/testsuite/gfortran.dg/pr43505.f90 @@ -39,5 +39,6 @@ end subroutine END PROGRAM TEST +! { dg-final { cleanup-modules "main1" } } diff --git a/gcc/testsuite/gfortran.dg/private_type_11.f90 b/gcc/testsuite/gfortran.dg/private_type_11.f90 index 53d5f4c705c..57c22dd5232 100644 --- a/gcc/testsuite/gfortran.dg/private_type_11.f90 +++ b/gcc/testsuite/gfortran.dg/private_type_11.f90 @@ -21,3 +21,4 @@ CONTAINS TYPE(T1) FUNCTION F2() END FUNCTION F2 END MODULE M1 +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/private_type_12.f90 b/gcc/testsuite/gfortran.dg/private_type_12.f90 index c9867bcf87b..5bebcf030b7 100644 --- a/gcc/testsuite/gfortran.dg/private_type_12.f90 +++ b/gcc/testsuite/gfortran.dg/private_type_12.f90 @@ -21,3 +21,4 @@ CONTAINS TYPE(T1) FUNCTION F2() ! { dg-error "Fortran 2003: PUBLIC variable 'f2'" } END FUNCTION F2 END MODULE M1 +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/proc_decl_23.f90 b/gcc/testsuite/gfortran.dg/proc_decl_23.f90 index fa50dc13c86..66cf5fff736 100644 --- a/gcc/testsuite/gfortran.dg/proc_decl_23.f90 +++ b/gcc/testsuite/gfortran.dg/proc_decl_23.f90 @@ -41,3 +41,4 @@ end module m_string print *, char1 (["j","k","l"]) end ! { dg-final { cleanup-tree-dump "m_string" } } +! { dg-final { cleanup-modules "m_string" } } diff --git a/gcc/testsuite/gfortran.dg/recursive_check_3.f90 b/gcc/testsuite/gfortran.dg/recursive_check_3.f90 index ec358cb12c0..76782861087 100644 --- a/gcc/testsuite/gfortran.dg/recursive_check_3.f90 +++ b/gcc/testsuite/gfortran.dg/recursive_check_3.f90 @@ -20,3 +20,4 @@ recursive recursive subroutine a3(b) ! { dg-error "Duplicate RECURSIVE attribute real, intent(in) :: b ! { dg-error "Unexpected data declaration statement" } end subroutine a3 ! { dg-error "Expecting END MODULE" } end module m3 +! { dg-final { cleanup-modules "m1 m2 m3" } } diff --git a/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90 b/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90 index 40a0910b1ed..8eb47e19b81 100644 --- a/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90 +++ b/gcc/testsuite/gfortran.dg/redefined_intrinsic_assignment.f90 @@ -16,3 +16,4 @@ CONTAINS I=-J END SUBROUTINE T1 END MODULE M1 +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/select_type_4.f90 b/gcc/testsuite/gfortran.dg/select_type_4.f90 index 7e12d935447..95488e5f72c 100644 --- a/gcc/testsuite/gfortran.dg/select_type_4.f90 +++ b/gcc/testsuite/gfortran.dg/select_type_4.f90 @@ -172,3 +172,4 @@ program main call destroy_list(list) stop end program main +! { dg-final { cleanup-modules "poly_list" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 b/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 index eb6330def63..2d4018049d5 100644 --- a/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 @@ -35,3 +35,4 @@ ENDIF END SUBROUTINE ACCONV ! { dg-final { cleanup-tree-dump "vect" } } +! { dg-final { cleanup-modules "yomphy0" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 b/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 index 019b4155844..66e878d3dee 100644 --- a/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 +++ b/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 @@ -55,3 +55,4 @@ END MODULE UPML_mod ! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } ! { dg-final { cleanup-tree-dump "vect" } } +! { dg-final { cleanup-modules "upml_mod" } } diff --git a/gcc/testsuite/gfortran.dg/where_operator_assign_4.f90 b/gcc/testsuite/gfortran.dg/where_operator_assign_4.f90 index 74ce1ba6ad3..e1c479e5f93 100644 --- a/gcc/testsuite/gfortran.dg/where_operator_assign_4.f90 +++ b/gcc/testsuite/gfortran.dg/where_operator_assign_4.f90 @@ -28,3 +28,4 @@ END WHERE WHERE (I(:)%I>0) J=I ! { dg-error "Non-ELEMENTAL user-defined assignment in WHERE" } END +! { dg-final { cleanup-modules "m1" } } diff --git a/gcc/testsuite/gfortran.dg/whole_file_11.f90 b/gcc/testsuite/gfortran.dg/whole_file_11.f90 index d01b2100c4b..d50e4810704 100644 --- a/gcc/testsuite/gfortran.dg/whole_file_11.f90 +++ b/gcc/testsuite/gfortran.dg/whole_file_11.f90 @@ -35,3 +35,5 @@ FUNCTION foo_count() USE module_foo, ONLY: foo INTEGER :: foo_count END FUNCTION + +! { dg-final { cleanup-modules "module_foo" } } diff --git a/gcc/testsuite/lib/dg-pch.exp b/gcc/testsuite/lib/dg-pch.exp index 5320880bb43..2e0631fdc94 100644 --- a/gcc/testsuite/lib/dg-pch.exp +++ b/gcc/testsuite/lib/dg-pch.exp @@ -16,7 +16,7 @@ load_lib copy-file.exp -proc dg-pch { subdir test options suffix } { +proc dg-flags-pch { subdir test otherflags options suffix } { global runtests dg-do-what-default # If we're only testing specific files and this isn't one of them, skip it. @@ -33,13 +33,13 @@ proc dg-pch { subdir test options suffix } { # We don't try to use the loop-optimizing options, since they are highly # unlikely to make any difference to PCH. foreach flags $options { - verbose "Testing $nshort, $flags" 1 + verbose "Testing $nshort, $otherflags $flags" 1 # For the header files, the default is to precompile. set dg-do-what-default precompile catch { file_on_host delete "$bname$suffix" } gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" - dg-test -keep-output "./$bname$suffix" $flags "" + dg-test -keep-output "./$bname$suffix" "$otherflags $flags" "" # For the rest, the default is to compile to .s. set dg-do-what-default compile @@ -50,23 +50,23 @@ proc dg-pch { subdir test options suffix } { # Ensure that the PCH file is used, not the original header. file_on_host delete "$bname$suffix" - dg-test -keep-output $test "$flags -I." "" + dg-test -keep-output $test "$otherflags $flags -I." "" file_on_host delete "$bname$suffix.gch" if { !$have_errs } { if { [ file_on_host exists "$bname.s" ] } { remote_upload host "$bname.s" "$bname.s-gch" remote_download host "$bname.s-gch" gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix" - dg-test -keep-output $test $flags "-I." + dg-test -keep-output $test "$otherflags $flags -I." "" remote_upload host "$bname.s" set tmp [ diff "$bname.s" "$bname.s-gch" ] if { $tmp == 0 } { verbose -log "assembly file '$bname.s', '$bname.s-gch' comparison error" - fail "$nshort $flags assembly comparison" + fail "$nshort $otherflags $flags assembly comparison" } elseif { $tmp == 1 } { - pass "$nshort $flags assembly comparison" + pass "$nshort $otherflags $flags assembly comparison" } else { - fail "$nshort $flags assembly comparison" + fail "$nshort $otherflags $flags assembly comparison" } file_on_host delete "$bname$suffix" file_on_host delete "$bname.s" @@ -86,3 +86,7 @@ proc dg-pch { subdir test options suffix } { } } } + +proc dg-pch { subdir test options suffix } { + return [dg-flags-pch $subdir $test "" $options $suffix] +} \ No newline at end of file diff --git a/gcc/testsuite/lib/lto.exp b/gcc/testsuite/lib/lto.exp index 1dd9c34df55..3d40efc32b9 100644 --- a/gcc/testsuite/lib/lto.exp +++ b/gcc/testsuite/lib/lto.exp @@ -16,6 +16,19 @@ # Contributed by Diego Novillo +# Prune messages from gcc that aren't useful. + +proc lto_prune_vis_warns { text } { + + # Many tests that use visibility will still pass on platforms that don't support it. + regsub -all "(^|\n)\[^\n\]*: warning: visibility attribute not supported in this configuration; ignored\[^\n\]*" $text "" text + + # And any stray location lines. + regsub -all "(^|\n)\[^\n\]*: In function \[^\n\]*" $text "" text + regsub -all "(^|\n)In file included from :\[^\n\]*" $text "" text + + return $text +} # lto_init -- called at the start of each subdir of tests @@ -147,6 +160,10 @@ proc lto-link-and-maybe-run { testname objlist dest optall optfile optstr } { # Link the objects into an executable. set comp_output [${tool}_target_compile "$objlist" $dest executable \ "$options"] + + # Prune unimportant visibility warnings before checking output. + set comp_output [lto_prune_vis_warns $comp_output] + if ![${tool}_check_compile "$testcase $testname link" "" \ $dest $comp_output] then { unresolved "$testcase $testname execute $optstr" diff --git a/gcc/testsuite/lib/objc-torture.exp b/gcc/testsuite/lib/objc-torture.exp index 0b6362bb1d8..a3d1ef2446e 100644 --- a/gcc/testsuite/lib/objc-torture.exp +++ b/gcc/testsuite/lib/objc-torture.exp @@ -46,28 +46,55 @@ proc objc-set-runtime-options { dowhat args } { lappend options $args } verbose "options $options" - set test_obj "trivial.exe" - set comp_output [objc_target_compile \ - "$srcdir/$subdir/trivial.m" $test_obj executable $options] - - # If we get any error, then we failed. - if ![string match "" $comp_output] then { - remote_file build delete $test_obj - continue; - } if [info exists dowhat] { - if { $dowhat == "execute" } { - set result [objc_load "$tmpdir/$test_obj" "" ""] - set status [lindex $result 0] - set output [lindex $result 1] - if { $status != "pass" } { - remote_file build delete $test_obj - verbose -log "trivial execute failed with $status $output" - continue; - } + switch $dowhat { + "compile" { + set compile_type "assembly" + set output_file "trivial.s" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" "$output_file" "$compile_type" $options] + + remote_file build delete $output_file + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + continue; + } + } + "execute" { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj "executable" $options] + + # If we get any error, then we failed. + if ![string match "" $comp_output] then { + remote_file build delete $test_obj + continue; + } + set result [objc_load "$tmpdir/$test_obj" "" ""] + set status [lindex $result 0] + set output [lindex $result 1] + remote_file build delete $test_obj + if { $status != "pass" } { + verbose -log "trivial execute failed with $status $output" + continue; + } + } + default { + perror "$dowhat: not a valid objc-torture action" + return "" } + } + } else { + set test_obj "trivial.exe" + set comp_output [objc_target_compile \ + "$srcdir/$subdir/trivial.m" $test_obj executable $options] + + # If we get any error, then we failed. + remote_file build delete $test_obj + if ![string match "" $comp_output] then { + continue; + } } - remote_file build delete $test_obj lappend OBJC_RUNTIME_OPTIONS $type } diff --git a/gcc/testsuite/lib/plugin-support.exp b/gcc/testsuite/lib/plugin-support.exp index 3a7b78ab956..fe4526549b3 100644 --- a/gcc/testsuite/lib/plugin-support.exp +++ b/gcc/testsuite/lib/plugin-support.exp @@ -88,6 +88,10 @@ proc plugin-test-execute { plugin_src plugin_tests } { set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared" + if { [ ishost *-*-darwin* ] } { + set optstr [concat $optstr "-undefined dynamic_lookup"] + } + # Temporarily switch to the environment for the plugin compiler. restore_ld_library_path_env_vars set status [remote_exec build "$PLUGINCC $PLUGINCFLAGS $plugin_src $optstr -o $plugin_lib"] diff --git a/gcc/testsuite/lib/prune.exp b/gcc/testsuite/lib/prune.exp index 160f651b6e7..769169d4271 100644 --- a/gcc/testsuite/lib/prune.exp +++ b/gcc/testsuite/lib/prune.exp @@ -22,7 +22,7 @@ proc prune_gcc_output { text } { regsub -all "(^|\n)(\[^\n\]*: )?In ((static member |lambda )?function|member|method|(copy )?constructor|destructor|instantiation|program|subroutine|block-data)\[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text - regsub -all "(^|\n)\[^\n\]*: instantiated from \[^\n\]*" $text "" text + regsub -all "(^|\n)\[^\n\]*: (recursively )?instantiated from \[^\n\]*" $text "" text regsub -all "(^|\n)\[^\n\]*: . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text regsub -all "(^|\n) inlined from \[^\n\]*" $text "" text regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text diff --git a/gcc/testsuite/obj-c++.dg/stubify-1.mm b/gcc/testsuite/obj-c++.dg/stubify-1.mm index 0dafa4bcdd1..687739ceccd 100644 --- a/gcc/testsuite/obj-c++.dg/stubify-1.mm +++ b/gcc/testsuite/obj-c++.dg/stubify-1.mm @@ -1,8 +1,10 @@ /* All calls must be properly stubified. Complain about any "call _objc_msgSend" without the $stub suffix. */ -/* { dg-do compile { target powerpc*-*-darwin* } } */ -/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions" } */ +/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions -mmacosx-version-min=10.4" } */ typedef struct objc_object { } *id ; int x = 41 ; diff --git a/gcc/testsuite/obj-c++.dg/stubify-2.mm b/gcc/testsuite/obj-c++.dg/stubify-2.mm index 9db573e8afa..9968672ed34 100644 --- a/gcc/testsuite/obj-c++.dg/stubify-2.mm +++ b/gcc/testsuite/obj-c++.dg/stubify-2.mm @@ -2,7 +2,9 @@ /* Testcase extracted from TextEdit:Document.m. */ /* { dg-do compile { target *-*-darwin* } } */ -/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump" } */ +/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4" } */ typedef struct objc_object { } *id ; int x = 41 ; @@ -27,5 +29,5 @@ extern int bogonic (int, int, int) ; @end /* Any symbol_ref of an un-stubified objc_msgSend is an error; look - for "objc_msgSend" in quotes, without the $stub suffix. */ -/* { dg-final { scan-file-not stubify-2.mm.147r.jump "symbol_ref.*\"objc_msgSend\"" } } */ + for "objc_msgSend" in quotes, without the $stub suffix. */ +/* { dg-final { scan-rtl-dump-not "symbol_ref.*\"objc_msgSend\"" "jump" } } */ diff --git a/gcc/testsuite/objc.dg/next-runtime-1.m b/gcc/testsuite/objc.dg/next-runtime-1.m index 7d4a7d949c6..9a0951cabee 100644 --- a/gcc/testsuite/objc.dg/next-runtime-1.m +++ b/gcc/testsuite/objc.dg/next-runtime-1.m @@ -15,4 +15,5 @@ - (void)boo { } @end -/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.long\t6\n" } } */ +/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.long\t6\n" { target { *-*-darwin* && { ! lp64 } } } } } */ +/* { dg-final { scan-assembler "L_OBJC_MODULES:\n\[ \t\]*\.quad\t6\n" { target { *-*-darwin* && { lp64 } } } } } */ diff --git a/gcc/testsuite/objc.dg/pch/pch.exp b/gcc/testsuite/objc.dg/pch/pch.exp index 3747bde409e..ca406fd94da 100644 --- a/gcc/testsuite/objc.dg/pch/pch.exp +++ b/gcc/testsuite/objc.dg/pch/pch.exp @@ -26,19 +26,34 @@ load_lib torture-options.exp dg-init torture-init + set-torture-options $DG_TORTURE_OPTIONS set old_dg_do_what_default "${dg-do-what-default}" +global torture_without_loops +set mytorture [concat [list {-O0 -g}] $torture_without_loops] + # Main loop. foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.m]] { + + # We don't try to use the loop-optimizing options, since they are highly + # unlikely to make any difference to PCH. However, we do want to + # add -O0 -g, since users who want PCH usually want debugging and quick + # compiles. + dg-flags-pch $subdir $test "-fgnu-runtime" $mytorture ".h" +} + +if [istarget "*-*-darwin*" ] { + foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.m]] { global torture_without_loops # We don't try to use the loop-optimizing options, since they are highly # unlikely to make any difference to PCH. However, we do want to # add -O0 -g, since users who want PCH usually want debugging and quick # compiles. - dg-pch $subdir $test [concat [list {-O0 -g}] $torture_without_loops] ".h" + dg-flags-pch $subdir $test "-fnext-runtime" $mytorture ".h" + } } set dg-do-what-default "$old_dg_do_what_default" diff --git a/gcc/testsuite/objc.dg/stret-2.m b/gcc/testsuite/objc.dg/stret-2.m index ded3ae41997..fccda323433 100644 --- a/gcc/testsuite/objc.dg/stret-2.m +++ b/gcc/testsuite/objc.dg/stret-2.m @@ -4,6 +4,7 @@ /* Contributed by Ziemowit Laski . */ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ +/* { dg-require-effective-target ilp32 } */ #include "../objc-obj-c++-shared/Object1.h" diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m index 72de75beffc..91bf73a14f7 100644 --- a/gcc/testsuite/objc.dg/stubify-1.m +++ b/gcc/testsuite/objc.dg/stubify-1.m @@ -3,7 +3,8 @@ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ -/* { dg-options "-Os -mdynamic-no-pic" } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-Os -mdynamic-no-pic -mmacosx-version-min=10.4" } */ typedef struct objc_object { } *id ; int x = 41 ; diff --git a/gcc/testsuite/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m index b474d4f8927..eaf4b964e4b 100644 --- a/gcc/testsuite/objc.dg/stubify-2.m +++ b/gcc/testsuite/objc.dg/stubify-2.m @@ -1,9 +1,10 @@ -/* All calls must be properly stubified. */ +/* All calls must be properly stubified, m32 only. */ /* Testcase extracted from TextEdit:Document.m. */ -/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-do compile { target powerpc*-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ -/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump" } */ +/* { dg-require-effective-target ilp32 } */ +/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4" } */ typedef struct objc_object { } *id ; int x = 41 ; diff --git a/gcc/testsuite/objc.dg/symtab-1.m b/gcc/testsuite/objc.dg/symtab-1.m index dade2084478..90a79691721 100644 --- a/gcc/testsuite/objc.dg/symtab-1.m +++ b/gcc/testsuite/objc.dg/symtab-1.m @@ -22,4 +22,6 @@ -(void)checkValues { } @end -/* { dg-final { scan-assembler "L_OBJC_SYMBOLS.*:\n\t.long\t0\n\t.long\t0\n\t.short\t2\n\t.short\t0\n\t.long\tL_OBJC_CLASS_Derived.*\n\t.long\tL_OBJC_CLASS_Base.*\n" } } */ +/* { dg-final { scan-assembler "L_OBJC_SYMBOLS.*:\n\t.long\t0\n\t.long\t0\n\t.word\t2\n\t.word\t0\n\t.long\tL_OBJC_CLASS_Derived.*\n\t.long\tL_OBJC_CLASS_Base.*\n" { target { i?86-*-darwin* && { ! lp64 } } } } } */ +/* { dg-final { scan-assembler "L_OBJC_SYMBOLS.*:\n\t.long\t0\n\t.long\t0\n\t.short\t2\n\t.short\t0\n\t.long\tL_OBJC_CLASS_Derived.*\n\t.long\tL_OBJC_CLASS_Base.*\n" { target { powerpc-*-darwin* && { ! lp64 } } } } } */ +/* { dg-final { scan-assembler "L_OBJC_SYMBOLS.*:\n\t.quad\t0\n\t.long\t0\n\t.space 4\n\t.word\t2\n\t.word\t0\n\t.space 4\n\t.quad\tL_OBJC_CLASS_Derived.*\n\t.quad\tL_OBJC_CLASS_Base.*\n" { target { *-*-darwin* && { lp64 } } } } } */ diff --git a/gcc/timevar.def b/gcc/timevar.def index 63530b8e973..c43847b5248 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -59,6 +59,7 @@ DEFTIMEVAR (TV_WHOPR_WPA_IO , "whopr wpa I/O") DEFTIMEVAR (TV_WHOPR_LTRANS , "whopr ltrans") DEFTIMEVAR (TV_WHOPR_WPA_LTRANS_EXEC , "whopr wpa->ltrans") DEFTIMEVAR (TV_IPA_REFERENCE , "ipa reference") +DEFTIMEVAR (TV_IPA_PROFILE , "ipa profile") DEFTIMEVAR (TV_IPA_PURE_CONST , "ipa pure const") DEFTIMEVAR (TV_IPA_TYPE_ESCAPE , "ipa type escape") DEFTIMEVAR (TV_IPA_PTA , "ipa points-to") @@ -218,6 +219,7 @@ DEFTIMEVAR (TV_FINAL , "final") DEFTIMEVAR (TV_SYMOUT , "symout") DEFTIMEVAR (TV_VAR_TRACKING , "variable tracking") DEFTIMEVAR (TV_TREE_IFCOMBINE , "tree if-combine") +DEFTIMEVAR (TV_TREE_UNINIT , "uninit var anaysis") DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization") DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution") diff --git a/gcc/tlink.c b/gcc/tlink.c index 1894c6c709a..7b589832b06 100644 --- a/gcc/tlink.c +++ b/gcc/tlink.c @@ -32,6 +32,10 @@ along with GCC; see the file COPYING3. If not see #include "collect2.h" #include "libiberty.h" +/* TARGET_64BIT may be defined to use driver specific functionality. */ +#undef TARGET_64BIT +#define TARGET_64BIT TARGET_64BIT_DEFAULT + #define MAX_ITERATIONS 17 /* Defined in the automatically-generated underscore.c. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 8f9ab5de0f1..465cf2e252b 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -575,6 +575,8 @@ extern void flush_pending_stmts (edge); extern void verify_ssa (bool); extern void delete_tree_ssa (void); extern bool ssa_undefined_value_p (tree); +extern void warn_uninit (tree, const char *, void *); +extern unsigned int warn_uninitialized_vars (bool); extern void execute_update_addresses_taken (bool); /* Call-back function for walk_use_def_chains(). At each reaching diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 59661a7d509..383cc86f243 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -101,10 +101,6 @@ along with GCC; see the file COPYING3. If not see calls? */ -/* Weights that estimate_num_insns uses for heuristics in inlining. */ - -eni_weights eni_inlining_weights; - /* Weights that estimate_num_insns uses to estimate the size of the produced code. */ @@ -669,9 +665,23 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id) } if (BIND_EXPR_VARS (*tp)) - /* This will remap a lot of the same decls again, but this should be - harmless. */ - BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id); + { + tree t; + + /* This will remap a lot of the same decls again, but this should be + harmless. */ + BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id); + + /* Also copy value-expressions. */ + for (t = BIND_EXPR_VARS (*tp); t; t = TREE_CHAIN (t)) + if (TREE_CODE (t) == VAR_DECL + && DECL_HAS_VALUE_EXPR_P (t)) + { + tree tem = DECL_VALUE_EXPR (t); + walk_tree (&tem, copy_tree_body_r, id, NULL); + SET_DECL_VALUE_EXPR (t, tem); + } + } } @@ -1688,9 +1698,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, /* Constant propagation on argument done during inlining may create new direct call. Produce an edge for it. */ if ((!edge - || (edge->indirect_call + || (edge->indirect_inlining_edge && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) - && is_gimple_call (stmt) && (fn = gimple_call_fndecl (stmt)) != NULL) { struct cgraph_node *dest = cgraph_node (fn); @@ -2014,7 +2023,6 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) cfun->last_verified = src_cfun->last_verified; cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; cfun->va_list_fpr_size = src_cfun->va_list_fpr_size; - cfun->function_frequency = src_cfun->function_frequency; cfun->has_nonlocal_label = src_cfun->has_nonlocal_label; cfun->stdarg = src_cfun->stdarg; cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p; @@ -3269,22 +3277,93 @@ estimate_num_insns (gimple stmt, eni_weights *weights) if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) switch (DECL_FUNCTION_CODE (decl)) { + /* Builtins that expand to constants. */ case BUILT_IN_CONSTANT_P: - return 0; case BUILT_IN_EXPECT: - return 0; - - /* Prefetch instruction is not expensive. */ - case BUILT_IN_PREFETCH: - cost = weights->target_builtin_call_cost; - break; - + case BUILT_IN_OBJECT_SIZE: + case BUILT_IN_UNREACHABLE: + /* Simple register moves or loads from stack. */ + case BUILT_IN_RETURN_ADDRESS: + case BUILT_IN_EXTRACT_RETURN_ADDR: + case BUILT_IN_FROB_RETURN_ADDR: + case BUILT_IN_RETURN: + case BUILT_IN_AGGREGATE_INCOMING_ADDRESS: + case BUILT_IN_FRAME_ADDRESS: + case BUILT_IN_VA_END: + case BUILT_IN_STACK_SAVE: + case BUILT_IN_STACK_RESTORE: /* Exception state returns or moves registers around. */ case BUILT_IN_EH_FILTER: case BUILT_IN_EH_POINTER: case BUILT_IN_EH_COPY_VALUES: return 0; + /* builtins that are not expensive (that is they are most probably + expanded inline into resonably simple code). */ + case BUILT_IN_ABS: + case BUILT_IN_ALLOCA: + case BUILT_IN_BSWAP32: + case BUILT_IN_BSWAP64: + case BUILT_IN_CLZ: + case BUILT_IN_CLZIMAX: + case BUILT_IN_CLZL: + case BUILT_IN_CLZLL: + case BUILT_IN_CTZ: + case BUILT_IN_CTZIMAX: + case BUILT_IN_CTZL: + case BUILT_IN_CTZLL: + case BUILT_IN_FFS: + case BUILT_IN_FFSIMAX: + case BUILT_IN_FFSL: + case BUILT_IN_FFSLL: + case BUILT_IN_IMAXABS: + case BUILT_IN_FINITE: + case BUILT_IN_FINITEF: + case BUILT_IN_FINITEL: + case BUILT_IN_FINITED32: + case BUILT_IN_FINITED64: + case BUILT_IN_FINITED128: + case BUILT_IN_FPCLASSIFY: + case BUILT_IN_ISFINITE: + case BUILT_IN_ISINF_SIGN: + case BUILT_IN_ISINF: + case BUILT_IN_ISINFF: + case BUILT_IN_ISINFL: + case BUILT_IN_ISINFD32: + case BUILT_IN_ISINFD64: + case BUILT_IN_ISINFD128: + case BUILT_IN_ISNAN: + case BUILT_IN_ISNANF: + case BUILT_IN_ISNANL: + case BUILT_IN_ISNAND32: + case BUILT_IN_ISNAND64: + case BUILT_IN_ISNAND128: + case BUILT_IN_ISNORMAL: + case BUILT_IN_ISGREATER: + case BUILT_IN_ISGREATEREQUAL: + case BUILT_IN_ISLESS: + case BUILT_IN_ISLESSEQUAL: + case BUILT_IN_ISLESSGREATER: + case BUILT_IN_ISUNORDERED: + case BUILT_IN_VA_ARG_PACK: + case BUILT_IN_VA_ARG_PACK_LEN: + case BUILT_IN_VA_COPY: + case BUILT_IN_TRAP: + case BUILT_IN_SAVEREGS: + case BUILT_IN_POPCOUNTL: + case BUILT_IN_POPCOUNTLL: + case BUILT_IN_POPCOUNTIMAX: + case BUILT_IN_POPCOUNT: + case BUILT_IN_PARITYL: + case BUILT_IN_PARITYLL: + case BUILT_IN_PARITYIMAX: + case BUILT_IN_PARITY: + case BUILT_IN_LABS: + case BUILT_IN_LLABS: + case BUILT_IN_PREFETCH: + cost = weights->target_builtin_call_cost; + break; + default: break; } @@ -3473,7 +3552,7 @@ get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt) struct cgraph_edge *cs; cs = cgraph_edge (node, stmt); - if (cs) + if (cs && !cs->indirect_unknown_callee) return cs->callee->decl; return NULL_TREE; @@ -3556,7 +3635,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* If this call was originally indirect, we do not want to emit any inlining related warnings or sorry messages because there are no guarantees regarding those. */ - if (cg_edge->indirect_call) + if (cg_edge->indirect_inlining_edge) goto egress; if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 3d7798e4ca4..8542aabc79c 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -168,6 +168,7 @@ struct rtl_opt_pass struct varpool_node; struct cgraph_node; struct cgraph_node_set_def; +struct varpool_node_set_def; /* Description of IPA pass with generate summary, write, execute, read and transform stages. */ @@ -180,13 +181,15 @@ struct ipa_opt_pass_d void (*generate_summary) (void); /* This hook is used to serialize IPA summaries on disk. */ - void (*write_summary) (struct cgraph_node_set_def *); + void (*write_summary) (struct cgraph_node_set_def *, + struct varpool_node_set_def *); /* This hook is used to deserialize IPA summaries from disk. */ void (*read_summary) (void); /* This hook is used to serialize IPA optimization summaries on disk. */ - void (*write_optimization_summary) (struct cgraph_node_set_def *); + void (*write_optimization_summary) (struct cgraph_node_set_def *, + struct varpool_node_set_def *); /* This hook is used to deserialize IPA summaries from disk. */ void (*read_optimization_summary) (void); @@ -459,6 +462,7 @@ extern struct simple_ipa_opt_pass pass_ipa_pta; extern struct simple_ipa_opt_pass pass_ipa_struct_reorg; extern struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup; extern struct ipa_opt_pass_d pass_ipa_lto_finish_out; +extern struct ipa_opt_pass_d pass_ipa_profile; extern struct gimple_opt_pass pass_all_optimizations; extern struct gimple_opt_pass pass_cleanup_cfg_post_optimizing; @@ -606,7 +610,8 @@ extern const char *get_current_pass_name (void); extern void print_current_pass (FILE *); extern void debug_pass (void); extern void ipa_write_summaries (void); -extern void ipa_write_optimization_summaries (struct cgraph_node_set_def *); +extern void ipa_write_optimization_summaries (struct cgraph_node_set_def *, + struct varpool_node_set_def *); extern void ipa_read_summaries (void); extern void ipa_read_optimization_summaries (void); extern void register_one_dump_file (struct opt_pass *); diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index f6db2415a36..a64950ec85c 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -120,8 +120,8 @@ struct version_info struct iv *iv; /* Induction variable description. */ bool has_nonlin_use; /* For a loop-level invariant, whether it is used in an expression that is not an induction variable. */ - unsigned inv_id; /* Id of an invariant. */ bool preserve_biv; /* For the original biv, whether to preserve it. */ + unsigned inv_id; /* Id of an invariant. */ }; /* Types of uses. */ @@ -192,7 +192,7 @@ struct iv_cand unsigned id; /* The number of the candidate. */ bool important; /* Whether this is an "important" candidate, i.e. such that it should be considered by all uses. */ - enum iv_position pos; /* Where it is computed. */ + ENUM_BITFIELD(iv_position) pos : 8; /* Where it is computed. */ gimple incremented_at;/* For original biv, the statement where it is incremented. */ tree var_before; /* The variable used for it before increment. */ @@ -2738,9 +2738,10 @@ computation_cost (tree expr, bool speed) unsigned cost; /* Avoid using hard regs in ways which may be unsupported. */ int regno = LAST_VIRTUAL_REGISTER + 1; - enum function_frequency real_frequency = cfun->function_frequency; + struct cgraph_node *node = cgraph_node (current_function_decl); + enum node_frequency real_frequency = node->frequency; - cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL; + node->frequency = NODE_FREQUENCY_NORMAL; crtl->maybe_hot_insn_p = speed; walk_tree (&expr, prepare_decl_rtl, ®no, NULL); start_sequence (); @@ -2748,7 +2749,7 @@ computation_cost (tree expr, bool speed) seq = get_insns (); end_sequence (); default_rtl_profile (); - cfun->function_frequency = real_frequency; + node->frequency = real_frequency; cost = seq_cost (seq, speed); if (MEM_P (rslt)) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 207cb178115..08d3fa7e15b 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -275,6 +275,9 @@ struct variable_info /* True if this field may contain pointers. */ unsigned int may_have_pointers : 1; + /* True if this field has only restrict qualified pointers. */ + unsigned int only_restrict_pointers : 1; + /* True if this represents a global variable. */ unsigned int is_global_var : 1; @@ -412,6 +415,7 @@ new_var_info (tree t, const char *name) ret->is_heap_var = false; ret->is_restrict_var = false; ret->may_have_pointers = true; + ret->only_restrict_pointers = false; ret->is_global_var = (t == NULL_TREE); ret->is_fn_info = false; if (t && DECL_P (t)) @@ -420,6 +424,8 @@ new_var_info (tree t, const char *name) ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack); ret->next = NULL; + stats.total_vars++; + VEC_safe_push (varinfo_t, heap, varmap, ret); return ret; @@ -3641,7 +3647,10 @@ get_function_part_constraint (varinfo_t fi, unsigned part) else if (TREE_CODE (fi->decl) == FUNCTION_DECL) { varinfo_t ai = first_vi_for_offset (fi, part); - c.var = ai ? ai->id : anything_id; + if (ai) + c.var = ai->id; + else + c.var = anything_id; c.offset = 0; c.type = SCALAR; } @@ -4723,19 +4732,6 @@ first_or_preceding_vi_for_offset (varinfo_t start, } -/* Insert the varinfo FIELD into the field list for BASE, at the front - of the list. */ - -static void -insert_into_field_list (varinfo_t base, varinfo_t field) -{ - varinfo_t prev = base; - varinfo_t curr = base->next; - - field->next = curr; - prev->next = field; -} - /* This structure is used during pushing fields onto the fieldstack to track the offset of the field, since bitpos_of_field gives it relative to its immediate containing type, and we want it relative @@ -4821,37 +4817,37 @@ 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. */ + Returns false if the caller is supposed to handle the field we + recursed for. */ -static int +static bool push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, HOST_WIDE_INT offset) { tree field; - int count = 0; + bool empty_p = true; if (TREE_CODE (type) != RECORD_TYPE) - return 0; + return false; /* If the vector of fields is growing too big, bail out early. Callers check for VEC_length <= MAX_FIELDS_FOR_FIELD_SENSITIVE, make sure this fails. */ if (VEC_length (fieldoff_s, *fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE) - return 0; + return false; for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) == FIELD_DECL) { bool push = false; - int pushed = 0; HOST_WIDE_INT foff = bitpos_of_field (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 + foff)) + else if (!push_fields_onto_fieldstack + (TREE_TYPE (field), fieldstack, offset + foff) && (DECL_SIZE (field) && !integer_zerop (DECL_SIZE (field)))) /* Empty structures may have actual size, like in C++. So @@ -4874,12 +4870,11 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, /* 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->offset + (HOST_WIDE_INT)pair->size == offset + foff + && !could_have_pointers (field)) { - pair = VEC_last (fieldoff_s, *fieldstack); pair->size += TREE_INT_CST_LOW (DECL_SIZE (field)); } else @@ -4896,14 +4891,13 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack, = (!has_unknown_size && POINTER_TYPE_P (TREE_TYPE (field)) && TYPE_RESTRICT (TREE_TYPE (field))); - count++; } } - else - count += pushed; + + empty_p = false; } - return count; + return !empty_p; } /* Count the number of arguments DECL has, and set IS_VARARGS to true @@ -4955,8 +4949,6 @@ create_function_info_for (tree decl, const char *name) vi->fullsize = ~0; insert_vi_for_tree (vi->decl, vi); - stats.total_vars++; - prev_vi = vi; /* Create a variable for things the function clobbers and one for @@ -4979,7 +4971,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < clobbervi->offset); prev_vi->next = clobbervi; prev_vi = clobbervi; - stats.total_vars++; asprintf (&tempname, "%s.use", name); newname = ggc_strdup (tempname); @@ -4994,7 +4985,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < usevi->offset); prev_vi->next = usevi; prev_vi = usevi; - stats.total_vars++; } /* And one for the static chain. */ @@ -5017,7 +5007,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < chainvi->offset); prev_vi->next = chainvi; prev_vi = chainvi; - stats.total_vars++; insert_vi_for_tree (fn->static_chain_decl, chainvi); } @@ -5047,7 +5036,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < resultvi->offset); prev_vi->next = resultvi; prev_vi = resultvi; - stats.total_vars++; if (DECL_RESULT (decl)) insert_vi_for_tree (DECL_RESULT (decl), resultvi); } @@ -5078,7 +5066,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < argvi->offset); prev_vi->next = argvi; prev_vi = argvi; - stats.total_vars++; if (arg) { insert_vi_for_tree (arg, argvi); @@ -5111,7 +5098,6 @@ create_function_info_for (tree decl, const char *name) gcc_assert (prev_vi->offset < argvi->offset); prev_vi->next = argvi; prev_vi = argvi; - stats.total_vars++; } return vi->id; @@ -5141,48 +5127,135 @@ check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack) This will also create any varinfo structures necessary for fields of DECL. */ -static unsigned int -create_variable_info_for (tree decl, const char *name) +static varinfo_t +create_variable_info_for_1 (tree decl, const char *name) { - varinfo_t vi; + varinfo_t vi, newvi; tree decl_type = TREE_TYPE (decl); tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type); VEC (fieldoff_s,heap) *fieldstack = NULL; + fieldoff_s *fo; + unsigned int i; - if (var_can_have_subvars (decl) && use_field_sensitive) - push_fields_onto_fieldstack (decl_type, &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 - fields. */ - vi = new_var_info (decl, name); - vi->offset = 0; - vi->may_have_pointers = could_have_pointers (decl); if (!declsize || !host_integerp (declsize, 1)) { - vi->is_unknown_size_var = true; - vi->fullsize = ~0; + vi = new_var_info (decl, name); + vi->offset = 0; vi->size = ~0; + vi->fullsize = ~0; + vi->is_unknown_size_var = true; + vi->is_full_var = true; + vi->may_have_pointers = could_have_pointers (decl); + return vi; } - else + + /* Collect field information. */ + if (use_field_sensitive + && var_can_have_subvars (decl) + /* ??? Force us to not use subfields for global initializers + in IPA mode. Else we'd have to parse arbitrary initializers. */ + && !(in_ipa_mode + && is_global_var (decl) + && DECL_INITIAL (decl))) + { + fieldoff_s *fo = NULL; + bool notokay = false; + unsigned int i; + + push_fields_onto_fieldstack (decl_type, &fieldstack, 0); + + for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) + if (fo->has_unknown_size + || fo->offset < 0) + { + notokay = true; + break; + } + + /* We can't sort them if we have a field with a variable sized type, + which will make notokay = true. In that case, we are going to return + without creating varinfos for the fields anyway, so sorting them is a + waste to boot. */ + if (!notokay) + { + sort_fieldstack (fieldstack); + /* Due to some C++ FE issues, like PR 22488, we might end up + what appear to be overlapping fields even though they, + in reality, do not overlap. Until the C++ FE is fixed, + we will simply disable field-sensitivity for these cases. */ + notokay = check_for_overlaps (fieldstack); + } + + if (notokay) + VEC_free (fieldoff_s, heap, fieldstack); + } + + /* If we didn't end up collecting sub-variables create a full + variable for the decl. */ + if (VEC_length (fieldoff_s, fieldstack) <= 1 + || VEC_length (fieldoff_s, fieldstack) > MAX_FIELDS_FOR_FIELD_SENSITIVE) { + vi = new_var_info (decl, name); + vi->offset = 0; + vi->may_have_pointers = could_have_pointers (decl); vi->fullsize = TREE_INT_CST_LOW (declsize); vi->size = vi->fullsize; + vi->is_full_var = true; + VEC_free (fieldoff_s, heap, fieldstack); + return vi; } - insert_vi_for_tree (vi->decl, vi); + vi = new_var_info (decl, name); + vi->fullsize = TREE_INT_CST_LOW (declsize); + for (i = 0, newvi = vi; + VEC_iterate (fieldoff_s, fieldstack, i, fo); + ++i, newvi = newvi->next) + { + const char *newname = "NULL"; + char *tempname; - /* ??? The setting of vi->may_have_pointers is too conservative here - and may get refined below. Thus we have superfluous constraints - here sometimes which triggers the commented assert in - dump_sa_points_to_info. */ - if (vi->is_global_var - && vi->may_have_pointers) + if (dump_file) + { + asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC + "+" HOST_WIDE_INT_PRINT_DEC, name, fo->offset, fo->size); + newname = ggc_strdup (tempname); + free (tempname); + } + newvi->name = newname; + newvi->offset = fo->offset; + newvi->size = fo->size; + newvi->fullsize = vi->fullsize; + newvi->may_have_pointers = fo->may_have_pointers; + newvi->only_restrict_pointers = fo->only_restrict_pointers; + if (i + 1 < VEC_length (fieldoff_s, fieldstack)) + newvi->next = new_var_info (decl, name); + } + + VEC_free (fieldoff_s, heap, fieldstack); + + return vi; +} + +static unsigned int +create_variable_info_for (tree decl, const char *name) +{ + varinfo_t vi = create_variable_info_for_1 (decl, name); + unsigned int id = vi->id; + + insert_vi_for_tree (decl, vi); + + /* Create initial constraints for globals. */ + for (; vi; vi = vi->next) { + if (!vi->may_have_pointers + || !vi->is_global_var) + continue; + /* Mark global restrict qualified pointers. */ - if (POINTER_TYPE_P (TREE_TYPE (decl)) - && TYPE_RESTRICT (TREE_TYPE (decl))) + if ((POINTER_TYPE_P (TREE_TYPE (decl)) + && TYPE_RESTRICT (TREE_TYPE (decl))) + || vi->only_restrict_pointers) make_constraint_from_restrict (vi, "GLOBAL_RESTRICT"); /* For escaped variables initialize them from nonlocal. */ @@ -5194,12 +5267,12 @@ create_variable_info_for (tree decl, const char *name) IPA mode generate constraints for it. In non-IPA mode the initializer from nonlocal is all we need. */ if (in_ipa_mode - && DECL_INITIAL (vi->decl)) + && DECL_INITIAL (decl)) { VEC (ce_s, heap) *rhsc = NULL; struct constraint_expr lhs, *rhsp; unsigned i; - get_constraint_for (DECL_INITIAL (vi->decl), &rhsc); + get_constraint_for (DECL_INITIAL (decl), &rhsc); lhs.var = vi->id; lhs.offset = 0; lhs.type = SCALAR; @@ -5216,110 +5289,10 @@ create_variable_info_for (tree decl, const char *name) process_constraint (new_constraint (lhs, *rhsp)); } VEC_free (ce_s, heap, rhsc); - /* ??? Force us to not use subfields. Else we'd have to parse - arbitrary initializers. */ - VEC_free (fieldoff_s, heap, fieldstack); } } - stats.total_vars++; - if (use_field_sensitive - && !vi->is_unknown_size_var - && var_can_have_subvars (decl) - && VEC_length (fieldoff_s, fieldstack) > 1 - && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE) - { - fieldoff_s *fo = NULL; - bool notokay = false; - unsigned int i; - - for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++) - { - if (fo->has_unknown_size - || fo->offset < 0) - { - notokay = true; - break; - } - } - - /* We can't sort them if we have a field with a variable sized type, - which will make notokay = true. In that case, we are going to return - without creating varinfos for the fields anyway, so sorting them is a - waste to boot. */ - if (!notokay) - { - sort_fieldstack (fieldstack); - /* Due to some C++ FE issues, like PR 22488, we might end up - what appear to be overlapping fields even though they, - in reality, do not overlap. Until the C++ FE is fixed, - we will simply disable field-sensitivity for these cases. */ - notokay = check_for_overlaps (fieldstack); - } - - - if (VEC_length (fieldoff_s, fieldstack) != 0) - fo = VEC_index (fieldoff_s, fieldstack, 0); - - if (fo == NULL || notokay) - { - vi->is_unknown_size_var = 1; - vi->fullsize = ~0; - vi->size = ~0; - vi->is_full_var = true; - VEC_free (fieldoff_s, heap, fieldstack); - return vi->id; - } - - vi->size = fo->size; - vi->offset = fo->offset; - vi->may_have_pointers = fo->may_have_pointers; - if (vi->is_global_var - && vi->may_have_pointers) - { - if (fo->only_restrict_pointers) - make_constraint_from_restrict (vi, "GLOBAL_RESTRICT"); - } - for (i = VEC_length (fieldoff_s, fieldstack) - 1; - i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo); - i--) - { - varinfo_t newvi; - const char *newname = "NULL"; - char *tempname; - - if (dump_file) - { - 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, newname); - newvi->offset = fo->offset; - newvi->size = fo->size; - newvi->fullsize = vi->fullsize; - newvi->may_have_pointers = fo->may_have_pointers; - insert_into_field_list (vi, newvi); - if ((newvi->is_global_var || TREE_CODE (decl) == PARM_DECL) - && newvi->may_have_pointers) - { - if (fo->only_restrict_pointers) - make_constraint_from_restrict (newvi, "GLOBAL_RESTRICT"); - if (newvi->is_global_var && !in_ipa_mode) - make_copy_constraint (newvi, nonlocal_id); - } - - stats.total_vars++; - } - } - else - vi->is_full_var = true; - - VEC_free (fieldoff_s, heap, fieldstack); - - return vi->id; + return id; } /* Print out the points-to solution for VAR to FILE. */ @@ -5405,8 +5378,12 @@ intra_create_variable_infos (void) } for (p = get_vi_for_tree (t); p; p = p->next) - if (p->may_have_pointers) - make_constraint_from (p, nonlocal_id); + { + if (p->may_have_pointers) + make_constraint_from (p, nonlocal_id); + if (p->only_restrict_pointers) + make_constraint_from_restrict (p, "PARM_RESTRICT"); + } if (POINTER_TYPE_P (TREE_TYPE (t)) && TYPE_RESTRICT (TREE_TYPE (t))) make_constraint_from_restrict (get_vi_for_tree (t), "PARM_RESTRICT"); diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c new file mode 100644 index 00000000000..4f23962485f --- /dev/null +++ b/gcc/tree-ssa-uninit.c @@ -0,0 +1,1762 @@ +/* Predicate aware uninitialized variable warning. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software + Foundation, Inc. + Contributed by Xinliang David Li + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "flags.h" +#include "rtl.h" +#include "tm_p.h" +#include "ggc.h" +#include "langhooks.h" +#include "hard-reg-set.h" +#include "basic-block.h" +#include "output.h" +#include "expr.h" +#include "function.h" +#include "diagnostic.h" +#include "bitmap.h" +#include "pointer-set.h" +#include "tree-flow.h" +#include "gimple.h" +#include "tree-inline.h" +#include "varray.h" +#include "timevar.h" +#include "hashtab.h" +#include "tree-dump.h" +#include "tree-pass.h" +#include "toplev.h" +#include "timevar.h" + +/* This implements the pass that does predicate aware warning on uses of + possibly uninitialized variables. The pass first collects the set of + possibly uninitialized SSA names. For each such name, it walks through + all its immediate uses. For each immediate use, it rebuilds the condition + expression (the predicate) that guards the use. The predicate is then + examined to see if the variable is always defined under that same condition. + This is done either by pruning the unrealizable paths that lead to the + default definitions or by checking if the predicate set that guards the + defining paths is a superset of the use predicate. */ + + +/* Pointer set of potentially undefined ssa names, i.e., + ssa names that are defined by phi with operands that + are not defined or potentially undefined. */ +static struct pointer_set_t *possibly_undefined_names = 0; + +/* Bit mask handling macros. */ +#define MASK_SET_BIT(mask, pos) mask |= (1 << pos) +#define MASK_TEST_BIT(mask, pos) (mask & (1 << pos)) +#define MASK_EMPTY(mask) (mask == 0) + +/* Returns the first bit position (starting from LSB) + in mask that is non zero. Returns -1 if the mask is empty. */ +static int +get_mask_first_set_bit (unsigned mask) +{ + int pos = 0; + if (mask == 0) + return -1; + + while ((mask & (1 << pos)) == 0) + pos++; + + return pos; +} +#define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask) + + +/* Return true if T, an SSA_NAME, has an undefined value. */ + +bool +ssa_undefined_value_p (tree t) +{ + tree var = SSA_NAME_VAR (t); + + /* Parameters get their initial value from the function entry. */ + if (TREE_CODE (var) == PARM_DECL) + return false; + + /* Hard register variables get their initial value from the ether. */ + if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) + return false; + + /* The value is undefined iff its definition statement is empty. */ + return (gimple_nop_p (SSA_NAME_DEF_STMT (t)) + || (possibly_undefined_names + && pointer_set_contains (possibly_undefined_names, t))); +} + +/* Checks if the operand OPND of PHI is defined by + another phi with one operand defined by this PHI, + but the rest operands are all defined. If yes, + returns true to skip this this operand as being + redundant. Can be enhanced to be more general. */ + +static bool +can_skip_redundant_opnd (tree opnd, gimple phi) +{ + gimple op_def; + tree phi_def; + int i, n; + + phi_def = gimple_phi_result (phi); + op_def = SSA_NAME_DEF_STMT (opnd); + if (gimple_code (op_def) != GIMPLE_PHI) + return false; + n = gimple_phi_num_args (op_def); + for (i = 0; i < n; ++i) + { + tree op = gimple_phi_arg_def (op_def, i); + if (TREE_CODE (op) != SSA_NAME) + continue; + if (op != phi_def && ssa_undefined_value_p (op)) + return false; + } + + return true; +} + +/* Returns a bit mask holding the positions of arguments in PHI + that have empty (or possibly empty) definitions. */ + +static unsigned +compute_uninit_opnds_pos (gimple phi) +{ + size_t i, n; + unsigned uninit_opnds = 0; + + n = gimple_phi_num_args (phi); + + for (i = 0; i < n; ++i) + { + tree op = gimple_phi_arg_def (phi, i); + if (TREE_CODE (op) == SSA_NAME + && ssa_undefined_value_p (op) + && !can_skip_redundant_opnd (op, phi)) + MASK_SET_BIT (uninit_opnds, i); + } + return uninit_opnds; +} + +/* Find the immediate postdominator PDOM of the specified + basic block BLOCK. */ + +static inline basic_block +find_pdom (basic_block block) +{ + if (block == EXIT_BLOCK_PTR) + return EXIT_BLOCK_PTR; + else + { + basic_block bb + = get_immediate_dominator (CDI_POST_DOMINATORS, block); + if (! bb) + return EXIT_BLOCK_PTR; + return bb; + } +} + +/* Find the immediate DOM of the specified + basic block BLOCK. */ + +static inline basic_block +find_dom (basic_block block) +{ + if (block == ENTRY_BLOCK_PTR) + return ENTRY_BLOCK_PTR; + else + { + basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block); + if (! bb) + return ENTRY_BLOCK_PTR; + return bb; + } +} + +/* Returns true if BB1 is postdominating BB2 and BB1 is + not a loop exit bb. The loop exit bb check is simple and does + not cover all cases. */ + +static bool +is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2) +{ + if (!dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1)) + return false; + + if (single_pred_p (bb1) && !single_succ_p (bb2)) + return false; + + return true; +} + +/* Find the closest postdominator of a specified BB, which is control + equivalent to BB. */ + +static inline basic_block +find_control_equiv_block (basic_block bb) +{ + basic_block pdom; + + pdom = find_pdom (bb); + + /* Skip the postdominating bb that is also loop exit. */ + if (!is_non_loop_exit_postdominating (pdom, bb)) + return NULL; + + if (dominated_by_p (CDI_DOMINATORS, pdom, bb)) + return pdom; + + return NULL; +} + +#define MAX_NUM_CHAINS 8 +#define MAX_CHAIN_LEN 5 + +/* Computes the control dependence chains (paths of edges) + for DEP_BB up to the dominating basic block BB (the head node of a + chain should be dominated by it). CD_CHAINS is pointer to a + dynamic array holding the result chains. CUR_CD_CHAIN is the current + chain being computed. *NUM_CHAINS is total number of chains. The + function returns true if the information is successfully computed, + return false if there is no control dependence or not computed. */ + +static bool +compute_control_dep_chain (basic_block bb, basic_block dep_bb, + VEC(edge, heap) **cd_chains, + size_t *num_chains, + VEC(edge, heap) **cur_cd_chain) +{ + edge_iterator ei; + edge e; + size_t i; + bool found_cd_chain = false; + size_t cur_chain_len = 0; + + if (EDGE_COUNT (bb->succs) < 2) + return false; + + /* Could use a set instead. */ + cur_chain_len = VEC_length (edge, *cur_cd_chain); + if (cur_chain_len > MAX_CHAIN_LEN) + return false; + + for (i = 0; i < cur_chain_len; i++) + { + edge e = VEC_index (edge, *cur_cd_chain, i); + /* cycle detected. */ + if (e->src == bb) + return false; + } + + FOR_EACH_EDGE (e, ei, bb->succs) + { + basic_block cd_bb; + if (e->flags & (EDGE_FAKE | EDGE_ABNORMAL)) + continue; + + cd_bb = e->dest; + VEC_safe_push (edge, heap, *cur_cd_chain, e); + while (!is_non_loop_exit_postdominating (cd_bb, bb)) + { + if (cd_bb == dep_bb) + { + /* Found a direct control dependence. */ + if (*num_chains < MAX_NUM_CHAINS) + { + cd_chains[*num_chains] + = VEC_copy (edge, heap, *cur_cd_chain); + (*num_chains)++; + } + found_cd_chain = true; + /* check path from next edge. */ + break; + } + + /* Now check if DEP_BB is indirectly control dependent on BB. */ + if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains, + num_chains, cur_cd_chain)) + { + found_cd_chain = true; + break; + } + + cd_bb = find_pdom (cd_bb); + if (cd_bb == EXIT_BLOCK_PTR) + break; + } + VEC_pop (edge, *cur_cd_chain); + gcc_assert (VEC_length (edge, *cur_cd_chain) == cur_chain_len); + } + gcc_assert (VEC_length (edge, *cur_cd_chain) == cur_chain_len); + + return found_cd_chain; +} + +typedef struct use_pred_info +{ + gimple cond; + bool invert; +} *use_pred_info_t; + +DEF_VEC_P(use_pred_info_t); +DEF_VEC_ALLOC_P(use_pred_info_t, heap); + + +/* Converts the chains of control dependence edges into a set of + predicates. A control dependence chain is represented by a vector + edges. DEP_CHAINS points to an array of dependence chains. + NUM_CHAINS is the size of the chain array. One edge in a dependence + chain is mapped to predicate expression represented by use_pred_info_t + type. One dependence chain is converted to a composite predicate that + is the result of AND operation of use_pred_info_t mapped to each edge. + A composite predicate is presented by a vector of use_pred_info_t. On + return, *PREDS points to the resulting array of composite predicates. + *NUM_PREDS is the number of composite predictes. */ + +static bool +convert_control_dep_chain_into_preds (VEC(edge, heap) **dep_chains, + size_t num_chains, + VEC(use_pred_info_t, heap) ***preds, + size_t *num_preds) +{ + bool has_valid_pred = false; + size_t i, j; + if (num_chains == 0 || num_chains >= MAX_NUM_CHAINS) + return false; + + /* Now convert CD chains into predicates */ + has_valid_pred = true; + + /* Now convert the control dep chain into a set + of predicates. */ + *preds = XCNEWVEC (VEC(use_pred_info_t, heap) *, + num_chains); + *num_preds = num_chains; + + for (i = 0; i < num_chains; i++) + { + VEC(edge, heap) *one_cd_chain = dep_chains[i]; + for (j = 0; j < VEC_length (edge, one_cd_chain); j++) + { + gimple cond_stmt; + gimple_stmt_iterator gsi; + basic_block guard_bb; + use_pred_info_t one_pred; + edge e; + + e = VEC_index (edge, one_cd_chain, j); + guard_bb = e->src; + gsi = gsi_last_bb (guard_bb); + if (gsi_end_p (gsi)) + { + has_valid_pred = false; + break; + } + cond_stmt = gsi_stmt (gsi); + if (gimple_code (cond_stmt) == GIMPLE_CALL + && EDGE_COUNT (e->src->succs) >= 2) + { + /* Ignore EH edge. Can add assertion + on the other edge's flag. */ + continue; + } + /* Skip if there is essentially one succesor. */ + if (EDGE_COUNT (e->src->succs) == 2) + { + edge e1; + edge_iterator ei1; + bool skip = false; + + FOR_EACH_EDGE (e1, ei1, e->src->succs) + { + if (EDGE_COUNT (e1->dest->succs) == 0) + { + skip = true; + break; + } + } + if (skip) + continue; + } + if (gimple_code (cond_stmt) != GIMPLE_COND) + { + has_valid_pred = false; + break; + } + one_pred = XNEW (struct use_pred_info); + one_pred->cond = cond_stmt; + one_pred->invert = !!(e->flags & EDGE_FALSE_VALUE); + VEC_safe_push (use_pred_info_t, heap, (*preds)[i], one_pred); + } + + if (!has_valid_pred) + break; + } + return has_valid_pred; +} + +/* Computes all control dependence chains for USE_BB. The control + dependence chains are then converted to an array of composite + predicates pointed to by PREDS. PHI_BB is the basic block of + the phi whose result is used in USE_BB. */ + +static bool +find_predicates (VEC(use_pred_info_t, heap) ***preds, + size_t *num_preds, + basic_block phi_bb, + basic_block use_bb) +{ + size_t num_chains = 0, i; + VEC(edge, heap) **dep_chains = 0; + VEC(edge, heap) *cur_chain = 0; + bool has_valid_pred = false; + basic_block cd_root = 0; + + dep_chains = XCNEWVEC (VEC(edge, heap) *, MAX_NUM_CHAINS); + + /* First find the closest bb that is control equivalent to PHI_BB + that also dominates USE_BB. */ + cd_root = phi_bb; + while (dominated_by_p (CDI_DOMINATORS, use_bb, cd_root)) + { + basic_block ctrl_eq_bb = find_control_equiv_block (cd_root); + if (ctrl_eq_bb && dominated_by_p (CDI_DOMINATORS, use_bb, ctrl_eq_bb)) + cd_root = ctrl_eq_bb; + else + break; + } + + compute_control_dep_chain (cd_root, use_bb, + dep_chains, &num_chains, + &cur_chain); + + has_valid_pred + = convert_control_dep_chain_into_preds (dep_chains, + num_chains, + preds, + num_preds); + /* Free individual chain */ + VEC_free (edge, heap, cur_chain); + for (i = 0; i < num_chains; i++) + VEC_free (edge, heap, dep_chains[i]); + free (dep_chains); + return has_valid_pred; +} + +/* Computes the set of incoming edges of PHI that have non empty + definitions of a phi chain. The collection will be done + recursively on operands that are defined by phis. CD_ROOT + is the control dependence root. *EDGES holds the result, and + VISITED_PHIS is a pointer set for detecting cycles. */ + +static void +collect_phi_def_edges (gimple phi, basic_block cd_root, + VEC(edge, heap) **edges, + struct pointer_set_t *visited_phis) +{ + size_t i, n; + edge opnd_edge; + tree opnd; + + if (pointer_set_insert (visited_phis, phi)) + return; + + n = gimple_phi_num_args (phi); + for (i = 0; i < n; i++) + { + opnd_edge = gimple_phi_arg_edge (phi, i); + opnd = gimple_phi_arg_def (phi, i); + + if (TREE_CODE (opnd) != SSA_NAME + || !ssa_undefined_value_p (opnd)) + VEC_safe_push (edge, heap, *edges, opnd_edge); + else + { + gimple def = SSA_NAME_DEF_STMT (opnd); + if (gimple_code (def) == GIMPLE_PHI + && dominated_by_p (CDI_DOMINATORS, + gimple_bb (def), cd_root)) + collect_phi_def_edges (def, cd_root, edges, + visited_phis); + } + } +} + +/* For each use edge of PHI, computes all control dependence chains. + The control dependence chains are then converted to an array of + composite predicates pointed to by PREDS. */ + +static bool +find_def_preds (VEC(use_pred_info_t, heap) ***preds, + size_t *num_preds, gimple phi) +{ + size_t num_chains = 0, i, n; + VEC(edge, heap) **dep_chains = 0; + VEC(edge, heap) *cur_chain = 0; + VEC(edge, heap) *def_edges = 0; + bool has_valid_pred = false; + basic_block phi_bb, cd_root = 0; + struct pointer_set_t *visited_phis; + + dep_chains = XCNEWVEC (VEC(edge, heap) *, MAX_NUM_CHAINS); + + phi_bb = gimple_bb (phi); + /* First find the closest dominating bb to be + the control dependence root */ + cd_root = find_dom (phi_bb); + if (!cd_root) + return false; + + visited_phis = pointer_set_create (); + collect_phi_def_edges (phi, cd_root, &def_edges, visited_phis); + pointer_set_destroy (visited_phis); + + n = VEC_length (edge, def_edges); + if (n == 0) + return false; + + for (i = 0; i < n; i++) + { + size_t prev_nc, j; + edge opnd_edge; + + opnd_edge = VEC_index (edge, def_edges, i); + prev_nc = num_chains; + compute_control_dep_chain (cd_root, opnd_edge->src, + dep_chains, &num_chains, + &cur_chain); + /* Free individual chain */ + VEC_free (edge, heap, cur_chain); + cur_chain = 0; + + /* Now update the newly added chains with + the phi operand edge: */ + if (EDGE_COUNT (opnd_edge->src->succs) > 1) + { + if (prev_nc == num_chains + && num_chains < MAX_NUM_CHAINS) + num_chains++; + for (j = prev_nc; j < num_chains; j++) + { + VEC_safe_push (edge, heap, dep_chains[j], opnd_edge); + } + } + } + + has_valid_pred + = convert_control_dep_chain_into_preds (dep_chains, + num_chains, + preds, + num_preds); + for (i = 0; i < num_chains; i++) + VEC_free (edge, heap, dep_chains[i]); + free (dep_chains); + return has_valid_pred; +} + +/* Dumps the predicates (PREDS) for USESTMT. */ + +static void +dump_predicates (gimple usestmt, size_t num_preds, + VEC(use_pred_info_t, heap) **preds, + const char* msg) +{ + size_t i, j; + VEC(use_pred_info_t, heap) *one_pred_chain; + fprintf (dump_file, msg); + print_gimple_stmt (dump_file, usestmt, 0, 0); + fprintf (dump_file, "is guarded by :\n"); + /* do some dumping here: */ + for (i = 0; i < num_preds; i++) + { + size_t np; + + one_pred_chain = preds[i]; + np = VEC_length (use_pred_info_t, one_pred_chain); + + for (j = 0; j < np; j++) + { + use_pred_info_t one_pred + = VEC_index (use_pred_info_t, one_pred_chain, j); + if (one_pred->invert) + fprintf (dump_file, " (.NOT.) "); + print_gimple_stmt (dump_file, one_pred->cond, 0, 0); + if (j < np - 1) + fprintf (dump_file, "(.AND.)\n"); + } + if (i < num_preds - 1) + fprintf (dump_file, "(.OR.)\n"); + } +} + +/* Destroys the predicate set *PREDS. */ + +static void +destroy_predicate_vecs (size_t n, + VEC(use_pred_info_t, heap) ** preds) +{ + size_t i, j; + for (i = 0; i < n; i++) + { + for (j = 0; j < VEC_length (use_pred_info_t, preds[i]); j++) + free (VEC_index (use_pred_info_t, preds[i], j)); + VEC_free (use_pred_info_t, heap, preds[i]); + } + free (preds); +} + + +/* Computes the 'normalized' conditional code with operand + swapping and condition inversion. */ + +static enum tree_code +get_cmp_code (enum tree_code orig_cmp_code, + bool swap_cond, bool invert) +{ + enum tree_code tc = orig_cmp_code; + + if (swap_cond) + tc = swap_tree_comparison (orig_cmp_code); + if (invert) + tc = invert_tree_comparison (tc, false); + + switch (tc) + { + case LT_EXPR: + case LE_EXPR: + case GT_EXPR: + case GE_EXPR: + case EQ_EXPR: + case NE_EXPR: + break; + default: + return ERROR_MARK; + } + return tc; +} + +/* Returns true if VAL falls in the range defined by BOUNDARY and CMPC, i.e. + all values in the range satisfies (x CMPC BOUNDARY) == true. */ + +static bool +is_value_included_in (tree val, tree boundary, enum tree_code cmpc) +{ + bool inverted = false; + bool is_unsigned; + bool result; + + /* Only handle integer constant here. */ + if (TREE_CODE (val) != INTEGER_CST + || TREE_CODE (boundary) != INTEGER_CST) + return true; + + is_unsigned = TYPE_UNSIGNED (TREE_TYPE (val)); + + if (cmpc == GE_EXPR || cmpc == GT_EXPR + || cmpc == NE_EXPR) + { + cmpc = invert_tree_comparison (cmpc, false); + inverted = true; + } + + if (is_unsigned) + { + if (cmpc == EQ_EXPR) + result = tree_int_cst_equal (val, boundary); + else if (cmpc == LT_EXPR) + result = INT_CST_LT_UNSIGNED (val, boundary); + else + { + gcc_assert (cmpc == LE_EXPR); + result = (tree_int_cst_equal (val, boundary) + || INT_CST_LT_UNSIGNED (val, boundary)); + } + } + else + { + if (cmpc == EQ_EXPR) + result = tree_int_cst_equal (val, boundary); + else if (cmpc == LT_EXPR) + result = INT_CST_LT (val, boundary); + else + { + gcc_assert (cmpc == LE_EXPR); + result = (tree_int_cst_equal (val, boundary) + || INT_CST_LT (val, boundary)); + } + } + + if (inverted) + result ^= 1; + + return result; +} + +/* Returns true if PRED is common among all the predicate + chains (PREDS) (and therefore can be factored out). + NUM_PRED_CHAIN is the size of array PREDS. */ + +static bool +find_matching_predicate_in_rest_chains (use_pred_info_t pred, + VEC(use_pred_info_t, heap) **preds, + size_t num_pred_chains) +{ + size_t i, j, n; + + /* trival case */ + if (num_pred_chains == 1) + return true; + + for (i = 1; i < num_pred_chains; i++) + { + bool found = false; + VEC(use_pred_info_t, heap) *one_chain = preds[i]; + n = VEC_length (use_pred_info_t, one_chain); + for (j = 0; j < n; j++) + { + use_pred_info_t pred2 + = VEC_index (use_pred_info_t, one_chain, j); + /* can relax the condition comparison to not + use address comparison. However, the most common + case is that multiple control dependent paths share + a common path prefix, so address comparison should + be ok. */ + + if (pred2->cond == pred->cond + && pred2->invert == pred->invert) + { + found = true; + break; + } + } + if (!found) + return false; + } + return true; +} + +/* Forward declaration. */ +static bool +is_use_properly_guarded (gimple use_stmt, + basic_block use_bb, + gimple phi, + unsigned uninit_opnds, + struct pointer_set_t *visited_phis); + +/* A helper function that determines if the predicate set + of the use is not overlapping with that of the uninit paths. + The most common senario of guarded use is in Example 1: + Example 1: + if (some_cond) + { + x = ...; + flag = true; + } + + ... some code ... + + if (flag) + use (x); + + The real world examples are usually more complicated, but similar + and usually result from inlining: + + bool init_func (int * x) + { + if (some_cond) + return false; + *x = .. + return true; + } + + void foo(..) + { + int x; + + if (!init_func(&x)) + return; + + .. some_code ... + use (x); + } + + Another possible use scenario is in the following trivial example: + + Example 2: + if (n > 0) + x = 1; + ... + if (n > 0) + { + if (m < 2) + .. = x; + } + + Predicate analysis needs to compute the composite predicate: + + 1) 'x' use predicate: (n > 0) .AND. (m < 2) + 2) 'x' default value (non-def) predicate: .NOT. (n > 0) + (the predicate chain for phi operand defs can be computed + starting from a bb that is control equivalent to the phi's + bb and is dominating the operand def.) + + and check overlapping: + (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0)) + <==> false + + This implementation provides framework that can handle + scenarios. (Note that many simple cases are handled properly + without the predicate analysis -- this is due to jump threading + transformation which eliminates the merge point thus makes + path sensitive analysis unnecessary.) + + NUM_PREDS is the number is the number predicate chains, PREDS is + the array of chains, PHI is the phi node whose incoming (undefined) + paths need to be pruned, and UNINIT_OPNDS is the bitmap holding + uninit operand positions. VISITED_PHIS is the pointer set of phi + stmts being checked. */ + + +static bool +use_pred_not_overlap_with_undef_path_pred ( + size_t num_preds, + VEC(use_pred_info_t, heap) **preds, + gimple phi, unsigned uninit_opnds, + struct pointer_set_t *visited_phis) +{ + unsigned int i, n; + gimple flag_def = 0; + tree boundary_cst = 0; + enum tree_code cmp_code; + bool swap_cond = false; + bool invert = false; + VEC(use_pred_info_t, heap) *the_pred_chain; + + gcc_assert (num_preds > 0); + /* Find within the common prefix of multiple predicate chains + a predicate that is a comparison of a flag variable against + a constant. */ + the_pred_chain = preds[0]; + n = VEC_length (use_pred_info_t, the_pred_chain); + for (i = 0; i < n; i++) + { + gimple cond; + tree cond_lhs, cond_rhs, flag = 0; + + use_pred_info_t the_pred + = VEC_index (use_pred_info_t, the_pred_chain, i); + + cond = the_pred->cond; + invert = the_pred->invert; + cond_lhs = gimple_cond_lhs (cond); + cond_rhs = gimple_cond_rhs (cond); + cmp_code = gimple_cond_code (cond); + + if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME + && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs)) + { + boundary_cst = cond_rhs; + flag = cond_lhs; + } + else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME + && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs)) + { + boundary_cst = cond_lhs; + flag = cond_rhs; + swap_cond = true; + } + + if (!flag) + continue; + + flag_def = SSA_NAME_DEF_STMT (flag); + + if (!flag_def) + continue; + + if ((gimple_code (flag_def) == GIMPLE_PHI) + && (gimple_bb (flag_def) == gimple_bb (phi)) + && find_matching_predicate_in_rest_chains ( + the_pred, preds, num_preds)) + break; + + flag_def = 0; + } + + if (!flag_def) + return false; + + /* Now check all the uninit incoming edge has a constant flag value + that is in conflict with the use guard/predicate. */ + cmp_code = get_cmp_code (cmp_code, swap_cond, invert); + + if (cmp_code == ERROR_MARK) + return false; + + for (i = 0; i < sizeof (unsigned); i++) + { + tree flag_arg; + + if (!MASK_TEST_BIT (uninit_opnds, i)) + continue; + + flag_arg = gimple_phi_arg_def (flag_def, i); + if (!is_gimple_constant (flag_arg)) + return false; + + /* Now check if the constant is in the guarded range. */ + if (is_value_included_in (flag_arg, boundary_cst, cmp_code)) + { + tree opnd; + gimple opnd_def; + + /* Now that we know that this undefined edge is not + pruned. If the operand is defined by another phi, + we can further prune the incoming edges of that + phi by checking the predicates of this operands. */ + + opnd = gimple_phi_arg_def (phi, i); + opnd_def = SSA_NAME_DEF_STMT (opnd); + if (gimple_code (opnd_def) == GIMPLE_PHI) + { + edge opnd_edge; + unsigned uninit_opnds2 + = compute_uninit_opnds_pos (opnd_def); + gcc_assert (!MASK_EMPTY (uninit_opnds2)); + opnd_edge = gimple_phi_arg_edge (phi, i); + if (!is_use_properly_guarded (phi, + opnd_edge->src, + opnd_def, + uninit_opnds2, + visited_phis)) + return false; + } + else + return false; + } + } + + return true; +} + +/* Returns true if TC is AND or OR */ + +static inline bool +is_and_or_or (enum tree_code tc, tree typ) +{ + return (tc == TRUTH_AND_EXPR + || tc == TRUTH_OR_EXPR + || tc == BIT_IOR_EXPR + || (tc == BIT_AND_EXPR + && (typ == 0 || TREE_CODE (typ) == BOOLEAN_TYPE))); +} + +typedef struct norm_cond +{ + VEC(gimple, heap) *conds; + enum tree_code cond_code; + bool invert; +} *norm_cond_t; + + +/* Normalizes gimple condition COND. The normalization follows + UD chains to form larger condition expression trees. NORM_COND + holds the normalized result. COND_CODE is the logical opcode + (AND or OR) of the normalized tree. */ + +static void +normalize_cond_1 (gimple cond, + norm_cond_t norm_cond, + enum tree_code cond_code) +{ + enum gimple_code gc; + enum tree_code cur_cond_code; + tree rhs1, rhs2; + + gc = gimple_code (cond); + if (gc != GIMPLE_ASSIGN) + { + VEC_safe_push (gimple, heap, norm_cond->conds, cond); + return; + } + + cur_cond_code = gimple_assign_rhs_code (cond); + rhs1 = gimple_assign_rhs1 (cond); + rhs2 = gimple_assign_rhs2 (cond); + if (cur_cond_code == NE_EXPR) + { + if (integer_zerop (rhs2) + && (TREE_CODE (rhs1) == SSA_NAME)) + normalize_cond_1 ( + SSA_NAME_DEF_STMT (rhs1), + norm_cond, cond_code); + else if (integer_zerop (rhs1) + && (TREE_CODE (rhs2) == SSA_NAME)) + normalize_cond_1 ( + SSA_NAME_DEF_STMT (rhs2), + norm_cond, cond_code); + else + VEC_safe_push (gimple, heap, norm_cond->conds, cond); + + return; + } + + if (is_and_or_or (cur_cond_code, TREE_TYPE (rhs1)) + && (cond_code == cur_cond_code || cond_code == ERROR_MARK) + && (TREE_CODE (rhs1) == SSA_NAME && TREE_CODE (rhs2) == SSA_NAME)) + { + normalize_cond_1 (SSA_NAME_DEF_STMT (rhs1), + norm_cond, cur_cond_code); + normalize_cond_1 (SSA_NAME_DEF_STMT (rhs2), + norm_cond, cur_cond_code); + norm_cond->cond_code = cur_cond_code; + } + else + VEC_safe_push (gimple, heap, norm_cond->conds, cond); +} + +/* See normalize_cond_1 for details. INVERT is a flag to indicate + if COND needs to be inverted or not. */ + +static void +normalize_cond (gimple cond, norm_cond_t norm_cond, bool invert) +{ + enum tree_code cond_code; + + norm_cond->cond_code = ERROR_MARK; + norm_cond->invert = false; + norm_cond->conds = NULL; + gcc_assert (gimple_code (cond) == GIMPLE_COND); + cond_code = gimple_cond_code (cond); + if (invert) + cond_code = invert_tree_comparison (cond_code, false); + + if (cond_code == NE_EXPR) + { + if (integer_zerop (gimple_cond_rhs (cond)) + && (TREE_CODE (gimple_cond_lhs (cond)) == SSA_NAME)) + normalize_cond_1 ( + SSA_NAME_DEF_STMT (gimple_cond_lhs (cond)), + norm_cond, ERROR_MARK); + else if (integer_zerop (gimple_cond_lhs (cond)) + && (TREE_CODE (gimple_cond_rhs (cond)) == SSA_NAME)) + normalize_cond_1 ( + SSA_NAME_DEF_STMT (gimple_cond_rhs (cond)), + norm_cond, ERROR_MARK); + else + { + VEC_safe_push (gimple, heap, norm_cond->conds, cond); + norm_cond->invert = invert; + } + } + else + { + VEC_safe_push (gimple, heap, norm_cond->conds, cond); + norm_cond->invert = invert; + } + + gcc_assert (VEC_length (gimple, norm_cond->conds) == 1 + || is_and_or_or (norm_cond->cond_code, NULL)); +} + +/* Returns true if the domain for condition COND1 is a subset of + COND2. REVERSE is a flag. when it is true the function checks + if COND1 is a superset of COND2. INVERT1 and INVERT2 are flags + to indicate if COND1 and COND2 need to be inverted or not. */ + +static bool +is_gcond_subset_of (gimple cond1, bool invert1, + gimple cond2, bool invert2, + bool reverse) +{ + enum gimple_code gc1, gc2; + enum tree_code cond1_code, cond2_code; + gimple tmp; + tree cond1_lhs, cond1_rhs, cond2_lhs, cond2_rhs; + + /* Take the short cut. */ + if (cond1 == cond2) + return true; + + if (reverse) + { + tmp = cond1; + cond1 = cond2; + cond2 = tmp; + } + + gc1 = gimple_code (cond1); + gc2 = gimple_code (cond2); + + if ((gc1 != GIMPLE_ASSIGN && gc1 != GIMPLE_COND) + || (gc2 != GIMPLE_ASSIGN && gc2 != GIMPLE_COND)) + return cond1 == cond2; + + cond1_code = ((gc1 == GIMPLE_ASSIGN) + ? gimple_assign_rhs_code (cond1) + : gimple_cond_code (cond1)); + + cond2_code = ((gc2 == GIMPLE_ASSIGN) + ? gimple_assign_rhs_code (cond2) + : gimple_cond_code (cond2)); + + if (TREE_CODE_CLASS (cond1_code) != tcc_comparison + || TREE_CODE_CLASS (cond2_code) != tcc_comparison) + return false; + + if (invert1) + cond1_code = invert_tree_comparison (cond1_code, false); + if (invert2) + cond2_code = invert_tree_comparison (cond2_code, false); + + cond1_lhs = ((gc1 == GIMPLE_ASSIGN) + ? gimple_assign_rhs1 (cond1) + : gimple_cond_lhs (cond1)); + cond1_rhs = ((gc1 == GIMPLE_ASSIGN) + ? gimple_assign_rhs2 (cond1) + : gimple_cond_rhs (cond1)); + cond2_lhs = ((gc2 == GIMPLE_ASSIGN) + ? gimple_assign_rhs1 (cond2) + : gimple_cond_lhs (cond2)); + cond2_rhs = ((gc2 == GIMPLE_ASSIGN) + ? gimple_assign_rhs2 (cond2) + : gimple_cond_rhs (cond2)); + + /* Assuming const operands have been swapped to the + rhs at this point of the analysis. */ + + if (cond1_lhs != cond2_lhs) + return false; + + if (!is_gimple_constant (cond1_rhs) + || TREE_CODE (cond1_rhs) != INTEGER_CST) + return (cond1_rhs == cond2_rhs); + + if (!is_gimple_constant (cond2_rhs) + || TREE_CODE (cond2_rhs) != INTEGER_CST) + return (cond1_rhs == cond2_rhs); + + if (cond1_code == EQ_EXPR) + return is_value_included_in (cond1_rhs, + cond2_rhs, cond2_code); + if (cond1_code == NE_EXPR || cond2_code == EQ_EXPR) + return ((cond2_code == cond1_code) + && tree_int_cst_equal (cond1_rhs, cond2_rhs)); + + if (((cond1_code == GE_EXPR || cond1_code == GT_EXPR) + && (cond2_code == LE_EXPR || cond2_code == LT_EXPR)) + || ((cond1_code == LE_EXPR || cond1_code == LT_EXPR) + && (cond2_code == GE_EXPR || cond2_code == GT_EXPR))) + return false; + + if (cond1_code != GE_EXPR && cond1_code != GT_EXPR + && cond1_code != LE_EXPR && cond1_code != LT_EXPR) + return false; + + if (cond1_code == GT_EXPR) + { + cond1_code = GE_EXPR; + cond1_rhs = fold_binary (PLUS_EXPR, TREE_TYPE (cond1_rhs), + cond1_rhs, + fold_convert (TREE_TYPE (cond1_rhs), + integer_one_node)); + } + else if (cond1_code == LT_EXPR) + { + cond1_code = LE_EXPR; + cond1_rhs = fold_binary (MINUS_EXPR, TREE_TYPE (cond1_rhs), + cond1_rhs, + fold_convert (TREE_TYPE (cond1_rhs), + integer_one_node)); + } + + if (!cond1_rhs) + return false; + + gcc_assert (cond1_code == GE_EXPR || cond1_code == LE_EXPR); + + if (cond2_code == GE_EXPR || cond2_code == GT_EXPR || + cond2_code == LE_EXPR || cond2_code == LT_EXPR) + return is_value_included_in (cond1_rhs, + cond2_rhs, cond2_code); + else if (cond2_code == NE_EXPR) + return + (is_value_included_in (cond1_rhs, + cond2_rhs, cond2_code) + && !is_value_included_in (cond2_rhs, + cond1_rhs, cond1_code)); + return false; +} + +/* Returns true if the domain of the condition expression + in COND is a subset of any of the sub-conditions + of the normalized condtion NORM_COND. INVERT is a flag + to indicate of the COND needs to be inverted. + REVERSE is a flag. When it is true, the check is reversed -- + it returns true if COND is a superset of any of the subconditions + of NORM_COND. */ + +static bool +is_subset_of_any (gimple cond, bool invert, + norm_cond_t norm_cond, bool reverse) +{ + size_t i; + size_t len = VEC_length (gimple, norm_cond->conds); + + for (i = 0; i < len; i++) + { + if (is_gcond_subset_of (cond, invert, + VEC_index (gimple, norm_cond->conds, i), + false, reverse)) + return true; + } + return false; +} + +/* NORM_COND1 and NORM_COND2 are normalized logical/BIT OR + expressions (formed by following UD chains not control + dependence chains). The function returns true of domain + of and expression NORM_COND1 is a subset of NORM_COND2's. + The implementation is conservative, and it returns false if + it the inclusion relationship may not hold. */ + +static bool +is_or_set_subset_of (norm_cond_t norm_cond1, + norm_cond_t norm_cond2) +{ + size_t i; + size_t len = VEC_length (gimple, norm_cond1->conds); + + for (i = 0; i < len; i++) + { + if (!is_subset_of_any (VEC_index (gimple, norm_cond1->conds, i), + false, norm_cond2, false)) + return false; + } + return true; +} + +/* NORM_COND1 and NORM_COND2 are normalized logical AND + expressions (formed by following UD chains not control + dependence chains). The function returns true of domain + of and expression NORM_COND1 is a subset of NORM_COND2's. */ + +static bool +is_and_set_subset_of (norm_cond_t norm_cond1, + norm_cond_t norm_cond2) +{ + size_t i; + size_t len = VEC_length (gimple, norm_cond2->conds); + + for (i = 0; i < len; i++) + { + if (!is_subset_of_any (VEC_index (gimple, norm_cond2->conds, i), + false, norm_cond1, true)) + return false; + } + return true; +} + +/* Returns true of the domain if NORM_COND1 is a subset + of that of NORM_COND2. Returns false if it can not be + proved to be so. */ + +static bool +is_norm_cond_subset_of (norm_cond_t norm_cond1, + norm_cond_t norm_cond2) +{ + size_t i; + enum tree_code code1, code2; + + code1 = norm_cond1->cond_code; + code2 = norm_cond2->cond_code; + + if (code1 == TRUTH_AND_EXPR || code1 == BIT_AND_EXPR) + { + /* Both conditions are AND expressions. */ + if (code2 == TRUTH_AND_EXPR || code2 == BIT_AND_EXPR) + return is_and_set_subset_of (norm_cond1, norm_cond2); + /* NORM_COND1 is an AND expression, and NORM_COND2 is an OR + expression. In this case, returns true if any subexpression + of NORM_COND1 is a subset of any subexpression of NORM_COND2. */ + else if (code2 == TRUTH_OR_EXPR || code2 == BIT_IOR_EXPR) + { + size_t len1; + len1 = VEC_length (gimple, norm_cond1->conds); + for (i = 0; i < len1; i++) + { + gimple cond1 = VEC_index (gimple, norm_cond1->conds, i); + if (is_subset_of_any (cond1, false, norm_cond2, false)) + return true; + } + return false; + } + else + { + gcc_assert (code2 == ERROR_MARK); + gcc_assert (VEC_length (gimple, norm_cond2->conds) == 1); + return is_subset_of_any (VEC_index (gimple, norm_cond2->conds, 0), + norm_cond2->invert, norm_cond1, true); + } + } + /* NORM_COND1 is an OR expression */ + else if (code1 == TRUTH_OR_EXPR || code1 == BIT_IOR_EXPR) + { + if (code2 != code1) + return false; + + return is_or_set_subset_of (norm_cond1, norm_cond2); + } + else + { + gcc_assert (code1 == ERROR_MARK); + gcc_assert (VEC_length (gimple, norm_cond1->conds) == 1); + /* Conservatively returns false if NORM_COND1 is non-decomposible + and NORM_COND2 is an AND expression. */ + if (code2 == TRUTH_AND_EXPR || code2 == BIT_AND_EXPR) + return false; + + if (code2 == TRUTH_OR_EXPR || code2 == BIT_IOR_EXPR) + return is_subset_of_any (VEC_index (gimple, norm_cond1->conds, 0), + norm_cond1->invert, norm_cond2, false); + + gcc_assert (code2 == ERROR_MARK); + gcc_assert (VEC_length (gimple, norm_cond2->conds) == 1); + return is_gcond_subset_of (VEC_index (gimple, norm_cond1->conds, 0), + norm_cond1->invert, + VEC_index (gimple, norm_cond2->conds, 0), + norm_cond2->invert, false); + } +} + +/* Returns true of the domain of single predicate expression + EXPR1 is a subset of that of EXPR2. Returns false if it + can not be proved. */ + +static bool +is_pred_expr_subset_of (use_pred_info_t expr1, + use_pred_info_t expr2) +{ + gimple cond1, cond2; + enum tree_code code1, code2; + struct norm_cond norm_cond1, norm_cond2; + bool is_subset = false; + + cond1 = expr1->cond; + cond2 = expr2->cond; + code1 = gimple_cond_code (cond1); + code2 = gimple_cond_code (cond2); + + if (expr1->invert) + code1 = invert_tree_comparison (code1, false); + if (expr2->invert) + code2 = invert_tree_comparison (code2, false); + + /* Fast path -- match exactly */ + if ((gimple_cond_lhs (cond1) == gimple_cond_lhs (cond2)) + && (gimple_cond_rhs (cond1) == gimple_cond_rhs (cond2)) + && (code1 == code2)) + return true; + + /* Normalize conditions. To keep NE_EXPR, do not invert + with both need inversion. */ + normalize_cond (cond1, &norm_cond1, (expr1->invert)); + normalize_cond (cond2, &norm_cond2, (expr2->invert)); + + is_subset = is_norm_cond_subset_of (&norm_cond1, &norm_cond2); + + /* Free memory */ + VEC_free (gimple, heap, norm_cond1.conds); + VEC_free (gimple, heap, norm_cond2.conds); + return is_subset ; +} + +/* Returns true if the domain of PRED1 is a subset + of that of PRED2. Returns false if it can not be proved so. */ + +static bool +is_pred_chain_subset_of (VEC(use_pred_info_t, heap) *pred1, + VEC(use_pred_info_t, heap) *pred2) +{ + size_t np1, np2, i1, i2; + + np1 = VEC_length (use_pred_info_t, pred1); + np2 = VEC_length (use_pred_info_t, pred2); + + for (i2 = 0; i2 < np2; i2++) + { + bool found = false; + use_pred_info_t info2 + = VEC_index (use_pred_info_t, pred2, i2); + for (i1 = 0; i1 < np1; i1++) + { + use_pred_info_t info1 + = VEC_index (use_pred_info_t, pred1, i1); + if (is_pred_expr_subset_of (info1, info2)) + { + found = true; + break; + } + } + if (!found) + return false; + } + return true; +} + +/* Returns true if the domain defined by + one pred chain ONE_PRED is a subset of the domain + of *PREDS. It returns false if ONE_PRED's domain is + not a subset of any of the sub-domains of PREDS ( + corresponding to each individual chains in it), even + though it may be still be a subset of whole domain + of PREDS which is the union (ORed) of all its subdomains. + In other words, the result is conservative. */ + +static bool +is_included_in (VEC(use_pred_info_t, heap) *one_pred, + VEC(use_pred_info_t, heap) **preds, + size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) + { + if (is_pred_chain_subset_of (one_pred, preds[i])) + return true; + } + + return false; +} + +/* compares two predicate sets PREDS1 and PREDS2 and returns + true if the domain defined by PREDS1 is a superset + of PREDS2's domain. N1 and N2 are array sizes of PREDS1 and + PREDS2 respectively. The implementation chooses not to build + generic trees (and relying on the folding capability of the + compiler), but instead performs brute force comparison of + individual predicate chains (won't be a compile time problem + as the chains are pretty short). When the function returns + false, it does not necessarily mean *PREDS1 is not a superset + of *PREDS2, but mean it may not be so since the analysis can + not prove it. In such cases, false warnings may still be + emitted. */ + +static bool +is_superset_of (VEC(use_pred_info_t, heap) **preds1, + size_t n1, + VEC(use_pred_info_t, heap) **preds2, + size_t n2) +{ + size_t i; + VEC(use_pred_info_t, heap) *one_pred_chain; + + for (i = 0; i < n2; i++) + { + one_pred_chain = preds2[i]; + if (!is_included_in (one_pred_chain, preds1, n1)) + return false; + } + + return true; +} + +/* Computes the predicates that guard the use and checks + if the incoming paths that have empty (or possibly + empty) defintion can be pruned/filtered. The function returns + true if it can be determined that the use of PHI's def in + USE_STMT is guarded with a predicate set not overlapping with + predicate sets of all runtime paths that do not have a definition. + Returns false if it is not or it can not be determined. USE_BB is + the bb of the use (for phi operand use, the bb is not the bb of + the phi stmt, but the src bb of the operand edge). UNINIT_OPNDS + is a bit vector. If an operand of PHI is uninitialized, the + correponding bit in the vector is 1. VISIED_PHIS is a pointer + set of phis being visted. */ + +static bool +is_use_properly_guarded (gimple use_stmt, + basic_block use_bb, + gimple phi, + unsigned uninit_opnds, + struct pointer_set_t *visited_phis) +{ + basic_block phi_bb; + VEC(use_pred_info_t, heap) **preds = 0; + VEC(use_pred_info_t, heap) **def_preds = 0; + size_t num_preds = 0, num_def_preds = 0; + bool has_valid_preds = false; + bool is_properly_guarded = false; + + if (pointer_set_insert (visited_phis, phi)) + return false; + + phi_bb = gimple_bb (phi); + + if (is_non_loop_exit_postdominating (use_bb, phi_bb)) + return false; + + has_valid_preds = find_predicates (&preds, &num_preds, + phi_bb, use_bb); + + if (!has_valid_preds) + { + destroy_predicate_vecs (num_preds, preds); + return false; + } + + if (dump_file) + dump_predicates (use_stmt, num_preds, preds, + "Use in stmt "); + + has_valid_preds = find_def_preds (&def_preds, + &num_def_preds, phi); + + if (has_valid_preds) + { + if (dump_file) + dump_predicates (phi, num_def_preds, def_preds, + "Operand defs of phi "); + is_properly_guarded = + is_superset_of (def_preds, num_def_preds, + preds, num_preds); + } + + /* further prune the dead incoming phi edges. */ + if (!is_properly_guarded) + is_properly_guarded + = use_pred_not_overlap_with_undef_path_pred ( + num_preds, preds, phi, uninit_opnds, visited_phis); + + destroy_predicate_vecs (num_preds, preds); + destroy_predicate_vecs (num_def_preds, def_preds); + return is_properly_guarded; +} + +/* Searches through all uses of a potentially + uninitialized variable defined by PHI and returns a use + statement if the use is not properly guarded. It returns + NULL if all uses are guarded. UNINIT_OPNDS is a bitvector + holding the position(s) of uninit PHI operands. WORKLIST + is the vector of candidate phis that may be updated by this + function. ADDED_TO_WORKLIST is the pointer set tracking + if the new phi is already in the worklist. */ + +static gimple +find_uninit_use (gimple phi, unsigned uninit_opnds, + VEC(gimple, heap) **worklist, + struct pointer_set_t *added_to_worklist) +{ + tree phi_result; + use_operand_p use_p; + gimple use_stmt; + imm_use_iterator iter; + + phi_result = gimple_phi_result (phi); + + FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result) + { + struct pointer_set_t *visited_phis; + basic_block use_bb; + + use_stmt = use_p->loc.stmt; + + visited_phis = pointer_set_create (); + + use_bb = gimple_bb (use_stmt); + if (gimple_code (use_stmt) == GIMPLE_PHI) + { + unsigned i, n; + n = gimple_phi_num_args (use_stmt); + + /* Find the matching phi argument of the use. */ + for (i = 0; i < n; ++i) + { + if (gimple_phi_arg_def_ptr (use_stmt, i) == use_p->use) + { + edge e = gimple_phi_arg_edge (use_stmt, i); + use_bb = e->src; + break; + } + } + } + + if (is_use_properly_guarded (use_stmt, + use_bb, + phi, + uninit_opnds, + visited_phis)) + { + pointer_set_destroy (visited_phis); + continue; + } + pointer_set_destroy (visited_phis); + + /* Found one real use, return. */ + if (gimple_code (use_stmt) != GIMPLE_PHI) + return use_stmt; + + /* Found a phi use that is not guarded, + add the phi to the worklist. */ + if (!pointer_set_insert (added_to_worklist, + use_stmt)) + { + VEC_safe_push (gimple, heap, *worklist, use_stmt); + pointer_set_insert (possibly_undefined_names, + phi_result); + } + } + + return NULL; +} + +/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions + and gives warning if there exists a runtime path from the entry to a + use of the PHI def that does not contain a definition. In other words, + the warning is on the real use. The more dead paths that can be pruned + by the compiler, the fewer false positives the warning is. WORKLIST + is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is + a pointer set tracking if the new phi is added to the worklist or not. */ + +static void +warn_uninitialized_phi (gimple phi, VEC(gimple, heap) **worklist, + struct pointer_set_t *added_to_worklist) +{ + unsigned uninit_opnds; + gimple uninit_use_stmt = 0; + tree uninit_op; + + /* Don't look at memory tags. */ + if (!is_gimple_reg (gimple_phi_result (phi))) + return; + + uninit_opnds = compute_uninit_opnds_pos (phi); + + if (MASK_EMPTY (uninit_opnds)) + return; + + /* Now check if we have any use of the value without proper guard. */ + uninit_use_stmt = find_uninit_use (phi, uninit_opnds, + worklist, added_to_worklist); + + /* All uses are properly guarded. */ + if (!uninit_use_stmt) + return; + + uninit_op = gimple_phi_arg_def (phi, MASK_FIRST_SET_BIT (uninit_opnds)); + warn_uninit (uninit_op, + "%qD may be used uninitialized in this function", + uninit_use_stmt); + +} + + +/* Entry point to the late uninitialized warning pass. */ + +static unsigned int +execute_late_warn_uninitialized (void) +{ + basic_block bb; + gimple_stmt_iterator gsi; + VEC(gimple, heap) *worklist = 0; + struct pointer_set_t *added_to_worklist; + + calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); + /* Re-do the plain uninitialized variable check, as optimization may have + straightened control flow. Do this first so that we don't accidentally + get a "may be" warning when we'd have seen an "is" warning later. */ + warn_uninitialized_vars (/*warn_possibly_uninitialized=*/1); + + timevar_push (TV_TREE_UNINIT); + + possibly_undefined_names = pointer_set_create (); + added_to_worklist = pointer_set_create (); + + /* Initialize worklist */ + FOR_EACH_BB (bb) + for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple phi = gsi_stmt (gsi); + size_t n, i; + + n = gimple_phi_num_args (phi); + + /* Don't look at memory tags. */ + if (!is_gimple_reg (gimple_phi_result (phi))) + continue; + + for (i = 0; i < n; ++i) + { + tree op = gimple_phi_arg_def (phi, i); + if (TREE_CODE (op) == SSA_NAME + && ssa_undefined_value_p (op)) + { + VEC_safe_push (gimple, heap, worklist, phi); + pointer_set_insert (added_to_worklist, phi); + break; + } + } + } + + while (VEC_length (gimple, worklist) != 0) + { + gimple cur_phi = 0; + cur_phi = VEC_pop (gimple, worklist); + warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist); + } + + VEC_free (gimple, heap, worklist); + pointer_set_destroy (added_to_worklist); + pointer_set_destroy (possibly_undefined_names); + possibly_undefined_names = NULL; + free_dominance_info (CDI_POST_DOMINATORS); + timevar_pop (TV_TREE_UNINIT); + return 0; +} + +static bool +gate_warn_uninitialized (void) +{ + return warn_uninitialized != 0; +} + +struct gimple_opt_pass pass_late_warn_uninitialized = +{ + { + GIMPLE_PASS, + "uninit", /* name */ + gate_warn_uninitialized, /* gate */ + execute_late_warn_uninitialized, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7915bb88b22..820eb3b376a 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1603,25 +1603,6 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data, } -/* Return true if T, an SSA_NAME, has an undefined value. */ - -bool -ssa_undefined_value_p (tree t) -{ - tree var = SSA_NAME_VAR (t); - - /* Parameters get their initial value from the function entry. */ - if (TREE_CODE (var) == PARM_DECL) - return false; - - /* Hard register variables get their initial value from the ether. */ - if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) - return false; - - /* The value is undefined iff its definition statement is empty. */ - return gimple_nop_p (SSA_NAME_DEF_STMT (t)); -} - /* Emit warnings for uninitialized variables. This is done in two passes. The first pass notices real uses of SSA names with undefined values. @@ -1640,7 +1621,7 @@ ssa_undefined_value_p (tree t) /* Emit a warning for T, an SSA_NAME, being uninitialized. The exact warning text is in MSGID and LOCUS may contain a location or be null. */ -static void +void warn_uninit (tree t, const char *gmsgid, void *data) { tree var = SSA_NAME_VAR (t); @@ -1770,28 +1751,7 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_) return NULL_TREE; } -/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions - and warn about them. */ - -static void -warn_uninitialized_phi (gimple phi) -{ - size_t i, n = gimple_phi_num_args (phi); - - /* Don't look at memory tags. */ - if (!is_gimple_reg (gimple_phi_result (phi))) - return; - - for (i = 0; i < n; ++i) - { - tree op = gimple_phi_arg_def (phi, i); - if (TREE_CODE (op) == SSA_NAME) - warn_uninit (op, "%qD may be used uninitialized in this function", - NULL); - } -} - -static unsigned int +unsigned int warn_uninitialized_vars (bool warn_possibly_uninitialized) { gimple_stmt_iterator gsi; @@ -1800,7 +1760,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) data.warn_possibly_uninitialized = warn_possibly_uninitialized; - calculate_dominance_info (CDI_POST_DOMINATORS); FOR_EACH_BB (bb) { @@ -1818,10 +1777,6 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized) } } - /* Post-dominator information can not be reliably updated. Free it - after the use. */ - - free_dominance_info (CDI_POST_DOMINATORS); return 0; } @@ -1834,25 +1789,14 @@ execute_early_warn_uninitialized (void) as possible, thus don't do it here. However, without optimization we need to warn here about "may be uninitialized". */ - warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize); - return 0; -} - -static unsigned int -execute_late_warn_uninitialized (void) -{ - basic_block bb; - gimple_stmt_iterator gsi; + calculate_dominance_info (CDI_POST_DOMINATORS); - /* Re-do the plain uninitialized variable check, as optimization may have - straightened control flow. Do this first so that we don't accidentally - get a "may be" warning when we'd have seen an "is" warning later. */ - warn_uninitialized_vars (/*warn_possibly_uninitialized=*/1); + warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize); - FOR_EACH_BB (bb) - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - warn_uninitialized_phi (gsi_stmt (gsi)); + /* Post-dominator information can not be reliably updated. Free it + after the use. */ + free_dominance_info (CDI_POST_DOMINATORS); return 0; } @@ -1881,25 +1825,6 @@ struct gimple_opt_pass pass_early_warn_uninitialized = } }; -struct gimple_opt_pass pass_late_warn_uninitialized = -{ - { - GIMPLE_PASS, - "*late_warn_uninitialized", /* name */ - gate_warn_uninitialized, /* gate */ - execute_late_warn_uninitialized, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } -}; - /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */ void diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index ba537a062ef..cf2ac21fca2 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -503,6 +503,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, lambda_vector dist_v; unsigned int loop_depth; + /* Don't bother to analyze statements marked as unvectorizable. */ + if (!STMT_VINFO_VECTORIZABLE (stmtinfo_a) + || !STMT_VINFO_VECTORIZABLE (stmtinfo_b)) + return false; + if (DDR_ARE_DEPENDENT (ddr) == chrec_known) { /* Independent data accesses. */ @@ -546,7 +551,11 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr, print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM); } - return true; + /* Mark the statements as unvectorizable. */ + STMT_VINFO_VECTORIZABLE (stmtinfo_a) = false; + STMT_VINFO_VECTORIZABLE (stmtinfo_b) = false; + + return false; } /* Versioning for alias is not yet supported for basic block SLP, and @@ -851,8 +860,18 @@ vect_compute_data_refs_alignment (loop_vec_info loop_vinfo, datarefs = BB_VINFO_DATAREFS (bb_vinfo); for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) - if (!vect_compute_data_ref_alignment (dr)) - return false; + if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) + && !vect_compute_data_ref_alignment (dr)) + { + if (bb_vinfo) + { + /* Mark unsupported statement as unvectorizable. */ + STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false; + continue; + } + else + return false; + } return true; } @@ -939,9 +958,11 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) gimple stmt = DR_STMT (dr); stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - /* For interleaving, only the alignment of the first access matters. */ - if (STMT_VINFO_STRIDED_ACCESS (stmt_info) - && DR_GROUP_FIRST_DR (stmt_info) != stmt) + /* For interleaving, only the alignment of the first access matters. + Skip statements marked as not vectorizable. */ + if ((STMT_VINFO_STRIDED_ACCESS (stmt_info) + && DR_GROUP_FIRST_DR (stmt_info) != stmt) + || !STMT_VINFO_VECTORIZABLE (stmt_info)) continue; supportable_dr_alignment = vect_supportable_dr_alignment (dr); @@ -955,6 +976,8 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) else fprintf (vect_dump, "not vectorized: unsupported unaligned store."); + + print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM); } return false; } @@ -1564,8 +1587,20 @@ vect_analyze_group_access (struct data_reference *dr) } return true; } + if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "not consecutive access"); + { + fprintf (vect_dump, "not consecutive access "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + + if (bb_vinfo) + { + /* Mark the statement as unvectorizable. */ + STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false; + return true; + } + return false; } @@ -1836,11 +1871,20 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo) datarefs = BB_VINFO_DATAREFS (bb_vinfo); for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++) - if (!vect_analyze_data_ref_access (dr)) + if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) + && !vect_analyze_data_ref_access (dr)) { if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: complicated access pattern."); - return false; + + if (bb_vinfo) + { + /* Mark the statement as not vectorizable. */ + STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false; + continue; + } + else + return false; } return true; @@ -2013,7 +2057,15 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, fprintf (vect_dump, "not vectorized: data ref analysis failed "); print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } - return false; + + if (bb_vinfo) + { + /* Mark the statement as not vectorizable. */ + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + continue; + } + else + return false; } if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST) @@ -2021,7 +2073,14 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)) fprintf (vect_dump, "not vectorized: base addr of dr is a " "constant"); - return false; + if (bb_vinfo) + { + /* Mark the statement as not vectorizable. */ + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + continue; + } + else + return false; } base = unshare_expr (DR_BASE_ADDRESS (dr)); @@ -2163,7 +2222,15 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, fprintf (vect_dump, " scalar_type: "); print_generic_expr (vect_dump, scalar_type, TDF_DETAILS); } - return false; + + if (bb_vinfo) + { + /* Mark the statement as not vectorizable. */ + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + continue; + } + else + return false; } /* Adjust the minimal vectorization factor according to the diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 6949ebdf873..f313294bd29 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -344,6 +344,19 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); } + /* Fail to vectorize statements marked as unvectorizable. */ + if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt))) + { + if (vect_print_dump_info (REPORT_SLP)) + { + fprintf (vect_dump, + "Build SLP failed: unvectorizable statement "); + print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM); + } + + return false; + } + lhs = gimple_get_lhs (stmt); if (lhs == NULL_TREE) { diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 988749b792f..0dabb6a365b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3031,12 +3031,17 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, } if (slp) - strided_store = false; - - /* VEC_NUM is the number of vect stmts to be created for this group. */ - if (slp) - vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + { + strided_store = false; + /* VEC_NUM is the number of vect stmts to be created for this + group. */ + vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0); + first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)); + } else + /* VEC_NUM is the number of vect stmts to be created for this + group. */ vec_num = group_size; } else @@ -4327,6 +4332,7 @@ new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo, STMT_VINFO_LIVE_P (res) = false; STMT_VINFO_VECTYPE (res) = NULL; STMT_VINFO_VEC_STMT (res) = NULL; + STMT_VINFO_VECTORIZABLE (res) = true; STMT_VINFO_IN_PATTERN_P (res) = false; STMT_VINFO_RELATED_STMT (res) = NULL; STMT_VINFO_DATA_REF (res) = NULL; diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index bd43a4bc173..fc9f0e93af0 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -198,6 +198,9 @@ typedef struct _loop_vec_info { /* Unrolling factor */ int vectorization_factor; + /* The loop location in the source. */ + LOC loop_line_number; + /* Unknown DRs according to which loop was peeled. */ struct data_reference *unaligned_dr; @@ -228,9 +231,6 @@ typedef struct _loop_vec_info { runtime (loop versioning) misalignment check. */ VEC(gimple,heap) *may_misalign_stmts; - /* The loop location in the source. */ - LOC loop_line_number; - /* All interleaving chains of stores in the loop, represented by the first stmt in the chain. */ VEC(gimple, heap) *strided_stores; @@ -398,21 +398,23 @@ typedef struct _stmt_vec_info { enum stmt_vec_info_type type; + /* Indicates whether this stmts is part of a computation whose result is + used outside the loop. */ + bool live; + + /* Stmt is part of some pattern (computation idiom) */ + bool in_pattern_p; + + /* For loads only, if there is a store with the same location, this field is + TRUE. */ + bool read_write_dep; + /* The stmt to which this info struct refers to. */ gimple stmt; /* The loop_vec_info with respect to which STMT is vectorized. */ loop_vec_info loop_vinfo; - /* Not all stmts in the loop need to be vectorized. e.g, the increment - of the loop induction variable and computation of array indexes. relevant - indicates whether the stmt needs to be vectorized. */ - enum vect_relevant relevant; - - /* Indicates whether this stmts is part of a computation whose result is - used outside the loop. */ - bool live; - /* The vector type to be used for the LHS of this statement. */ tree vectype; @@ -436,9 +438,6 @@ typedef struct _stmt_vec_info { tree dr_step; tree dr_aligned_to; - /* Stmt is part of some pattern (computation idiom) */ - bool in_pattern_p; - /* Used for various bookkeeping purposes, generally holding a pointer to some other stmt S that is in some way "related" to this stmt. Current use of this field is: @@ -457,11 +456,17 @@ typedef struct _stmt_vec_info { /* Classify the def of this stmt. */ enum vect_def_type def_type; + /* Whether the stmt is SLPed, loop-based vectorized, or both. */ + enum slp_vect_type slp_type; + /* Interleaving info. */ /* First data-ref in the interleaving group. */ gimple first_dr; /* Pointer to the next data-ref in the group. */ gimple next_dr; + /* In case that two or more stmts share data-ref, this is the pointer to the + previously detected stmt with the same dr. */ + gimple same_dr_stmt; /* The size of the interleaving group. */ unsigned int size; /* For stores, number of stores from this group seen. We vectorize the last @@ -470,12 +475,11 @@ typedef struct _stmt_vec_info { /* For loads only, the gap from the previous load. For consecutive loads, GAP is 1. */ unsigned int gap; - /* In case that two or more stmts share data-ref, this is the pointer to the - previously detected stmt with the same dr. */ - gimple same_dr_stmt; - /* For loads only, if there is a store with the same location, this field is - TRUE. */ - bool read_write_dep; + + /* Not all stmts in the loop need to be vectorized. e.g, the increment + of the loop induction variable and computation of array indexes. relevant + indicates whether the stmt needs to be vectorized. */ + enum vect_relevant relevant; /* Vectorization costs associated with statement. */ struct @@ -484,11 +488,12 @@ typedef struct _stmt_vec_info { int inside_of_loop; /* Statements generated inside loop. */ } cost; - /* Whether the stmt is SLPed, loop-based vectorized, or both. */ - enum slp_vect_type slp_type; - /* The bb_vec_info with respect to which STMT is vectorized. */ bb_vec_info bb_vinfo; + + /* Is this statement vectorizable or should it be skipped in (partial) + vectorization. */ + bool vectorizable; } *stmt_vec_info; /* Access Functions. */ @@ -500,6 +505,7 @@ typedef struct _stmt_vec_info { #define STMT_VINFO_LIVE_P(S) (S)->live #define STMT_VINFO_VECTYPE(S) (S)->vectype #define STMT_VINFO_VEC_STMT(S) (S)->vectorized_stmt +#define STMT_VINFO_VECTORIZABLE(S) (S)->vectorizable #define STMT_VINFO_DATA_REF(S) (S)->data_ref_info #define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b23132ca043..d8ebbe8f369 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -764,6 +764,27 @@ range_is_null (value_range_t *vr) && integer_zerop (vr->max); } +/* Return true if max and min of VR are INTEGER_CST. It's not necessary + a singleton. */ + +static inline bool +range_int_cst_p (value_range_t *vr) +{ + return (vr->type == VR_RANGE + && TREE_CODE (vr->max) == INTEGER_CST + && TREE_CODE (vr->min) == INTEGER_CST + && !TREE_OVERFLOW (vr->max) + && !TREE_OVERFLOW (vr->min)); +} + +/* Return true if VR is a INTEGER_CST singleton. */ + +static inline bool +range_int_cst_singleton_p (value_range_t *vr) +{ + return (range_int_cst_p (vr) + && tree_int_cst_equal (vr->min, vr->max)); +} /* Return true if value range VR involves at least one symbol. */ @@ -2498,19 +2519,20 @@ extract_range_from_binary_expr (value_range_t *vr, } else if (code == BIT_AND_EXPR) { - if (vr0.type == VR_RANGE - && vr0.min == vr0.max - && TREE_CODE (vr0.max) == INTEGER_CST - && !TREE_OVERFLOW (vr0.max) - && tree_int_cst_sgn (vr0.max) >= 0) + bool vr0_int_cst_singleton_p, vr1_int_cst_singleton_p; + + vr0_int_cst_singleton_p = range_int_cst_singleton_p (&vr0); + vr1_int_cst_singleton_p = range_int_cst_singleton_p (&vr1); + + if (vr0_int_cst_singleton_p && vr1_int_cst_singleton_p) + min = max = int_const_binop (code, vr0.max, vr1.max, 0); + else if (vr0_int_cst_singleton_p + && tree_int_cst_sgn (vr0.max) >= 0) { min = build_int_cst (expr_type, 0); max = vr0.max; } - else if (vr1.type == VR_RANGE - && vr1.min == vr1.max - && TREE_CODE (vr1.max) == INTEGER_CST - && !TREE_OVERFLOW (vr1.max) + else if (vr1_int_cst_singleton_p && tree_int_cst_sgn (vr1.max) >= 0) { type = VR_RANGE; @@ -2525,12 +2547,8 @@ extract_range_from_binary_expr (value_range_t *vr, } else if (code == BIT_IOR_EXPR) { - if (vr0.type == VR_RANGE - && vr1.type == VR_RANGE - && TREE_CODE (vr0.min) == INTEGER_CST - && TREE_CODE (vr1.min) == INTEGER_CST - && TREE_CODE (vr0.max) == INTEGER_CST - && TREE_CODE (vr1.max) == INTEGER_CST + if (range_int_cst_p (&vr0) + && range_int_cst_p (&vr1) && tree_int_cst_sgn (vr0.min) >= 0 && tree_int_cst_sgn (vr1.min) >= 0) { diff --git a/gcc/tree.c b/gcc/tree.c index 561367bdd43..8eeecff7122 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4258,7 +4258,12 @@ free_lang_data_in_type (tree type) TYPE_LANG_SLOT_1 (type) = NULL_TREE; } - TYPE_CONTEXT (type) = NULL_TREE; + if (debug_info_level < DINFO_LEVEL_TERSE + || (TYPE_CONTEXT (type) + && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_DECL + && TREE_CODE (TYPE_CONTEXT (type)) != NAMESPACE_DECL)) + TYPE_CONTEXT (type) = NULL_TREE; + if (debug_info_level < DINFO_LEVEL_TERSE) TYPE_STUB_DECL (type) = NULL_TREE; } diff --git a/gcc/tree.h b/gcc/tree.h index 8e063b0c630..2055aed7f27 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1419,7 +1419,8 @@ struct GTY(()) tree_real_cst { /* In a FIXED_CST node. */ struct fixed_value; -#define TREE_FIXED_CST_PTR(NODE) (FIXED_CST_CHECK (NODE)->fixed_cst.fixed_cst_ptr) +#define TREE_FIXED_CST_PTR(NODE) \ + (FIXED_CST_CHECK (NODE)->fixed_cst.fixed_cst_ptr) #define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE)) struct GTY(()) tree_fixed_cst { @@ -1506,7 +1507,8 @@ struct GTY(()) tree_vec { #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))) +#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 @@ -1587,7 +1589,8 @@ struct GTY(()) tree_constructor { /* The source location of this expression. Non-tree_exp nodes such as decls and constants can be shared among multiple locations, so return nothing. */ -#define EXPR_LOCATION(NODE) (EXPR_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION) +#define EXPR_LOCATION(NODE) \ + (EXPR_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION) #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK ((NODE))->exp.locus = (LOCUS) #define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION) #define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus) @@ -1882,7 +1885,7 @@ struct GTY(()) tree_exp { the very first reference to S in the function is a read operation. Default definitions are always created by an empty statement and belong to no basic block. */ -#define SSA_NAME_IS_DEFAULT_DEF(NODE) \ +#define SSA_NAME_IS_DEFAULT_DEF(NODE) \ SSA_NAME_CHECK (NODE)->base.default_def_flag /* Attributes for SSA_NAMEs for pointer-type variables. */ @@ -1975,9 +1978,12 @@ struct varray_head_tag; /* In a BLOCK node. */ #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars) -#define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars) -#define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE)) -#define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N) +#define BLOCK_NONLOCALIZED_VARS(NODE) \ + (BLOCK_CHECK (NODE)->block.nonlocalized_vars) +#define BLOCK_NUM_NONLOCALIZED_VARS(NODE) \ + VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE)) +#define BLOCK_NONLOCALIZED_VAR(NODE,N) \ + VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N) #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks) #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext) /* Note: when changing this, make sure to find the places @@ -2118,7 +2124,8 @@ extern enum machine_mode vector_type_mode (const_tree); /* For a VECTOR_TYPE node, this describes a different type which is emitted in the debugging output. We use this to describe a vector as a structure containing an array. */ -#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (VECTOR_TYPE_CHECK (NODE)->type.values) +#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) \ + (VECTOR_TYPE_CHECK (NODE)->type.values) /* For record and union types, information about this type, as a base type for itself. */ @@ -2504,18 +2511,23 @@ struct function; /* Every ..._DECL node gets a unique number that stays the same even when the decl is copied by the inliner once it is set. */ -#define DECL_PT_UID(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid == -1u ? (NODE)->decl_minimal.uid : (NODE)->decl_common.pt_uid) +#define DECL_PT_UID(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid == -1u \ + ? (NODE)->decl_minimal.uid : (NODE)->decl_common.pt_uid) /* Initialize the ..._DECL node pt-uid to the decls uid. */ -#define SET_DECL_PT_UID(NODE, UID) (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid = (UID)) +#define SET_DECL_PT_UID(NODE, UID) \ + (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid = (UID)) /* Whether the ..._DECL node pt-uid has been initialized and thus needs to be preserved when copyin the decl. */ -#define DECL_PT_UID_SET_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid != -1u) +#define DECL_PT_UID_SET_P(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.pt_uid != -1u) /* These two fields describe where in the source code the declaration was. If the declaration appears in several places (as for a C function that is declared first and then defined later), this information should refer to the definition. */ -#define DECL_SOURCE_LOCATION(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.locus) +#define DECL_SOURCE_LOCATION(NODE) \ + (DECL_MINIMAL_CHECK (NODE)->decl_minimal.locus) #define DECL_SOURCE_FILE(NODE) LOCATION_FILE (DECL_SOURCE_LOCATION (NODE)) #define DECL_SOURCE_LINE(NODE) LOCATION_LINE (DECL_SOURCE_LOCATION (NODE)) #define DECL_IS_BUILTIN(DECL) \ @@ -2529,7 +2541,8 @@ struct function; NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file scope". */ #define DECL_CONTEXT(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.context) -#define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl_minimal.context) +#define DECL_FIELD_CONTEXT(NODE) \ + (FIELD_DECL_CHECK (NODE)->decl_minimal.context) struct GTY(()) tree_decl_minimal { struct tree_common common; location_t locus; @@ -2545,7 +2558,8 @@ struct GTY(()) tree_decl_minimal { The C front-end also uses this in a nested declaration of an inline function, to point back to the definition. */ -#define DECL_ABSTRACT_ORIGIN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.abstract_origin) +#define DECL_ABSTRACT_ORIGIN(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.abstract_origin) /* Like DECL_ABSTRACT_ORIGIN, but returns NODE if there's no abstract origin. This is useful when setting the DECL_ABSTRACT_ORIGIN. */ @@ -2556,11 +2570,13 @@ struct GTY(()) tree_decl_minimal { inline instance of some original (abstract) decl from an inline function; suppress any warnings about shadowing some other variable. FUNCTION_DECL nodes can also have their abstract origin set to themselves. */ -#define DECL_FROM_INLINE(NODE) (DECL_ABSTRACT_ORIGIN (NODE) != NULL_TREE \ - && DECL_ABSTRACT_ORIGIN (NODE) != (NODE)) +#define DECL_FROM_INLINE(NODE) \ + (DECL_ABSTRACT_ORIGIN (NODE) != NULL_TREE \ + && DECL_ABSTRACT_ORIGIN (NODE) != (NODE)) /* In a DECL this is the field where attributes are stored. */ -#define DECL_ATTRIBUTES(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.attributes) +#define DECL_ATTRIBUTES(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.attributes) /* For a FUNCTION_DECL, holds the tree of BINDINGs. For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK. @@ -2585,7 +2601,8 @@ struct GTY(()) tree_decl_minimal { #define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT) /* Set if the alignment of this DECL has been set by the user, for example with an 'aligned' attribute. */ -#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->common.base.user_align) +#define DECL_USER_ALIGN(NODE) \ + (DECL_COMMON_CHECK (NODE)->common.base.user_align) /* Holds the machine mode corresponding to the declaration of a variable or field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a FIELD_DECL. */ @@ -2606,7 +2623,8 @@ struct GTY(()) tree_decl_minimal { /* Nonzero for a given ..._DECL node means that the name of this node should be ignored for symbolic debug purposes. Moreover, for a FUNCTION_DECL, the body of the function should also be ignored. */ -#define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag) +#define DECL_IGNORED_P(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag) /* Nonzero for a given ..._DECL node means that this node represents an "abstract instance" of the given declaration (e.g. in the original @@ -2614,10 +2632,12 @@ struct GTY(()) tree_decl_minimal { information, we mustn't try to generate any address information for nodes marked as "abstract instances" because we don't actually generate any code or allocate any data space for such instances. */ -#define DECL_ABSTRACT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.abstract_flag) +#define DECL_ABSTRACT(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.abstract_flag) /* Language-specific decl information. */ -#define DECL_LANG_SPECIFIC(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_specific) +#define DECL_LANG_SPECIFIC(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_specific) /* In a VAR_DECL or FUNCTION_DECL, nonzero means external reference: do not allocate storage, and refer to a definition elsewhere. Note that @@ -2635,26 +2655,38 @@ struct GTY(()) tree_decl_minimal { Also set in some languages for variables, etc., outside the normal lexical scope, such as class instance variables. */ -#define DECL_NONLOCAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.nonlocal_flag) +#define DECL_NONLOCAL(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.nonlocal_flag) /* Used in VAR_DECLs to indicate that the variable is a vtable. Used in FIELD_DECLs for vtable pointers. Used in FUNCTION_DECLs to indicate that the function is virtual. */ -#define DECL_VIRTUAL_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.virtual_flag) +#define DECL_VIRTUAL_P(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.virtual_flag) /* Used to indicate that this DECL represents a compiler-generated entity. */ -#define DECL_ARTIFICIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.artificial_flag) +#define DECL_ARTIFICIAL(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.artificial_flag) /* Additional flags for language-specific uses. */ -#define DECL_LANG_FLAG_0(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_0) -#define DECL_LANG_FLAG_1(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_1) -#define DECL_LANG_FLAG_2(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_2) -#define DECL_LANG_FLAG_3(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_3) -#define DECL_LANG_FLAG_4(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_4) -#define DECL_LANG_FLAG_5(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_5) -#define DECL_LANG_FLAG_6(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_6) -#define DECL_LANG_FLAG_7(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_7) -#define DECL_LANG_FLAG_8(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_8) +#define DECL_LANG_FLAG_0(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_0) +#define DECL_LANG_FLAG_1(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_1) +#define DECL_LANG_FLAG_2(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_2) +#define DECL_LANG_FLAG_3(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_3) +#define DECL_LANG_FLAG_4(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_4) +#define DECL_LANG_FLAG_5(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_5) +#define DECL_LANG_FLAG_6(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_6) +#define DECL_LANG_FLAG_7(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_7) +#define DECL_LANG_FLAG_8(NODE) \ + (DECL_COMMON_CHECK (NODE)->decl_common.lang_flag_8) /* Nonzero for a decl which is at file scope. */ #define DECL_FILE_SCOPE_P(EXP) \ @@ -2755,7 +2787,7 @@ extern void decl_value_expr_insert (tree, tree); (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2) #define DECL_VALUE_EXPR(NODE) \ (decl_value_expr_lookup (DECL_WRTL_CHECK (NODE))) -#define SET_DECL_VALUE_EXPR(NODE, VAL) \ +#define SET_DECL_VALUE_EXPR(NODE, VAL) \ (decl_value_expr_insert (DECL_WRTL_CHECK (NODE), VAL)) /* Holds the RTL expression for the value of a variable or function. @@ -2773,12 +2805,14 @@ extern void decl_value_expr_insert (tree, tree); #define HAS_RTL_P(NODE) (CODE_CONTAINS_STRUCT (TREE_CODE (NODE), TS_DECL_WRTL)) /* Returns nonzero if the DECL_RTL for NODE has already been set. */ -#define DECL_RTL_SET_P(NODE) (HAS_RTL_P (NODE) && DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl != NULL) +#define DECL_RTL_SET_P(NODE) \ + (HAS_RTL_P (NODE) && DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl != NULL) /* Copy the RTL from NODE1 to NODE2. If the RTL was not set for NODE1, it will not be set for NODE2; this is a lazy copy. */ #define COPY_DECL_RTL(NODE1, NODE2) \ - (DECL_WRTL_CHECK (NODE2)->decl_with_rtl.rtl = DECL_WRTL_CHECK (NODE1)->decl_with_rtl.rtl) + (DECL_WRTL_CHECK (NODE2)->decl_with_rtl.rtl \ + = DECL_WRTL_CHECK (NODE1)->decl_with_rtl.rtl) /* The DECL_RTL for NODE, if it is set, or NULL, if it is not set. */ #define DECL_RTL_IF_SET(NODE) (DECL_RTL_SET_P (NODE) ? DECL_RTL (NODE) : NULL) @@ -2800,12 +2834,14 @@ struct GTY(()) tree_decl_with_rtl { field from DECL_FIELD_OFFSET. This field may be nonzero even for fields that are not bit fields (since DECL_OFFSET_ALIGN may be larger than the natural alignment of the field's type). */ -#define DECL_FIELD_BIT_OFFSET(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.bit_offset) +#define DECL_FIELD_BIT_OFFSET(NODE) \ + (FIELD_DECL_CHECK (NODE)->field_decl.bit_offset) /* In a FIELD_DECL, this indicates whether the field was a bit-field and if so, the type that was originally specified for it. TREE_TYPE may have been modified (in finish_struct). */ -#define DECL_BIT_FIELD_TYPE(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.bit_field_type) +#define DECL_BIT_FIELD_TYPE(NODE) \ + (FIELD_DECL_CHECK (NODE)->field_decl.bit_field_type) /* For a FIELD_DECL in a QUAL_UNION_TYPE, records the expression, which if nonzero, indicates that the field occupies the type. */ @@ -2902,7 +2938,8 @@ struct GTY(()) tree_const_decl { /* For PARM_DECL, holds an RTL for the stack slot or register where the data was actually passed. */ -#define DECL_INCOMING_RTL(NODE) (PARM_DECL_CHECK (NODE)->parm_decl.incoming_rtl) +#define DECL_INCOMING_RTL(NODE) \ + (PARM_DECL_CHECK (NODE)->parm_decl.incoming_rtl) struct GTY(()) tree_parm_decl { struct tree_decl_with_rtl common; @@ -2911,25 +2948,43 @@ struct GTY(()) tree_parm_decl { }; -/* Nonzero in a decl means that the gimplifier has seen (or placed) - this variable in a BIND_EXPR. */ -#define DECL_SEEN_IN_BIND_EXPR_P(NODE) \ - (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.seen_in_bind_expr) - -/* Used to indicate that the linkage status of this DECL is not yet known, - so it should not be output now. */ -#define DECL_DEFER_OUTPUT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.defer_output) - /* Nonzero for a given ..._DECL node means that no warnings should be generated just because this node is unused. */ #define DECL_IN_SYSTEM_HEADER(NODE) \ (in_system_header_at (DECL_SOURCE_LOCATION (NODE))) +/* Used to indicate that the linkage status of this DECL is not yet known, + so it should not be output now. */ +#define DECL_DEFER_OUTPUT(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.defer_output) + +/* In a VAR_DECL that's static, + nonzero if the space is in the text section. */ +#define DECL_IN_TEXT_SECTION(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.in_text_section) + +/* In a VAR_DECL that's static, + nonzero if it belongs to the global constant pool. */ +#define DECL_IN_CONSTANT_POOL(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.in_constant_pool) + +/* Nonzero for a given ..._DECL node means that this node should be + put in .common, if possible. If a DECL_INITIAL is given, and it + is not error_mark_node, then the decl cannot be put in .common. */ +#define DECL_COMMON(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.common_flag) + +/* In a VAR_DECL, nonzero if the decl is a register variable with + an explicit asm specification. */ +#define DECL_HARD_REGISTER(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.hard_register) + /* Used to indicate that this DECL has weak linkage. */ #define DECL_WEAK(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.weak_flag) /* Used to indicate that the DECL is a dllimport. */ -#define DECL_DLLIMPORT_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag) +#define DECL_DLLIMPORT_P(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag) /* Used in a DECL to indicate that, even if it TREE_PUBLIC, it need not be put out unless it is needed in this translation unit. @@ -2940,9 +2995,15 @@ struct GTY(()) tree_parm_decl { back-end; it is up to front-ends which set this flag to ensure that there will never be any harm, other than bloat, in putting out something which is DECL_COMDAT. */ -#define DECL_COMDAT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag) +#define DECL_COMDAT(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag) + +#define DECL_COMDAT_GROUP(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group) -#define DECL_COMDAT_GROUP(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group) +/* Used in TREE_PUBLIC decls to indicate that copies of this DECL in + multiple translation units should be merged. */ +#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE) /* A replaceable function is one which may be replaced at link-time with an entirely different definition, provided that the @@ -2978,7 +3039,8 @@ struct GTY(()) tree_parm_decl { the NODE might still have a DECL_ASSEMBLER_NAME -- it just hasn't been set yet. */ #define DECL_ASSEMBLER_NAME_SET_P(NODE) \ - (HAS_DECL_ASSEMBLER_NAME_P (NODE) && DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.assembler_name != NULL_TREE) + (HAS_DECL_ASSEMBLER_NAME_P (NODE) \ + && DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.assembler_name != NULL_TREE) /* Set the DECL_ASSEMBLER_NAME for NODE to NAME. */ #define SET_DECL_ASSEMBLER_NAME(NODE, NAME) \ @@ -3001,18 +3063,37 @@ struct GTY(()) tree_parm_decl { /* Records the section name in a section attribute. Used to pass the name from decl_attributes to make_function_rtl and make_decl_rtl. */ -#define DECL_SECTION_NAME(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.section_name) +#define DECL_SECTION_NAME(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.section_name) + +/* Nonzero in a decl means that the gimplifier has seen (or placed) + this variable in a BIND_EXPR. */ +#define DECL_SEEN_IN_BIND_EXPR_P(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.seen_in_bind_expr) /* Value of the decls's visibility attribute */ -#define DECL_VISIBILITY(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility) +#define DECL_VISIBILITY(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility) /* Nonzero means that the decl had its visibility specified rather than being inferred. */ -#define DECL_VISIBILITY_SPECIFIED(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility_specified) +#define DECL_VISIBILITY_SPECIFIED(NODE) \ + (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility_specified) -/* Used in TREE_PUBLIC decls to indicate that copies of this DECL in - multiple translation units should be merged. */ -#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE) +/* In a VAR_DECL, the model to use if the data should be allocated from + thread-local storage. */ +#define DECL_TLS_MODEL(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model) + +/* In a VAR_DECL, nonzero if the data should be allocated from + thread-local storage. */ +#define DECL_THREAD_LOCAL_P(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) + +/* In a non-local VAR_DECL with static storage duration, true if the + variable has an initialization priority. If false, the variable + will be initialized at the DEFAULT_INIT_PRIORITY. */ +#define DECL_HAS_INIT_PRIORITY_P(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p) struct GTY(()) tree_decl_with_vis { struct tree_decl_with_rtl common; @@ -3026,9 +3107,8 @@ struct GTY(()) tree_decl_with_vis { unsigned thread_local : 1; unsigned common_flag : 1; unsigned in_text_section : 1; + unsigned in_constant_pool : 1; unsigned dllimport_flag : 1; - /* Used by C++. Might become a generic decl flag. */ - unsigned shadowed_for_var_p : 1; /* Don't belong to VAR_DECL exclusively. */ unsigned weak_flag : 1; @@ -3041,23 +3121,12 @@ struct GTY(()) tree_decl_with_vis { /* Belong to FUNCTION_DECL exclusively. */ unsigned init_priority_p : 1; + /* Used by C++ only. Might become a generic decl flag. */ + unsigned shadowed_for_var_p : 1; unsigned ifunc_flag : 1; - /* 14 unused bits. */ + /* 13 unused bits. */ }; -/* In a VAR_DECL that's static, - nonzero if the space is in the text section. */ -#define DECL_IN_TEXT_SECTION(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.in_text_section) - -/* Nonzero for a given ..._DECL node means that this node should be - put in .common, if possible. If a DECL_INITIAL is given, and it - is not error_mark_node, then the decl cannot be put in .common. */ -#define DECL_COMMON(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.common_flag) - -/* In a VAR_DECL, nonzero if the decl is a register variable with - an explicit asm specification. */ -#define DECL_HARD_REGISTER(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.hard_register) - extern tree decl_debug_expr_lookup (tree); extern void decl_debug_expr_insert (tree, tree); /* For VAR_DECL, this is set to either an expression that it was split @@ -3077,12 +3146,6 @@ extern priority_type decl_fini_priority_lookup (tree); extern void decl_init_priority_insert (tree, priority_type); extern void decl_fini_priority_insert (tree, priority_type); -/* In a non-local VAR_DECL with static storage duration, true if the - variable has an initialization priority. If false, the variable - will be initialized at the DEFAULT_INIT_PRIORITY. */ -#define DECL_HAS_INIT_PRIORITY_P(NODE) \ - (VAR_DECL_CHECK (NODE)->decl_with_vis.init_priority_p) - /* For a VAR_DECL or FUNCTION_DECL the initialization priority of NODE. */ #define DECL_INIT_PRIORITY(NODE) \ @@ -3113,15 +3176,6 @@ extern void decl_fini_priority_insert (tree, priority_type); #define DECL_IS_IFUNC(NODE) \ (DECL_WITH_VIS_CHECK(NODE)->decl_with_vis.ifunc_flag) -/* In a VAR_DECL, the model to use if the data should be allocated from - thread-local storage. */ -#define DECL_TLS_MODEL(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model) - -/* In a VAR_DECL, nonzero if the data should be allocated from - thread-local storage. */ -#define DECL_THREAD_LOCAL_P(NODE) \ - (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) - #define DECL_VAR_ANN_PTR(NODE) \ (TREE_CODE (NODE) == VAR_DECL ? &(NODE)->var_decl.ann \ : TREE_CODE (NODE) == PARM_DECL ? &(NODE)->parm_decl.ann \ @@ -3136,7 +3190,8 @@ struct GTY(()) tree_var_decl { /* This field is used to reference anything in decl.result and is meant only for use by the garbage collector. */ -#define DECL_RESULT_FLD(NODE) (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.result) +#define DECL_RESULT_FLD(NODE) \ + (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.result) /* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways. Before the struct containing the FUNCTION_DECL is laid out, @@ -3146,7 +3201,8 @@ struct GTY(()) tree_var_decl { to an INTEGER_CST node which is suitable for use as an index into the virtual function table. C++ also uses this field in namespaces, hence the DECL_NON_COMMON_CHECK. */ -#define DECL_VINDEX(NODE) (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.vindex) +#define DECL_VINDEX(NODE) \ + (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.vindex) struct GTY(()) tree_decl_non_common { @@ -3165,16 +3221,19 @@ struct GTY(()) #define DECL_RESULT(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.result) /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */ -#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.uninlinable) +#define DECL_UNINLINABLE(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.uninlinable) /* In a FUNCTION_DECL, the saved representation of the body of the entire function. */ -#define DECL_SAVED_TREE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.saved_tree) +#define DECL_SAVED_TREE(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->decl_non_common.saved_tree) /* Nonzero in a FUNCTION_DECL means this function should be treated as if it were a malloc, meaning it returns a pointer that is not an alias. */ -#define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag) +#define DECL_IS_MALLOC(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag) /* Nonzero in a FUNCTION_DECL means this function should be treated as C++ operator new, meaning that it returns a pointer for which we @@ -3203,7 +3262,8 @@ struct GTY(()) /* Nonzero in a FUNCTION_DECL means this function should be treated as "novops" function (function that does not read global memory, but may have arbitrary side effects). */ -#define DECL_IS_NOVOPS(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.novops_flag) +#define DECL_IS_NOVOPS(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.novops_flag) /* Used in FUNCTION_DECLs to indicate that they should be run automatically at the beginning or end of execution. */ @@ -3253,7 +3313,8 @@ struct GTY(()) /* For FUNCTION_DECL, this holds a pointer to a structure ("struct function") that describes the status of this function. */ -#define DECL_STRUCT_FUNCTION(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.f) +#define DECL_STRUCT_FUNCTION(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.f) /* In a FUNCTION_DECL, nonzero means a built in function. */ #define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN) @@ -3265,8 +3326,10 @@ struct GTY(()) /* In FUNCTION_DECL, a chain of ..._DECL nodes. VAR_DECL and PARM_DECL reserve the arguments slot for language-specific uses. */ -#define DECL_ARGUMENTS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments) -#define DECL_ARGUMENT_FLD(NODE) (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments) +#define DECL_ARGUMENTS(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments) +#define DECL_ARGUMENT_FLD(NODE) \ + (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments) /* In FUNCTION_DECL, the function specific target options to use when compiling this function. */ @@ -3326,7 +3389,8 @@ struct GTY(()) tree_function_decl { }; /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */ -#define DECL_ORIGINAL_TYPE(NODE) (TYPE_DECL_CHECK (NODE)->decl_non_common.result) +#define DECL_ORIGINAL_TYPE(NODE) \ + (TYPE_DECL_CHECK (NODE)->decl_non_common.result) /* In a TYPE_DECL nonzero means the detail info about this type is not dumped into stabs. Instead it will generate cross reference ('x') of names. @@ -3760,7 +3824,8 @@ extern GTY(()) tree global_trees[TI_MAX]; #define void_list_node global_trees[TI_VOID_LIST_NODE] #define main_identifier_node global_trees[TI_MAIN_IDENTIFIER] -#define MAIN_NAME_P(NODE) (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node) +#define MAIN_NAME_P(NODE) \ + (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node) /* Optimization options (OPTIMIZATION_NODE) to use for default and current functions. */ @@ -5130,6 +5195,7 @@ extern void internal_reference_types (void); extern unsigned int update_alignment_for_field (record_layout_info, tree, unsigned int); /* varasm.c */ +extern tree tree_output_constant_def (tree); extern void make_decl_rtl (tree); extern rtx make_decl_rtl_for_debug (tree); extern void make_decl_one_only (tree, tree); diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index 65d639d4301..2ea9adb06ea 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -1482,7 +1482,8 @@ uw_init_context_1 (struct _Unwind_Context *context, context->ra = __builtin_extract_return_addr (outer_ra); } -static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__)); +static void _Unwind_DebugHook (void *, void *) + __attribute__ ((__noinline__, __used__, __noclone__)); /* This function is called during unwinding. It is intended as a hook for a debugger to intercept exceptions. CFA is the CFA of the diff --git a/gcc/varasm.c b/gcc/varasm.c index 44fdd50b818..03b08dbcc1a 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -170,11 +170,9 @@ bool in_cold_section_p; static GTY(()) section *unnamed_sections; /* Return a nonzero value if DECL has a section attribute. */ -#ifndef IN_NAMED_SECTION #define IN_NAMED_SECTION(DECL) \ ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL) \ && DECL_SECTION_NAME (DECL) != NULL_TREE) -#endif /* Hash table of named sections. */ static GTY((param_is (section))) htab_t section_htab; @@ -1356,6 +1354,14 @@ make_decl_rtl (tree decl) return; } + /* If this variable belongs to the global constant pool, retrieve the + pre-computed RTL or recompute it in LTO mode. */ + if (TREE_CODE (decl) == VAR_DECL && DECL_IN_CONSTANT_POOL (decl)) + { + SET_DECL_RTL (decl, output_constant_def (DECL_INITIAL (decl), 1)); + return; + } + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL @@ -2200,8 +2206,6 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, if (flag_syntax_only) return; - app_disable (); - if (! dont_output_data && ! host_integerp (DECL_SIZE_UNIT (decl), 1)) { @@ -2212,6 +2216,19 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, gcc_assert (MEM_P (decl_rtl)); gcc_assert (GET_CODE (XEXP (decl_rtl, 0)) == SYMBOL_REF); symbol = XEXP (decl_rtl, 0); + + /* If this symbol belongs to the tree constant pool, output the constant + if it hasn't already been written. */ + if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) + { + tree decl = SYMBOL_REF_DECL (symbol); + if (!TREE_ASM_WRITTEN (DECL_INITIAL (decl))) + output_constant_def_contents (symbol); + return; + } + + app_disable (); + name = XSTR (symbol, 0); if (TREE_PUBLIC (decl) && DECL_NAME (decl)) notice_global_symbol (decl); @@ -2792,7 +2809,6 @@ decode_addr_const (tree exp, struct addr_const *value) { if (TREE_CODE (target) == COMPONENT_REF && host_integerp (byte_position (TREE_OPERAND (target, 1)), 0)) - { offset += int_byte_position (TREE_OPERAND (target, 1)); target = TREE_OPERAND (target, 0); @@ -2804,6 +2820,11 @@ decode_addr_const (tree exp, struct addr_const *value) * tree_low_cst (TREE_OPERAND (target, 1), 0)); target = TREE_OPERAND (target, 0); } + else if (TREE_CODE (target) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (target, 0)) == NOP_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (target, 0), 0)) + == ADDR_EXPR) + target = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (target, 0), 0), 0); else break; } @@ -2844,7 +2865,6 @@ decode_addr_const (tree exp, struct addr_const *value) static GTY((param_is (struct constant_descriptor_tree))) htab_t const_desc_htab; -static struct constant_descriptor_tree * build_constant_desc (tree); static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int); /* Constant pool accessor function. */ @@ -2896,6 +2916,18 @@ const_hash_1 (const tree exp) return (const_hash_1 (TREE_REALPART (exp)) * 5 + const_hash_1 (TREE_IMAGPART (exp))); + case VECTOR_CST: + { + tree link; + + hi = 7 + TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp)); + + for (link = TREE_VECTOR_CST_ELTS (exp); link; link = TREE_CHAIN (link)) + hi = hi * 563 + const_hash_1 (TREE_VALUE (link)); + + return hi; + } + case CONSTRUCTOR: { unsigned HOST_WIDE_INT idx; @@ -3024,6 +3056,27 @@ compare_constant (const tree t1, const tree t2) return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2)) && compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2))); + case VECTOR_CST: + { + tree link1, link2; + + if (TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)) + != TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))) + return 0; + + link2 = TREE_VECTOR_CST_ELTS (t2); + for (link1 = TREE_VECTOR_CST_ELTS (t1); + link1; + link1 = TREE_CHAIN (link1)) + { + if (!compare_constant (TREE_VALUE (link1), TREE_VALUE (link2))) + return 0; + link2 = TREE_CHAIN (link2); + } + + return 1; + } + case CONSTRUCTOR: { VEC(constructor_elt, gc) *v1, *v2; @@ -3084,11 +3137,34 @@ compare_constant (const tree t1, const tree t2) case FDESC_EXPR: { struct addr_const value1, value2; + enum rtx_code code; + int ret; decode_addr_const (t1, &value1); decode_addr_const (t2, &value2); - return (value1.offset == value2.offset - && strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0); + + if (value1.offset != value2.offset) + return 0; + + code = GET_CODE (value1.base); + if (code != GET_CODE (value2.base)) + return 0; + + switch (code) + { + case SYMBOL_REF: + ret = (strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0); + break; + + case LABEL_REF: + ret = (CODE_LABEL_NUMBER (XEXP (value1.base, 0)) + == CODE_LABEL_NUMBER (XEXP (value2.base, 0))); + break; + + default: + gcc_unreachable (); + } + return ret; } case PLUS_EXPR: @@ -3149,6 +3225,10 @@ copy_constant (tree exp) return build1 (TREE_CODE (exp), TREE_TYPE (exp), copy_constant (TREE_OPERAND (exp, 0))); + case VECTOR_CST: + return build_vector (TREE_TYPE (exp), + copy_list (TREE_VECTOR_CST_ELTS (exp))); + case CONSTRUCTOR: { tree copy = copy_node (exp); @@ -3173,31 +3253,14 @@ copy_constant (tree exp) } } -/* Return the alignment of constant EXP in bits. */ - -static unsigned int -get_constant_alignment (tree exp) -{ - unsigned int align; - - align = TYPE_ALIGN (TREE_TYPE (exp)); -#ifdef CONSTANT_ALIGNMENT - align = CONSTANT_ALIGNMENT (exp, align); -#endif - return align; -} - /* Return the section into which constant EXP should be placed. */ static section * -get_constant_section (tree exp) +get_constant_section (tree exp, unsigned int align) { - if (IN_NAMED_SECTION (exp)) - return get_named_section (exp, NULL, compute_reloc_for_constant (exp)); - else - return targetm.asm_out.select_section (exp, - compute_reloc_for_constant (exp), - get_constant_alignment (exp)); + return targetm.asm_out.select_section (exp, + compute_reloc_for_constant (exp), + align); } /* Return the size of constant EXP in bytes. */ @@ -3223,11 +3286,11 @@ get_constant_size (tree exp) static struct constant_descriptor_tree * build_constant_desc (tree exp) { - rtx symbol; - rtx rtl; + struct constant_descriptor_tree *desc; + rtx symbol, rtl; char label[256]; int labelno; - struct constant_descriptor_tree *desc; + tree decl; desc = GGC_NEW (struct constant_descriptor_tree); desc->value = copy_constant (exp); @@ -3240,17 +3303,41 @@ build_constant_desc (tree exp) labelno = const_labelno++; ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno); - /* We have a symbol name; construct the SYMBOL_REF and the MEM. */ + /* Construct the VAR_DECL associated with the constant. */ + decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (label), + TREE_TYPE (exp)); + DECL_ARTIFICIAL (decl) = 1; + DECL_IGNORED_P (decl) = 1; + TREE_READONLY (decl) = 1; + TREE_STATIC (decl) = 1; + TREE_ADDRESSABLE (decl) = 1; + /* We don't set the RTL yet as this would cause varpool to assume that the + variable is referenced. Moreover, it would just be dropped in LTO mode. + Instead we set the flag that will be recognized in make_decl_rtl. */ + DECL_IN_CONSTANT_POOL (decl) = 1; + DECL_INITIAL (decl) = desc->value; + /* ??? CONSTANT_ALIGNMENT hasn't been updated for vector types on most + architectures so use DATA_ALIGNMENT as well, except for strings. */ + if (TREE_CODE (exp) == STRING_CST) + { +#ifdef CONSTANT_ALIGNMENT + DECL_ALIGN (decl) = CONSTANT_ALIGNMENT (exp, DECL_ALIGN (decl)); +#endif + } + else + align_variable (decl, 0); + + /* Now construct the SYMBOL_REF and the MEM. */ if (use_object_blocks_p ()) { - section *sect = get_constant_section (exp); + section *sect = get_constant_section (exp, DECL_ALIGN (decl)); symbol = create_block_symbol (ggc_strdup (label), get_block_for_section (sect), -1); } else symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)); SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL; - SET_SYMBOL_REF_DECL (symbol, desc->value); + SET_SYMBOL_REF_DECL (symbol, decl); TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1; rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol); @@ -3267,7 +3354,6 @@ build_constant_desc (tree exp) ASM_OUTPUT_LABELREF will have to know how to strip this information. This call might invalidate our local variable SYMBOL; we can't use it afterward. */ - targetm.encode_section_info (exp, rtl, true); desc->rtl = rtl; @@ -3374,7 +3460,8 @@ assemble_constant_contents (tree exp, const char *label, unsigned int align) static void output_constant_def_contents (rtx symbol) { - tree exp = SYMBOL_REF_DECL (symbol); + tree decl = SYMBOL_REF_DECL (symbol); + tree exp = DECL_INITIAL (decl); unsigned int align; /* Make sure any other constants whose addresses appear in EXP @@ -3391,8 +3478,8 @@ output_constant_def_contents (rtx symbol) place_block_symbol (symbol); else { - switch_to_section (get_constant_section (exp)); - align = get_constant_alignment (exp); + align = DECL_ALIGN (decl); + switch_to_section (get_constant_section (exp, align)); if (align > BITS_PER_UNIT) ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); assemble_constant_contents (exp, XSTR (symbol, 0), align); @@ -3417,6 +3504,37 @@ lookup_constant_def (tree exp) return (desc ? desc->rtl : NULL_RTX); } + +/* Return a tree representing a reference to constant data in memory + for the constant expression EXP. + + This is the counterpart of output_constant_def at the Tree level. */ + +tree +tree_output_constant_def (tree exp) +{ + struct constant_descriptor_tree *desc, key; + void **loc; + tree decl; + + /* Look up EXP in the table of constant descriptors. If we didn't find + it, create a new one. */ + key.value = exp; + key.hash = const_hash_1 (exp); + loc = htab_find_slot_with_hash (const_desc_htab, &key, key.hash, INSERT); + + desc = (struct constant_descriptor_tree *) *loc; + if (desc == 0) + { + desc = build_constant_desc (exp); + desc->hash = key.hash; + *loc = desc; + } + + decl = SYMBOL_REF_DECL (XEXP (desc->rtl, 0)); + varpool_finalize_decl (decl); + return decl; +} /* Used in the hash tables to avoid outputting the same constant twice. Unlike 'struct constant_descriptor_tree', RTX constants @@ -3886,8 +4004,8 @@ mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED) } else if (TREE_CONSTANT_POOL_ADDRESS_P (x)) { - tree exp = SYMBOL_REF_DECL (x); - if (!TREE_ASM_WRITTEN (exp)) + tree decl = SYMBOL_REF_DECL (x); + if (!TREE_ASM_WRITTEN (DECL_INITIAL (decl))) { n_deferred_constants--; output_constant_def_contents (x); @@ -6854,8 +6972,8 @@ place_block_symbol (rtx symbol) else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) { decl = SYMBOL_REF_DECL (symbol); - alignment = get_constant_alignment (decl); - size = get_constant_size (decl); + alignment = DECL_ALIGN (decl); + size = get_constant_size (DECL_INITIAL (decl)); } else { @@ -7001,9 +7119,9 @@ output_object_block (struct object_block *block) else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol)) { decl = SYMBOL_REF_DECL (symbol); - assemble_constant_contents (decl, XSTR (symbol, 0), - get_constant_alignment (decl)); - offset += get_constant_size (decl); + assemble_constant_contents (DECL_INITIAL (decl), XSTR (symbol, 0), + DECL_ALIGN (decl)); + offset += get_constant_size (DECL_INITIAL (decl)); } else { diff --git a/gcc/varpool.c b/gcc/varpool.c index 40decfc867b..77f52c3dee6 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -105,6 +105,22 @@ eq_varpool_node (const void *p1, const void *p2) return DECL_UID (n1->decl) == DECL_UID (n2->decl); } +/* Return varpool node assigned to DECL without creating new one. */ +struct varpool_node * +varpool_get_node (tree decl) +{ + struct varpool_node key, **slot; + + gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL); + + if (!varpool_hash) + return NULL; + key.decl = decl; + slot = (struct varpool_node **) + htab_find_slot (varpool_hash, &key, INSERT); + return *slot; +} + /* Return varpool node assigned to DECL. Create new one when needed. */ struct varpool_node * varpool_node (tree decl) @@ -125,11 +141,50 @@ varpool_node (tree decl) node->decl = decl; node->order = cgraph_order++; node->next = varpool_nodes; + if (varpool_nodes) + varpool_nodes->prev = node; varpool_nodes = node; *slot = node; return node; } +/* Remove node from the varpool. */ +void +varpool_remove_node (struct varpool_node *node) +{ + void **slot; + slot = htab_find_slot (varpool_hash, node, NO_INSERT); + gcc_assert (*slot == node); + htab_clear_slot (varpool_hash, slot); + gcc_assert (!varpool_assembled_nodes_queue); + if (node->next) + node->next->prev = node->prev; + if (node->prev) + node->prev->next = node->next; + else if (node->next) + { + gcc_assert (varpool_nodes == node); + varpool_nodes = node->next; + } + if (varpool_first_unanalyzed_node == node) + varpool_first_unanalyzed_node = node->next_needed; + if (node->next_needed) + node->next_needed->prev_needed = node->prev_needed; + else if (node->prev_needed) + { + gcc_assert (varpool_last_needed_node); + varpool_last_needed_node = node->prev_needed; + } + if (node->prev_needed) + node->prev_needed->next_needed = node->next_needed; + else if (node->next_needed) + { + gcc_assert (varpool_nodes_queue == node); + varpool_nodes_queue = node->next_needed; + } + node->decl = NULL; +} + /* Dump given cgraph node. */ void dump_varpool_node (FILE *f, struct varpool_node *node) @@ -139,8 +194,12 @@ dump_varpool_node (FILE *f, struct varpool_node *node) cgraph_function_flags_ready ? cgraph_availability_names[cgraph_variable_initializer_availability (node)] : "not-ready"); + if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) + fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); if (DECL_INITIAL (node->decl)) fprintf (f, " initialized"); + if (TREE_ASM_WRITTEN (node->decl)) + fprintf (f, " (asm written)"); if (node->needed) fprintf (f, " needed"); if (node->analyzed) @@ -151,6 +210,10 @@ dump_varpool_node (FILE *f, struct varpool_node *node) fprintf (f, " output"); if (node->externally_visible) fprintf (f, " externally_visible"); + if (node->in_other_partition) + fprintf (f, " in_other_partition"); + else if (node->used_from_other_partition) + fprintf (f, " used_from_other_partition"); fprintf (f, "\n"); } @@ -192,7 +255,10 @@ static void varpool_enqueue_needed_node (struct varpool_node *node) { if (varpool_last_needed_node) - varpool_last_needed_node->next_needed = node; + { + varpool_last_needed_node->next_needed = node; + node->prev_needed = varpool_last_needed_node; + } varpool_last_needed_node = node; node->next_needed = NULL; if (!varpool_nodes_queue) @@ -230,11 +296,7 @@ varpool_reset_queue (void) bool decide_is_variable_needed (struct varpool_node *node, tree decl) { - /* We do not track variable references at all and thus have no idea if the - variable was referenced in some other partition or not. - FIXME: We really need address taken edges in callgraph and varpool to - drive WPA and decide whether other partition might reference it or not. */ - if (flag_ltrans) + if (node->used_from_other_partition) return true; /* If the user told us it is used, then it must be so. */ if ((node->externally_visible && !DECL_COMDAT (decl)) @@ -288,17 +350,6 @@ varpool_finalize_decl (tree decl) { struct varpool_node *node = varpool_node (decl); - /* FIXME: We don't really stream varpool datastructure and instead rebuild it - by varpool_finalize_decl. This is not quite correct since this way we can't - attach any info to varpool. Eventually we will want to stream varpool nodes - and the flags. - - For the moment just prevent analysis of varpool nodes to happen again, so - we will re-try to compute "address_taken" flag of varpool that breaks - in presence of clones. */ - if (in_lto_p) - node->analyzed = true; - /* The first declaration of a variable that comes through this function decides whether it is global (in C, has external linkage) or local (in C, has internal linkage). So do nothing more @@ -364,7 +415,7 @@ varpool_analyze_pending_decls (void) We however don't want to re-analyze already analyzed nodes. */ if (!analyzed) { - gcc_assert (!in_lto_p); + gcc_assert (!in_lto_p || cgraph_function_flags_ready); /* Compute the alignment early so function body expanders are already informed about increased alignment. */ align_variable (decl, 0); @@ -385,6 +436,7 @@ varpool_assemble_decl (struct varpool_node *node) if (!TREE_ASM_WRITTEN (decl) && !node->alias + && !node->in_other_partition && !DECL_EXTERNAL (decl) && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) { @@ -394,6 +446,9 @@ varpool_assemble_decl (struct varpool_node *node) struct varpool_node *alias; node->next_needed = varpool_assembled_nodes_queue; + node->prev_needed = NULL; + if (varpool_assembled_nodes_queue) + varpool_assembled_nodes_queue->prev_needed = node; varpool_assembled_nodes_queue = node; node->finalized = 1; @@ -476,7 +531,10 @@ varpool_assemble_pending_decls (void) if (varpool_assemble_decl (node)) changed = true; else - node->next_needed = NULL; + { + node->prev_needed = NULL; + node->next_needed = NULL; + } } /* varpool_nodes_queue is now empty, clear the pointer to the last element in the queue. */ @@ -498,6 +556,7 @@ varpool_empty_needed_queue (void) struct varpool_node *node = varpool_nodes_queue; varpool_nodes_queue = varpool_nodes_queue->next_needed; node->next_needed = NULL; + node->prev_needed = NULL; } /* varpool_nodes_queue is now empty, clear the pointer to the last element in the queue. */ @@ -559,6 +618,8 @@ varpool_extra_name_alias (tree alias, tree decl) alias_node->alias = 1; alias_node->extra_name = decl_node; alias_node->next = decl_node->extra_name; + if (decl_node->extra_name) + decl_node->extra_name->prev = alias_node; decl_node->extra_name = alias_node; *slot = alias_node; return true; diff --git a/include/ChangeLog b/include/ChangeLog index 5c01852a529..65cc946df6c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,8 +1,13 @@ +2010-04-26 Pedro Alves + + * filenames.h (PATH_SEPARATOR): Delete. + 2010-04-23 Pedro Alves * filenames.h (IS_DIR_SEPARATOR_1): Rename from IS_DIR_SEPARATOR, always define it independently of host, add `dos_based' parameter, and handle it. + (PATH_SEPARATOR): Define. (HAS_DRIVE_SPEC_1): Rename from HAS_DRIVE_SPEC, always define it independently of host, add `dos_based' parameter, and handle it. (IS_ABSOLUTE_PATH_1): Rename from IS_ABSOLUTE_PATH, always define @@ -98,7 +103,7 @@ * plugin-api.h: Fix compile. -2008-10-03 Rafael Espindola +2009-10-03 Rafael Espindola * plugin-api.h: New. * lto-symtab.h: New. @@ -186,7 +191,7 @@ * ansidecl.h: Add extern "C" when compiling with C++. Treat C++ the way we treat an ISO C compiler. Don't define inline as a - macdro when compiling with C++. + macro when compiling with C++. * dyn-string.h: Add header guard DYN_STRING_H. Add extern "C" when compiling with C++. * fibheap.h: Add extern "C" when compiling with C++. diff --git a/include/filenames.h b/include/filenames.h index ff4e5ac6e75..ca23d325314 100644 --- a/include/filenames.h +++ b/include/filenames.h @@ -34,12 +34,10 @@ extern "C" { # ifndef HAVE_DOS_BASED_FILE_SYSTEM # define HAVE_DOS_BASED_FILE_SYSTEM 1 # endif -# define PATH_SEPARATOR ';' # define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f) # define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c) # define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f) #else /* not DOSish */ -# define PATH_SEPARATOR ':' # define HAS_DRIVE_SPEC(f) (0) # define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c) # define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f) diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 24838d3cd10..cc77ca013bc 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,10 @@ +2010-04-25 Joseph Myers + + * include/cpplib.h (enum c_lang): Add CLK_GNUC1X and CLK_STDC1X. + * init.c (lang_defaults): Add entries for new language variants. + (cpp_init_builtins): Define __STDC_VERSION__ to 201000L for C1X + variants. + 2010-04-09 Manuel López-Ibáñez PR cpp/43195 diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 9f29e6e63ae..0828ea40f93 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -155,7 +155,8 @@ enum cpp_ttype #undef TK /* C language kind, used when calling cpp_create_reader. */ -enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99, +enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC1X, + CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC1X, CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX0X, CLK_CXX0X, CLK_ASM}; /* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ diff --git a/libcpp/init.c b/libcpp/init.c index f5bf0ea7b7d..ae5ae4548c8 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -84,9 +84,11 @@ static const struct lang_flags lang_defaults[] = { /* c99 c++ xnum xid std // digr ulit */ /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0 }, /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1 }, + /* GNUC1X */ { 1, 0, 1, 0, 0, 1, 1, 1 }, /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0 }, /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0 }, + /* STDC1X */ { 1, 0, 1, 0, 1, 1, 1, 0 }, /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0 }, /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0 }, /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1, 1 }, @@ -457,6 +459,9 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) _cpp_define_builtin (pfile, "__ASSEMBLER__ 1"); else if (CPP_OPTION (pfile, lang) == CLK_STDC94) _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L"); + else if (CPP_OPTION (pfile, lang) == CLK_STDC1X + || CPP_OPTION (pfile, lang) == CLK_GNUC1X) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 201000L"); else if (CPP_OPTION (pfile, c99)) _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L"); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 2b267e437a8..351672afbef 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,9 @@ +2010-04-26 Jakub Jelinek + + PR c/43893 + * testsuite/libgomp.c/pr43893.c: New test. + * testsuite/libgomp.c++/pr43893.C: New test. + 2010-04-21 Jakub Jelinek PR middle-end/43570 diff --git a/libgomp/testsuite/libgomp.c++/pr43893.C b/libgomp/testsuite/libgomp.c++/pr43893.C new file mode 100644 index 00000000000..be0b6f4abd4 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr43893.C @@ -0,0 +1,125 @@ +// PR c/43893 +// { dg-do run } + +extern "C" void abort (); + +template +void +f1 () +{ + int c; + T i; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = M; i < N; i++) + c++; + if (c != 1) + abort (); +} + +template +void +f2 () +{ + int c; + T i; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = M; i <= N; i++) + c++; + if (c != 1) + abort (); +} + +template +void +f3 () +{ + int c; + T i; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = M; i > N; i--) + c++; + if (c != 1) + abort (); +} + +template +void +f4 () +{ + int c; + T i; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = M; i >= N; i--) + c++; + if (c != 1) + abort (); +} + +int +main () +{ + int c; + unsigned int i; + int j; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i < 1; i++) + c++; + if (c != 1) + abort (); + f1 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i <= 0; i++) + c++; + if (c != 1) + abort (); + f2 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j < - __INT_MAX__; j++) + c++; + if (c != 1) + abort (); + f1 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j <= - __INT_MAX__ - 1; j++) + c++; + if (c != 1) + abort (); + f2 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i > 2U * __INT_MAX__; i--) + c++; + if (c != 1) + abort (); + f3 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i >= 2U * __INT_MAX__ + 1; i--) + c++; + if (c != 1) + abort (); + f4 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j > __INT_MAX__ - 1; j--) + c++; + if (c != 1) + abort (); + f3 (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j >= __INT_MAX__; j--) + c++; + if (c != 1) + abort (); + f4 (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/pr43893.c b/libgomp/testsuite/libgomp.c/pr43893.c new file mode 100644 index 00000000000..b85e9242bb3 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr43893.c @@ -0,0 +1,61 @@ +/* PR c/43893 */ +/* { dg-do run } */ + +extern void abort (void); + +int +main () +{ + int c; + unsigned int i; + int j; + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i < 1; i++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 0; i <= 0; i++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j < - __INT_MAX__; j++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = - __INT_MAX__ - 1; j <= - __INT_MAX__ - 1; j++) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i > 2U * __INT_MAX__; i--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (i = 2U * __INT_MAX__ + 1; i >= 2U * __INT_MAX__ + 1; i--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j > __INT_MAX__ - 1; j--) + c++; + if (c != 1) + abort (); + c = 0; +#pragma omp parallel for reduction(+:c) + for (j = __INT_MAX__; j >= __INT_MAX__; j--) + c++; + if (c != 1) + abort (); + return 0; +} diff --git a/libjava/classpath/ChangeLog b/libjava/classpath/ChangeLog index 71db5159ff7..1db1158ff9a 100644 --- a/libjava/classpath/ChangeLog +++ b/libjava/classpath/ChangeLog @@ -1,3 +1,18 @@ +2010-04-27 Andrew Haley + + * java/util/concurrent/CopyOnWriteArrayList.java: Fix for empty + list. + +2010-04-27 Andrew Haley + + * gnu/javax/print/ipp/IppResponse.java (parseAttributes): Handle + IppValueTag.UNKNOWN. + * gnu/javax/print/ipp/IppRequest.java (writeOperationAttributes): + Handle RequestedAttributes. + * gnu/javax/print/ipp/IppPrintService.java (processResponse): Add + DocFlavor.SERVICE_FORMATTED.PAGEABLE and + DocFlavor.SERVICE_FORMATTED.PRINTABLE. + 2010-04-02 Ralf Wildenhues * HACKING: Update required Automake version. diff --git a/libjava/classpath/gnu/javax/print/ipp/IppPrintService.java b/libjava/classpath/gnu/javax/print/ipp/IppPrintService.java index ce3ef9e1538..56a41381fb6 100644 --- a/libjava/classpath/gnu/javax/print/ipp/IppPrintService.java +++ b/libjava/classpath/gnu/javax/print/ipp/IppPrintService.java @@ -356,8 +356,17 @@ public class IppPrintService implements PrintService // should not happen, all fields are public } } + + if (this.getClass() + .isAssignableFrom(gnu.javax.print.CupsPrintService.class)) + { +// CUPS always provides filters to convert from Postscript. +// This logic looks odd, but it's what OpenJDK does. + flavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE); + flavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE); + } } - + // printer uris Set uris = getPrinterAttributeSet(PrinterUriSupported.class); printerUris = new ArrayList(uris.size()); diff --git a/libjava/classpath/gnu/javax/print/ipp/IppRequest.java b/libjava/classpath/gnu/javax/print/ipp/IppRequest.java index 3de88715a68..869f8224be9 100644 --- a/libjava/classpath/gnu/javax/print/ipp/IppRequest.java +++ b/libjava/classpath/gnu/javax/print/ipp/IppRequest.java @@ -434,6 +434,8 @@ public class IppRequest PrinterURI printerUri = (PrinterURI) attributes.get(PrinterURI.class); JobUri jobUri = (JobUri) attributes.get(JobUri.class); JobId jobId = (JobId) attributes.get(JobId.class); + RequestedAttributes reqAttrs + = (RequestedAttributes)attributes.get(RequestedAttributes.class); if (printerUri != null && jobId == null && jobUri == null) { write(printerUri); @@ -467,6 +469,12 @@ public class IppRequest logger.log(Component.IPP, "Attribute: Name: <" + jobUri.getCategory() .getName() + "> Value: <" + jobUri.toString() + ">"); } + else if (reqAttrs != null) + { + write(reqAttrs); + attributes.remove(RequestedAttributes.class); + logger.log(Component.IPP, "RequestedAttributes: <" + reqAttrs + ">"); + } else { throw new IppException("Unknown target operation attribute combination."); diff --git a/libjava/classpath/gnu/javax/print/ipp/IppResponse.java b/libjava/classpath/gnu/javax/print/ipp/IppResponse.java index 21784d0f076..81a1eb47b03 100644 --- a/libjava/classpath/gnu/javax/print/ipp/IppResponse.java +++ b/libjava/classpath/gnu/javax/print/ipp/IppResponse.java @@ -302,11 +302,14 @@ public class IppResponse // out-of-band values case IppValueTag.UNSUPPORTED: case IppValueTag.UNKNOWN: - case IppValueTag.NO_VALUE: // TODO implement out-of-band handling - // We currently throw an exception to see when it occurs - not yet :-) - throw new IppException( - "Unexpected name value for out-of-band value tag"); + // We currently throw an exception to see when it occurs - not yet :-) + throw new IppException( + "Unexpected name value for out-of-band value tag " + tag); + case IppValueTag.NO_VALUE: + attribute = null; + + break; case IppValueTag.INTEGER: int intValue = IppUtilities.convertToInt(value); attribute = IppUtilities.getIntegerAttribute(name, intValue); diff --git a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java index 6e4fb9a8ac9..02071829269 100644 --- a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java +++ b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java @@ -452,7 +452,12 @@ public class CopyOnWriteArrayList public synchronized boolean remove(Object element) { E[] snapshot = this.data; - E[] newData = (E[]) new Object[snapshot.length - 1]; + int len = snapshot.length; + + if (len == 0) + return false; + + E[] newData = (E[]) new Object[len - 1]; // search the element to remove while filling the backup array // this way we can run this method in O(n) diff --git a/libjava/classpath/lib/gnu/javax/print/ipp/IppPrintService.class b/libjava/classpath/lib/gnu/javax/print/ipp/IppPrintService.class dissimilarity index 63% index c44e1cf7f15803a7d346d926ac3fda023c8cd260..7ec693ef159c1e0b0c181039742b3a780ada1838 100644 GIT binary patch delta 7031 zcwUWJ2Ygi3(w~`ockgC%N!zpyq!L0Jq@a`pg%ARS5+b1m1}QNKNKscrY;=#P zbVLMHYS2wWC;_D?A|NUv7C;dT!b3%TPoKUycNcO${l4Gt`|(TeIWu$SoHOM=bHXR9 z@bnsN@y;K+_5wf_{h|ShAV-8)WC`5Sp(&`q4hnYCu`|Xa*zR%FUamtc6|QO>pTp;Oy29g8T_df2tyQeJ8ey~h;c9$Q z$94FUXpHEFFN?D11hFs6->Tt8gf48rR53i#k@$*^ufll*|FKgh*OXUGuI}fWVP}(V z)?qVj(QvEWaY^e0z0Z`1VrN}U~79rW-mfY)d)o{$bj?l@g+Zm{O zY>>A_Iq-l8 zYL#FssTk*C{cnjMqB^UGd^Zg!nmTEWt7=H4hDQ)O8cQB(8I13UMJ+qyyW(1Wyyzb7 zCw^=hjqkCV6!io`2PqaZz%{O-yr*k?`P7Lu8orN^$qEz2{4||U`T;^WL)ocTQTUO# z(kc@_<~w)8PuPqZ_^DVFoo73PpX>Mqo)aHOcg72R_71l5cu@w=*P?&S*misCtT?ZO=!s{V{n=nH1M*caPc{Y5%o+RPFctp3^@>UJ?N&cR;2 zf&Z4f{wB)edPe+5$3LX=Y&V^!5i~FH7hlFXEJR+*7)nA7GnP!PtejF+;~J-t>b-cZ z7?vJv)yRraaBIV*@i7*%nO2K)@qt8kHft{;oo|yS#wA3k0aAp6Kzx?qFE%ImV~|+b zx(&}-s39^jBrB+O2!C|4Mb|Sh>8zqA> zMM0Z9H5(zzxW%S6VF6k2yPa;QP8xOehF^?0mmF@f*lyNQuB{`+UkGfHwM%~5Iqy(i0<%?ZOsaPN`CdFEN>qyi`*xSZi`%-_6`iZQz z(aHcS5_h%j(yEwqtZ-n#^s%l=nf7+-OM`S8KqUzIVno|?G0WjEK5H8gH3UH~EG}-A z1f*d)4X4tbmgEGqrPCOl#?m;Ek@jqX}d-f zb(%zz#rBjk|DUK*PVPtOCr+khb8@z{-Johos}WOD^K`P%G&y5P?QKY0Ne$OYqZyJo zQ>G>p9YzA>+R2X|l=O!XdK$t((H7340G<5FEg6r|6DtsrAH-sj<}kZug;a} z7@ro;;TM|u1Y3CI$U-|Q^ps9d(>w$_dtiV|=6E%NB{{{%ULdcwP^?Hl)S{n1JOleQ zT7eKbQea|)nA>hn+!~$M0x!{r=JhY^nK!tgtna`c{W z7~Hs#w^JkS z(TJfesM!;FRaNCP*rt1FpV*dhJN`#p%y^{JJbFu~gR;!}%QDN}x@St2gj+hSQ%h>a z)s)`W=^eZsL93`XlxXy>*pV5jzK76S9wVx7GB0ygmCWFjpKizNbb?WUPD&&$)*?k% zR7s-SYn5x#lxZ#-U6P?zS!on>S5;1&Jju5@ zUJ@6xUkM5RTS?wIzeAqlcM>e%4?tPsqmJ2FyVI}JQ|R_!M+bKCVD2)APJJDY)?&8? z_=aGZcT(V+IIvG0>@G@egd?Tx8n7=y9S(Q{i`zB8afBRoBeZs^4R8vf3H#(&QeVg7 zM(ADYw0Lk(9Ta-7WEk_2(|P%yXLf)B=WqkQf`g-s!4@29e0Sh*An3-;&IJxuwaZTT zy|@o6xJFFE4{vmP~jZBk7YQTE%Ynwz;YY|R`?CZxp6G41r2S` zAIG5!Z0HY#IG$;Km;q6|{9dr*chDOvShYe5v^P|%6at|z1}CsW#QSg}A0V2KlPl-^ z4Q|9qrKxP7Ni}9fJUq-b>Or* zoW9S2Gt$_F%O!Cr6KB=oL;F(G*kc3I4?$$Q;jq;ZnBD-~7AVf6Qx2+s5dN%=*CBUXFS7m z3xCTRadv4P&gsuL9NB=6AvEBVVsUO<@Vp$=sqV)a%Ro<)L9syW&y93H(|n%xGE8wT zTYDWu;7e@hmmvi=aDm>$$9M(0ap%*A=XWu01a37OIV4F!`n@?beSzxD0V5d*u4YNRWg?Dp*JlNFTp`kUgQu1x&?FBTGlO0`3Aog4|I!*;uQw27$8Kxr6`M`*wHP`Manj82H!(gm zpZBbZamKu&g}a$Ufo4vyiQzCa!c2?^FGGTtZxoVrbCBs9q!||7gFy|jm!OH9&55xA zQrtYYfsOnjf^>+d7LZ8+kVAn`NI_6S!7zsF+C*}|EDD9W6b8>yB&;MS)KV1erdDv2 zqTxe|fv+eQu23BOhvHGA1PrIv7)ObiL2a-Lm+L$SWYQ;A7$W7F5iz)n=BNR zjjN~wZl>GNL$~8WZuO5-7d%5bc!6^9d%8nR=@H?M;<|&d65?)FAlZd^D-g+|YvZu) z`nM`M&s-%bT2@J}kKw859*Vt1ZtX3e9%{23EV%tvF$lHn!PTV-mxPj1i&{&`C0rU> zDfN^lQu4FiS*1?3jyib2?XeLL52j=8hxGSQZj#`+u42r`v zbq(|l(=2PCXDuYw(w&WPolnuT4t@*MJk-mBs)q_ULQ;;^%XiQ~)X5A;l0#gTP58kVr$=n?oU&hC@D;LIK?k18EeDrhh;MmBAz$4b!L` zX3{u#gvP@hs(=-2%2jk9tmp4Wnh2X|66~VM@FrElVXA^-R1F`{G&oDs;R4NoOEeRH zpjq$}KPrOz@B_j@b1;$SViG-xx6wQUdn%3M-t`u2b@joP9LaV{f?8J^K_j_PKf*zE zw>Z`_I%O0eQ{%2MgO4g3G6#2gFTy&oVv-#3;jMgKergFvL87~yZLB&i4e&AtIc&6#zerhI6 zF$mX9daoOL-BR&&gL$J_y2>E@=`CF>d%jdL)uyWBg9V%+68B*ks)O_d`Ekr z_jTF}ztKLlQWNU5A0y}hM$=oEOouse4&j~jHWu<93y4iy(*tE*KZnVg?VD`+}!w33DybhD-Bu1{o{f3FSC~=5qMm z%{lZ8J;5Dn8Fvh0jrTw$gplBo9ar*8;8|J`(evWpy`x6GAYnJLftE?LFaJxs zPhXhIvh!wHrj@kH2WhAH9I{6rnCq?r_gfFB(0+Q)P5p zZ~WfGtAo-cAXzy*tP+q^2Be~P5{|54RtZN|1CFf!D;!z>2OO!*aHRU+NUiO66ORlU zD}GHj`whg`H_+6na_B9QS^2!g!3NsmV>HrMPP^?gRc}2OrWdBF^E|XeY$)vHz6?73 zz|nM-;p|7qqMx`h{mc<{9eU9(3}rW982t;z(Qhz;euql>6KWKMnF_&d#R5+#8Z1z3 z@QmUIFDQ0ct>~~@352~$2pm^J;iM7)Unni%qS6YkD$#IFiG@FuIJ7D8Xjj^xBSA^R zc%>~SDk+$$q+%B(4ZAAo*q^^cnLb*{5D)i_a7zf2U^do(FygmVUs%C~N`Wkx2dmg4 zD&)YURLdc6ftjF@gf=TI@Ijju_WGbrg_AyLQ{f^!%;^!tqd&mKNn&G@IiMKoIa#b2 z4?T=Gj)s|TNaEaS;K1y{PdNG9kwMs&L)ZH{o5lxWgoW(?Pi;)~P<=h^N^77dg3Y%= zHe5cnlun>3ogq-k0jH7+iOL;D2n*3K#NXG4(tbK1w)YElzlo5}p>Rls!eOu|n>jeJ zqlb<#@bq^xexK zHmwQQ%c8)5FGI{jr)0hSV4d7RX}($!IQVM4K~wsGAAbXszTi;$L6}kmamql*PzFJF zr388?!=P9h4x^M2aGx>~rYoc1ait9AE2BXu<*-&61M8Fu!z6u*xN-rkzgh7Z;XdTY zr%d(rH!B{~ycI71p2NrKBX;zB2&dEZG22>j5kEtpNT@LWsv0yPd^|gj&PvB|t8w(N z4hoQeBv7i@LDlS_sm-qih`MzM@82$@mp-Go9Jb@u-ge1Ro@DDiW!l$%YhOFDKA{)Ibo!bhg(K`6k94*A7erK+m=H1S79xH} z-}B2RanuSE*W%+6T{eFIKv(#i!`TqR&Bs+vfG_#`Pe$la{$AtxW&ZvM^1rDP8Aklz P8h?N0c{qQsgWrDvBDTG` delta 6994 zcwT*230RfY)?RCU-x>L2I!p%znM62%AesYuRRmEK0mC7(uA-7*2n0Bm9ZegxvUX`s zIb@op<#_OfQ<+1VX<3!2ETjbjeP*nmA?zbDE8GL9sj|Cl)}`}HbCsJfdj(q*aNBK!egiVh127>oaui;P1k5BrI8mGqOT1x7#ro zr)YQ&R*POCF2#y9q9nW<=8O5^Bh^NPY!M$GA+CnUwrhZb09cAMG@OaEM2Cpv#QWf+ z1@A`)n^G~oB6C_}Rdr@wZFP0!#Kx-H8Vf#v&{3a#CCL^LfOGLd3(iC6!m>1LS!JUJ z-{E{Q+>&g&-Hs38BNlv^x0R(lijVC`ii}6~X@t&VM2C*zwJ59IhKo^X_$)prW=Hi` zmm;`y>|9hkbs0i$zJSgm%o!2CLc^8t6+*zo+M33Ss+xvjm9y-8l`m+p8Mat(jehpU ziJGW$2H-kzKE@?BIK$QT2r2rC=bZuS285oz6{ADdm*qer0clZe##ayubnMCKc-$#>2OVZ2ksOnIwS;?RZXg7#DmaH zM?PsEsP6WkH?Vlx)CraKqv|a920{-V@7o~+_lV*Sy>Oq{nh-B;#@NKR4l#IuS4&mj z@-GuQymC@iMSkU771OF4E%-J5F(xrAUE|FkM(EF)>0)V2I3CrnVvQPTA2F?> zx~g%O1>fcS=#TG-*w{>bUlhmYT94sL4L`sS#nRYb_z|D2oAnf)mOl2W2Abr-zgjf^)*FQ_FP6#6Wlkc;D@CI)@O(Z5pB8ZTrPGWpwgvv3Tp|5gh zVxZYVstgA?d@nH^&C<%;vnv*|@{B&Jy+yk=DHuz|+@!@AEJ8Y^nnN{mP?#9dsRu@g z8J%LyQ5rcp;8t{sPh3pxHR^!RA+#$f%pX)#II?`)$XiDZvQsR@S*RmIoDA)d!n(Rq z9AH(ARh11I#Z!V%lXKN1gsu$7ipk00fr;>^ojOyhg;JzD&P(lX(#S<=;$ZUBqzsL^ zP$qw6a%E##V@2b%hP>KIl?X~oYMG6?Qa1}_i;p%w!eiQ=G_(aW%D# zaV5jzGU6uJHs;vj8Zmbf<%oAW$D8|7KMVas{MsZz@B5?#`AHT;e4mZK_!!Ma9Whp@mtcKn0xk>Y9@x-1UXBa7wNsYc3cMM(M( z4gaEh<)~gpm7IJcMhjr2 zolP>lQbv3Of+;1{54+`w=8D@h4!7fE@eJ&@&=YKvu_Cu!gvjf%Ans|6o&lbsjm|A9 z%+DP;Xxz|}fdTX^_O=lFQ-Ys+HMh`yhb3>9TB2AQqVc^Qvf~n%X2PqXYY8or+bK>OI&TDu^Jk@Q}j-u}U z729$!K>z^R#j`!Lap8_5Js(521A8>Vo?=%s94*iAVlRXy?6V8|Wq9EPQ=YmJ5}m3S zP9Yq?9yuo0PVCnVgUg*J4-RO8LJ#JSVH~p&mft+H4HWniH{d25sJB}%UvIZz0TA@( zhs1}_9RMRac}0Q3t@yR~2KN*^$m#kctY(``#V@cHzsEYfiBrjj^)P^^Jqdww<1ij7 zc;vv}a0t8w2$^^m3&G2a=Wrq(io7R{&ZKMUe`H&*yp+Q{2ixE+*s z1Ol6JLb(GcHQ`HF^P+lPPORu}`j@o~Uhh-6i1LV{FC!G*e?^n?&x#D`Y-Fi-Nq^~2B^9ut4~a+(7d zdoW=cShnLc;$~h44wWUkAX=W!fzNw!Il(draB;s0S8e4PtBne44GL@h3NIQJUNR`W z(^*D zYV0*EvDdG#->C4WLE%lm!a<|LA%nspzrqot!aM9Vts3w6HIC^T5k8IM{w3I4CnR`E z2ZNgNRJrQFkDKrlV@SLOS#0FjIL=>(K$b`1HfWFAIUIJdgLohtn;;i=GcS0d4Bz0W zZ+62J+yjlc7v|$WScv=KIXnRC@lDu_Z-Ivi;}E_L$MF!H#>4O}9)T-(6n@8dkl&yf zgvZc{?_mla$1HpwbMOQf;z=CA&%?3!Ax^B>%Cw_+e zFyt&xJ;&;wGwGejOZcT|Hz3mHi%evq&lr&GylkKtQ!B-MhG#|ffVgP<%>Yv?%$ZPZ z7!d0|@4v!!e0@v2_$5cF?{2>`0IQ9_1q1M+5x8goHX4CT2H;gAaM|njA!%&k%R05` zw5G0MUfYh}d+`dva(&+G#(7r_3!X9pzZifWM&OzOXfgn9{LO$g8>jqX0QMV!>jvPU z5%|jh95DjN4ZtxYaMRs}5E>9t41mc9SPX#82T0oT_d=6fI$8csntr2uG1v?H2o6v{ zTR?1pR5$y=O|TL{BqxvYWPviW!UVEGHK*bGC;%QJ4W6YSSV_UKokCy_ zIp7$D!N(L1-%tcxp-A|PqR_&HK?Fr(9JR+xt_ylo3=W}Kyp=0~3W~#fC>du{XIwxd zQcw_6Jh^Z)rJ;w?@epO;3ChAV)D^#`Z2X?Ow z;x>Y+$}FyYqLJP>Bui;K$@&IV=W>UN42H}X1S zjEK$8&PptIs!i0%18%38EmOoDUN<;>Hzns-oMxv*M?5e;$HWgON*8nUqw=zv;TnIA zpI_I*EgtISLDfTjHbQcanR#eCWjQF9CsE!;aI}dEbdk$x;tdWFXY=FS1)$Pk2%fjRH3qMjl{6dWw;-(qspxKy2_hT}- zu{%Aeo2X9D-+f!&5ZKrMhLAn^!jeh0FBS1t6`0H3Q>;JP=Ckouuo+GKcRH-%M~xYd zgM~`?C>Hn{GRgONbMS+3Evy4G1|`cb-O7rpEV6{PAjw_E7p*!?UU-S!9A3^bJ53He z?=z#*tnS70dIZRq()q0t`%1?`n{jn{GmR;4BK~)~j$F_Yo723T?$iYr+XNN5;F4k8 zOZvKQx$q?&yxgWeNf%u8B`wxHRjwGaQ<;wb)}}sL7yQvCn4$}=w+W`|g1_1Xb-LiV z$K5Jv&?VP&mD%ixW7Ok;Yjs+b?5+N>=@8AN9IMj9#xCi!gxj(`G+W75 zy7aI+t>HG)9(%bGZZ9cU`A^vb8;0Bb6W8AS$lZ+B%AM9GdLYNEd*(+qc?0~0+D zA;d2`S`M9P9lPv{kW1^Kh+cxRw1LaJjm$JJ!wlL4bLbU#lwO5pw3%IW3%o+F!7h3o zj?z{*Mcd#EZD+>W0pHP1uHtvWb;|XinTs`zc4H)YF@~Bkh4!(#?Ztj{01LSUE9Tnk z4tg6WaJ5xONAN-JKTYrAN;<~1_xqx1NPMMqSbo~FY#s!&n}*Q^BFZk zC(hW5*lEq!4=R}0X0UVK!I8IsW-%{~TyYOp<@VJo*zJp&Rf7-Gpa2>pZXU z%_s`&QOvMUvB3!?06tIx;R_`cE-DWANeP3iN(9_cBGIZupMF;X**1O!i^e%*S_LSYyQ;vX1*(`nM z4G-;QHg~EA=s?>Jbi_AB=R=d~6SXjSFze%`v;*{(hu&_1uC+nee9(~==)7CUI;I`K zB{JV|E|CuCp`$WKzq3w$KxsR7F*x|#{lKF12OGD6N-j8*fe@|?f;goBGL=FYpbUk9 zN->lwC2*%Q0`5_6g_+7ocvu+?iD=sh~l7ccms@IIZ8#3Fye^;httSzFGGZvEYXPD-;fH5~i9`2ywB zOQ~Y>O=0s@yA5`WZnayq-*1sVq*MNn3}hXtW#?5#@$2QIG22=fwM#^q&i69Iu%5kj zJv)8OEGXAI{kQc3+7|p&%qz}NSW#d}Y|pdIIqZR-d!)71zfr34sDV<$TPgJm`cjN8 zNgDOc|4~H|eWm~Xnl6BJQ8R|}o97#jhYQ?ZWQq^t_FEqR!0jb&uX6h@mPc@V8EpRp D&~A}7 diff --git a/libjava/classpath/lib/gnu/javax/print/ipp/IppRequest$RequestWriter.class b/libjava/classpath/lib/gnu/javax/print/ipp/IppRequest$RequestWriter.class index c4e62948ad1aeb5773ba53c213b52e8675bbfb82..a7697f9415a210e041dd0f1d8f00683fefd5fb72 100644 GIT binary patch delta 868 zcwR-4YfQ~y9LK-kUv=-{t$S`$YTVawcQ74CA6du^`Avt@lzg~wf<6`gIyD~_??1IH36@ryUO zwz^U`xk}chE-BjJUgOd7Ln4GuEy6m}Kia~W3#+US+6mJZcbR@qc@Ww;$--1l)^^!4 z($e*Y`}NjSb+=h}({xv)yBWG$p}Q>I<(Zg$q0hEGD6kI!FalDel|;4%C)qC6p-s?) zi&+LOGinL?^LBgD$xG;>4{uqA zcdW-(HZXu!7^^g%jhx0NX0w^|d7TBk!3w22d6WBii-&ld$9RX8yvu5~@-o}_L}?e> z*~fcgWV;0OfjHP9PCk-}d@N~vB6;kT)k=#uu}e1cnUwLl>|nQ?6m1v&9xW(yGvy>`ZS)>2ZuqRIUl7K2FgN$J$des&I6uRybTM^l^F>b`7oO53lC? zn5jLCE!b@zMmmAon delta 692 zcwRk{OGuPa7>3{HXsOd=PBvPW<7MpPrA+OjX%~{9EQtte++|1?A-53-5=2qa!v0N{ zMT-^_M3hNQYNZlQ=~R}rD3V%5K~Z5hyLWz-_~3jGA7}A?&pCtZj;{6e|LMFbsf6Wi zo+-Y#MADpQUuFCZFB$D!zH~g3be}n1<}%NDJ#}$qfmhRY#3LwjX^%?_T-xr^LYKC< zRO-?imlnBnIguspwW<3iB^}fRO_WTdGZ2V5;jE2paK2@2GWzb+WVf=@8Oja?lDibG zOT`}{y}O|BD%0C+Mx#`FMpfb*&Z%y>qGv?(f@^w1heqhcPX{x(PChp&rke_SsG*l# zwl{H$W^S{eD2KR1D|b0fALr?})JM$LOYZT5m=O<*hleJGM<#?s|&+ASCm=WtA>+GDX`R|h6wY+IzBoL{hx*+6o=J3I<5Ub zt&LFPoCt1BE(>d1=3*<;`5nw?d8-88$;*2M_@D)R)Jn^%8P<9}Da2>h^F>X3)n2~o z03$lacb(#g&hk^2_@xehE6N`Y@K-}ddS%eCG5TrZNHp>I%me}^!M?;hN=?$Jr~7Hr7zXg?|32-ior?9)t=+U;WHLp4gfzuIWSF$wnvTvUQd>txvNXXWJ6W=D zS>j{<2MOgM6JHl}IEaJ!IQSYai-ZJahDa|ibuj-py-$95p1ir1T+7YhZmS1n;?I}d z4wc#ri`2m`TTvmca7zp|5=TJV5SDgCC4mlOJ0*!e>A-+&$DpJzES)$ZT{tCaG>afb{7gZb8khXgotjA!L<2vSPwVpO>w>r0`OxU3(Z@!g7~SK1Wn{|88zXQ3_wH9u zN8TI#VDu9_@)s`%>0j; z|26YD_^1$~ppis^7WB}HgDk@cZP1*DaoTZ*4m@Q!ra2$8bfUxs%E5)IQsz{EuKXEa zQ4I%RV=Y`3A958o)YcRyM=EXXUGK?`saDnS_i5qa8 z4Yxe3p>1ykIHcZ}jAV<<3=8MdLwxUw*z%9&Jd?oi$!Q_9C(s-C;mYNl0$ bJu1px)ya(N<~}vZel^1VYLxvtSbOLnYW#h} delta 559 zcwQaLO-R#m9LMp`@B7&_7dyI+nqq*yc8H&QHMf|9<0&BO^Qg?^OsKF4==v&Tr3y6`ps>3p+r3SqT6A* z8(@&qQkQ8!~#&zk% zec6mBx}V7wtH-;~?6e+x8_aI2%-3i?2)i7z+IU2Nk@JpG;4;u zD5VeO48X%6!VICBRjB0x)N>)4xd>@4#xA}6jNkxkkmV8#vlb^=hfyxad9J`kuEaIg zW1OpSk5Npr5l`8IX|Bc$V<<3=k8H&(na?)k=33*Au)~DdWvaQ+)G=kE>@i8E XO^UrH&8=pT8Ixt78D_?cRPFr-g_MB2 diff --git a/libjava/classpath/lib/gnu/javax/print/ipp/IppResponse$ResponseReader.class b/libjava/classpath/lib/gnu/javax/print/ipp/IppResponse$ResponseReader.class index 2d0d8045d7e2f5e016627ab35470ce059e002c5d..89113302b6839d6ffe8c910a80d8a57f67983e1c 100644 GIT binary patch delta 1234 zcwRk|drX&A7{|Zg=bZEE4@i)U$*lyHh3Npfm@!wyJzz}7cvX^qO za;Y+1`KK}ykQ!xH7jwIq*ToUaZOV~=S)(ifY_W2ba*1*@kZfC2o&;R-e#A`OkG!ej zNB5y1DtIp@?!}~i$gJluTWhb@H6`_RQ4OHEZtj?N9)KW1FG#}bfEoCNKb_r~!Dyy4 zo>}a}$Jm#{IDpyO8LpjNj%Gf`a3m+NfU|Tpn@_Ql&u}rvaT&*RoqqX{6Ish5?&hEV8xWW4PnT_P< zHj!W0LELDwxycr=))sNIE#?+m&aL(pZnG=6-LB^jyMbTYt=wt%aJT)2U)x6Ru`S$Z zFY#O3#_#M6?zipy-Z>s{5&XeD#Cn&^1~-t6em8`NT^^6PaXjj#@tB*-<8Bd8I6s?Q z6`S2!o^~JbjH~5Y_Z82%2A+4P*y676qHE=4_Xn@If0X~S)f4{Y_2kc9Z~o%Nvdv57 zH7{2=g29N?=?g<_#~kZ4cg&?4{q;Nu-fwQfR-Fy;MzVp2VBowwHmX^~d5`cgJbebq zFg(Je>LWaKS)ps^F=aQ5bGLXLo6z0d(S0X)5=DO-cW4E4g~AV3Fj#d4B-H+W?hGH0wQ=??Ex;v44&ax^xzFl<~i+!ia`#~tA$Ar zhO$Mir%b^oywH&)l~~D(Y7yq1p1;J)2xO#8i~bAUcvE9R! z<30GqcRw*&LXaq-7${*#k#G!_2xLkW@}w6ES~#0)+1E*bJo`N7?0lc!e!t&y)|Xyi z`spAa1L1gIpl-UaEWuX^hgiT1h8u~22T&D?HIQr0LZ1Lj%f6u{;yA5tz;P6hn7LCrM4`43^x{C-XK z$U0nib@&h$+Xk9ebIo+{8wg@FD-l)UxRi;ZO!ilH^D!RdJhpQ_J9Xj~pWt0C zkiJ|f2`rKkTr6oUkvuMu!Vs6rlPr~IxJ)X!TwZ0Fyv-G|hb!d(%cY5{A83%{}%F*4k~{XLs;3yN{pS2JW{DiCq}M+sNeKbxi@`Y@;vXAzC63Cq5)g zBvK>_0qKLFL?cW3Ay;CMFMiCGSQJTrtds#*Epb>QgRn^wP%VS;nqIjYNy0Ws4#%Z8 z4olP2bWIIvYNn=+($vwKIu6+~7UN_*@?=7o!LBinqo*uDZ&?Vx6d^$tVW=!dsub(V f66DAd%#c!j_A)GyGOUsncv{L)A*;e^83q3VXWCgYy*j;>o&Y{kD o0m!mpyaVPh1oEGOS@(dfk6@NGry3K}UobO*Q=O50as#Ih0GdE5ZU6uP diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$1.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$1.class index 2dba6818fd6a03953ff6ec07e3f7265bef82587f..a8f5b0acb70ed7c46066f234568cad84935dab23 100644 GIT binary patch delta 107 zcwXxg>Jr+pn3eY`11HOM1}>Hx3{osNCvRZ&WPCFD7poKFhsm~VnY{lP_*nikh_Ny- zD6le4-prQ7%g?~hD!{Jr+pn3eYe11HNR1}>J%3{ostCU0Q%WV}E57poKF>&doknY=$4_*i~1h_U=; zP+<8pc{5uQFBbzlD>nl_D-VMtEAM0_c27o$$vHq$dGa=PM@FN`KY(nn$tyVYCl_*< JF~$K|NdTVC9x(s_ diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$2.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$2.class index 03ab92a5ec1c40913c7650053f31eb9c9de6a35f..2ac9719071063f4612865ce253ed391511283cfb 100644 GIT binary patch delta 40 wcwRfkb&P9+3Jd2K22Q4L41!GGC+o7fGya}j%Hq$&%rN;Fiz6fJWDZt400NZ@Y5)KL delta 40 wcwRfkb&P9+3Jd3Z22Q4r41!FbChM}eGk%*~%Hq$&^n3C#7Dq;g$sDY901G<|O8@`> diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$3.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$3.class index 1f2e00af9baf1856c0ec34abd2c29e2248bc2353..c20c1fecf979a6c6306ed089d581fc5d6f392aae 100644 GIT binary patch delta 99 zcwRd!a9Ci2C@ZHf11GaSgCMiPWI0w(Mw7`e+4Uz+XEmA3$Hp`HI;%OO!(@K8curRa zc4jvQerAu!<{9 delta 99 zcwRd!a9Ci2C@ZH111GZdA)F2j z?97e~{LIdi%h~K0Jtl8si|6zOiunP>0w&9`+cAbtj%9b89K+5tc@>bC2s9@O0Fvz( AGXMYp diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$RandomAccessSubList.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$RandomAccessSubList.class index 83fd284ec57228fa27faa131df244e7903382687..df5d0783cd3f6e7adf05ec0c6d0de11297640179 100644 GIT binary patch delta 17 YcwXDdv6ExNK4#V$26ook$%mQC05*9A%>V!Z delta 17 YcwXDdv6ExNK4#W(26onp$%mQC05&rP!vFvP diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$SubList.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList$SubList.class index 572a880ad34c81e7cc08c820a41382ddc35509ef..1265019707288804f991f99b39a122bedd389b33 100644 GIT binary patch delta 360 zcwP<6yGw#m9LDiS&I9p!e_zp3FltDO6fKE@D1yXtj=)KbE<}@?WE73j;Bp4(LeUgO zLo~cpYxl;Y%haUx2V_B8zv;m9{rpZfR*jw3jo>w?Zegf9nCc!O^?;~))PKf?@d~ec zljU7+IxA)!Zq<xkzpoRF)e{F8#8{pesCy&RCsgl>3j zGb1%CbwX-RYDS-U52FQHi?YthI*WGBqlXJfvw&eP>XPpwS{AV^q9S5N#Hxrj5$hOa zS!ew>oi!0#BDO{BppCoe=AMXsjPd~Etm(LUWZ0t45umL<%q7Q_&RKKD6Ub*6e9^X* F{|AC*Obq}4 delta 360 zcwP<5&nv@m9LMpOKJPW3eYfxS`T7y7iGwvZHaSpYek^g8+9FMyoV5J*56EGMef)^r zMGi)-IFKJZk{@@!;%Xe#!u#~D*YojC`_ulzcUf@`5*Lu-5=va5Qe49)^7==v$a|RL zftN?U>R3|GaEcdhuL$vth&R1&gmugqR-ar7T)wyzxO{V&H$@S4@e4!z!4gFscAmD_ zU?)4=R0=OSP)|-o$c1(?(aE=)JQyH_A+iuB8YpddWdgj#AwkRtpU z&>yaxigNAY+RHV@HL4HHU0;IN5ne}m9YYNz(Lm#9r35-?LQlI-d?^+)EM{5Eu~=ZS z$YL37l+yj4d|igc8jE!n8>pg91Za!JHo9mBeU#B5wI{Qzj!{Ng{iLQ!&h(%)DQ`e@ L3rTl6XT|>kZ6r>4 diff --git a/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList.class b/libjava/classpath/lib/java/util/concurrent/CopyOnWriteArrayList.class index 0e7bd0f5aee8e5df8ffeefad416d36fad3471e43..97d63d83b3f3b3325a29099aca211ed91d6361b8 100644 GIT binary patch delta 2179 zcwSvqYjjlA75?_Q_s;W9GLB5h!_^Nto8kaf;w!F||o$1uUW zs__Sn#j878+ls3?IvVf4SI3h$Adfm{(yP+rs#kxn<8|5QDpHRV;_|$1q?NjG3~%Yk zz}ti=lDr8??nSnDb)3L^vfe!>a*ANDZf|P7uOjTgN4!XcYg->^u5h6Xr*-@iXXF8Q zsd{c4aheNf@rjA}Cql7>xJ;iN{5$?($EV{Q+Zx+f7T0!mw6?F*@lTwWd-eSE&j?Dm zGVH=5$g<<#@>6}bdlVN;s4odqO(=VHb!>?pU&*^XWy(cdkUgHoB;?ngOs7gVJ86V0 zdDN3NM<+Wb5`0a~Esd+&I_o-GJDb0=Vpa1Uoi0+zsgsM`1jib4zq-AXphg+leCN^e z4W$wM@<-aWa+X(>8`382+M8CCwzd>D*a5T~yOCX!7_Q8H0-Dm7t2XU}QlW}6O)0bW zA{I~hZKZ=)wh=DBtxW4h&~FQh ztx0Vf#7ZNezKCqKk0UC`1=eCACIEB@8jZj~uR*87NTVajpkoNoafIkC7<2+t=p;($ zU6j*%n9cjQ(kU#U4^c}WV>zA19c)|Z4BF@%f($=zEG>i(1}tw2DnZcDip{td0uHpG zyc;u^Nd|7iPkB>C0E_Vy?`g=vR5Y+>LmnU3`REv2gl!(S%1gNmX`7rMtf~4OP8x-q zzJQl5FzGLmLtioROPD5rNlKu%kgZ(JWl}zREsRARqdi7nXmjBZx5$selgpmN z0+xtN!_ViD$+n)q=XBsU%vKqWC-Iw98CfKjM=X&u@^19-MNS=kL9WXitZIcWRv}-s zAujGhv1mt$xEnW!dsv)%nd%zcD(=G)@c`5PA?_9r;(oS25f4F%A7i6fCm)Q&X_wp{ z$)(+LByt12C@)8%)01^qItf1345EuOSPz%j0I&Fk)d(3DYhS7nd>EA9os{h##4IMA zhdtPvqB|tJCOuxY8FsM+ZqdyOZ-q~6L#F6Kmgr^L+fgBQU=I5=f;AG)qgL$Xn(ji2 z*o}Kc5^KbuY{|dgQdmWa6|X11m<5fkJT;DEKZT|It+fAP4X-LhRc8wb%x1*KGQE6XJ6wDW#5??fnDk4iJQa`xxO&x zn$r;C46{DRjL$IJPvpMBiS&j%QCJ>5YGKahXy)Z}4&m5RV*qbnE#WA4Y{4|*@qRK@ z$v;>}XR~J>wHZnh?_70GnJ9lgd9sK96jG<&mj@?Ln)|^3WOfpd`#wzKW3w#mC-KAp zHtiq6*`-GI0RDIdE5j5~i9uHkM3guZY^N$k(ukIL{*1q*u>UIWj0T;5V{G5Q7*}>h zbJu>p-*^f3jYu29DC6b~;EVntTpV*RU5ODihncd8yJIu*l`V|ljp@o(+@x&7x0R=@ zVutx!@bnrl=3;!!(~B(cKkSMBn`4W|=2#_feuK*p=AKze8mr>38Op3;Jf0-Qy6rRL zIZ1LTmA&xB&5hjBBmJ@gcs@4UUwjSx4#02e81lbzeV{%h$qC1_u9MHv~yXApc z)MW*-aX^xv#padpoYS6xQ`?Sfv>nLMo<*2#RO_=cGAt6YR7NpMm)|oM`CjR>1WgrE g>zBukTX-g9#(P4?F!nq9KRe1VLfFHD=xh-_wHt&SvG89$Yyu5Nj95(7y`;8NFWs`=@2aPGQ=WjlVVyX2-S-1 zI4M)7(+X&vf2J*wl7K+4q#6qDhNcA23I$QHfW=BgvG!rBR8flcLC@ak#=Jn2L)`Uqp9^=g#vQy$wKN~y2emRNp= zK`ZvF{k8(j0YXKzNv(C~skd$A^m~wvTn3z#pB+$0@?~iaZHr zbu6%)b>cK$R?Uu^!{-Rr`u3LAH8r6eyef-CXnx!GT5Ifh7_T|;3%srlJI2u);w$MG zZ^s3^nQ`}5Rqb3A_$S`B;$H;Mx0=7(T(zRPeR*7IU4`61vZ(3q!W@lqoMa=rYIcuyXykO_6LJxJYORr{ zrh9btb9bq(t!QoE)9j2MiKzaLd)RK7A7mtvBJ*^<_z)o*4A$EqY5omdBD$p-AtQ zAR3D0ISZozIt+u3pufV8kF2X_Y3e5LVNSENJ4-llw7*8LemOjP|`VC~A5GYf9ReVT+t8z?1?y<1S{sbe<7#IxAra36>!%jO z#zD9^gj_DgXf8uBM-bu)+`yHX#xcwm{Z<}}My^H^kH^>f2CU!-Sk04EQz-5jjuw){ zd()ZX&&CS;bVyMacRx-n87E6J14O~^rd_X z%lIXg8!7NTYgVlgU&dh^k*ZV)+&`!(k@DihIQsb-je>WE3{tn$QJ3?_)cuiyIZw|O zXvxo!HF$zWcP5U&s`bcSn!#?TVeQuxy~R+?As zuBdRyHy~^EXZ2=9>C9KsP(>;H%sZ6A`Ai=~PoXo7%?Ac>p)ppJ#$QH!nMr76aBAfU zYY`+wj@6>7AzJPF8~&d4{SUP+8t8aSe0%>be*Gg(i-cYNOq^|S3}8cJ8t)y59fEZu z+yl5I@%(9g&^Lf9!|H!WVh1vO)iw%EI#H%QDseYqlC~Msv@U!_>o%t&Bxiwz!_(1X zsvpU{N2d0%X#9l>aN%cz!uSNA%JZt|(q!4nl=GM3N=6Xzc#7D(Bc{gvDY9y{J@CXc zFN(*d$f4F(`U`&y-FOgoV;yphhcMcB7y*$n^g zQ~6@EtG9~rW3U<9Fv{4Dd}9YfBBMh8Ohz#iL}hl~E6J@MiY@Ry(`zEnHrUvu-jB_q bJ~bu2BX|PCzYCwqOOjOrV{k=e688TA_`=TQ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e72219227f9..3c4b8db4b62 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,39 @@ +2010-04-27 Jonathan Wakely + + PR libstdc++/43865 + * include/c_global/cstdlib (abort, exit): _GLIBCXX_NORETURN typo. + +2010-04-27 Jonathan Wakely + + * doc/xml/manual/status_cxx200x.xml: Update quick_exit status. + * doc/html/*: Regenerate. + +2010-04-27 Fabien Chêne + + * testsuite/util/testsuite_error.h: Add empty default constructor + to __gnu_test::test_category and + __gnu_test::test_derived_category. + * src/future.cc: Add empty default constructor to + future_error_category. + * src/system_error.cc: Add default ctor to generic_error_category + and system_error_category. + +2010-04-27 Alexander Monakov + + * testsuite/22_locale/codecvt/unshift/char/1.c (test01): Clarify size + definition. Use memcpy and memcmp to avoid access beyond allocated + memory. + +2010-04-27 Jonathan Wakely + + * doc/xml/manual/status_cxx200x.xml: Update to match n3092. + * doc/html/*: Regenerate. + +2010-04-25 Jonathan Wakely + + * doc/xml/manual/status_cxx200x.xml: Update Threads status. + * doc/html/manual/status.html: Regenerate. + 2010-04-24 Jonathan Wakely * include/bits/unique_ptr (unique_ptr::pointer): Use deleter's diff --git a/libstdc++-v3/doc/html/api.html b/libstdc++-v3/doc/html/api.html index 5a40764298d..b96eb6eeffa 100644 --- a/libstdc++-v3/doc/html/api.html +++ b/libstdc++-v3/doc/html/api.html @@ -7,7 +7,7 @@ FSF -


diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html index 046cbb3bc83..15798d68840 100644 --- a/libstdc++-v3/doc/html/faq.html +++ b/libstdc++-v3/doc/html/faq.html @@ -4,7 +4,7 @@ 2008 FSF -



Bibliography

+

Bibliography

+ .

+ .

+ .

+ .

+ .

+ . Ulrich Drepper.

+ .

+ . Benjamin Kosnik.

+ . Benjamin Kosnik.

Chapter 11.  Algorithms - +

Table of Contents

Mutating
swap

The neatest accomplishment of the algorithms sect1 is that all the work is done via iterators, not containers directly. This means two diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html index a8b88b7d5a9..6a3b094b5b5 100644 --- a/libstdc++-v3/doc/html/manual/api.html +++ b/libstdc++-v3/doc/html/manual/api.html @@ -75,11 +75,11 @@ _Alloc_traits have been removed. __alloc to select an underlying allocator that satisfied memory allocation requests. The selection of this underlying allocator was not user-configurable. -

Table B.1. Extension Allocators

Allocator (3.4)Header (3.4)Allocator (3.[0-3])Header (3.[0-3])
__gnu_cxx::new_allocator<T>ext/new_allocator.hstd::__new_allocmemory
__gnu_cxx::malloc_allocator<T>ext/malloc_allocator.hstd::__malloc_alloc_template<int>memory
__gnu_cxx::debug_allocator<T>ext/debug_allocator.hstd::debug_alloc<T>memory
__gnu_cxx::__pool_alloc<T>ext/pool_allocator.hstd::__default_alloc_template<bool,int>memory
__gnu_cxx::__mt_alloc<T>ext/mt_allocator.h
__gnu_cxx::bitmap_allocator<T>ext/bitmap_allocator.h

Releases after gcc-3.4 have continued to add to the collection +

Table B.1. Extension Allocators

Allocator (3.4)Header (3.4)Allocator (3.[0-3])Header (3.[0-3])
__gnu_cxx::new_allocator<T>ext/new_allocator.hstd::__new_allocmemory
__gnu_cxx::malloc_allocator<T>ext/malloc_allocator.hstd::__malloc_alloc_template<int>memory
__gnu_cxx::debug_allocator<T>ext/debug_allocator.hstd::debug_alloc<T>memory
__gnu_cxx::__pool_alloc<T>ext/pool_allocator.hstd::__default_alloc_template<bool,int>memory
__gnu_cxx::__mt_alloc<T>ext/mt_allocator.h
__gnu_cxx::bitmap_allocator<T>ext/bitmap_allocator.h

Releases after gcc-3.4 have continued to add to the collection of available allocators. All of these new allocators are standard-style. The following table includes details, along with the first released version of GCC that included the extension allocator. -

Table B.2. Extension Allocators Continued

AllocatorIncludeVersion
__gnu_cxx::array_allocator<T>ext/array_allocator.h4.0.0
__gnu_cxx::throw_allocator<T>ext/throw_allocator.h4.2.0

+

Table B.2. Extension Allocators Continued

AllocatorIncludeVersion
__gnu_cxx::array_allocator<T>ext/array_allocator.h4.0.0
__gnu_cxx::throw_allocator<T>ext/throw_allocator.h4.2.0

Debug mode first appears.

Precompiled header support PCH support. diff --git a/libstdc++-v3/doc/html/manual/appendix_contributing.html b/libstdc++-v3/doc/html/manual/appendix_contributing.html index 467f7fd0988..fc792adc087 100644 --- a/libstdc++-v3/doc/html/manual/appendix_contributing.html +++ b/libstdc++-v3/doc/html/manual/appendix_contributing.html @@ -7,7 +7,7 @@ Appendices  Next


Appendix A.  Contributing - +

The GNU C++ Library follows an open development model. Active contributors are assigned maintainer-ship responsibility, and given diff --git a/libstdc++-v3/doc/html/manual/appendix_free.html b/libstdc++-v3/doc/html/manual/appendix_free.html index bc6c37655ea..827ff6288cc 100644 --- a/libstdc++-v3/doc/html/manual/appendix_free.html +++ b/libstdc++-v3/doc/html/manual/appendix_free.html @@ -7,7 +7,7 @@ Appendices  Next


Appendix C.  Free Software Needs Free Documentation - +

The biggest deficiency in free operating systems is not in the software--it is the lack of good free manuals that we can include in diff --git a/libstdc++-v3/doc/html/manual/appendix_gpl.html b/libstdc++-v3/doc/html/manual/appendix_gpl.html index 42a68eca06d..012c9086be4 100644 --- a/libstdc++-v3/doc/html/manual/appendix_gpl.html +++ b/libstdc++-v3/doc/html/manual/appendix_gpl.html @@ -78,7 +78,7 @@

The precise terms and conditions for copying, distribution and modification follow. -

+

TERMS AND CONDITIONS

0. Definitions. @@ -619,7 +619,7 @@ waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. -

+

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs diff --git a/libstdc++-v3/doc/html/manual/appendix_porting.html b/libstdc++-v3/doc/html/manual/appendix_porting.html index 47d342a193f..46ee854f2c1 100644 --- a/libstdc++-v3/doc/html/manual/appendix_porting.html +++ b/libstdc++-v3/doc/html/manual/appendix_porting.html @@ -7,7 +7,7 @@ Appendices  Next

Appendix B.  Porting and Maintenance - +

Configure and Build Hacking

Prerequisites

As noted previously, certain other tools are necessary for hacking on files that diff --git a/libstdc++-v3/doc/html/manual/atomics.html b/libstdc++-v3/doc/html/manual/atomics.html index 1db9a81fbe1..a01126003fa 100644 --- a/libstdc++-v3/doc/html/manual/atomics.html +++ b/libstdc++-v3/doc/html/manual/atomics.html @@ -7,7 +7,7 @@ Standard Contents  Next


Chapter 14.  Atomics - +

Table of Contents

API Reference

Facilities for atomic operations.

API Reference

diff --git a/libstdc++-v3/doc/html/manual/backwards.html b/libstdc++-v3/doc/html/manual/backwards.html index 8656c934d1f..dc8e7d1cdc8 100644 --- a/libstdc++-v3/doc/html/manual/backwards.html +++ b/libstdc++-v3/doc/html/manual/backwards.html @@ -17,8 +17,8 @@ ISO Standard (e.g., statistical analysis). While there are a lot of really useful things that are used by a lot of people, the Standards Committee couldn't include everything, and so a lot of those obvious classes didn't get included. -

Known Issues include many of the limitations of its immediate ancestor.

Portability notes and known implementation limitations are as follows.

No ios_base

At least some older implementations don't have std::ios_base, so you should use std::ios::badbit, std::ios::failbit and std::ios::eofbit and std::ios::goodbit. -

No cout in ostream.h, no cin in istream.h

+

Known Issues include many of the limitations of its immediate ancestor.

Portability notes and known implementation limitations are as follows.

No ios_base

At least some older implementations don't have std::ios_base, so you should use std::ios::badbit, std::ios::failbit and std::ios::eofbit and std::ios::goodbit. +

No cout in ostream.h, no cin in istream.h

In earlier versions of the standard, fstream.h, ostream.h @@ -44,7 +44,7 @@ considered replaced and rewritten. archived. The code is considered replaced and rewritten.

Portability notes and known implementation limitations are as follows. -

Namespace std:: not supported

+

Namespace std:: not supported

Some care is required to support C++ compiler and or library implementation that do not have the standard library in namespace std. @@ -108,7 +108,7 @@ AC_DEFUN([AC_CXX_NAMESPACE_STD], [ AC_DEFINE(HAVE_NAMESPACE_STD,,[Define if g++ supports namespace std. ]) fi ]) -

Illegal iterator usage

+

Illegal iterator usage

The following illustrate implementation-allowed illegal iterator use, and then correct use.

  • @@ -121,7 +121,7 @@ AC_DEFUN([AC_CXX_NAMESPACE_STD], [

  • if (iterator) won't work any more => use if (iterator != iterator_type()) -

isspace from cctype is a macro +

isspace from cctype is a macro

Glibc 2.0.x and 2.1.x define ctype.h functionality as macros (isspace, isalpha etc.). @@ -154,7 +154,7 @@ std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) _ISspace ) ; (ctype.h) and the definitions in namespace std:: (<cctype>). -

No vector::at, deque::at, string::at

+

No vector::at, deque::at, string::at

One solution is to add an autoconf-test for this:

 AC_MSG_CHECKING(for container::at)
@@ -180,7 +180,7 @@ AC_DEFINE(HAVE_CONTAINER_AT)],
 

If you are using other (non-GNU) compilers it might be a good idea to check for string::at separately. -

No std::char_traits<char>::eof

+

No std::char_traits<char>::eof

Use some kind of autoconf test, plus this:

 #ifdef HAVE_CHAR_TRAITS
@@ -188,7 +188,7 @@ AC_DEFINE(HAVE_CONTAINER_AT)],
 #else
 #define CPP_EOF EOF
 #endif
-

No string::clear

+

No string::clear

There are two functions for deleting the contents of a string: clear and erase (the latter returns the string). @@ -206,12 +206,12 @@ erase(size_type __pos = 0, size_type __n = npos) Unfortunately, clear is not implemented in this version, so you should use erase (which is probably faster than operator=(charT*)). -

+

Removal of ostream::form and istream::scan extensions

These are no longer supported. Please use stringstreams instead. -

No basic_stringbuf, basic_stringstream

+

No basic_stringbuf, basic_stringstream

Although the ISO standard i/ostringstream-classes are provided, (sstream), for compatibility with older implementations the pre-ISO @@ -299,14 +299,14 @@ any = temp; Another example of using stringstreams is in this howto.

There is additional information in the libstdc++-v2 info files, in particular info iostream. -

Little or no wide character support

+

Little or no wide character support

Classes wstring and char_traits<wchar_t> are not supported. -

No templatized iostreams

+

No templatized iostreams

Classes wfilebuf and wstringstream are not supported. -

Thread safety issues

+

Thread safety issues

Earlier GCC releases had a somewhat different approach to threading configuration and proper compilation. Before GCC 3.0, configuration of the threading model was dictated by compiler @@ -364,7 +364,7 @@ libstdc++-v3. of the SGI STL (version 3.3), with extensive changes.

A more formal description of the V3 goals can be found in the official design document. -

Portability notes and known implementation limitations are as follows.

Pre-ISO headers moved to backwards or removed

The pre-ISO C++ headers +

Portability notes and known implementation limitations are as follows.

Pre-ISO headers moved to backwards or removed

The pre-ISO C++ headers (iostream.h, defalloc.h etc.) are available, unlike previous libstdc++ versions, but inclusion generates a warning that you are using deprecated headers. @@ -436,7 +436,7 @@ like vector.h can be replaced with using namespace std; can be put at the global scope. This should be enough to get this code compiling, assuming the other usage is correct. -

Extension headers hash_map, hash_set moved to ext or backwards

At this time most of the features of the SGI STL extension have been +

Extension headers hash_map, hash_set moved to ext or backwards

At this time most of the features of the SGI STL extension have been replaced by standardized libraries. In particular, the unordered_map and unordered_set containers of TR1 are suitable replacement for the non-standard hash_map and hash_set @@ -508,7 +508,7 @@ AC_DEFUN([AC_HEADER_EXT_HASH_SET], [ AC_DEFINE(HAVE_EXT_HASH_SET,,[Define if ext/hash_set is present. ]) fi ]) -

No ios::nocreate/ios::noreplace. +

No ios::nocreate/ios::noreplace.

The existence of ios::nocreate being used for input-streams has been confirmed, most probably because the author thought it would be more correct to specify nocreate explicitly. So @@ -519,7 +519,7 @@ open the file for reading, check if it has been opened, and then decide whether you want to create/replace or not. To my knowledge, even older implementations support app, ate and trunc (except for app ?). -

+

No stream::attach(int fd)

Phil Edwards writes: It was considered and rejected for the ISO @@ -542,7 +542,7 @@ No stream::attach(int fd) For another example of this, refer to fdstream example by Nicolai Josuttis. -

+

Support for C++98 dialect.

Check for complete library coverage of the C++1998/2003 standard.

@@ -610,7 +610,7 @@ AC_DEFUN([AC_HEADER_STDCXX_98], [
     AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ])
   fi
 ])
-

+

Support for C++TR1 dialect.

Check for library coverage of the TR1 standard.

@@ -687,7 +687,7 @@ AC_DEFUN([AC_HEADER_TR1_UNORDERED_SET], [
     AC_DEFINE(HAVE_TR1_UNORDERED_SET,,[Define if tr1/unordered_set is present. ])
   fi
 ])
-

+

Support for C++0x dialect.

Check for baseline language coverage in the compiler for the C++0xstandard.

@@ -899,25 +899,25 @@ AC_DEFUN([AC_HEADER_UNORDERED_SET], [
     AC_DEFINE(HAVE_UNORDERED_SET,,[Define if unordered_set is present. ])
   fi
 ])
-

+

Container::iterator_type is not necessarily Container::value_type*

This is a change in behavior from the previous version. Now, most iterator_type typedefs in container classes are POD objects, not value_type pointers. -

Bibliography

+

Bibliography

Migrating to GCC 4.1 - . Dan Kegel.

+ . Dan Kegel.

+ . Martin Michlmayr.

Consider a block of size 64 ints. In memory, it would look like this: (assume a 32-bit system where, size_t is a 32-bit entity). -

Table 20.1. Bitmap Allocator Memory Map

268042949672954294967295Data -> Space for 64 ints

+

Table 20.1. Bitmap Allocator Memory Map

268042949672954294967295Data -> Space for 64 ints

The first Column(268) represents the size of the Block in bytes as seen by the Bitmap Allocator. Internally, a global free list is used to keep track of the free blocks used and given back by the diff --git a/libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html b/libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html index ae2b3b830ae..5ea9732886e 100644 --- a/libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html +++ b/libstdc++-v3/doc/html/manual/bk01pt03ch17s03.html @@ -19,6 +19,6 @@ mode or with debug mode. The following table provides the names and headers of the debugging containers: -

Table 17.1. Debugging Containers

ContainerHeaderDebug containerDebug header
std::bitsetbitset__gnu_debug::bitset<debug/bitset>
std::dequedeque__gnu_debug::deque<debug/deque>
std::listlist__gnu_debug::list<debug/list>
std::mapmap__gnu_debug::map<debug/map>
std::multimapmap__gnu_debug::multimap<debug/map>
std::multisetset__gnu_debug::multiset<debug/set>
std::setset__gnu_debug::set<debug/set>
std::stringstring__gnu_debug::string<debug/string>
std::wstringstring__gnu_debug::wstring<debug/string>
std::basic_stringstring__gnu_debug::basic_string<debug/string>
std::vectorvector__gnu_debug::vector<debug/vector>

In addition, when compiling in C++0x mode, these additional +

Table 17.1. Debugging Containers

ContainerHeaderDebug containerDebug header
std::bitsetbitset__gnu_debug::bitset<debug/bitset>
std::dequedeque__gnu_debug::deque<debug/deque>
std::listlist__gnu_debug::list<debug/list>
std::mapmap__gnu_debug::map<debug/map>
std::multimapmap__gnu_debug::multimap<debug/map>
std::multisetset__gnu_debug::multiset<debug/set>
std::setset__gnu_debug::set<debug/set>
std::stringstring__gnu_debug::string<debug/string>
std::wstringstring__gnu_debug::wstring<debug/string>
std::basic_stringstring__gnu_debug::basic_string<debug/string>
std::vectorvector__gnu_debug::vector<debug/vector>

In addition, when compiling in C++0x mode, these additional containers have additional debug capability. -

Table 17.2. Debugging Containers C++0x

ContainerHeaderDebug containerDebug header
std::unordered_mapunordered_map__gnu_debug::unordered_map<debug/unordered_map>
std::unordered_multimapunordered_map__gnu_debug::unordered_multimap<debug/unordered_map>
std::unordered_setunordered_set__gnu_debug::unordered_set<debug/unordered_set>
std::unordered_multisetunordered_set__gnu_debug::unordered_multiset<debug/unordered_set>

+

Table 17.2. Debugging Containers C++0x

ContainerHeaderDebug containerDebug header
std::unordered_mapunordered_map__gnu_debug::unordered_map<debug/unordered_map>
std::unordered_multimapunordered_map__gnu_debug::unordered_multimap<debug/unordered_map>
std::unordered_setunordered_set__gnu_debug::unordered_set<debug/unordered_set>
std::unordered_multisetunordered_set__gnu_debug::unordered_multiset<debug/unordered_set>

diff --git a/libstdc++-v3/doc/html/manual/bk01pt03ch18s03.html b/libstdc++-v3/doc/html/manual/bk01pt03ch18s03.html index 778d35acbcd..76645a52876 100644 --- a/libstdc++-v3/doc/html/manual/bk01pt03ch18s03.html +++ b/libstdc++-v3/doc/html/manual/bk01pt03ch18s03.html @@ -63,4 +63,4 @@ Then compile this code with the prerequisite compiler flags flags for atomic operations.)

The following table provides the names and headers of all the parallel algorithms that can be used in a similar manner: -

Table 18.1. Parallel Algorithms

AlgorithmHeaderParallel algorithmParallel header
std::accumulatenumeric__gnu_parallel::accumulateparallel/numeric
std::adjacent_differencenumeric__gnu_parallel::adjacent_differenceparallel/numeric
std::inner_productnumeric__gnu_parallel::inner_productparallel/numeric
std::partial_sumnumeric__gnu_parallel::partial_sumparallel/numeric
std::adjacent_findalgorithm__gnu_parallel::adjacent_findparallel/algorithm
std::countalgorithm__gnu_parallel::countparallel/algorithm
std::count_ifalgorithm__gnu_parallel::count_ifparallel/algorithm
std::equalalgorithm__gnu_parallel::equalparallel/algorithm
std::findalgorithm__gnu_parallel::findparallel/algorithm
std::find_ifalgorithm__gnu_parallel::find_ifparallel/algorithm
std::find_first_ofalgorithm__gnu_parallel::find_first_ofparallel/algorithm
std::for_eachalgorithm__gnu_parallel::for_eachparallel/algorithm
std::generatealgorithm__gnu_parallel::generateparallel/algorithm
std::generate_nalgorithm__gnu_parallel::generate_nparallel/algorithm
std::lexicographical_comparealgorithm__gnu_parallel::lexicographical_compareparallel/algorithm
std::mismatchalgorithm__gnu_parallel::mismatchparallel/algorithm
std::searchalgorithm__gnu_parallel::searchparallel/algorithm
std::search_nalgorithm__gnu_parallel::search_nparallel/algorithm
std::transformalgorithm__gnu_parallel::transformparallel/algorithm
std::replacealgorithm__gnu_parallel::replaceparallel/algorithm
std::replace_ifalgorithm__gnu_parallel::replace_ifparallel/algorithm
std::max_elementalgorithm__gnu_parallel::max_elementparallel/algorithm
std::mergealgorithm__gnu_parallel::mergeparallel/algorithm
std::min_elementalgorithm__gnu_parallel::min_elementparallel/algorithm
std::nth_elementalgorithm__gnu_parallel::nth_elementparallel/algorithm
std::partial_sortalgorithm__gnu_parallel::partial_sortparallel/algorithm
std::partitionalgorithm__gnu_parallel::partitionparallel/algorithm
std::random_shufflealgorithm__gnu_parallel::random_shuffleparallel/algorithm
std::set_unionalgorithm__gnu_parallel::set_unionparallel/algorithm
std::set_intersectionalgorithm__gnu_parallel::set_intersectionparallel/algorithm
std::set_symmetric_differencealgorithm__gnu_parallel::set_symmetric_differenceparallel/algorithm
std::set_differencealgorithm__gnu_parallel::set_differenceparallel/algorithm
std::sortalgorithm__gnu_parallel::sortparallel/algorithm
std::stable_sortalgorithm__gnu_parallel::stable_sortparallel/algorithm
std::unique_copyalgorithm__gnu_parallel::unique_copyparallel/algorithm

+

Table 18.1. Parallel Algorithms

AlgorithmHeaderParallel algorithmParallel header
std::accumulatenumeric__gnu_parallel::accumulateparallel/numeric
std::adjacent_differencenumeric__gnu_parallel::adjacent_differenceparallel/numeric
std::inner_productnumeric__gnu_parallel::inner_productparallel/numeric
std::partial_sumnumeric__gnu_parallel::partial_sumparallel/numeric
std::adjacent_findalgorithm__gnu_parallel::adjacent_findparallel/algorithm
std::countalgorithm__gnu_parallel::countparallel/algorithm
std::count_ifalgorithm__gnu_parallel::count_ifparallel/algorithm
std::equalalgorithm__gnu_parallel::equalparallel/algorithm
std::findalgorithm__gnu_parallel::findparallel/algorithm
std::find_ifalgorithm__gnu_parallel::find_ifparallel/algorithm
std::find_first_ofalgorithm__gnu_parallel::find_first_ofparallel/algorithm
std::for_eachalgorithm__gnu_parallel::for_eachparallel/algorithm
std::generatealgorithm__gnu_parallel::generateparallel/algorithm
std::generate_nalgorithm__gnu_parallel::generate_nparallel/algorithm
std::lexicographical_comparealgorithm__gnu_parallel::lexicographical_compareparallel/algorithm
std::mismatchalgorithm__gnu_parallel::mismatchparallel/algorithm
std::searchalgorithm__gnu_parallel::searchparallel/algorithm
std::search_nalgorithm__gnu_parallel::search_nparallel/algorithm
std::transformalgorithm__gnu_parallel::transformparallel/algorithm
std::replacealgorithm__gnu_parallel::replaceparallel/algorithm
std::replace_ifalgorithm__gnu_parallel::replace_ifparallel/algorithm
std::max_elementalgorithm__gnu_parallel::max_elementparallel/algorithm
std::mergealgorithm__gnu_parallel::mergeparallel/algorithm
std::min_elementalgorithm__gnu_parallel::min_elementparallel/algorithm
std::nth_elementalgorithm__gnu_parallel::nth_elementparallel/algorithm
std::partial_sortalgorithm__gnu_parallel::partial_sortparallel/algorithm
std::partitionalgorithm__gnu_parallel::partitionparallel/algorithm
std::random_shufflealgorithm__gnu_parallel::random_shuffleparallel/algorithm
std::set_unionalgorithm__gnu_parallel::set_unionparallel/algorithm
std::set_intersectionalgorithm__gnu_parallel::set_intersectionparallel/algorithm
std::set_symmetric_differencealgorithm__gnu_parallel::set_symmetric_differenceparallel/algorithm
std::set_differencealgorithm__gnu_parallel::set_differenceparallel/algorithm
std::sortalgorithm__gnu_parallel::sortparallel/algorithm
std::stable_sortalgorithm__gnu_parallel::stable_sortparallel/algorithm
std::unique_copyalgorithm__gnu_parallel::unique_copyparallel/algorithm

diff --git a/libstdc++-v3/doc/html/manual/bk01pt03ch19s02.html b/libstdc++-v3/doc/html/manual/bk01pt03ch19s02.html index 575a89dc0c2..1dc6efe132b 100644 --- a/libstdc++-v3/doc/html/manual/bk01pt03ch19s02.html +++ b/libstdc++-v3/doc/html/manual/bk01pt03ch19s02.html @@ -1,7 +1,7 @@ Design

Design

-

Table 19.1. Profile Code Location

Code LocationUse
libstdc++-v3/include/std/*Preprocessor code to redirect to profile extension headers.
libstdc++-v3/include/profile/*Profile extension public headers (map, vector, ...).
libstdc++-v3/include/profile/impl/*Profile extension internals. Implementation files are +

Table 19.1. Profile Code Location

Code LocationUse
libstdc++-v3/include/std/*Preprocessor code to redirect to profile extension headers.
libstdc++-v3/include/profile/*Profile extension public headers (map, vector, ...).
libstdc++-v3/include/profile/impl/*Profile extension internals. Implementation files are only included from impl/profiler.h, which is the only file included from the public headers.

Wrapper Model

diff --git a/libstdc++-v3/doc/html/manual/bk01pt03ch19s07.html b/libstdc++-v3/doc/html/manual/bk01pt03ch19s07.html index e5d00f5a9d9..ec719afd244 100644 --- a/libstdc++-v3/doc/html/manual/bk01pt03ch19s07.html +++ b/libstdc++-v3/doc/html/manual/bk01pt03ch19s07.html @@ -18,7 +18,7 @@ A high accuracy means that the diagnostic is unlikely to be wrong. These grades are not perfect. They are just meant to guide users with specific needs or time budgets. -

Table 19.2. Profile Diagnostics

GroupFlagBenefitCostFreq.Implemented 
+

Table 19.2. Profile Diagnostics

Here we will make an attempt at describing the non-Standard extensions to the library. Some of these are from SGI's STL, some of these are GNU's, and some just seemed to appear on the doorstep. diff --git a/libstdc++-v3/doc/html/manual/concurrency.html b/libstdc++-v3/doc/html/manual/concurrency.html index 86de72e9c04..0265da4c443 100644 --- a/libstdc++-v3/doc/html/manual/concurrency.html +++ b/libstdc++-v3/doc/html/manual/concurrency.html @@ -7,7 +7,7 @@ Standard Contents

 Next

Chapter 15.  Concurrency - +

Table of Contents

API Reference

Facilities for concurrent operation, and control thereof.

API Reference

diff --git a/libstdc++-v3/doc/html/manual/containers.html b/libstdc++-v3/doc/html/manual/containers.html index 4aceb1bbedc..c427178f494 100644 --- a/libstdc++-v3/doc/html/manual/containers.html +++ b/libstdc++-v3/doc/html/manual/containers.html @@ -7,7 +7,7 @@ Standard Contents

 Next

Chapter 9.  Containers - +

Sequences

list

list::size() is O(n)

Yes it is, and that's okay. This is a decision that we preserved when we imported SGI's STL implementation. The following is diff --git a/libstdc++-v3/doc/html/manual/diagnostics.html b/libstdc++-v3/doc/html/manual/diagnostics.html index d04585fbcd9..0cdf35293d0 100644 --- a/libstdc++-v3/doc/html/manual/diagnostics.html +++ b/libstdc++-v3/doc/html/manual/diagnostics.html @@ -7,7 +7,7 @@ Standard Contents  Next


Chapter 5.  Diagnostics - +

Exceptions

API Reference

All exception objects are defined in one of the standard header files: exception, diff --git a/libstdc++-v3/doc/html/manual/documentation_style.html b/libstdc++-v3/doc/html/manual/documentation_style.html index e32947a2626..8292e253165 100644 --- a/libstdc++-v3/doc/html/manual/documentation_style.html +++ b/libstdc++-v3/doc/html/manual/documentation_style.html @@ -4,7 +4,7 @@ Contributing  Next


Documentation Style

Doxygen

Prerequisites

- Prerequisite tools are Bash 2.x or higher, + Prerequisite tools are Bash 2.0 or later, Doxygen, and the GNU coreutils. (GNU versions of find, xargs, and possibly @@ -108,7 +108,7 @@ writing Doxygen comments. Single and double quotes, and separators in filenames are two common trouble spots. When in doubt, consult the following table. -

Table A.1. HTML to Doxygen Markup Comparison

HTMLDoxygen
\\\
"\"
'\'
<i>@a word
<b>@b word
<code>@c word
<em>@a word
<em><em>two words or more</em>

Docbook

Prerequisites

+

Table A.1. HTML to Doxygen Markup Comparison

HTMLDoxygen
\\\
"\"
'\'
<i>@a word
<b>@b word
<code>@c word
<em>@a word
<em><em>two words or more</em>

Docbook

Prerequisites

Editing the DocBook sources requires an XML editor. Many exist: some notable options include emacs, Kate, @@ -238,11 +238,11 @@ xmllint --noout --valid xml/index.xml online. An incomplete reference for HTML to Docbook conversion is detailed in the table below. -

Table A.2. HTML to Docbook XML Markup Comparison

HTMLDocbook
<p><para>
<pre><computeroutput>, <programlisting>, +

Table A.2. HTML to Docbook XML Markup Comparison

HTMLDocbook
<p><para>
<pre><computeroutput>, <programlisting>, <literallayout>
<ul><itemizedlist>
<ol><orderedlist>
<il><listitem>
<dl><variablelist>
<dt><term>
<dd><listitem>
<a href=""><ulink url="">
<code><literal>, <programlisting>
<strong><emphasis>
<em><emphasis>
"<quote>

And examples of detailed markup for which there are no real HTML equivalents are listed in the table below. -

Table A.3. Docbook XML Element Use

ElementUse
<structname><structname>char_traits</structname>
<classname><classname>string</classname>
<function> +

Table A.3. Docbook XML Element Use

ElementUse
<structname><structname>char_traits</structname>
<classname><classname>string</classname>
<function>

<function>clear()</function>

<function>fs.clear()</function>

<type><type>long long</type>
<varname><varname>fs</varname>
<literal> diff --git a/libstdc++-v3/doc/html/manual/extensions.html b/libstdc++-v3/doc/html/manual/extensions.html index 1046b4ba442..e1967c062d7 100644 --- a/libstdc++-v3/doc/html/manual/extensions.html +++ b/libstdc++-v3/doc/html/manual/extensions.html @@ -5,5 +5,5 @@
Prev The GNU C++ Library Next

diff --git a/libstdc++-v3/doc/html/manual/facets.html b/libstdc++-v3/doc/html/manual/facets.html index 3a8542aff28..c51a54f5478 100644 --- a/libstdc++-v3/doc/html/manual/facets.html +++ b/libstdc++-v3/doc/html/manual/facets.html @@ -3,7 +3,7 @@ Facets

Facets

ctype

Implementation

Specializations

+

 Next

Facets

ctype

Implementation

Specializations

For the required specialization codecvt<wchar_t, char, mbstate_t> , conversions are made between the internal character set (always UCS4 on GNU/Linux) and whatever the currently selected locale for the @@ -50,26 +50,26 @@ characters.

  • Rename abstract base class. See if just smash-overriding is a better approach. Clarify, add sanity to naming. -

  • Bibliography

    +

    Bibliography

    The GNU C Library - . Roland McGrath. Ulrich Drepper. Copyright © 2007 FSF. Chapters 6 Character Set Handling and 7 Locales and Internationalization.

    + . Roland McGrath. Ulrich Drepper. Copyright © 2007 FSF. Chapters 6 Character Set Handling and 7 Locales and Internationalization.

    Correspondence - . Ulrich Drepper. Copyright © 2002 .

    + . Ulrich Drepper. Copyright © 2002 .

    ISO/IEC 14882:1998 Programming languages - C++ - . Copyright © 1998 ISO.

    + . Copyright © 1998 ISO.

    ISO/IEC 9899:1999 Programming languages - C - . Copyright © 1999 ISO.

    + . Copyright © 1999 ISO.

    The Open Group Base Specifications, Issue 6 (IEEE Std. 1003.1-2004) . Copyright © 1999 - The Open Group/The Institute of Electrical and Electronics Engineers, Inc..

    + The Open Group/The Institute of Electrical and Electronics Engineers, Inc..

    The C++ Programming Language, Special Edition . Bjarne Stroustrup. Copyright © 2000 Addison Wesley, Inc.. Appendix D. Addison Wesley - .

    + .

    Standard C++ IOStreams and Locales . Advanced Programmer's Guide and Reference @@ -412,17 +412,17 @@ codecvt usage.

  • wchar_t/char internal buffers and conversions between internal/external buffers? -

  • Bibliography

    +

    Bibliography

    The GNU C Library . Roland McGrath. Ulrich Drepper. Copyright © 2007 FSF. Chapters 6 Character Set Handling and 7 Locales and Internationalization - .

    + .

    Correspondence - . Ulrich Drepper. Copyright © 2002 .

    + . Ulrich Drepper. Copyright © 2002 .

    ISO/IEC 14882:1998 Programming languages - C++ - . Copyright © 1998 ISO.

    + . Copyright © 1998 ISO.

    ISO/IEC 9899:1999 Programming languages - C - . Copyright © 1999 ISO.

    + . Copyright © 1999 ISO.

    + .

    The C++ Programming Language, Special Edition . Bjarne Stroustrup. Copyright © 2000 Addison Wesley, Inc.. Appendix D. Addison Wesley - .

    + .

    Standard C++ IOStreams and Locales . Advanced Programmer's Guide and Reference . Angelika Langer. Klaus Kreft. Copyright © 2000 Addison Wesley Longman, Inc.. Addison Wesley Longman - .

    + .

    A brief description of Normative Addendum 1 - . Clive Feather. Extended Character Sets.

    + . Clive Feather. Extended Character Sets.

    The Unicode HOWTO - . Bruno Haible.

    + . Bruno Haible.

    Bibliography

    +

    Bibliography

    The GNU C Library . Roland McGrath. Ulrich Drepper. Copyright © 2007 FSF. Chapters 6 Character Set Handling, and 7 Locales and Internationalization - .

    + .

    Correspondence - . Ulrich Drepper. Copyright © 2002 .

    + . Ulrich Drepper. Copyright © 2002 .

    ISO/IEC 14882:1998 Programming languages - C++ - . Copyright © 1998 ISO.

    + . Copyright © 1998 ISO.

    ISO/IEC 9899:1999 Programming languages - C - . Copyright © 1999 ISO.

    + . Copyright © 1999 ISO.

    + .

    The C++ Programming Language, Special Edition . Bjarne Stroustrup. Copyright © 2000 Addison Wesley, Inc.. Appendix D. Addison Wesley - .

    + .

    Standard C++ IOStreams and Locales . Advanced Programmer's Guide and Reference . Angelika Langer. Klaus Kreft. Copyright © 2000 Addison Wesley Longman, Inc.. Addison Wesley Longman - .

    + .

    API Specifications, Java Platform @@ -736,7 +736,7 @@ void test01() . java.util.Properties, java.text.MessageFormat, java.util.Locale, java.util.ResourceBundle - .

    + .

    Prev The GNU C++ Library Next

    diff --git a/libstdc++-v3/doc/html/manual/io.html b/libstdc++-v3/doc/html/manual/io.html index 65f598db241..ab1d88338a4 100644 --- a/libstdc++-v3/doc/html/manual/io.html +++ b/libstdc++-v3/doc/html/manual/io.html @@ -7,7 +7,7 @@ Standard Contents  Next

    Chapter 13.  Input and Output - +

    Iostream Objects

    To minimize the time you have to wait on the compiler, it's good to only include the headers you really need. Many people simply include <iostream> when they don't need to -- and that can penalize diff --git a/libstdc++-v3/doc/html/manual/iterators.html b/libstdc++-v3/doc/html/manual/iterators.html index 6e29f5fcc94..ab4848eb0b5 100644 --- a/libstdc++-v3/doc/html/manual/iterators.html +++ b/libstdc++-v3/doc/html/manual/iterators.html @@ -7,7 +7,7 @@ Standard Contents  Next


    Chapter 10.  Iterators - +

    Predefined

    Iterators vs. Pointers

    The following FAQ entry points out that diff --git a/libstdc++-v3/doc/html/manual/localization.html b/libstdc++-v3/doc/html/manual/localization.html index a1f30163645..fdae02ae1c2 100644 --- a/libstdc++-v3/doc/html/manual/localization.html +++ b/libstdc++-v3/doc/html/manual/localization.html @@ -7,7 +7,7 @@ Standard Contents  Next


    Chapter 8.  Localization - +

    Locales

    locale

    Describes the basic locale object, including nested classes id, facet, and the reference-counted implementation object, @@ -403,18 +403,18 @@ global locale" (emphasis Paolo), that is: What should non-required facet instantiations do? If the generic implementation is provided, then how to end-users provide specializations? -

    Bibliography

    +

    Bibliography

    The GNU C Library . Roland McGrath. Ulrich Drepper. Copyright © 2007 FSF. Chapters 6 Character Set Handling and 7 Locales and Internationalization - .

    + .

    Correspondence - . Ulrich Drepper. Copyright © 2002 .

    + . Ulrich Drepper. Copyright © 2002 .

    ISO/IEC 14882:1998 Programming languages - C++ - . Copyright © 1998 ISO.

    + . Copyright © 1998 ISO.

    ISO/IEC 9899:1999 Programming languages - C - . Copyright © 1999 ISO.

    + . Copyright © 1999 ISO.

    + .

    The C++ Programming Language, Special Edition . Bjarne Stroustrup. Copyright © 2000 Addison Wesley, Inc.. Appendix D. Addison Wesley - .

    + .

    Standard C++ IOStreams and Locales . Advanced Programmer's Guide and Reference diff --git a/libstdc++-v3/doc/html/manual/memory.html b/libstdc++-v3/doc/html/manual/memory.html index 82ef8c7125f..bbc0e941272 100644 --- a/libstdc++-v3/doc/html/manual/memory.html +++ b/libstdc++-v3/doc/html/manual/memory.html @@ -93,7 +93,7 @@ or loading and unloading shared objects in memory. As such, using caching allocators on systems that do not support abi::__cxa_atexit is not recommended. -

    Implementation

    Interface Design

    +

    Implementation

    Interface Design

    The only allocator interface that is supported is the standard C++ interface. As such, all STL containers have been adjusted, and all external allocators have @@ -106,7 +106,7 @@

    The base class that allocator is derived from may not be user-configurable. -

    Selecting Default Allocation Policy

    +

    Selecting Default Allocation Policy

    It's difficult to pick an allocation strategy that will provide maximum utility, without excessively penalizing some behavior. In fact, it's difficult just deciding which typical actions to measure @@ -143,7 +143,7 @@ The current default choice for allocator is __gnu_cxx::new_allocator. -

    Disabling Memory Caching

    +

    Disabling Memory Caching

    In use, allocator may allocate and deallocate using implementation-specified strategies and heuristics. Because of this, every call to an allocator object's @@ -308,11 +308,11 @@ A high-performance allocator that uses a bit-map to keep track of the used and unused memory locations. It has its own documentation, found here. -

    Bibliography

    +

    Bibliography

    ISO/IEC 14882:1998 Programming languages - C++ . isoc++_1998 - 20.4 Memory.

    + 20.4 Memory.

    + .

    + . Emery Berger.

    Reconsidering Custom Memory Allocation - . Emery Berger. Ben Zorn. Kathryn McKinley. Copyright © 2002 OOPSLA.

    + . Emery Berger. Ben Zorn. Kathryn McKinley. Copyright © 2002 OOPSLA.

    Allocator Types @@ -340,9 +340,9 @@ . Klaus Kreft. Angelika Langer. C/C++ Users Journal - .

    The C++ Programming Language. Bjarne Stroustrup. Copyright © 2000 . 19.4 Allocators. + .

    The C++ Programming Language. Bjarne Stroustrup. Copyright © 2000 . 19.4 Allocators. Addison Wesley - .

    Yalloc: A Recycling C++ Allocator. Felix Yen.

    auto_ptr

    Limitations

    Explaining all of the fun and delicious things that can + .

    Yalloc: A Recycling C++ Allocator. Felix Yen.

    auto_ptr

    Limitations

    Explaining all of the fun and delicious things that can happen with misuse of the auto_ptr class template (called AP here) would take some time. Suffice it to say that the use of AP @@ -458,7 +458,7 @@ drops to zero. Derived classes override those functions to destroy resources in a context where the correct dynamic type is known. This is an application of the technique known as type erasure. -

    Implementation

    Class Hierarchy

    +

    Implementation

    Class Hierarchy

    A shared_ptr<T> contains a pointer of type T* and an object of type __shared_count. The shared_count contains a @@ -500,7 +500,7 @@ be forwarded to Tp's constructor. Unlike the other _Sp_counted_* classes, this one is parameterized on the type of object, not the type of pointer; this is purely a convenience that simplifies the implementation slightly. -

    Thread Safety

    +

    Thread Safety

    The interface of tr1::shared_ptr was extended for C++0x with support for rvalue-references and the other features from N2351. As with other libstdc++ headers shared by TR1 and C++0x, @@ -558,7 +558,7 @@ compiler, standard library, platform etc. For the version of shared_ptr in libstdc++ the compiler and library are fixed, which makes things much simpler: we have an atomic CAS or we don't, see Lock Policy below for details. -

    Selecting Lock Policy

    +

    Selecting Lock Policy

    There is a single _Sp_counted_base class, which is a template parameterized on the enum @@ -599,7 +599,7 @@ used when libstdc++ is built without --enable-threadsext/atomicity.h, which detect if the program is multi-threaded. If only one thread of execution exists in the program then less expensive non-atomic operations are used. -

    Dual C++0x and TR1 Implementation

    +

    Dual C++0x and TR1 Implementation

    The classes derived from _Sp_counted_base (see Class Hierarchy below) and __shared_count are implemented separately for C++0x and TR1, in bits/boost_sp_shared_count.h and @@ -610,7 +610,7 @@ The TR1 implementation is considered relatively stable, so is unlikely to change unless bug fixes require it. If the code that is common to both C++0x and TR1 modes needs to diverge further then it might be necessary to duplicate additional classes and only make changes to the C++0x versions. -

    Related functions and classes
    dynamic_pointer_cast, static_pointer_cast, +

    Related functions and classes
    dynamic_pointer_cast, static_pointer_cast, const_pointer_cast

    As noted in N2351, these functions can be implemented non-intrusively using the alias constructor. However the aliasing constructor is only available @@ -643,10 +643,10 @@ is called. Users should not try to use this. As well as the extra constructors, this implementation also needs some members of _Sp_counted_deleter to be protected where they could otherwise be private. -

    Use

    Examples

    +

    Use

    Examples

    Examples of use can be found in the testsuite, under testsuite/tr1/2_general_utilities/shared_ptr. -

    Unresolved Issues

    +

    Unresolved Issues

    The resolution to C++ Standard Library issue 674, "shared_ptr interface changes for consistency with N1856" will need to be implemented after it is accepted into the working @@ -694,7 +694,7 @@ be private. code to work with, Peter Dimov in particular for his help and invaluable advice on thread safety. Phillip Jordan and Paolo Carlini for the lock policy implementation. -

    Bibliography

    +

    Bibliography

    + .

    + .

    + .

    Chapter 12.  Numerics - +

    Complex

    complex Processing

    Using complex<> becomes even more comple- er, sorry, diff --git a/libstdc++-v3/doc/html/manual/parallel_mode.html b/libstdc++-v3/doc/html/manual/parallel_mode.html index b8993b5c9d2..0b4decfc067 100644 --- a/libstdc++-v3/doc/html/manual/parallel_mode.html +++ b/libstdc++-v3/doc/html/manual/parallel_mode.html @@ -13,11 +13,11 @@ explicit source declaration or by compiling existing sources with a specific compiler flag.

    Intro

    The following library components in the include numeric are included in the parallel mode:

    • std::accumulate

    • std::adjacent_difference

    • std::inner_product

    • std::partial_sum

    The following library components in the include -algorithm are included in the parallel mode:

    • std::adjacent_find

    • std::count

    • std::count_if

    • std::equal

    • std::find

    • std::find_if

    • std::find_first_of

    • std::for_each

    • std::generate

    • std::generate_n

    • std::lexicographical_compare

    • std::mismatch

    • std::search

    • std::search_n

    • std::transform

    • std::replace

    • std::replace_if

    • std::max_element

    • std::merge

    • std::min_element

    • std::nth_element

    • std::partial_sort

    • std::partition

    • std::random_shuffle

    • std::set_union

    • std::set_intersection

    • std::set_symmetric_difference

    • std::set_difference

    • std::sort

    • std::stable_sort

    • std::unique_copy

    Bibliography

    +algorithm are included in the parallel mode:

    • std::adjacent_find

    • std::count

    • std::count_if

    • std::equal

    • std::find

    • std::find_if

    • std::find_first_of

    • std::for_each

    • std::generate

    • std::generate_n

    • std::lexicographical_compare

    • std::mismatch

    • std::search

    • std::search_n

    • std::transform

    • std::replace

    • std::replace_if

    • std::max_element

    • std::merge

    • std::min_element

    • std::nth_element

    • std::partial_sort

    • std::partition

    • std::random_shuffle

    • std::set_union

    • std::set_intersection

    • std::set_symmetric_difference

    • std::set_difference

    • std::sort

    • std::stable_sort

    • std::unique_copy

    Bibliography

    Parallelization of Bulk Operations for STL Dictionaries . Johannes Singler. Leonor Frias. Copyright © 2007 . Workshop on Highly Parallel Processing on a Chip (HPPC) 2007. (LNCS) - .

    + .

    The Multi-Core Standard Template Library . Johannes Singler. Peter Sanders. Felix Putze. Copyright © 2007 . Euro-Par 2007: Parallel Processing. (LNCS 4641) diff --git a/libstdc++-v3/doc/html/manual/profile_mode.html b/libstdc++-v3/doc/html/manual/profile_mode.html index 8fc828ef1e3..78e8a52a489 100644 --- a/libstdc++-v3/doc/html/manual/profile_mode.html +++ b/libstdc++-v3/doc/html/manual/profile_mode.html @@ -138,7 +138,7 @@ vector-size: improvement = 3: call stack = 0x804842c ... call context. (Environment variable not supported.)

    -

    Bibliography

    +

    Bibliography

    Perflint: A Context Sensitive Performance Advisor for C++ Programs . Lixia Liu. Silvius Rus. Copyright © 2009 . Proceedings of the 2009 International Symposium on Code Generation diff --git a/libstdc++-v3/doc/html/manual/spine.html b/libstdc++-v3/doc/html/manual/spine.html index bbc038e09bd..9de2812422f 100644 --- a/libstdc++-v3/doc/html/manual/spine.html +++ b/libstdc++-v3/doc/html/manual/spine.html @@ -2,7 +2,7 @@ The GNU C++ Library