summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-02-22 11:51:54 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-02-22 11:51:54 +0000
commit8564db8424b6988dd1b665e29f579c732a6001dc (patch)
treec203317dc88ea9f1a0fdb079333a2e6086f51b0e
parent49e6b159a6b2225a0198f8e261c6b6f3772fba3f (diff)
downloadgcc-8564db8424b6988dd1b665e29f579c732a6001dc.tar.gz
2013-02-22 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 196218 using svnmerge.py git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@196219 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog4
-rw-r--r--ChangeLog.MELT4
-rw-r--r--MAINTAINERS1
-rw-r--r--gcc/ChangeLog220
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/ada/gnat-style.texi2
-rw-r--r--gcc/ada/projects.texi12
-rw-r--r--gcc/c-family/ChangeLog14
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/c-family/c-opts.c10
-rw-r--r--gcc/config/i386/i386.c5
-rw-r--r--gcc/config/microblaze/microblaze.c11
-rw-r--r--gcc/config/microblaze/microblaze.h4
-rw-r--r--gcc/config/microblaze/microblaze.md24
-rw-r--r--gcc/config/mips/mips.c2
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/cvt.c13
-rw-r--r--gcc/cp/decl.c9
-rw-r--r--gcc/cp/tree.c15
-rw-r--r--gcc/cp/typeck.c9
-rw-r--r--gcc/doc/invoke.texi12
-rw-r--r--gcc/doc/rtl.texi17
-rw-r--r--gcc/expmed.c35
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/expr.h2
-rw-r--r--gcc/fortran/ChangeLog14
-rw-r--r--gcc/fortran/gfortran.texi6
-rw-r--r--gcc/fortran/intrinsic.texi196
-rw-r--r--gcc/fortran/trans-array.c7
-rw-r--r--gcc/function.c20
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/genopinit.c10
-rw-r--r--gcc/genpreds.c5
-rw-r--r--gcc/ipa-cp.c33
-rw-r--r--gcc/ipa-prop.c61
-rw-r--r--gcc/lower-subreg.c56
-rw-r--r--gcc/lower-subreg.h1
-rw-r--r--gcc/optabs.c35
-rw-r--r--gcc/optabs.h1
-rw-r--r--gcc/passes.c5
-rw-r--r--gcc/sel-sched-dump.c4
-rw-r--r--gcc/sel-sched.c67
-rw-r--r--gcc/target-globals.c29
-rw-r--r--gcc/target-globals.h1
-rw-r--r--gcc/testsuite/ChangeLog95
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C14
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-11.C50
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr56310.C36
-rw-r--r--gcc/testsuite/g++.dg/opt/pr56381.C156
-rw-r--r--gcc/testsuite/g++.dg/pch/pch.exp2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr56398.C22
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-6.C30
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr52555.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr56405.c7
-rw-r--r--gcc/testsuite/gcc.dg/pch/pch.exp2
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1.hs1
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1b.c1
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1b.hs1
-rw-r--r--gcc/testsuite/gcc.dg/pr56350.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr56396.c22
-rw-r--r--gcc/testsuite/gcc.dg/tm/memopt-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr56108.c9
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr56384.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr56420.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21559.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp17.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp18.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp23.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp24.c8
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_37.f9025
-rw-r--r--gcc/testsuite/lib/dg-pch.exp51
-rw-r--r--gcc/testsuite/objc.dg/pch/pch.exp3
-rw-r--r--gcc/trans-mem.c19
-rw-r--r--gcc/tree-call-cdce.c7
-rw-r--r--gcc/tree-ssa-ccp.c9
-rw-r--r--gcc/tree-ssa-copy.c9
-rw-r--r--gcc/tree-ssa-copyrename.c40
-rw-r--r--gcc/tree-ssa-dce.c6
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-live.c5
-rw-r--r--gcc/tree-ssa-loop-ivopts.c17
-rw-r--r--gcc/tree-ssa-pre.c2
-rw-r--r--gcc/tree-ssa-sccvn.c11
-rw-r--r--gcc/tree-ssa-sccvn.h17
-rw-r--r--gcc/tree-ssanames.c4
-rw-r--r--gcc/tree-vect-loop-manip.c1
-rw-r--r--gcc/tree-vect-loop.c19
-rw-r--r--gcc/tree-vrp.c13
-rw-r--r--gcc/tree.h11
-rw-r--r--libgcc/ChangeLog4
-rw-r--r--libgcc/config/microblaze/modsi3.S2
-rw-r--r--libgfortran/ChangeLog17
-rw-r--r--libgfortran/acinclude.m412
-rw-r--r--libgfortran/config.h.in3
-rwxr-xr-xlibgfortran/configure22
-rw-r--r--libgfortran/configure.ac3
-rw-r--r--libgfortran/intrinsics/c99_functions.c2
-rw-r--r--libgfortran/io/open.c8
-rw-r--r--libgfortran/io/unix.c15
-rw-r--r--libgo/Makefile.am19
-rw-r--r--libgo/Makefile.in16
-rw-r--r--libgo/go/syscall/sockcmsg_unix.go10
-rw-r--r--libgo/go/syscall/socket.go24
-rw-r--r--libgo/go/syscall/socket_posix.go31
-rw-r--r--libgo/go/syscall/socket_xnet.go32
-rw-r--r--libgo/runtime/lfstack.c7
-rw-r--r--libjava/classpath/ChangeLog.gcj6
-rw-r--r--libjava/classpath/doc/cp-tools.texinfo2
-rw-r--r--libquadmath/ChangeLog6
-rw-r--r--libquadmath/strtod/strtod_l.c44
-rw-r--r--libsanitizer/ChangeLog18
-rw-r--r--libsanitizer/MERGE2
-rw-r--r--libsanitizer/asan/Makefile.am1
-rw-r--r--libsanitizer/asan/Makefile.in24
-rw-r--r--libsanitizer/asan/asan_flags.h8
-rw-r--r--libsanitizer/asan/asan_intercepted_functions.h59
-rw-r--r--libsanitizer/asan/asan_interceptors.cc13
-rw-r--r--libsanitizer/asan/asan_internal.h6
-rw-r--r--libsanitizer/asan/asan_mac.cc110
-rw-r--r--libsanitizer/asan/asan_mapping.h112
-rw-r--r--libsanitizer/asan/asan_report.cc4
-rw-r--r--libsanitizer/asan/asan_rtl.cc177
-rw-r--r--libsanitizer/asan/dynamic/asan_interceptors_dynamic.cc114
-rw-r--r--libsanitizer/include/sanitizer/asan_interface.h4
-rw-r--r--libsanitizer/include/sanitizer/common_interface_defs.h5
-rwxr-xr-xlibsanitizer/merge.sh1
-rw-r--r--libsanitizer/sanitizer_common/Makefile.am1
-rw-r--r--libsanitizer/sanitizer_common/Makefile.in13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc103
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.cc3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_internal_defs.h2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libc.h6
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cc36
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac.cc4
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h10
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc68
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h41
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.cc8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.cc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win.cc12
-rw-r--r--libsanitizer/tsan/tsan_platform_linux.cc2
-rw-r--r--libsanitizer/tsan/tsan_platform_mac.cc2
-rw-r--r--libsanitizer/tsan/tsan_platform_windows.cc2
-rw-r--r--libsanitizer/tsan/tsan_rtl.h2
-rw-r--r--libsanitizer/tsan/tsan_rtl_thread.cc22
-rw-r--r--libsanitizer/tsan/tsan_stat.cc8
-rw-r--r--libsanitizer/tsan/tsan_stat.h8
-rw-r--r--libsanitizer/tsan/tsan_suppressions.cc2
-rw-r--r--libstdc++-v3/ChangeLog38
-rw-r--r--libstdc++-v3/doc/doxygen/user.cfg.in111
-rw-r--r--libstdc++-v3/doc/html/faq.html2
-rw-r--r--libstdc++-v3/doc/xml/faq.xml2
-rw-r--r--libstdc++-v3/include/bits/basic_ios.h2
-rw-r--r--libstdc++-v3/include/bits/regex.h4
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h9
-rw-r--r--libstdc++-v3/include/bits/stringfwd.h15
-rw-r--r--libstdc++-v3/include/std/istream2
-rw-r--r--libstdc++-v3/include/std/limits24
-rw-r--r--libstdc++-v3/include/std/streambuf27
-rw-r--r--libstdc++-v3/include/std/tuple12
-rw-r--r--libstdc++-v3/include/std/type_traits37
-rw-r--r--libstdc++-v3/include/std/typeindex13
-rw-r--r--libstdc++-v3/include/tr1/memory4
-rw-r--r--libstdc++-v3/include/tr1/regex8
-rw-r--r--libstdc++-v3/scripts/run_doxygen2
-rw-r--r--libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc2
176 files changed, 2695 insertions, 782 deletions
diff --git a/ChangeLog b/ChangeLog
index f9c8f298233..6ef875812c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-02-20 Andrew Sutton <andrew.n.sutton@gmail.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
2013-02-15 Yufeng Zhang <yufeng.zhang@arm.com>
* configure.ac: Set libgloss_dir for the aarch64*-*-* targets.
diff --git a/ChangeLog.MELT b/ChangeLog.MELT
index 2fcc3e9e4eb..c2969a2ba7f 100644
--- a/ChangeLog.MELT
+++ b/ChangeLog.MELT
@@ -1,4 +1,8 @@
+2013-02-22 Basile Starynkevitch <basile@starynkevitch.net>
+
+ MELT branch merged with trunk rev 196218 using svnmerge.py
+
2013-02-18 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 196123 using svnmerge.py
diff --git a/MAINTAINERS b/MAINTAINERS
index 3f57f2fdefc..9affec84353 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -523,6 +523,7 @@ Graham Stott graham.stott@btinternet.com
Andrew Stubbs ams@codesourcery.com
Mike Stump mikestump@comcast.net
Jeff Sturm jsturm@gcc.gnu.org
+Andrew Sutton andrew.n.sutton@gmail.com
Gabriele Svelto gabriele.svelto@st.com
Sriraman Tallam tmsriram@google.com
Chung-Lin Tang cltang@codesourcery.com
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e8be788a8c7..c2b35d3538c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,223 @@
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/56420
+ * expmed.c (EXACT_POWER_OF_2_OR_ZERO_P): Do subtraction in uhwi, to
+ avoid signed wrapping.
+ (expand_mult): Handle properly multiplication by
+ ((dword_type) -1) << (BITS_PER_WORD - 1). Improve multiplication by
+ ((dword_type) 1) << (BITS_PER_WORD - 1). Avoid undefined behavior
+ in the compiler if coeff is HOST_WIDE_INT_MIN.
+ (expand_divmod): Don't make ext_op1 static, change it's type to
+ uhwi. Avoid undefined behavior in -INTVAL (op1).
+
+ PR rtl-optimization/50339
+ * lower-subreg.h (struct lower_subreg_choices): Add splitting_ashiftrt
+ field.
+ * lower-subreg.c (compute_splitting_shift): Handle ASHIFTRT.
+ (compute_costs): Call compute_splitting_shift also for ASHIFTRT
+ into splitting_ashiftrt field.
+ (find_decomposable_shift_zext, resolve_shift_zext): Handle also
+ ASHIFTRT.
+ (dump_choices): Fix up printing LSHIFTRT choices, print ASHIFTRT
+ choices.
+
+2013-02-20 Aldy Hernandez <aldyh@redhat.com>
+
+ PR middle-end/56108
+ * trans-mem.c (execute_tm_mark): Do not expand transactions that
+ are sure to go irrevocable.
+
+2013-02-21 Hans-Peter Nilsson <hp@axis.com>
+
+ * doc/rtl.texi (vec_concat, vec_duplicate): Mention that
+ scalars are valid operands.
+
+2013-02-21 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/56310
+ * ipa-cp.c (agg_replacements_to_vector): New parameter index, copy
+ only matching indices and non-negative final offsets.
+ (intersect_aggregates_with_edge): Pass src_idx to
+ agg_replacements_to_vector. Pass src_idx insstead of index to
+ intersect_with_agg_replacements.
+
+2013-02-21 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (good_cloning_opportunity_p): Dump the real threshold
+ instead of hard-wired defaults.
+
+2013-02-21 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * doc/invoke.texi (MIPS Options): Update documentation of the
+ floating-point multiply-accumulate instruction restrictions.
+
+2013-02-21 Kostya Serebryany <kcc@google.com>
+
+ * config/i386/i386.c (ix86_asan_shadow_offset): Use 0x7fff8000 as
+ asan_shadow_offset on x86_64 linux.
+
+2013-02-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56415
+ Revert
+ 2013-02-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56273
+ * tree-vrp.c (simplify_cond_using_ranges): Disable for the
+ first VRP run.
+
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/56258
+ * doc/invoke.texi (-fdump-rtl-pro_and_epilogue): Use @item
+ instead of @itemx.
+
+ PR inline-asm/56405
+ * expr.c (expand_expr_real_1) <case TARGET_MEM_REF, MEM_REF>: Don't
+ use movmisalign or extract_bit_field for EXPAND_MEMORY modifier.
+
+2013-02-20 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/56265
+ * ipa-prop.c (ipa_make_edge_direct_to_target): Fixup callgraph when target is
+ referenced for firs ttime.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+
+ * tree-call-cdce.c (tree_call_cdce): Do not remove unused locals.
+ * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Likewise.
+ * tree-ssa-dce.c (perform_tree_ssa_dce): Likewise.
+ * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Do
+ not return anything.
+ (rename_ssa_copies): Do not remove unused locals.
+ * tree-ssa-ccp.c (do_ssa_ccp): Likewise.
+ * tree-ssanames.c (pass_release_ssa_names): Remove unused
+ locals first.
+ * passes.c (execute_function_todo): Do not schedule unused locals
+ removal if cleanup_tree_cfg did something.
+ * tree-ssa-live.c (remove_unused_locals): Dump statistics
+ about the number of removed locals.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56398
+ * tree-vect-loop-manip.c (adjust_debug_stmts): Skip
+ SSA default defs.
+
+2013-02-20 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/55334
+ * ipa-cp.c (initialize_node_lattices): Disable IPA-CP through and to
+ restricted pointers to arrays.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56396
+ * tree-ssa-ccp.c (n_const_val): New static variable.
+ (get_value): Return NULL for SSA names we don't have a lattice
+ entry for.
+ (ccp_initialize): Initialize n_const_val.
+ * tree-ssa-copy.c (n_copy_of): New static variable.
+ (init_copy_prop): Initialize n_copy_of.
+ (get_value): Return NULL_TREE for SSA names we don't have a
+ lattice entry for.
+
+2013-02-20 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (initialize_node_lattices): Fix dumping condition.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+
+ * genpreds.c (write_lookup_constraint): Do not compare first
+ letter of the constraint again.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-ivopts.c (alloc_use_cost_map): Use bitmap_count_bits
+ and ceil_log2.
+ (get_use_iv_cost): Terminate hashtable walk when coming across
+ an empty entry.
+
+2013-02-20 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ * config/i386/i386.c (initial_ix86_tune_features): Turn on fp
+ reassociation for avx2 targets.
+
+2012-02-19 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ * config/microblaze/microblaze.c: microblaze_has_clz = 0
+ Add version check for v8.10.a to enable microblaze_has_clz
+ * config/microblaze/microblaze.h: Add TARGET_HAS_CLZ as combined
+ version and TARGET_PATTERN_COMPARE check
+ * config/microblaze/microblaze.md: New clzsi2 instruction
+
+2012-02-19 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+
+ * config/microblaze/microblaze.md (call_value_intern): Check symbol is
+ function before branching.
+
+2012-02-19 Andrey Belevantsev <abel@ispras.ru>
+
+ * sel-sched-dump.c (dump_insn_rtx_flags): Explicitly set
+ DUMP_INSN_RTX_UID.
+ (dump_insn_rtx_1): Pass PATTERN (insn) to str_pattern_slim.
+
+2012-02-19 Andrey Belevantsev <abel@ispras.ru>
+
+ PR middle-end/55889
+
+ * sel-sched.c: Include ira.h.
+ (implicit_clobber_conflict_p): New function.
+ (moveup_expr): Use it.
+ * Makefile.in (sel-sched.o): Depend on ira.h.
+
+2013-02-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56384
+ * tree-ssa-sccvn.h (struct vn_phi_s): Add type member.
+ (vn_hash_type): Split out from ...
+ (vn_hash_constant_with_type): ... here.
+ * tree-ssa-sccvn.c (vn_phi_compute_hash): Use vn_hash_type.
+ (vn_phi_eq): Compare types from vn_phi_s structure.
+ (vn_phi_lookup): Populate vn_phi_s type.
+ (vn_phi_insert): Likewise.
+
+2013-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56350
+ * tree-vect-loop.c (vectorizable_reduction): If orig_stmt, return false
+ if haven't found reduction or nested cycle operand, rather than
+ asserting we must find it.
+
+ PR tree-optimization/56381
+ * tree-ssa-pre.c (create_expression_by_pieces): Fix up last argument
+ to fold_build3.
+
+2013-02-18 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/52555
+ * genopinit.c (raw_optab_handler): Use this_fn_optabs.
+ (swap_optab_enable): Same.
+ (init_all_optabs): Use argument instead of global.
+ * tree.h (struct tree_optimization_option): New field
+ target_optabs.
+ * expr.h (init_all_optabs): Add argument to prototype.
+ (TREE_OPTIMIZATION_OPTABS): New.
+ (save_optabs_if_changed): Protoize.
+ * optabs.h: Declare this_fn_optabs.
+ * optabs.c (save_optabs_if_changed): New.
+ Declare this_fn_optabs.
+ (init_optabs): Add argument to init_all_optabs() call.
+ * function.c (invoke_set_current_function_hook): Handle per
+ function optabs.
+ * function.h (struct function): New field optabs.
+ * config/mips/mips.c (mips_set_mips16_mode): Handle when
+ optimization_current_node has changed.
+ * target-globals.h (save_target_globals_default_opts): Protoize.
+ * target-globals.c (save_target_globals_default_opts): New.
+
2013-02-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/56347
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 9e056c92577..cea0916f9b7 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20130218
+20130222
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ce34c04792b..c6bdac88e3b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3443,7 +3443,7 @@ sel-sched.o : sel-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FUNCTION_H) $(INSN_ATTR_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
$(TM_P_H) output.h $(TARGET_H) $(TREE_PASS_H) \
$(SCHED_INT_H) $(GGC_H) $(TREE_H) langhooks.h rtlhooks-def.h \
- $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h $(DBGCNT_H) $(EMIT_RTL_H)
+ $(SEL_SCHED_IR_H) $(SEL_SCHED_DUMP_H) sel-sched.h $(DBGCNT_H) $(EMIT_RTL_H) ira.h
sel-sched-dump.o : sel-sched-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(PARAMS_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 385e77118a3..d23568fedd6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/56258
+ * gnat-style.texi (@title): Remove @hfill.
+ * projects.texi: Avoid line wrapping inside of @pxref or
+ @xref.
+
2013-02-14 Rainer Emrich <rainer@emrich-ebersheim.de>
PR target/52123
diff --git a/gcc/ada/gnat-style.texi b/gcc/ada/gnat-style.texi
index 43e6b4310a1..df2d491e14f 100644
--- a/gcc/ada/gnat-style.texi
+++ b/gcc/ada/gnat-style.texi
@@ -42,7 +42,7 @@ Texts. A copy of the license is included in the section entitled
@titlepage
@titlefont{GNAT Coding Style:}
@sp 1
-@title @hfill A Guide for GNAT Developers
+@title A Guide for GNAT Developers
@subtitle GNAT, The GNU Ada Compiler
@versionsubtitle
@author Ada Core Technologies, Inc.
diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi
index 6bf1e0c7c20..32ae8f66c5f 100644
--- a/gcc/ada/projects.texi
+++ b/gcc/ada/projects.texi
@@ -48,8 +48,7 @@ project files allow you to specify:
@item Source file naming conventions; you can specify these either globally or for
individual compilation units (@pxref{Naming Schemes}).
@item Change any of the above settings depending on external values, thus enabling
- the reuse of the projects in various @b{scenarios} (@pxref{Scenarios
- in Projects}).
+ the reuse of the projects in various @b{scenarios} (@pxref{Scenarios in Projects}).
@item Automatically build libraries as part of the build process
(@pxref{Library Projects}).
@@ -360,8 +359,8 @@ locating the specified source files in the specified source directories.
@item For various reasons, it is sometimes useful to have a project with no
sources (most of the time because the attributes defined in the project
- file will be reused in other projects, as explained in @pxref{Organizing
- Projects into Subsystems}. To do this, the attribute
+ file will be reused in other projects, as explained in
+ @pxref{Organizing Projects into Subsystems}. To do this, the attribute
@emph{Source_Files} is set to the empty list, i.e. @code{()}. Alternatively,
@emph{Source_Dirs} can be set to the empty list, with the same
result.
@@ -388,8 +387,9 @@ locating the specified source files in the specified source directories.
This can be done thanks to the attribute @b{Excluded_Source_Files}
(or its synonym @b{Locally_Removed_Files}).
Its value is the list of file names that should not be taken into account.
- This attribute is often used when extending a project, @xref{Project
- Extension}. A similar attribute @b{Excluded_Source_List_File} plays the same
+ This attribute is often used when extending a project,
+ @xref{Project Extension}. A similar attribute
+ @b{Excluded_Source_List_File} plays the same
role but takes the name of file containing file names similarly to
@code{Source_List_File}.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 16ef84a3634..50ad1016f7c 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,17 @@
+2013-02-18 Aldy Hernandez <aldyh@redhat.com>
+
+ PR target/52555
+ * c-common.c (handle_optimize_attribute): Call
+ save_optabs_if_changed.
+
+2013-02-18 Jakub Jelinek <jakub@redhat.com>
+ Steven Bosscher <steven@gcc.gnu.org>
+
+ PR pch/54117
+ * c-opts.c (c_common_post_options): If debug info is enabled
+ and non-dwarf*, refuse to load PCH files and when writing PCH
+ file warn.
+
2013-02-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56167
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 1e6afaa77f2..a1d47a68045 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -8925,6 +8925,8 @@ handle_optimize_attribute (tree *node, tree name, tree args,
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
= build_optimization_node ();
+ save_optabs_if_changed (*node);
+
/* Restore current options. */
cl_optimization_restore (&global_options, &cur_opts);
}
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 1a922a81c35..4b6990a60c1 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -945,6 +945,16 @@ c_common_post_options (const char **pfilename)
because the default address space slot then can't be used
for the output PCH file. */
if (pch_file)
+ {
+ c_common_no_more_pch ();
+ /* Only -g0 and -gdwarf* are supported with PCH, for other
+ debug formats we warn here and refuse to load any PCH files. */
+ if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
+ warning (OPT_Wdeprecated,
+ "the \"%s\" debug format cannot be used with "
+ "pre-compiled headers", debug_type_names[write_symbols]);
+ }
+ else if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
c_common_no_more_pch ();
/* Yuk. WTF is this? I do know ObjC relies on it somewhere. */
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9a94c36bea9..b835c5da2ab 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2021,7 +2021,7 @@ static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
during reassociation of fp computation. */
- m_ATOM,
+ m_ATOM | m_HASWELL,
/* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
regs instead of memory. */
@@ -5436,7 +5436,8 @@ ix86_legitimate_combined_insn (rtx insn)
static unsigned HOST_WIDE_INT
ix86_asan_shadow_offset (void)
{
- return TARGET_LP64 ? (HOST_WIDE_INT_1 << 44)
+ return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
+ : HOST_WIDE_INT_C (0x7fff8000))
: (HOST_WIDE_INT_1 << 29);
}
diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
index 449626b2e38..fc0296e2c15 100644
--- a/gcc/config/microblaze/microblaze.c
+++ b/gcc/config/microblaze/microblaze.c
@@ -143,6 +143,9 @@ int microblaze_section_threshold = -1;
delay slots. -mcpu=v3.00.a or v4.00.a turns this on. */
int microblaze_no_unsafe_delay;
+/* Set to one if the targeted core has the CLZ insn. */
+int microblaze_has_clz = 0;
+
/* Which CPU pipeline do we use. We haven't really standardized on a CPU
version having only a particular type of pipeline. There can still be
options on the CPU to scale pipeline features up or down. :(
@@ -1369,6 +1372,14 @@ microblaze_option_override (void)
"-mxl-multiply-high can be used only with -mcpu=v6.00.a or greater");
}
+ ver = MICROBLAZE_VERSION_COMPARE (microblaze_select_cpu, "v8.10.a");
+ microblaze_has_clz = 1;
+ if (ver < 0)
+ {
+ /* MicroBlaze prior to 8.10.a didn't have clz. */
+ microblaze_has_clz = 0;
+ }
+
if (TARGET_MULTIPLY_HIGH && TARGET_SOFT_MUL)
error ("-mxl-multiply-high requires -mno-xl-soft-mul");
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index b552665ac63..a188a2eb113 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -42,6 +42,7 @@ extern int microblaze_section_threshold;
extern int microblaze_dbx_regno[];
extern int microblaze_no_unsafe_delay;
+extern int microblaze_has_clz;
extern enum pipeline_type microblaze_pipe;
#define OBJECT_FORMAT_ELF
@@ -58,6 +59,9 @@ extern enum pipeline_type microblaze_pipe;
#define TARGET_DEFAULT (MASK_SOFT_MUL | MASK_SOFT_DIV | MASK_SOFT_FLOAT \
| TARGET_ENDIAN_DEFAULT)
+/* Do we have CLZ? */
+#define TARGET_HAS_CLZ (TARGET_PATTERN_COMPARE && microblaze_has_clz)
+
/* The default is to support PIC. */
#define TARGET_SUPPORTS_PIC 1
diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
index 1d55a167be4..1b4200307cb 100644
--- a/gcc/config/microblaze/microblaze.md
+++ b/gcc/config/microblaze/microblaze.md
@@ -2128,9 +2128,17 @@
register rtx target = operands[1];
register rtx target2=gen_rtx_REG (Pmode,GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM);
- if (GET_CODE (target) == SYMBOL_REF){
- gen_rtx_CLOBBER (VOIDmode,target2);
- return "brlid\tr15,%1\;%#";
+ if (GET_CODE (target) == SYMBOL_REF)
+ {
+ gen_rtx_CLOBBER (VOIDmode,target2);
+ if (SYMBOL_REF_FLAGS (target) & SYMBOL_FLAG_FUNCTION)
+ {
+ return "brlid\tr15,%1\;%#";
+ }
+ else
+ {
+ return "bralid\tr15,%1\;%#";
+ }
}
else if (GET_CODE (target) == CONST_INT)
return "la\t%@,r0,%1\;brald\tr15,%@\;%#";
@@ -2192,3 +2200,13 @@
[(set_attr "type" "multi")
(set_attr "length" "12")])
+;; This insn gives the count of leading number of zeros for the second
+;; operand and stores the result in first operand.
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (clz:SI (match_operand:SI 1 "register_operand" "r")))]
+ "TARGET_HAS_CLZ"
+ "clz\t%0,%1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set_attr "length" "4")])
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b203cdd1ed2..252e828480e 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -16313,7 +16313,7 @@ mips_set_mips16_mode (int mips16_p)
if (mips16_p)
{
if (!mips16_globals)
- mips16_globals = save_target_globals ();
+ mips16_globals = save_target_globals_default_opts ();
else
restore_target_globals (mips16_globals);
}
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 52fac3af74c..b7816a90339 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2013-02-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56373
+ * tree.c (maybe_warn_zero_as_null_pointer_constant): Add.
+ * cvt.c (ocp_convert): Use the latter.
+ (cp_convert_to_pointer): Likewise.
+ * decl.c (check_default_argument): Likewise.
+ * typeck.c (cp_build_binary_op): Likewise.
+ * cp-tree.h (maybe_warn_zero_as_null_pointer_constant): Declare.
+
2013-02-15 Jonathan Wakely <jwakely.gcc@gmail.com>
Paolo Carlini <paolo.carlini@oracle.com>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d9270e2270d..4a597d8b3a6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5834,6 +5834,7 @@ extern bool cast_valid_in_integral_constant_expression_p (tree);
extern bool cxx_type_hash_eq (const_tree, const_tree);
extern void cxx_print_statistics (void);
+extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
/* in ptree.c */
extern void cxx_print_xnode (FILE *, tree, int);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 8e8ce53325e..348e6082ceb 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -203,11 +203,8 @@ cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain)
if (null_ptr_cst_p (expr))
{
- if ((complain & tf_warning)
- && c_inhibit_evaluation_warnings == 0
- && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
- warning_at (loc, OPT_Wzero_as_null_pointer_constant,
- "zero as null pointer constant");
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (expr, loc);
if (TYPE_PTRMEMFUNC_P (type))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
@@ -783,7 +780,11 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
return ignore_overflows (converted, e);
}
if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e))
- return nullptr_node;
+ {
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (e, loc);
+ return nullptr_node;
+ }
if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type))
return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain));
if (code == VECTOR_TYPE)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3d63389e404..661969f441c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10861,15 +10861,10 @@ check_default_argument (tree decl, tree arg)
--cp_unevaluated_operand;
if (warn_zero_as_null_pointer_constant
- && c_inhibit_evaluation_warnings == 0
&& TYPE_PTR_OR_PTRMEM_P (decl_type)
&& null_ptr_cst_p (arg)
- && !NULLPTR_TYPE_P (TREE_TYPE (arg)))
- {
- warning (OPT_Wzero_as_null_pointer_constant,
- "zero as null pointer constant");
- return nullptr_node;
- }
+ && maybe_warn_zero_as_null_pointer_constant (arg, input_location))
+ return nullptr_node;
/* [dcl.fct.default]
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0b033c2bfb4..41c8759096c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3939,6 +3939,21 @@ cp_tree_operand_length (const_tree t)
return TREE_OPERAND_LENGTH (t);
}
}
+
+/* Implement -Wzero_as_null_pointer_constant. Return true if the
+ conditions for the warning hold, false otherwise. */
+bool
+maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
+{
+ if (c_inhibit_evaluation_warnings == 0
+ && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
+ {
+ warning_at (loc, OPT_Wzero_as_null_pointer_constant,
+ "zero as null pointer constant");
+ return true;
+ }
+ return false;
+}
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 688c2665b4f..58295d73d15 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4293,12 +4293,9 @@ cp_build_binary_op (location_t location,
delta0,
integer_one_node,
complain);
-
- if ((complain & tf_warning)
- && c_inhibit_evaluation_warnings == 0
- && !NULLPTR_TYPE_P (TREE_TYPE (op1)))
- warning (OPT_Wzero_as_null_pointer_constant,
- "zero as null pointer constant");
+
+ if (complain & tf_warning)
+ maybe_warn_zero_as_null_pointer_constant (op1, input_location);
e2 = cp_build_binary_op (location,
EQ_EXPR, e2, integer_zero_node,
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a444dbafb75..49a04ccc262 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5617,7 +5617,7 @@ Dump after the peephole pass.
@opindex fdump-rtl-postreload
Dump after post-reload optimizations.
-@itemx -fdump-rtl-pro_and_epilogue
+@item -fdump-rtl-pro_and_epilogue
@opindex fdump-rtl-pro_and_epilogue
Dump after generating the function prologues and epilogues.
@@ -16445,10 +16445,12 @@ Enable (disable) use of the floating-point multiply-accumulate
instructions, when they are available. The default is
@option{-mfused-madd}.
-When multiply-accumulate instructions are used, the intermediate
-product is calculated to infinite precision and is not subject to
-the FCSR Flush to Zero bit. This may be undesirable in some
-circumstances.
+On the R8000 CPU when multiply-accumulate instructions are used,
+the intermediate product is calculated to infinite precision
+and is not subject to the FCSR Flush to Zero bit. This may be
+undesirable in some circumstances. On other processors the result
+is numerically identical to the equivalent computation using
+separate multiply, add, subtract and negate instructions.
@item -nocpp
@opindex nocpp
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index b0b0723af2e..aa33d1cd80d 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -2627,17 +2627,18 @@ The result mode @var{m} is either the submode for a single element of
with that element submode (if multiple subparts are selected).
@findex vec_concat
-@item (vec_concat:@var{m} @var{vec1} @var{vec2})
+@item (vec_concat:@var{m} @var{x1} @var{x2})
Describes a vector concat operation. The result is a concatenation of the
-vectors @var{vec1} and @var{vec2}; its length is the sum of the lengths of
-the two inputs.
+vectors or scalars @var{x1} and @var{x2}; its length is the sum of the
+lengths of the two inputs.
@findex vec_duplicate
-@item (vec_duplicate:@var{m} @var{vec})
-This operation converts a small vector into a larger one by duplicating the
-input values. The output vector mode must have the same submodes as the
-input vector mode, and the number of output parts must be an integer multiple
-of the number of input parts.
+@item (vec_duplicate:@var{m} @var{x})
+This operation converts a scalar into a vector or a small vector into a
+larger one by duplicating the input values. The output vector mode must have
+the same submodes as the input vector mode or the scalar modes, and the
+number of output parts must be an integer multiple of the number of input
+parts.
@end table
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 954a360c7b2..d66c6e667fb 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -64,7 +64,8 @@ static rtx expand_smod_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
/* Test whether a value is zero of a power of two. */
-#define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
+#define EXACT_POWER_OF_2_OR_ZERO_P(x) \
+ (((x) & ((x) - (unsigned HOST_WIDE_INT) 1)) == 0)
struct init_expmed_rtl
{
@@ -3079,7 +3080,10 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
/* If we are multiplying in DImode, it may still be a win
to try to work with shifts and adds. */
if (CONST_DOUBLE_HIGH (scalar_op1) == 0
- && CONST_DOUBLE_LOW (scalar_op1) > 0)
+ && (CONST_DOUBLE_LOW (scalar_op1) > 0
+ || (CONST_DOUBLE_LOW (scalar_op1) < 0
+ && EXACT_POWER_OF_2_OR_ZERO_P
+ (CONST_DOUBLE_LOW (scalar_op1)))))
{
coeff = CONST_DOUBLE_LOW (scalar_op1);
is_neg = false;
@@ -3109,7 +3113,8 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
use synth_mult. */
/* Special case powers of two. */
- if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
+ if (EXACT_POWER_OF_2_OR_ZERO_P (coeff)
+ && !(is_neg && mode_bitsize > HOST_BITS_PER_WIDE_INT))
return expand_shift (LSHIFT_EXPR, mode, op0,
floor_log2 (coeff), target, unsignedp);
@@ -3124,13 +3129,24 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
result is interpreted as an unsigned coefficient.
Exclude cost of op0 from max_cost to match the cost
calculation of the synth_mult. */
+ coeff = -(unsigned HOST_WIDE_INT) coeff;
max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), speed)
- neg_cost(speed, mode));
- if (max_cost > 0
- && choose_mult_variant (mode, -coeff, &algorithm,
- &variant, max_cost))
+ if (max_cost <= 0)
+ goto skip_synth;
+
+ /* Special case powers of two. */
+ if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
+ {
+ rtx temp = expand_shift (LSHIFT_EXPR, mode, op0,
+ floor_log2 (coeff), target, unsignedp);
+ return expand_unop (mode, neg_optab, temp, target, 0);
+ }
+
+ if (choose_mult_variant (mode, coeff, &algorithm, &variant,
+ max_cost))
{
- rtx temp = expand_mult_const (mode, op0, -coeff, NULL_RTX,
+ rtx temp = expand_mult_const (mode, op0, coeff, NULL_RTX,
&algorithm, variant);
return expand_unop (mode, neg_optab, temp, target, 0);
}
@@ -3813,13 +3829,12 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
int op1_is_constant, op1_is_pow2 = 0;
int max_cost, extra_cost;
static HOST_WIDE_INT last_div_const = 0;
- static HOST_WIDE_INT ext_op1;
bool speed = optimize_insn_for_speed_p ();
op1_is_constant = CONST_INT_P (op1);
if (op1_is_constant)
{
- ext_op1 = INTVAL (op1);
+ unsigned HOST_WIDE_INT ext_op1 = UINTVAL (op1);
if (unsignedp)
ext_op1 &= GET_MODE_MASK (mode);
op1_is_pow2 = ((EXACT_POWER_OF_2_OR_ZERO_P (ext_op1)
@@ -3967,7 +3982,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
op1_is_pow2 = (op1_is_constant
&& ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
|| (! unsignedp
- && EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1)))))) ;
+ && EXACT_POWER_OF_2_OR_ZERO_P (-UINTVAL (op1))))));
}
/* If one of the operands is a volatile MEM, copy it into a register. */
diff --git a/gcc/expr.c b/gcc/expr.c
index 08c5c9d0c58..d225479e84e 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9551,6 +9551,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
set_mem_addr_space (temp, as);
align = get_object_alignment (exp);
if (modifier != EXPAND_WRITE
+ && modifier != EXPAND_MEMORY
&& mode != BLKmode
&& align < GET_MODE_ALIGNMENT (mode)
/* If the target does not have special handling for unaligned
@@ -9639,6 +9640,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (TREE_THIS_VOLATILE (exp))
MEM_VOLATILE_P (temp) = 1;
if (modifier != EXPAND_WRITE
+ && modifier != EXPAND_MEMORY
&& mode != BLKmode
&& align < GET_MODE_ALIGNMENT (mode))
{
diff --git a/gcc/expr.h b/gcc/expr.h
index f5063b47cdd..15fcb471d8d 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -718,7 +718,7 @@ extern bool split_comparison (enum rtx_code, enum machine_mode,
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
extern void init_optabs (void);
-extern void init_all_optabs (void);
+extern void init_all_optabs (struct target_optabs *);
/* Call this to initialize an optab function entry. */
extern rtx init_one_libfunc (const char *);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 277ad3ef595..8aeded26d16 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,17 @@
+2013-02-21 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/56385
+ * trans-array.c (structure_alloc_comps): Handle procedure-pointer
+ components with allocatable result.
+
+2012-02-21 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/56416
+ * gfortran.texi (Part II: Language Reference, Extensions,
+ Non-Fortran Main Program): Sort @menu to match actual section order.
+ * intrinsic.texi (Intrinsic Procedures): Ditto.
+ (C_F_POINTER, PRECISION): Move to the alphabetically correct place.
+
2013-02-15 Tobias Burnus <burnus@net-b.de>
Mikael Morin <mikael@gcc.gnu.org>
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 2dccb16d81a..462b4436615 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -182,8 +182,8 @@ Part I: Invoking GNU Fortran
Part II: Language Reference
* Fortran 2003 and 2008 status:: Fortran 2003 and 2008 features supported by GNU Fortran.
* Compiler Characteristics:: User-visible implementation details.
+* Extensions:: Language extensions implemented by GNU Fortran.
* Mixed-Language Programming:: Interoperability with C
-* Extensions:: Language extensions implemented by GNU Fortran.
* Intrinsic Procedures:: Intrinsic procedures supported by GNU Fortran.
* Intrinsic Modules:: Intrinsic modules supported by GNU Fortran.
@@ -1348,8 +1348,8 @@ without warning.
* Commas in FORMAT specifications::
* Missing period in FORMAT specifications::
* I/O item lists::
-* BOZ literal constants::
* @code{Q} exponent-letter::
+* BOZ literal constants::
* Real array indices::
* Unary operators::
* Implicitly convert LOGICAL and INTEGER values::
@@ -2698,8 +2698,8 @@ the same declaration part as the variable or procedure pointer.
* _gfortran_set_options:: Set library option flags
* _gfortran_set_convert:: Set endian conversion
* _gfortran_set_record_marker:: Set length of record markers
-* _gfortran_set_max_subrecord_length:: Set subrecord length
* _gfortran_set_fpe:: Set when a Floating Point Exception should be raised
+* _gfortran_set_max_subrecord_length:: Set subrecord length
@end menu
Even if you are doing mixed-language programming, it is very
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 91f2fea8320..4a48425cd83 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -87,9 +87,9 @@ Some basic guidelines for editing this document:
* @code{CHMOD}: CHMOD, Change access permissions of files
* @code{CMPLX}: CMPLX, Complex conversion function
* @code{COMMAND_ARGUMENT_COUNT}: COMMAND_ARGUMENT_COUNT, Get number of command line arguments
-* @code{COMPLEX}: COMPLEX, Complex conversion function
-* @code{COMPILER_VERSION}: COMPILER_VERSION, Compiler version string
* @code{COMPILER_OPTIONS}: COMPILER_OPTIONS, Options passed to the compiler
+* @code{COMPILER_VERSION}: COMPILER_VERSION, Compiler version string
+* @code{COMPLEX}: COMPLEX, Complex conversion function
* @code{CONJG}: CONJG, Complex conjugate function
* @code{COS}: COS, Cosine function
* @code{COSH}: COSH, Hyperbolic cosine function
@@ -234,12 +234,12 @@ Some basic guidelines for editing this document:
* @code{PRESENT}: PRESENT, Determine whether an optional dummy argument is specified
* @code{PRODUCT}: PRODUCT, Product of array elements
* @code{RADIX}: RADIX, Base of a data model
+* @code{RAN}: RAN, Real pseudo-random number
+* @code{RAND}: RAND, Real pseudo-random number
* @code{RANDOM_NUMBER}: RANDOM_NUMBER, Pseudo-random number
* @code{RANDOM_SEED}: RANDOM_SEED, Initialize a pseudo-random number sequence
-* @code{RAND}: RAND, Real pseudo-random number
* @code{RANGE}: RANGE, Decimal exponent range
* @code{RANK} : RANK, Rank of a data object
-* @code{RAN}: RAN, Real pseudo-random number
* @code{REAL}: REAL, Convert to real type
* @code{RENAME}: RENAME, Rename a file
* @code{REPEAT}: REPEAT, Repeated string concatenation
@@ -2271,60 +2271,57 @@ end subroutine association_test
@end table
-@node C_FUNLOC
-@section @code{C_FUNLOC} --- Obtain the C address of a procedure
-@fnindex C_FUNLOC
-@cindex pointer, C address of procedures
+@node C_F_POINTER
+@section @code{C_F_POINTER} --- Convert C into Fortran pointer
+@fnindex C_F_POINTER
+@cindex pointer, convert C to Fortran
@table @asis
@item @emph{Description}:
-@code{C_FUNLOC(x)} determines the C address of the argument.
+@code{C_F_POINTER(CPTR, FPTR[, SHAPE])} assigns the target of the C pointer
+@var{CPTR} to the Fortran pointer @var{FPTR} and specifies its shape.
@item @emph{Standard}:
Fortran 2003 and later
@item @emph{Class}:
-Inquiry function
+Subroutine
@item @emph{Syntax}:
-@code{RESULT = C_FUNLOC(x)}
+@code{CALL C_F_POINTER(CPTR, FPTR[, SHAPE])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{x} @tab Interoperable function or pointer to such function.
+@item @var{CPTR} @tab scalar of the type @code{C_PTR}. It is
+@code{INTENT(IN)}.
+@item @var{FPTR} @tab pointer interoperable with @var{cptr}. It is
+@code{INTENT(OUT)}.
+@item @var{SHAPE} @tab (Optional) Rank-one array of type @code{INTEGER}
+with @code{INTENT(IN)}. It shall be present
+if and only if @var{fptr} is an array. The size
+must be equal to the rank of @var{fptr}.
@end multitable
-@item @emph{Return value}:
-The return value is of type @code{C_FUNPTR} and contains the C address
-of the argument.
-
@item @emph{Example}:
@smallexample
-module x
- use iso_c_binding
- implicit none
-contains
- subroutine sub(a) bind(c)
- real(c_float) :: a
- a = sqrt(a)+5.0
- end subroutine sub
-end module x
program main
use iso_c_binding
- use x
implicit none
interface
subroutine my_routine(p) bind(c,name='myC_func')
- import :: c_funptr
- type(c_funptr), intent(in) :: p
+ import :: c_ptr
+ type(c_ptr), intent(out) :: p
end subroutine
end interface
- call my_routine(c_funloc(sub))
+ type(c_ptr) :: cptr
+ real,pointer :: a(:)
+ call my_routine(cptr)
+ call c_f_pointer(cptr, a, [12])
end program main
@end smallexample
@item @emph{See also}:
-@ref{C_ASSOCIATED}, @ref{C_LOC}, @ref{C_F_POINTER}, @ref{C_F_PROCPOINTER}
+@ref{C_LOC}, @ref{C_F_PROCPOINTER}
@end table
@@ -2385,57 +2382,60 @@ end program main
@end table
-@node C_F_POINTER
-@section @code{C_F_POINTER} --- Convert C into Fortran pointer
-@fnindex C_F_POINTER
-@cindex pointer, convert C to Fortran
+@node C_FUNLOC
+@section @code{C_FUNLOC} --- Obtain the C address of a procedure
+@fnindex C_FUNLOC
+@cindex pointer, C address of procedures
@table @asis
@item @emph{Description}:
-@code{C_F_POINTER(CPTR, FPTR[, SHAPE])} assigns the target of the C pointer
-@var{CPTR} to the Fortran pointer @var{FPTR} and specifies its shape.
+@code{C_FUNLOC(x)} determines the C address of the argument.
@item @emph{Standard}:
Fortran 2003 and later
@item @emph{Class}:
-Subroutine
+Inquiry function
@item @emph{Syntax}:
-@code{CALL C_F_POINTER(CPTR, FPTR[, SHAPE])}
+@code{RESULT = C_FUNLOC(x)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{CPTR} @tab scalar of the type @code{C_PTR}. It is
-@code{INTENT(IN)}.
-@item @var{FPTR} @tab pointer interoperable with @var{cptr}. It is
-@code{INTENT(OUT)}.
-@item @var{SHAPE} @tab (Optional) Rank-one array of type @code{INTEGER}
-with @code{INTENT(IN)}. It shall be present
-if and only if @var{fptr} is an array. The size
-must be equal to the rank of @var{fptr}.
+@item @var{x} @tab Interoperable function or pointer to such function.
@end multitable
+@item @emph{Return value}:
+The return value is of type @code{C_FUNPTR} and contains the C address
+of the argument.
+
@item @emph{Example}:
@smallexample
+module x
+ use iso_c_binding
+ implicit none
+contains
+ subroutine sub(a) bind(c)
+ real(c_float) :: a
+ a = sqrt(a)+5.0
+ end subroutine sub
+end module x
program main
use iso_c_binding
+ use x
implicit none
interface
subroutine my_routine(p) bind(c,name='myC_func')
- import :: c_ptr
- type(c_ptr), intent(out) :: p
+ import :: c_funptr
+ type(c_funptr), intent(in) :: p
end subroutine
end interface
- type(c_ptr) :: cptr
- real,pointer :: a(:)
- call my_routine(cptr)
- call c_f_pointer(cptr, a, [12])
+ call my_routine(c_funloc(sub))
end program main
@end smallexample
@item @emph{See also}:
-@ref{C_LOC}, @ref{C_F_PROCPOINTER}
+@ref{C_ASSOCIATED}, @ref{C_LOC}, @ref{C_F_POINTER}, @ref{C_F_PROCPOINTER}
@end table
@@ -9749,51 +9749,6 @@ default kind.
-@node PRECISION
-@section @code{PRECISION} --- Decimal precision of a real kind
-@fnindex PRECISION
-@cindex model representation, precision
-
-@table @asis
-@item @emph{Description}:
-@code{PRECISION(X)} returns the decimal precision in the model of the
-type of @code{X}.
-
-@item @emph{Standard}:
-Fortran 95 and later
-
-@item @emph{Class}:
-Inquiry function
-
-@item @emph{Syntax}:
-@code{RESULT = PRECISION(X)}
-
-@item @emph{Arguments}:
-@multitable @columnfractions .15 .70
-@item @var{X} @tab Shall be of type @code{REAL} or @code{COMPLEX}.
-@end multitable
-
-@item @emph{Return value}:
-The return value is of type @code{INTEGER} and of the default integer
-kind.
-
-@item @emph{See also}:
-@ref{SELECTED_REAL_KIND}, @ref{RANGE}
-
-@item @emph{Example}:
-@smallexample
-program prec_and_range
- real(kind=4) :: x(2)
- complex(kind=8) :: y
-
- print *, precision(x), range(x)
- print *, precision(y), range(y)
-end program prec_and_range
-@end smallexample
-@end table
-
-
-
@node POPCNT
@section @code{POPCNT} --- Number of bits set
@fnindex POPCNT
@@ -9883,6 +9838,51 @@ end program test_population
+@node PRECISION
+@section @code{PRECISION} --- Decimal precision of a real kind
+@fnindex PRECISION
+@cindex model representation, precision
+
+@table @asis
+@item @emph{Description}:
+@code{PRECISION(X)} returns the decimal precision in the model of the
+type of @code{X}.
+
+@item @emph{Standard}:
+Fortran 95 and later
+
+@item @emph{Class}:
+Inquiry function
+
+@item @emph{Syntax}:
+@code{RESULT = PRECISION(X)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{X} @tab Shall be of type @code{REAL} or @code{COMPLEX}.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{INTEGER} and of the default integer
+kind.
+
+@item @emph{See also}:
+@ref{SELECTED_REAL_KIND}, @ref{RANGE}
+
+@item @emph{Example}:
+@smallexample
+program prec_and_range
+ real(kind=4) :: x(2)
+ complex(kind=8) :: y
+
+ print *, precision(x), range(x)
+ print *, precision(y), range(y)
+end program prec_and_range
+@end smallexample
+@end table
+
+
+
@node PRESENT
@section @code{PRESENT} --- Determine whether an optional dummy argument is specified
@fnindex PRESENT
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index ee2954e5bca..75fed2f651c 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -7547,8 +7547,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
called_dealloc_with_status = false;
gfc_init_block (&tmpblock);
- if (c->attr.allocatable
- && (c->attr.dimension || c->attr.codimension))
+ if (c->attr.allocatable && (c->attr.dimension || c->attr.codimension)
+ && !c->attr.proc_pointer)
{
comp = fold_build3_loc (input_location, COMPONENT_REF, ctype,
decl, cdecl, NULL_TREE);
@@ -7730,7 +7730,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
continue;
}
- if (c->attr.allocatable && !cmp_has_alloc_comps)
+ if (c->attr.allocatable && !c->attr.proc_pointer
+ && !cmp_has_alloc_comps)
{
rank = c->as ? c->as->rank : 0;
tmp = gfc_duplicate_allocatable (dcmp, comp, ctype, rank);
diff --git a/gcc/function.c b/gcc/function.c
index 4ce2259ef71..1b41cf2cb34 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4400,6 +4400,26 @@ invoke_set_current_function_hook (tree fndecl)
}
targetm.set_current_function (fndecl);
+
+ if (opts == optimization_default_node)
+ this_fn_optabs = this_target_optabs;
+ else
+ {
+ struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
+ if (fn->optabs == NULL)
+ {
+ if (this_target_optabs == &default_target_optabs)
+ fn->optabs = TREE_OPTIMIZATION_OPTABS (opts);
+ else
+ {
+ fn->optabs = (unsigned char *)
+ ggc_alloc_atomic (sizeof (struct target_optabs));
+ init_all_optabs ((struct target_optabs *) fn->optabs);
+ }
+ }
+ this_fn_optabs = fn->optabs ? (struct target_optabs *) fn->optabs
+ : this_target_optabs;
+ }
}
}
diff --git a/gcc/function.h b/gcc/function.h
index 89d71e592dd..53e28b768c0 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -580,6 +580,9 @@ struct GTY(()) function {
a string describing the reason for failure. */
const char * GTY((skip)) cannot_be_copied_reason;
+ /* Optabs for this function. This is of type `struct target_optabs *'. */
+ unsigned char *GTY ((atomic)) optabs;
+
/* Collected bit flags. */
/* Number of units of general registers that need saving in stdarg
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 1bb2f770d22..fb8071765dd 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -422,8 +422,8 @@ main (int argc, char **argv)
fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
fprintf (s_file, "};\n\n");
- fprintf (s_file, "void\ninit_all_optabs (void)\n{\n");
- fprintf (s_file, " bool *ena = this_target_optabs->pat_enable;\n");
+ fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
+ fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
for (i = 0; patterns.iterate (i, &p); ++i)
fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
fprintf (s_file, "}\n\n");
@@ -456,7 +456,7 @@ main (int argc, char **argv)
"raw_optab_handler (unsigned scode)\n"
"{\n"
" int i = lookup_handler (scode);\n"
- " return (i >= 0 && this_target_optabs->pat_enable[i]\n"
+ " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
" ? pats[i].icode : CODE_FOR_nothing);\n"
"}\n\n");
@@ -468,8 +468,8 @@ main (int argc, char **argv)
" int i = lookup_handler (scode);\n"
" if (i >= 0)\n"
" {\n"
- " bool ret = this_target_optabs->pat_enable[i];\n"
- " this_target_optabs->pat_enable[i] = set;\n"
+ " bool ret = this_fn_optabs->pat_enable[i];\n"
+ " this_fn_optabs->pat_enable[i] = set;\n"
" return ret;\n"
" }\n"
" else\n"
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index 09fc87b3dd1..98488e30b8b 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -945,9 +945,10 @@ write_lookup_constraint (void)
{
do
{
- printf (" if (!strncmp (str, \"%s\", %lu))\n"
+ printf (" if (!strncmp (str + 1, \"%s\", %lu))\n"
" return CONSTRAINT_%s;\n",
- c->name, (unsigned long int) c->namelen, c->c_name);
+ c->name + 1, (unsigned long int) c->namelen - 1,
+ c->c_name);
c = c->next_this_letter;
}
while (c);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 332e623f41a..9a67f3c0be3 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -725,11 +725,27 @@ initialize_node_lattices (struct cgraph_node *node)
set_all_contains_variable (plats);
}
if (dump_file && (dump_flags & TDF_DETAILS)
- && node->alias && node->thunk.thunk_p)
+ && !node->alias && !node->thunk.thunk_p)
fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
cgraph_node_name (node), node->uid,
disable ? "BOTTOM" : "VARIABLE");
}
+ if (!disable)
+ for (i = 0; i < ipa_get_param_count (info) ; i++)
+ {
+ struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ tree t = TREE_TYPE (ipa_get_param(info, i));
+
+ if (POINTER_TYPE_P (t) && TYPE_RESTRICT (t)
+ && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
+ {
+ set_lattice_to_bottom (&plats->itself);
+ if (dump_file && (dump_flags & TDF_DETAILS)
+ && !node->alias && !node->thunk.thunk_p)
+ fprintf (dump_file, "Going to ignore param %i of of %s/%i.\n",
+ i, cgraph_node_name (node), node->uid);
+ }
+ }
for (ie = node->indirect_calls; ie; ie = ie->next_callee)
if (ie->indirect_info->polymorphic)
@@ -1638,7 +1654,7 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
") -> evaluation: " HOST_WIDEST_INT_PRINT_DEC
", threshold: %i\n",
time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
- evaluation, 500);
+ evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
}
@@ -1652,7 +1668,7 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
"size: %i, freq_sum: %i) -> evaluation: "
HOST_WIDEST_INT_PRINT_DEC ", threshold: %i\n",
time_benefit, size_cost, freq_sum, evaluation,
- CGRAPH_FREQ_BASE /2);
+ PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
}
@@ -2791,12 +2807,15 @@ intersect_with_plats (struct ipcp_param_lattices *plats,
vector result while subtracting OFFSET from the individual value offsets. */
static vec<ipa_agg_jf_item_t>
-agg_replacements_to_vector (struct cgraph_node *node, HOST_WIDE_INT offset)
+agg_replacements_to_vector (struct cgraph_node *node, int index,
+ HOST_WIDE_INT offset)
{
struct ipa_agg_replacement_value *av;
vec<ipa_agg_jf_item_t> res = vNULL;
for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
+ if (av->index == index
+ && (av->offset - offset) >= 0)
{
struct ipa_agg_jf_item item;
gcc_checking_assert (av->value);
@@ -2876,7 +2895,7 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
if (agg_pass_through_permissible_p (orig_plats, jfunc))
{
if (!inter.exists ())
- inter = agg_replacements_to_vector (cs->caller, 0);
+ inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
else
intersect_with_agg_replacements (cs->caller, src_idx,
&inter, 0);
@@ -2909,9 +2928,9 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
if (caller_info->ipcp_orig_node)
{
if (!inter.exists ())
- inter = agg_replacements_to_vector (cs->caller, delta);
+ inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
else
- intersect_with_agg_replacements (cs->caller, index, &inter,
+ intersect_with_agg_replacements (cs->caller, src_idx, &inter,
delta);
}
else
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 5cc222d49f7..f68349363b0 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -2100,10 +2100,65 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
if (TREE_CODE (target) == ADDR_EXPR)
target = TREE_OPERAND (target, 0);
if (TREE_CODE (target) != FUNCTION_DECL)
- return NULL;
+ {
+ target = canonicalize_constructor_val (target, NULL);
+ if (!target || TREE_CODE (target) != FUNCTION_DECL)
+ {
+ if (dump_file)
+ fprintf (dump_file, "ipa-prop: Discovered direct call to non-function"
+ " in (%s/%i).\n",
+ cgraph_node_name (ie->caller), ie->caller->uid);
+ return NULL;
+ }
+ }
callee = cgraph_get_node (target);
- if (!callee)
- return NULL;
+
+ /* Because may-edges are not explicitely represented and vtable may be external,
+ we may create the first reference to the object in the unit. */
+ if (!callee || callee->global.inlined_to)
+ {
+ struct cgraph_node *first_clone = callee;
+
+ /* We are better to ensure we can refer to it.
+ In the case of static functions we are out of luck, since we already
+ removed its body. In the case of public functions we may or may
+ not introduce the reference. */
+ if (!canonicalize_constructor_val (target, NULL)
+ || !TREE_PUBLIC (target))
+ {
+ if (dump_file)
+ fprintf (dump_file, "ipa-prop: Discovered call to a known target "
+ "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
+ xstrdup (cgraph_node_name (ie->caller)), ie->caller->uid,
+ xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid);
+ return NULL;
+ }
+
+ /* Create symbol table node. Even if inline clone exists, we can not take
+ it as a target of non-inlined call. */
+ callee = cgraph_create_node (target);
+
+ /* OK, we previously inlined the function, then removed the offline copy and
+ now we want it back for external call. This can happen when devirtualizing
+ while inlining function called once that happens after extern inlined and
+ virtuals are already removed. In this case introduce the external node
+ and make it available for call. */
+ if (first_clone)
+ {
+ first_clone->clone_of = callee;
+ callee->clones = first_clone;
+ symtab_prevail_in_asm_name_hash ((symtab_node)callee);
+ symtab_insert_node_to_hashtable ((symtab_node)callee);
+ if (dump_file)
+ fprintf (dump_file, "ipa-prop: Introduced new external node "
+ "(%s/%i) and turned into root of the clone tree.\n",
+ xstrdup (cgraph_node_name (callee)), callee->uid);
+ }
+ else if (dump_file)
+ fprintf (dump_file, "ipa-prop: Introduced new external node "
+ "(%s/%i).\n",
+ xstrdup (cgraph_node_name (callee)), callee->uid);
+ }
ipa_check_create_node_params ();
/* We can not make edges to inline clones. It is bug that someone removed
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 228d3a28eae..05927e13b08 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -57,9 +57,9 @@ along with GCC; see the file COPYING3. If not see
to do this.
This pass only splits moves with modes that are wider than
- word_mode and ASHIFTs, LSHIFTRTs and ZERO_EXTENDs with integer
- modes that are twice the width of word_mode. The latter could be
- generalized if there was a need to do this, but the trend in
+ word_mode and ASHIFTs, LSHIFTRTs, ASHIFTRTs and ZERO_EXTENDs with
+ integer modes that are twice the width of word_mode. The latter
+ could be generalized if there was a need to do this, but the trend in
architectures is to not need this.
There are two useful preprocessor defines for use by maintainers:
@@ -152,7 +152,7 @@ compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes,
bool *splitting, enum rtx_code code,
int word_move_zero_cost, int word_move_cost)
{
- int wide_cost, narrow_cost, i;
+ int wide_cost, narrow_cost, upper_cost, i;
for (i = 0; i < BITS_PER_WORD; i++)
{
@@ -163,13 +163,20 @@ compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes,
else
narrow_cost = shift_cost (speed_p, rtxes, code, word_mode, i);
+ if (code != ASHIFTRT)
+ upper_cost = word_move_zero_cost;
+ else if (i == BITS_PER_WORD - 1)
+ upper_cost = word_move_cost;
+ else
+ upper_cost = shift_cost (speed_p, rtxes, code, word_mode,
+ BITS_PER_WORD - 1);
+
if (LOG_COSTS)
fprintf (stderr, "%s %s by %d: original cost %d, split cost %d + %d\n",
GET_MODE_NAME (twice_word_mode), GET_RTX_NAME (code),
- i + BITS_PER_WORD, wide_cost, narrow_cost,
- word_move_zero_cost);
+ i + BITS_PER_WORD, wide_cost, narrow_cost, upper_cost);
- if (FORCE_LOWERING || wide_cost >= narrow_cost + word_move_zero_cost)
+ if (FORCE_LOWERING || wide_cost >= narrow_cost + upper_cost)
splitting[i] = true;
}
}
@@ -248,6 +255,9 @@ compute_costs (bool speed_p, struct cost_rtxes *rtxes)
compute_splitting_shift (speed_p, rtxes,
choices[speed_p].splitting_lshiftrt, LSHIFTRT,
word_move_zero_cost, word_move_cost);
+ compute_splitting_shift (speed_p, rtxes,
+ choices[speed_p].splitting_ashiftrt, ASHIFTRT,
+ word_move_zero_cost, word_move_cost);
}
}
@@ -1153,6 +1163,7 @@ find_decomposable_shift_zext (rtx insn, bool speed_p)
op = SET_SRC (set);
if (GET_CODE (op) != ASHIFT
&& GET_CODE (op) != LSHIFTRT
+ && GET_CODE (op) != ASHIFTRT
&& GET_CODE (op) != ZERO_EXTEND)
return false;
@@ -1173,6 +1184,8 @@ find_decomposable_shift_zext (rtx insn, bool speed_p)
{
bool *splitting = (GET_CODE (op) == ASHIFT
? choices[speed_p].splitting_ashift
+ : GET_CODE (op) == ASHIFTRT
+ ? choices[speed_p].splitting_ashiftrt
: choices[speed_p].splitting_lshiftrt);
if (!CONST_INT_P (XEXP (op, 1))
|| !IN_RANGE (INTVAL (XEXP (op, 1)), BITS_PER_WORD,
@@ -1200,7 +1213,7 @@ resolve_shift_zext (rtx insn)
rtx op;
rtx op_operand;
rtx insns;
- rtx src_reg, dest_reg, dest_zero;
+ rtx src_reg, dest_reg, dest_upper, upper_src = NULL_RTX;
int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
set = single_set (insn);
@@ -1210,6 +1223,7 @@ resolve_shift_zext (rtx insn)
op = SET_SRC (set);
if (GET_CODE (op) != ASHIFT
&& GET_CODE (op) != LSHIFTRT
+ && GET_CODE (op) != ASHIFTRT
&& GET_CODE (op) != ZERO_EXTEND)
return NULL_RTX;
@@ -1223,7 +1237,8 @@ resolve_shift_zext (rtx insn)
/* src_reg_num is the number of the word mode register which we
are operating on. For a left shift and a zero_extend on little
endian machines this is register 0. */
- src_reg_num = GET_CODE (op) == LSHIFTRT ? 1 : 0;
+ src_reg_num = (GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT)
+ ? 1 : 0;
if (WORDS_BIG_ENDIAN
&& GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
@@ -1243,12 +1258,17 @@ resolve_shift_zext (rtx insn)
dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
GET_MODE (SET_DEST (set)),
offset1);
- dest_zero = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
- GET_MODE (SET_DEST (set)),
- offset2);
+ dest_upper = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
+ GET_MODE (SET_DEST (set)),
+ offset2);
src_reg = simplify_gen_subreg_concatn (word_mode, op_operand,
GET_MODE (op_operand),
src_offset);
+ if (GET_CODE (op) == ASHIFTRT
+ && INTVAL (XEXP (op, 1)) != 2 * BITS_PER_WORD - 1)
+ upper_src = expand_shift (RSHIFT_EXPR, word_mode, copy_rtx (src_reg),
+ BITS_PER_WORD - 1, NULL_RTX, 0);
+
if (GET_CODE (op) != ZERO_EXTEND)
{
int shift_count = INTVAL (XEXP (op, 1));
@@ -1257,12 +1277,17 @@ resolve_shift_zext (rtx insn)
LSHIFT_EXPR : RSHIFT_EXPR,
word_mode, src_reg,
shift_count - BITS_PER_WORD,
- dest_reg, 1);
+ dest_reg, GET_CODE (op) != ASHIFTRT);
}
if (dest_reg != src_reg)
emit_move_insn (dest_reg, src_reg);
- emit_move_insn (dest_zero, CONST0_RTX (word_mode));
+ if (GET_CODE (op) != ASHIFTRT)
+ emit_move_insn (dest_upper, CONST0_RTX (word_mode));
+ else if (INTVAL (XEXP (op, 1)) == 2 * BITS_PER_WORD - 1)
+ emit_move_insn (dest_upper, copy_rtx (src_reg));
+ else
+ emit_move_insn (dest_upper, upper_src);
insns = get_insns ();
end_sequence ();
@@ -1328,7 +1353,8 @@ dump_choices (bool speed_p, const char *description)
GET_MODE_NAME (twice_word_mode));
dump_shift_choices (ASHIFT, choices[speed_p].splitting_ashift);
- dump_shift_choices (LSHIFTRT, choices[speed_p].splitting_ashift);
+ dump_shift_choices (LSHIFTRT, choices[speed_p].splitting_lshiftrt);
+ dump_shift_choices (ASHIFTRT, choices[speed_p].splitting_ashiftrt);
fprintf (dump_file, "\n");
}
diff --git a/gcc/lower-subreg.h b/gcc/lower-subreg.h
index b4320826a28..16c48bf8cd8 100644
--- a/gcc/lower-subreg.h
+++ b/gcc/lower-subreg.h
@@ -34,6 +34,7 @@ struct lower_subreg_choices {
should be split. */
bool splitting_ashift[MAX_BITS_PER_WORD];
bool splitting_lshiftrt[MAX_BITS_PER_WORD];
+ bool splitting_ashiftrt[MAX_BITS_PER_WORD];
/* True if there is at least one mode that is worth splitting. */
bool something_to_do;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c1dacf487a0..c5778d1928b 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
struct target_optabs default_target_optabs;
struct target_libfuncs default_target_libfuncs;
+struct target_optabs *this_fn_optabs = &default_target_optabs;
#if SWITCHABLE_TARGET
struct target_optabs *this_target_optabs = &default_target_optabs;
struct target_libfuncs *this_target_libfuncs = &default_target_libfuncs;
@@ -6150,7 +6151,7 @@ init_optabs (void)
libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
/* Fill in the optabs with the insns we support. */
- init_all_optabs ();
+ init_all_optabs (this_fn_optabs);
/* The ffs function operates on `int'. Fall back on it if we do not
have a libgcc2 function for that width. */
@@ -6207,6 +6208,38 @@ init_optabs (void)
targetm.init_libfuncs ();
}
+/* Recompute the optabs and save them if they have changed. */
+
+void
+save_optabs_if_changed (tree fndecl)
+{
+ /* ?? If this fails, we should temporarily restore the default
+ target first (set_cfun (NULL) ??), do the rest of this function,
+ and then restore it. */
+ gcc_assert (this_target_optabs == &default_target_optabs);
+
+ struct target_optabs *tmp_optabs = (struct target_optabs *)
+ ggc_alloc_atomic (sizeof (struct target_optabs));
+ tree optnode = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+ /* Generate a new set of optabs into tmp_optabs. */
+ init_all_optabs (tmp_optabs);
+
+ /* If the optabs changed, record it. */
+ if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
+ {
+ if (TREE_OPTIMIZATION_OPTABS (optnode))
+ ggc_free (TREE_OPTIMIZATION_OPTABS (optnode));
+
+ TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
+ }
+ else
+ {
+ TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
+ ggc_free (tmp_optabs);
+ }
+}
+
/* A helper function for init_sync_libfuncs. Using the basename BASE,
install libfuncs into TAB for BASE_N for 1 <= N <= MAX. */
diff --git a/gcc/optabs.h b/gcc/optabs.h
index c08adcf454f..4de4409342d 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -76,6 +76,7 @@ struct target_optabs {
};
extern struct target_optabs default_target_optabs;
+extern struct target_optabs *this_fn_optabs;
#if SWITCHABLE_TARGET
extern struct target_optabs *this_target_optabs;
#else
diff --git a/gcc/passes.c b/gcc/passes.c
index d31f6e4dd81..cc2e9ca38f1 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1918,10 +1918,7 @@ execute_function_todo (void *data)
/* Always cleanup the CFG before trying to update SSA. */
if (flags & TODO_cleanup_cfg)
{
- bool cleanup = cleanup_tree_cfg ();
-
- if (cleanup && (cfun->curr_properties & PROP_ssa))
- flags |= TODO_remove_unused_locals;
+ cleanup_tree_cfg ();
/* When cleanup_tree_cfg merges consecutive blocks, it may
perform some simplistic propagation when removing single
diff --git a/gcc/sel-sched-dump.c b/gcc/sel-sched-dump.c
index 4b2be37796a..0dafe497add 100644
--- a/gcc/sel-sched-dump.c
+++ b/gcc/sel-sched-dump.c
@@ -91,7 +91,7 @@ restore_dump (void)
/* Functions for dumping instructions, av sets, and exprs. */
/* Default flags for dumping insns. */
-static int dump_insn_rtx_flags = DUMP_INSN_RTX_PATTERN;
+static int dump_insn_rtx_flags = DUMP_INSN_RTX_UID | DUMP_INSN_RTX_PATTERN;
/* Default flags for dumping vinsns. */
static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
@@ -136,7 +136,7 @@ dump_insn_rtx_1 (rtx insn, int flags)
sel_print ("%d;", INSN_UID (insn));
if (flags & DUMP_INSN_RTX_PATTERN)
- sel_print ("%s;", str_pattern_slim (insn));
+ sel_print ("%s;", str_pattern_slim (PATTERN (insn)));
if (flags & DUMP_INSN_RTX_BBN)
{
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 6f60d7063a3..11bf2e62c31 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "rtlhooks-def.h"
#include "emit-rtl.h"
+#include "ira.h"
#ifdef INSN_SCHEDULING
#include "sel-sched-ir.h"
@@ -2101,6 +2102,61 @@ moving_insn_creates_bookkeeping_block_p (insn_t insn,
return TRUE;
}
+/* Return true when the conflict with newly created implicit clobbers
+ between EXPR and THROUGH_INSN is found because of renaming. */
+static bool
+implicit_clobber_conflict_p (insn_t through_insn, expr_t expr)
+{
+ HARD_REG_SET temp;
+ rtx insn, reg, rhs, pat;
+ hard_reg_set_iterator hrsi;
+ unsigned regno;
+ bool valid;
+
+ /* Make a new pseudo register. */
+ reg = gen_reg_rtx (GET_MODE (EXPR_LHS (expr)));
+ max_regno = max_reg_num ();
+ maybe_extend_reg_info_p ();
+
+ /* Validate a change and bail out early. */
+ insn = EXPR_INSN_RTX (expr);
+ validate_change (insn, &SET_DEST (PATTERN (insn)), reg, true);
+ valid = verify_changes (0);
+ cancel_changes (0);
+ if (!valid)
+ {
+ if (sched_verbose >= 6)
+ sel_print ("implicit clobbers failed validation, ");
+ return true;
+ }
+
+ /* Make a new insn with it. */
+ rhs = copy_rtx (VINSN_RHS (EXPR_VINSN (expr)));
+ pat = gen_rtx_SET (VOIDmode, reg, rhs);
+ start_sequence ();
+ insn = emit_insn (pat);
+ end_sequence ();
+
+ /* Calculate implicit clobbers. */
+ extract_insn (insn);
+ preprocess_constraints ();
+ ira_implicitly_set_insn_hard_regs (&temp);
+ AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
+
+ /* If any implicit clobber registers intersect with regular ones in
+ through_insn, we have a dependency and thus bail out. */
+ EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi)
+ {
+ vinsn_t vi = INSN_VINSN (through_insn);
+ if (bitmap_bit_p (VINSN_REG_SETS (vi), regno)
+ || bitmap_bit_p (VINSN_REG_CLOBBERS (vi), regno)
+ || bitmap_bit_p (VINSN_REG_USES (vi), regno))
+ return true;
+ }
+
+ return false;
+}
+
/* Modifies EXPR so it can be moved through the THROUGH_INSN,
performing necessary transformations. Record the type of transformation
made in PTRANS_TYPE, when it is not NULL. When INSIDE_INSN_GROUP,
@@ -2233,6 +2289,17 @@ moveup_expr (expr_t expr, insn_t through_insn, bool inside_insn_group,
if (!enable_schedule_as_rhs_p || !EXPR_SEPARABLE_P (expr))
return MOVEUP_EXPR_NULL;
+ /* When renaming a hard register to a pseudo before reload, extra
+ dependencies can occur from the implicit clobbers of the insn.
+ Filter out such cases here. */
+ if (!reload_completed && REG_P (EXPR_LHS (expr))
+ && HARD_REGISTER_P (EXPR_LHS (expr))
+ && implicit_clobber_conflict_p (through_insn, expr))
+ {
+ if (sched_verbose >= 6)
+ sel_print ("implicit clobbers conflict detected, ");
+ return MOVEUP_EXPR_NULL;
+ }
EXPR_TARGET_AVAILABLE (expr) = false;
was_target_conflict = true;
as_rhs = true;
diff --git a/gcc/target-globals.c b/gcc/target-globals.c
index 533a8e58374..d72495da26d 100644
--- a/gcc/target-globals.c
+++ b/gcc/target-globals.c
@@ -91,4 +91,33 @@ save_target_globals (void)
return g;
}
+/* Like save_target_globals() above, but set *this_target_optabs
+ correctly when a previous function has changed
+ *this_target_optabs. */
+
+struct target_globals *
+save_target_globals_default_opts ()
+{
+ struct target_globals *globals;
+
+ if (optimization_current_node != optimization_default_node)
+ {
+ tree opts = optimization_current_node;
+ /* Temporarily switch to the default optimization node, so that
+ *this_target_optabs is set to the default, not reflecting
+ whatever a previous function used for the optimize
+ attribute. */
+ optimization_current_node = optimization_default_node;
+ cl_optimization_restore
+ (&global_options,
+ TREE_OPTIMIZATION (optimization_default_node));
+ globals = save_target_globals ();
+ optimization_current_node = opts;
+ cl_optimization_restore (&global_options,
+ TREE_OPTIMIZATION (opts));
+ return globals;
+ }
+ return save_target_globals ();
+}
+
#endif
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index 110f879cd7b..04eba530abe 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -60,6 +60,7 @@ struct GTY(()) target_globals {
extern struct target_globals default_target_globals;
extern struct target_globals *save_target_globals (void);
+extern struct target_globals *save_target_globals_default_opts (void);
static inline void
restore_target_globals (struct target_globals *g)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fe995e8e0ea..7df8623d288 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,98 @@
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/56420
+ * gcc.dg/torture/pr56420.c: New test.
+
+2013-02-20 Aldy Hernandez <aldyh@redhat.com>
+
+ PR middle-end/56108
+ * gcc.dg/tm/memopt-1.c: Declare functions transaction_safe.
+
+2013-02-21 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/56310
+ * g++.dg/ipa/pr56310.C: New test.
+
+2013-02-21 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/56385
+ * gfortran.dg/proc_ptr_comp_37.f90: New.
+
+2013-02-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56415
+ Revert
+ 2013-02-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56273
+ * g++.dg/warn/Warray-bounds-6.C: New testcase.
+ * gcc.dg/tree-ssa/pr21559.c: Adjust.
+ * gcc.dg/tree-ssa/vrp17.c: Likewise.
+ * gcc.dg/tree-ssa/vrp18.c: Likewise.
+ * gcc.dg/tree-ssa/vrp23.c: Likewise.
+ * gcc.dg/tree-ssa/vrp24.c: Likewise.
+
+2013-02-21 Marek Polacek <polacek@redhat.com>
+
+ PR tree-optimization/56398
+ * g++.dg/torture/pr56398.C: New test.
+
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR inline-asm/56405
+ * gcc.c-torture/compile/pr56405.c: New test.
+
+2013-02-20 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/56265
+ * testsuite/g++.dg/ipa/devirt-11.C: New testcase.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/forwprop-8.c: Adjust.
+
+2013-02-20 Richard Biener <rguenther@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56396
+ * gcc.dg/pr56396.c: New testcase.
+
+2013-02-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56373
+ * g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C: New.
+
+2013-02-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56384
+ * gcc.dg/torture/pr56384.c: New testcase.
+
+2013-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/56350
+ * gcc.dg/pr56350.c: New test.
+
+ PR tree-optimization/56381
+ * g++.dg/opt/pr56381.C: New test.
+
+2013-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR pch/54117
+ * lib/dg-pch.exp (pch-init, pch-finish,
+ check_effective_target_pch_supported_debug): New procs.
+ (dg-flags-pch): If $pch_unsupported, make tests UNSUPPORTED.
+ Likewise if $pch_unsupported_debug and $flags include -g.
+ Skip FAILs about missing *.gch file if $pch_unsupported_debug
+ and dg-require-effective-target pch_unsupported_debug.
+ * g++.dg/pch/pch.exp: Call pch-init and pch-finish.
+ * objc.dg/pch/pch.exp: Likewise.
+ * gcc.dg/pch/pch.exp: Likewise.
+ * gcc.dg/pch/valid-1.c: Add dg-require-effective-target
+ pch_unsupported_debug.
+ * gcc.dg/pch/valid-1.hs: Likewise.
+ * gcc.dg/pch/valid-1b.c: Likewise.
+ * gcc.dg/pch/valid-1b.hs: Likewise.
+
2013-02-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/56366
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C b/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C
new file mode 100644
index 00000000000..eea2c2fcf31
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wzero-as-null-pointer-constant-2.C
@@ -0,0 +1,14 @@
+// PR c++/56373
+// { dg-options "-std=c++11 -Wzero-as-null-pointer-constant" }
+
+struct shared_ptr
+{
+ shared_ptr(decltype(nullptr));
+};
+
+void f()
+{
+ shared_ptr a = 0; // { dg-warning "zero as null pointer" }
+ shared_ptr b(0); // { dg-warning "zero as null pointer" }
+ shared_ptr c{0}; // { dg-warning "zero as null pointer" }
+}
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-11.C b/gcc/testsuite/g++.dg/ipa/devirt-11.C
new file mode 100644
index 00000000000..c139f8f9633
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-11.C
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-inline" } */
+int baz ();
+struct A
+{
+ virtual int fn2 () = 0;
+ virtual int *fn3 ();
+ double *fn4 ();
+ int fn5 (int);
+ template <class T>
+ void fn1 (A &, T) { fn3 (); fn4 (); fn2 (); }
+};
+struct B : A
+{
+ int fn2 () { return 6; }
+ void fn3 (int, double);
+ B (bool = true);
+ B (int, int);
+};
+template <typename T>
+void
+foo (B &x, A &y, A &z)
+{
+ y.fn2 ();
+ z.fn2 ();
+ int i = baz ();
+ int j = (y.fn3 ())[i];
+ x.fn3 (j, (y.fn4 ())[i] + (z.fn4 ())[z.fn5 (j)]);
+}
+inline B
+operator+ (A &y, A &z)
+{
+ B x;
+ foo<int> (x, y, z);
+ return x;
+}
+void
+bar ()
+{
+ B a, b, c (4, 0), d;
+ a.fn1 (b, .6);
+ baz ();
+ c + d;
+}
+/* While inlining function called once we should devirtualize a new call to fn2
+ and two to fn3. While doing so the new symbol for fn2 needs to be
+ introduced. */
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */
+/* { dg-final { scan-ipa-dump-times "and turned into root of the clone tree" 1 "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/pr56310.C b/gcc/testsuite/g++.dg/ipa/pr56310.C
new file mode 100644
index 00000000000..af6979c8fd3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr56310.C
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fipa-cp -std=gnu++0x -fno-early-inlining -fipa-cp-clone --param=ipa-cp-eval-threshold=1" } */
+
+void bar (void *, void *);
+
+struct C
+{
+ constexpr C ():p (0)
+ {
+ }
+ void *get ()
+ {
+ return p;
+ }
+ void *p;
+};
+
+struct B:C
+{
+};
+
+struct A
+{
+ void f (B * x, B * y)
+ {
+ bar (x->get (), y->get ());
+ }
+};
+
+void
+foo ()
+{
+ A a;
+ B b;
+ a.f (&b, &b);
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr56381.C b/gcc/testsuite/g++.dg/opt/pr56381.C
new file mode 100644
index 00000000000..38a121d979a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr56381.C
@@ -0,0 +1,156 @@
+// PR tree-optimization/56381
+// { dg-do compile }
+// { dg-options "-std=c++11 -O2 -w" }
+
+template <class>
+class intrusive_ptr {};
+class BasicReferenceCounted
+{
+};
+template <class T>
+class ReferenceCountingPointer : intrusive_ptr <T>
+{
+};
+typedef BasicReferenceCounted ReferenceCountedInConditions;
+class PointTag;
+template <typename T, typename>
+struct PreciseFloatType
+{
+ typedef T Type;
+};
+template <typename T, int N>
+struct ExtVecTraits
+{
+ typedef T __attribute__ ((vector_size (N * sizeof (T)))) type;
+};
+template <typename T, int N>
+using ExtVec = typename ExtVecTraits <T, N>::type;
+template <typename T> using Vec4 = ExtVec <T, 4>;
+template <typename Vec>
+Vec cross3 (Vec x, Vec y)
+{
+ Vec x1200 = (Vec) { x[2], x[0] };
+ Vec y2010 { y[2], y[0], y[1], y[0] };
+ Vec x2010 = (Vec) { x[2], x[0], x[1], x[0] };
+ Vec y1200 = (Vec) { y[1], y[0] };
+ return x1200 * y2010 - x2010 * y1200;
+}
+template <typename T>
+struct Rot3
+{
+ typedef Vec4 <T> Vec;
+ Vec axis[3];
+};
+class Basic2DVector
+{
+};
+template <typename T>
+struct Basic3DVector
+{
+ typedef Vec4 <T> MathVector;
+ Basic3DVector (MathVector iv) : v { (iv[0]), (iv[1]), (iv[2]), (iv[3]) } {}
+ T mag2 () {}
+ Basic3DVector unit ()
+ {
+ T my_mag = mag2 ();
+ return (my_mag) ? (*this) * (T () / (my_mag)) : *this;
+ }
+ Basic3DVector
+ cross (Basic3DVector lh) { return cross3 (v, lh.v); }
+ Vec4 <T> v;
+};
+template <class T>
+Basic3DVector <T> operator * (Basic3DVector <T>, T);
+template <class T, class, class>
+struct PV3DBase
+{
+ typedef Basic3DVector <T> BasicVectorType;
+ template <class U>
+ PV3DBase (Basic3DVector <U> v) : theVector (v) {}
+ BasicVectorType basicVector () { return theVector; }
+ T x ();
+ T y ();
+ BasicVectorType theVector;
+};
+class VectorTag;
+template <class T, class FrameTag>
+struct Vector3DBase:public PV3DBase <T, VectorTag, FrameTag>
+{
+ typedef PV3DBase <T, VectorTag, FrameTag> BaseClass;
+ template <class U>
+ Vector3DBase (Basic3DVector <U> v) : BaseClass (v) {}
+ Vector3DBase unit () { return (this->basicVector ().unit ()); }
+ template <class U>
+ Vector3DBase <typename PreciseFloatType <T, U>::Type, FrameTag> cross (Vector3DBase <U, FrameTag> v)
+ {
+ return (this->theVector.cross (v.basicVector ()));
+ }
+};
+template <class T, class FrameTag>
+class Point3DBase : public PV3DBase <T, PointTag, FrameTag>
+{
+};
+template <typename T, typename U, class Frame>
+Vector3DBase <typename PreciseFloatType <T, U>::Type, Frame> operator - (Point3DBase <T, Frame>, Point3DBase <U, Frame>);
+class GlobalTag;
+template <class T>
+struct TkRotation
+{
+ typedef Vector3DBase <T, GlobalTag> GlobalVector;
+ TkRotation (GlobalVector aX, GlobalVector aY)
+ {
+ GlobalVector uX = aX.unit ();
+ GlobalVector uY = aY.unit ();
+ GlobalVector uZ (uX.cross (uY));
+ rot.axis[2] = uZ.basicVector ().v;
+ }
+ Basic3DVector <T> z ();
+ Rot3 <T> rot;
+};
+template <class T>
+struct GloballyPositioned
+{
+ typedef Point3DBase <T, GlobalTag> PositionType;
+ typedef TkRotation <T> RotationType;
+ typedef Point3DBase <T, GlobalTag> GlobalPoint;
+ typedef Vector3DBase <T, GlobalTag> GlobalVector;
+ T iniPhi () { return 999.9978; }
+ GloballyPositioned (PositionType pos, RotationType rot) : thePos (pos), theRot (rot) { resetCache (); }
+ PositionType position () const;
+ RotationType rotation () const;
+ PositionType thePos;
+ RotationType theRot;
+ void resetCache ()
+ {
+ if ((thePos.x () == 0.) && (thePos.y () == 0.))
+ thePhi = 0.;
+ else
+ thePhi = iniPhi ();
+ }
+ T thePhi;
+};
+class Plane;
+using TangentPlane = Plane;
+struct Surface : public GloballyPositioned <float>, ReferenceCountedInConditions
+{
+ typedef GloballyPositioned <float> Base;
+ Surface (PositionType pos, RotationType rot):
+ Base (pos, rot) {}
+};
+struct Plane : Surface
+{
+ template <typename ... Args>
+ Plane (Args ... args):
+ Surface ((args) ...) {}
+};
+class Cylinder : Surface
+{
+ void tangentPlane (const GlobalPoint &) const;
+};
+void
+Cylinder::tangentPlane (const GlobalPoint & aPoint) const
+{
+ GlobalVector yPlane (rotation ().z ());
+ GlobalVector xPlane (yPlane.cross (aPoint - position ()));
+ new TangentPlane (aPoint, RotationType (xPlane, yPlane));
+}
diff --git a/gcc/testsuite/g++.dg/pch/pch.exp b/gcc/testsuite/g++.dg/pch/pch.exp
index 0c5e13319ee..db67c24f5b9 100644
--- a/gcc/testsuite/g++.dg/pch/pch.exp
+++ b/gcc/testsuite/g++.dg/pch/pch.exp
@@ -23,6 +23,7 @@ load_lib dg-pch.exp
# Initialize `dg'.
dg-init
+pch-init
set old_dg_do_what_default "${dg-do-what-default}"
@@ -36,4 +37,5 @@ foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.C]] {
set dg-do-what-default "$old_dg_do_what_default"
# All done.
+pch-finish
dg-finish
diff --git a/gcc/testsuite/g++.dg/torture/pr56398.C b/gcc/testsuite/g++.dg/torture/pr56398.C
new file mode 100644
index 00000000000..5b7bcf279b2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr56398.C
@@ -0,0 +1,22 @@
+// { dg-do compile }
+// { dg-options "-g" }
+
+namespace
+{
+#0 "/usr/include/c/4.8/bits/postypes.h" 3
+}
+
+vtkpow (int b)
+{
+ int a1;
+ int b1;
+ int c;
+ while (b1)
+ {
+ while (b)
+ b1 = 0;
+ b1 = b1 - 1;
+ c = c * a1;
+ }
+ return c;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C
deleted file mode 100644
index ee2862f1ec1..00000000000
--- a/gcc/testsuite/g++.dg/warn/Warray-bounds-6.C
+++ /dev/null
@@ -1,30 +0,0 @@
-// { dg-do compile }
-// { dg-options "-O3 -Warray-bounds" }
-
-struct type {
- bool a, b;
- bool get_b() { return b; }
-};
-
-type stuff[9u];
-
-void bar();
-
-void foo() {
-
- for(unsigned i = 0u; i < 9u; i++) {
-
- if(!stuff[i].a) {
- continue;
- }
-
- bar();
-
- for(unsigned j = i + 1u; j < 9u; j++) {
- if(stuff[j].a && stuff[j].get_b()) { // { dg-bogus "array bounds" }
- return;
- }
- }
-
- }
-}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr52555.c b/gcc/testsuite/gcc.c-torture/compile/pr52555.c
new file mode 100644
index 00000000000..701683488df
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr52555.c
@@ -0,0 +1,10 @@
+/* { dg-options "-ffast-math" } */
+
+float farg;
+unsigned val;
+
+void __attribute__((optimize("O")))
+test()
+{
+ val = __builtin_ceilf(farg);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr56405.c b/gcc/testsuite/gcc.c-torture/compile/pr56405.c
new file mode 100644
index 00000000000..6e6a56e156c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr56405.c
@@ -0,0 +1,7 @@
+/* PR inline-asm/56405 */
+
+void
+foo (void)
+{
+ asm volatile ("" : "+m" (*(volatile unsigned short *) 0x1001UL));
+}
diff --git a/gcc/testsuite/gcc.dg/pch/pch.exp b/gcc/testsuite/gcc.dg/pch/pch.exp
index 4144243a7a1..7bf64df172c 100644
--- a/gcc/testsuite/gcc.dg/pch/pch.exp
+++ b/gcc/testsuite/gcc.dg/pch/pch.exp
@@ -26,6 +26,7 @@ load_lib torture-options.exp
dg-init
torture-init
set-torture-options $DG_TORTURE_OPTIONS
+pch-init
set old_dg_do_what_default "${dg-do-what-default}"
@@ -59,5 +60,6 @@ file delete $testh
set dg-do-what-default "$old_dg_do_what_default"
# All done.
+pch-finish
torture-finish
dg-finish
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.c b/gcc/testsuite/gcc.dg/pch/valid-1.c
index b7f22d0dc17..d445c47d6f3 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-1.c
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g" } */
#include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g" } */
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.hs b/gcc/testsuite/gcc.dg/pch/valid-1.hs
index e1ed11df4cc..20d9f65dd72 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1.hs
+++ b/gcc/testsuite/gcc.dg/pch/valid-1.hs
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g0" } */
extern int x;
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1b.c b/gcc/testsuite/gcc.dg/pch/valid-1b.c
index a2709967c07..3113d0f744d 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1b.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-1b.c
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g0" } */
#include "valid-1b.h"
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1b.hs b/gcc/testsuite/gcc.dg/pch/valid-1b.hs
index 6dc358735a7..93b2256e355 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1b.hs
+++ b/gcc/testsuite/gcc.dg/pch/valid-1b.hs
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target pch_supported_debug } */
/* { dg-options "-I. -Winvalid-pch -g" } */
extern int x;
diff --git a/gcc/testsuite/gcc.dg/pr56350.c b/gcc/testsuite/gcc.dg/pr56350.c
new file mode 100644
index 00000000000..899a507ee8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr56350.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/56350 */
+/* { dg-do compile } */
+/* { dg-options "-O -ftree-vectorize" } */
+
+int a, b, c;
+
+void
+f (void)
+{
+ for (; c; c++)
+ for (b = 0; b < 2; b++)
+ a /= 8;
+}
diff --git a/gcc/testsuite/gcc.dg/pr56396.c b/gcc/testsuite/gcc.dg/pr56396.c
new file mode 100644
index 00000000000..d2ec8fa9bff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr56396.c
@@ -0,0 +1,22 @@
+/* PR tree-optimization/56396 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic -g" } */
+
+struct S { char *s; int z; };
+struct T { int t; } *c, u;
+void bar (int, const char *);
+
+inline void *
+foo (void *x, char *y, int z)
+{
+ struct S s;
+ char b[256];
+ s.s = b;
+ s.z = __builtin___sprintf_chk (s.s, 1, __builtin_object_size (s.s, 2), "Require");
+ if (s.z < 0)
+ bar (u.t | c->t, "rls");
+ if (foo (x, s.s, s.z))
+ {
+ }
+ return (void *) 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tm/memopt-1.c b/gcc/testsuite/gcc.dg/tm/memopt-1.c
index b78a6d417dc..c5ac5ced56c 100644
--- a/gcc/testsuite/gcc.dg/tm/memopt-1.c
+++ b/gcc/testsuite/gcc.dg/tm/memopt-1.c
@@ -2,8 +2,8 @@
/* { dg-options "-fgnu-tm -O -fdump-tree-tmmemopt" } */
long g, xxx, yyy;
-extern george() __attribute__((transaction_callable));
-extern ringo(long int);
+extern george() __attribute__((transaction_safe));
+extern ringo(long int) __attribute__((transaction_safe));
int i;
f()
diff --git a/gcc/testsuite/gcc.dg/tm/pr56108.c b/gcc/testsuite/gcc.dg/tm/pr56108.c
new file mode 100644
index 00000000000..81ff574cd47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tm/pr56108.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fgnu-tm -O" } */
+
+int
+main()
+{
+ __transaction_relaxed { __asm__(""); }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr56384.c b/gcc/testsuite/gcc.dg/torture/pr56384.c
new file mode 100644
index 00000000000..ef3cf0536bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr56384.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+int a, c;
+
+void f(void)
+{
+ unsigned char b;
+
+ if(a)
+ {
+ for(; b < 1; b++);
+lbl1:
+ c = (b |= 0) ^ (b || a);
+ }
+
+ if((a = b))
+ {
+ b = c;
+ goto lbl1;
+ }
+
+ b = 5;
+ goto lbl1;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr56420.c b/gcc/testsuite/gcc.dg/torture/pr56420.c
new file mode 100644
index 00000000000..6fa1a803dd6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr56420.c
@@ -0,0 +1,37 @@
+/* PR middle-end/56420 */
+/* { dg-do run { target int128 } } */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) __uint128_t
+foo (__uint128_t x)
+{
+ return x * (((__uint128_t) -1) << 63);
+}
+
+__attribute__((noinline, noclone)) __uint128_t
+bar (__uint128_t x)
+{
+ return x * (((__uint128_t) 1) << 63);
+}
+
+__attribute__((noinline, noclone)) __uint128_t
+baz (__uint128_t x)
+{
+ return x * -(((__uint128_t) 1) << 62);
+}
+
+int
+main ()
+{
+ if (foo (1) != (((__uint128_t) -1) << 63)
+ || foo (8) != (((__uint128_t) -1) << 66))
+ abort ();
+ if (bar (1) != (((__uint128_t) 1) << 63)
+ || bar (8) != (((__uint128_t) 1) << 66))
+ abort ();
+ if (baz (1) != -(((__uint128_t) 1) << 62)
+ || baz (8) != ((-(((__uint128_t) 1) << 62)) << 3))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c
index fc74297242c..1c780c834c5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-8.c
@@ -11,6 +11,5 @@ int foo(struct X *q)
/* We should have propragated &q->a into (*pointer). */
-/* { dg-final { scan-tree-dump-times "pointer" 0 "forwprop1"} } */
-/* { dg-final { scan-tree-dump "\\\[0\\\]" "forwprop1" } } */
+/* { dg-final { scan-tree-dump "q_.\\\(D\\\)\\\]\\\[0\\\];" "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
index d7d3bab154d..34f4a01db00 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21559.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
static int blocksize = 4096;
@@ -32,7 +32,7 @@ void foo (void)
/* First, we should simplify the bits < 0 test within the loop. */
-/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
/* Second, we should thread the edge out of the loop via the break
statement. We also realize that the final bytes == 0 test is useless,
@@ -40,4 +40,4 @@ void foo (void)
/* { dg-final { scan-tree-dump-times "Threaded jump" 3 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
-/* { dg-final { cleanup-tree-dump "vrp2" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c
index 2f112ae268d..c04b9ba7843 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp17.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-tail-merge -fdump-tree-vrp2" } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
extern void abort (void) __attribute__ ((__noreturn__));
union tree_node;
@@ -27,5 +27,6 @@ gimplify_for_stmt (tree stmt)
abort ();
}
-/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
-/* { dg-final { cleanup-tree-dump "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c
index 610dd44cf2f..a3cc536ae56 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp18.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp2" } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
static int blocksize = 4096;
@@ -30,5 +30,5 @@ void foo (void)
eof_reached = 1;
}
-/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
-/* { dg-final { cleanup-tree-dump "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
index 6bca02b44e1..77899a65fca 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp2-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
blah (int code1, int code2)
{
@@ -40,5 +40,6 @@ L8:
/* The n_sets > 0 test can be simplified into n_sets == 1 since the
only way to reach the test is when n_sets <= 1, and the only value
which satisfies both conditions is n_sets == 1. */
-/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp2" } } */
-/* { dg-final { cleanup-tree-dump "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
index 28e1a924f54..85e5b62d148 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp2-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+
struct rtx_def;
typedef struct rtx_def *rtx;
@@ -85,5 +86,6 @@ L7:
The second n_sets > 0 test can also be simplified into n_sets == 1
as the only way to reach the tests is when n_sets <= 1 and the only
value which satisfies both conditions is n_sets == 1. */
-/* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp2" } } */
-/* { dg-final { cleanup-tree-dump "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_37.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_37.f90
new file mode 100644
index 00000000000..9695b96066c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_37.f90
@@ -0,0 +1,25 @@
+! { dg-do compile }
+!
+! PR 56385: [4.6/4.7/4.8 Regression] [OOP] ICE with allocatable function result in a procedure-pointer component
+!
+! Contributed by Vladimir Fuka <vladimir.fuka@gmail.com>
+
+ implicit none
+
+ type :: TGeometricShape
+ end type
+
+ type :: TVolumeSourceBody
+ class(TGeometricShape), allocatable :: GeometricShape
+ procedure(scalar_flux_interface), pointer :: get_scalar_flux
+ end type
+
+ abstract interface
+ function scalar_flux_interface(self) result(res)
+ import
+ real, allocatable :: res(:)
+ class(TVolumeSourceBody), intent(in) :: self
+ end function
+ end interface
+
+end
diff --git a/gcc/testsuite/lib/dg-pch.exp b/gcc/testsuite/lib/dg-pch.exp
index d6a55d89e12..1b3591a7506 100644
--- a/gcc/testsuite/lib/dg-pch.exp
+++ b/gcc/testsuite/lib/dg-pch.exp
@@ -16,8 +16,49 @@
load_lib copy-file.exp
+proc pch-init { args } {
+ global pch_unsupported_debug pch_unsupported
+
+ if [info exists pch_unsupported_debug] {
+ error "pch-init: pch_unsupported_debug is not empty as expected"
+ }
+ if [info exists pch_unsupported] {
+ error "pch-init: pch_unsupported is not empty as expected"
+ }
+
+ set result [check_compile pchtest object "int i;" "-g -x c-header"]
+ set pch_unsupported_debug \
+ [regexp "debug format cannot be used with pre-compiled headers" \
+ [lindex $result 0]]
+
+ set pch_unsupported 0
+ if { $pch_unsupported_debug } {
+ verbose -log "pch is unsupported with the debug info format"
+
+ set result [check_compile pchtest object "int i;" "-x c-header"]
+ set pch_unsupported \
+ [regexp "debug format cannot be used with pre-compiled headers" \
+ [lindex $result 0]]
+ }
+}
+
+proc pch-finish { args } {
+ global pch_unsupported_debug pch_unsupported
+ unset pch_unsupported_debug
+ unset pch_unsupported
+}
+
+proc check_effective_target_pch_supported_debug { } {
+ global pch_unsupported_debug
+ if { $pch_unsupported_debug } {
+ return 0
+ }
+ return 1
+}
+
proc dg-flags-pch { subdir test otherflags options suffix } {
global runtests dg-do-what-default
+ global pch_unsupported_debug pch_unsupported
# If we're only testing specific files and this isn't one of them, skip it.
if ![runtest_file_p $runtests $test] {
@@ -35,6 +76,13 @@ proc dg-flags-pch { subdir test otherflags options suffix } {
foreach flags $options {
verbose "Testing $nshort, $otherflags $flags" 1
+ if { $pch_unsupported != 0 \
+ || ( $pch_unsupported_debug != 0 && [regexp " -g" " $flags"] ) } {
+ verbose -log "$nshort unsupported because debug format conflicts with PCH"
+ unsupported "$nshort $flags"
+ continue
+ }
+
# For the header files, the default is to precompile.
set dg-do-what-default precompile
catch { file_on_host delete "$bname$suffix" }
@@ -78,7 +126,8 @@ proc dg-flags-pch { subdir test otherflags options suffix } {
fail "$nshort $flags assembly comparison"
}
}
- } else {
+ } elseif { $pch_unsupported_debug == 0 \
+ || [llength [grep $test "{\[ \t\]\+dg-require-effective-target\[ \t\]\+pch_supported_debug\[ \t\]\+.*\[ \t\]\+}"]] > 0 } {
verbose -log "pch file '$bname$suffix.gch' missing"
fail "$nshort $flags"
if { !$have_errs } {
diff --git a/gcc/testsuite/objc.dg/pch/pch.exp b/gcc/testsuite/objc.dg/pch/pch.exp
index 90b5b17d2a9..e380390bba6 100644
--- a/gcc/testsuite/objc.dg/pch/pch.exp
+++ b/gcc/testsuite/objc.dg/pch/pch.exp
@@ -24,8 +24,8 @@ load_lib torture-options.exp
# Initialize `dg'.
dg-init
-
torture-init
+pch-init
set-torture-options $DG_TORTURE_OPTIONS
@@ -59,5 +59,6 @@ if [istarget "*-*-darwin*" ] {
set dg-do-what-default "$old_dg_do_what_default"
# All done.
+pch-finish
torture-finish
dg-finish
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index dd3918edb1b..71eaa4464e0 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2859,8 +2859,23 @@ execute_tm_mark (void)
// Expand memory operations into calls into the runtime.
// This collects log entries as well.
FOR_EACH_VEC_ELT (bb_regions, i, r)
- if (r != NULL)
- expand_block_tm (r, BASIC_BLOCK (i));
+ {
+ if (r != NULL)
+ {
+ if (r->transaction_stmt)
+ {
+ unsigned sub = gimple_transaction_subcode (r->transaction_stmt);
+
+ /* If we're sure to go irrevocable, there won't be
+ anything to expand, since the run-time will go
+ irrevocable right away. */
+ if (sub & GTMA_DOES_GO_IRREVOCABLE
+ && sub & GTMA_MAY_ENTER_IRREVOCABLE)
+ continue;
+ }
+ expand_block_tm (r, BASIC_BLOCK (i));
+ }
+ }
bb_regions.release ();
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index bc7e23f786a..9b6186e3393 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -898,11 +898,10 @@ tree_call_cdce (void)
/* As we introduced new control-flow we need to insert PHI-nodes
for the call-clobbers of the remaining call. */
mark_virtual_operands_for_renaming (cfun);
- return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
- | TODO_remove_unused_locals);
+ return TODO_update_ssa;
}
- else
- return 0;
+
+ return 0;
}
static bool
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d8f03a1a343..a64bffcaec7 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -162,6 +162,7 @@ typedef struct prop_value_d prop_value_t;
memory reference used to store (i.e., the LHS of the assignment
doing the store). */
static prop_value_t *const_val;
+static unsigned n_const_val;
static void canonicalize_float_value (prop_value_t *);
static bool ccp_fold_stmt (gimple_stmt_iterator *);
@@ -295,7 +296,8 @@ get_value (tree var)
{
prop_value_t *val;
- if (const_val == NULL)
+ if (const_val == NULL
+ || SSA_NAME_VERSION (var) >= n_const_val)
return NULL;
val = &const_val[SSA_NAME_VERSION (var)];
@@ -713,7 +715,8 @@ ccp_initialize (void)
{
basic_block bb;
- const_val = XCNEWVEC (prop_value_t, num_ssa_names);
+ n_const_val = num_ssa_names;
+ const_val = XCNEWVEC (prop_value_t, n_const_val);
/* Initialize simulation flags for PHI nodes and statements. */
FOR_EACH_BB (bb)
@@ -2105,7 +2108,7 @@ do_ssa_ccp (void)
ccp_initialize ();
ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node);
if (ccp_finalize ())
- todo = (TODO_cleanup_cfg | TODO_update_ssa | TODO_remove_unused_locals);
+ todo = (TODO_cleanup_cfg | TODO_update_ssa);
free_dominance_info (CDI_DOMINATORS);
return todo;
}
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 551ebe3f0ed..75a415454de 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -280,6 +280,7 @@ struct prop_value_d {
typedef struct prop_value_d prop_value_t;
static prop_value_t *copy_of;
+static unsigned n_copy_of;
/* Return true if this statement may generate a useful copy. */
@@ -664,7 +665,8 @@ init_copy_prop (void)
{
basic_block bb;
- copy_of = XCNEWVEC (prop_value_t, num_ssa_names);
+ n_copy_of = num_ssa_names;
+ copy_of = XCNEWVEC (prop_value_t, n_copy_of);
FOR_EACH_BB (bb)
{
@@ -728,7 +730,10 @@ init_copy_prop (void)
static tree
get_value (tree name)
{
- tree val = copy_of[SSA_NAME_VERSION (name)].value;
+ tree val;
+ if (SSA_NAME_VERSION (name) >= n_copy_of)
+ return NULL_TREE;
+ val = copy_of[SSA_NAME_VERSION (name)].value;
if (val && val != name)
return val;
return NULL_TREE;
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 5348c57434f..6f49b7ecf5a 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -113,7 +113,7 @@ static struct
/* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid.
Choose a representative for the partition, and send debug info to DEBUG. */
-static bool
+static void
copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
int p1, p2, p3;
@@ -146,7 +146,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : Already coalesced.\n");
- return false;
+ return;
}
rep1 = partition_to_var (map, p1);
@@ -154,7 +154,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
root1 = SSA_NAME_VAR (rep1);
root2 = SSA_NAME_VAR (rep2);
if (!root1 && !root2)
- return false;
+ return;
/* Don't coalesce if one of the variables occurs in an abnormal PHI. */
abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1)
@@ -163,7 +163,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : Abnormal PHI barrier. No coalesce.\n");
- return false;
+ return;
}
/* Partitions already have the same root, simply merge them. */
@@ -172,7 +172,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
p1 = partition_union (map->var_partition, p1, p2);
if (debug)
fprintf (debug, " : Same root, coalesced --> P%d.\n", p1);
- return false;
+ return;
}
/* Never attempt to coalesce 2 different parameters. */
@@ -181,7 +181,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n");
- return false;
+ return;
}
if ((root1 && TREE_CODE (root1) == RESULT_DECL)
@@ -189,7 +189,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n");
- return false;
+ return;
}
ign1 = !root1 || (TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1));
@@ -206,7 +206,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : 2 different USER vars. No coalesce.\n");
- return false;
+ return;
}
else
ign2 = true;
@@ -220,7 +220,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : 2 default defs. No coalesce.\n");
- return false;
+ return;
}
else
{
@@ -240,7 +240,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : Choosen variable has no root. No coalesce.\n");
- return false;
+ return;
}
/* Don't coalesce if the new chosen root variable would be read-only.
@@ -253,7 +253,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : Readonly variable. No coalesce.\n");
- return false;
+ return;
}
/* Don't coalesce if the two variables aren't type compatible . */
@@ -266,7 +266,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
{
if (debug)
fprintf (debug, " : Incompatible types. No coalesce.\n");
- return false;
+ return;
}
/* Merge the two partitions. */
@@ -288,7 +288,6 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
TDF_SLIM);
fprintf (debug, "\n");
}
- return true;
}
@@ -308,7 +307,6 @@ rename_ssa_copies (void)
gimple stmt, phi;
unsigned x;
FILE *debug;
- bool updated = false;
memset (&stats, 0, sizeof (stats));
@@ -330,7 +328,7 @@ rename_ssa_copies (void)
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
- updated |= copy_rename_partition_coalesce (map, lhs, rhs, debug);
+ copy_rename_partition_coalesce (map, lhs, rhs, debug);
}
}
}
@@ -358,8 +356,8 @@ rename_ssa_copies (void)
{
tree arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) == SSA_NAME)
- updated |= copy_rename_partition_coalesce (map, res, arg,
- debug);
+ copy_rename_partition_coalesce (map, res, arg,
+ debug);
}
/* Else if all arguments are in the same partition try to merge
it with the result. */
@@ -390,9 +388,9 @@ rename_ssa_copies (void)
}
}
if (all_p_same == 1)
- updated |= copy_rename_partition_coalesce (map, res,
- PHI_ARG_DEF (phi, 0),
- debug);
+ copy_rename_partition_coalesce (map, res,
+ PHI_ARG_DEF (phi, 0),
+ debug);
}
}
}
@@ -426,7 +424,7 @@ rename_ssa_copies (void)
statistics_counter_event (cfun, "copies coalesced",
stats.coalesced);
delete_var_map (map);
- return updated ? TODO_remove_unused_locals : 0;
+ return 0;
}
/* Return true if copy rename is to be performed. */
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 28e3486157d..05c58feca5d 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1607,10 +1607,8 @@ perform_tree_ssa_dce (bool aggressive)
free_edge_list (el);
if (something_changed)
- return (TODO_update_ssa | TODO_cleanup_cfg | TODO_ggc_collect
- | TODO_remove_unused_locals);
- else
- return 0;
+ return TODO_update_ssa | TODO_cleanup_cfg;
+ return 0;
}
/* Pass entry points. */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 8bb783708b8..855c212b0ca 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2936,7 +2936,6 @@ ssa_forward_propagate_and_combine (void)
&& forward_propagate_addr_expr (lhs, rhs))
{
release_defs (stmt);
- todoflags |= TODO_remove_unused_locals;
gsi_remove (&gsi, true);
}
else
@@ -2961,7 +2960,6 @@ ssa_forward_propagate_and_combine (void)
off)))))
{
release_defs (stmt);
- todoflags |= TODO_remove_unused_locals;
gsi_remove (&gsi, true);
}
else if (is_gimple_min_invariant (rhs))
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 9055d91ddb3..a72e9d5a6b6 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -889,7 +889,10 @@ remove_unused_locals (void)
dstidx++;
}
if (dstidx != num)
- cfun->local_decls->truncate (dstidx);
+ {
+ statistics_counter_event (cfun, "unused VAR_DECLs removed", num - dstidx);
+ cfun->local_decls->truncate (dstidx);
+ }
remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
clear_unused_block_pointer ();
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index d30bfec5062..2940bf10044 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2574,26 +2574,20 @@ record_important_candidates (struct ivopts_data *data)
static void
alloc_use_cost_map (struct ivopts_data *data)
{
- unsigned i, size, s, j;
+ unsigned i, size, s;
for (i = 0; i < n_iv_uses (data); i++)
{
struct iv_use *use = iv_use (data, i);
- bitmap_iterator bi;
if (data->consider_all_candidates)
size = n_iv_cands (data);
else
{
- s = 0;
- EXECUTE_IF_SET_IN_BITMAP (use->related_cands, 0, j, bi)
- {
- s++;
- }
+ s = bitmap_count_bits (use->related_cands);
/* Round up to the power of two, so that moduling by it is fast. */
- for (size = 1; size < s; size <<= 1)
- continue;
+ size = s ? (1 << ceil_log2 (s)) : 1;
}
use->n_map_members = size;
@@ -2731,10 +2725,13 @@ get_use_iv_cost (struct ivopts_data *data, struct iv_use *use,
for (i = s; i < use->n_map_members; i++)
if (use->cost_map[i].cand == cand)
return use->cost_map + i;
-
+ else if (use->cost_map[i].cand == NULL)
+ return NULL;
for (i = 0; i < s; i++)
if (use->cost_map[i].cand == cand)
return use->cost_map + i;
+ else if (use->cost_map[i].cand == NULL)
+ return NULL;
return NULL;
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 9ccec2156eb..10c8091758e 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2923,7 +2923,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
break;
case 3:
folded = fold_build3 (nary->opcode, nary->type,
- genop[0], genop[1], genop[3]);
+ genop[0], genop[1], genop[2]);
break;
default:
gcc_unreachable ();
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 81a07aefb4f..202980c19ef 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -2401,10 +2401,8 @@ vn_phi_compute_hash (vn_phi_t vp1)
/* If all PHI arguments are constants we need to distinguish
the PHI node via its type. */
- type = TREE_TYPE (vp1->phiargs[0]);
- result += (INTEGRAL_TYPE_P (type)
- + (INTEGRAL_TYPE_P (type)
- ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0));
+ type = vp1->type;
+ result += vn_hash_type (type);
FOR_EACH_VEC_ELT (vp1->phiargs, i, phi1op)
{
@@ -2443,8 +2441,7 @@ vn_phi_eq (const void *p1, const void *p2)
/* If the PHI nodes do not have compatible types
they are not the same. */
- if (!types_compatible_p (TREE_TYPE (vp1->phiargs[0]),
- TREE_TYPE (vp2->phiargs[0])))
+ if (!types_compatible_p (vp1->type, vp2->type))
return false;
/* Any phi in the same block will have it's arguments in the
@@ -2484,6 +2481,7 @@ vn_phi_lookup (gimple phi)
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
shared_lookup_phiargs.safe_push (def);
}
+ vp1.type = TREE_TYPE (gimple_phi_result (phi));
vp1.phiargs = shared_lookup_phiargs;
vp1.block = gimple_bb (phi);
vp1.hashcode = vn_phi_compute_hash (&vp1);
@@ -2516,6 +2514,7 @@ vn_phi_insert (gimple phi, tree result)
args.safe_push (def);
}
vp1->value_id = VN_INFO (result)->value_id;
+ vp1->type = TREE_TYPE (gimple_phi_result (phi));
vp1->phiargs = args;
vp1->block = gimple_bb (phi);
vp1->result = result;
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index ea9020de21f..072f7ddf65e 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -67,6 +67,7 @@ typedef struct vn_phi_s
hashval_t hashcode;
vec<tree> phiargs;
basic_block block;
+ tree type;
tree result;
} *vn_phi_t;
typedef const struct vn_phi_s *const_vn_phi_t;
@@ -122,17 +123,25 @@ typedef struct vn_constant_s
enum vn_kind { VN_NONE, VN_CONSTANT, VN_NARY, VN_REFERENCE, VN_PHI };
enum vn_kind vn_get_stmt_kind (gimple);
+/* Hash the type TYPE using bits that distinguishes it in the
+ types_compatible_p sense. */
+
+static inline hashval_t
+vn_hash_type (tree type)
+{
+ return (INTEGRAL_TYPE_P (type)
+ + (INTEGRAL_TYPE_P (type)
+ ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0));
+}
+
/* Hash the constant CONSTANT with distinguishing type incompatible
constants in the types_compatible_p sense. */
static inline hashval_t
vn_hash_constant_with_type (tree constant)
{
- tree type = TREE_TYPE (constant);
return (iterative_hash_expr (constant, 0)
- + INTEGRAL_TYPE_P (type)
- + (INTEGRAL_TYPE_P (type)
- ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0));
+ + vn_hash_type (TREE_TYPE (constant)));
}
/* Compare the constants C1 and C2 with distinguishing type incompatible
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index be078ce96ce..0a405ce2a30 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -455,7 +455,7 @@ struct gimple_opt_pass pass_release_ssa_names =
PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
+ TODO_remove_unused_locals, /* todo_flags_start */
+ 0 /* todo_flags_finish */
}
};
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 8a8982ad2e0..559f6e9e997 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -187,6 +187,7 @@ adjust_debug_stmts (tree from, tree to, basic_block bb)
if (MAY_HAVE_DEBUG_STMTS
&& TREE_CODE (from) == SSA_NAME
+ && ! SSA_NAME_IS_DEFAULT_DEF (from)
&& ! virtual_operand_p (from))
{
ai.from = from;
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index a2f90138fc9..3693cd27a96 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -4707,7 +4707,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
The last use is the reduction variable. In case of nested cycle this
assumption is not true: we use reduc_index to record the index of the
reduction variable. */
- for (i = 0; i < op_type-1; i++)
+ for (i = 0; i < op_type - 1; i++)
{
/* The condition of COND_EXPR is checked in vectorizable_condition(). */
if (i == 0 && code == COND_EXPR)
@@ -4739,11 +4739,18 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (!vectype_in)
vectype_in = tem;
gcc_assert (is_simple_use);
- gcc_assert (dt == vect_reduction_def
- || dt == vect_nested_cycle
- || ((dt == vect_internal_def || dt == vect_external_def
- || dt == vect_constant_def || dt == vect_induction_def)
- && nested_cycle && found_nested_cycle_def));
+ if (!(dt == vect_reduction_def
+ || dt == vect_nested_cycle
+ || ((dt == vect_internal_def || dt == vect_external_def
+ || dt == vect_constant_def || dt == vect_induction_def)
+ && nested_cycle && found_nested_cycle_def)))
+ {
+ /* For pattern recognized stmts, orig_stmt might be a reduction,
+ but some helper statements for the pattern might not, or
+ might be COND_EXPRs with reduction uses in the condition. */
+ gcc_assert (orig_stmt);
+ return false;
+ }
if (!found_nested_cycle_def)
reduc_def_stmt = def_stmt;
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index a023a460371..a38b14d4956 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8503,8 +8503,9 @@ test_for_singularity (enum tree_code cond_code, tree op0,
return NULL;
}
-/* Simplify the conditional stmt STMT using final range information.
- Return true if we simplified the statement. */
+/* Simplify a conditional using a relational operator to an equality
+ test if the range information indicates only one value can satisfy
+ the original conditional. */
static bool
simplify_cond_using_ranges (gimple stmt)
@@ -8513,13 +8514,7 @@ simplify_cond_using_ranges (gimple stmt)
tree op1 = gimple_cond_rhs (stmt);
enum tree_code cond_code = gimple_cond_code (stmt);
- /* Simplify a conditional using a relational operator to an equality
- test if the range information indicates only one value can satisfy
- the original conditional.
- Do that only in the second VRP pass as otherwise assertions derived
- from this predicate are weakened. */
- if (!first_pass_instance
- && cond_code != NE_EXPR
+ if (cond_code != NE_EXPR
&& cond_code != EQ_EXPR
&& TREE_CODE (op0) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
diff --git a/gcc/tree.h b/gcc/tree.h
index c3c814ca33a..740d4382712 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3586,14 +3586,25 @@ struct GTY(()) tree_optimization_option {
/* The optimization options used by the user. */
struct cl_optimization opts;
+
+ /* Target optabs for this set of optimization options. This is of
+ type `struct target_optabs *'. */
+ unsigned char *GTY ((atomic)) target_optabs;
};
#define TREE_OPTIMIZATION(NODE) \
(&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
+#define TREE_OPTIMIZATION_OPTABS(NODE) \
+ (OPTIMIZATION_NODE_CHECK (NODE)->optimization.target_optabs)
+
/* Return a tree node that encapsulates the current optimization options. */
extern tree build_optimization_node (void);
+/* Save a new set of target_optabs in a TREE_OPTIMIZATION node if the
+ current set of optabs has changed. */
+extern void save_optabs_if_changed (tree);
+
/* Target options used by a function. */
struct GTY(()) tree_target_option {
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index d4bc8109e7d..6032f6f1a6a 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,7 @@
+2012-02-19 Edgar E. Iglesias <edgar.iglesias@gmail.com>
+ * config/microblaze/modsi3.S (modsi3): Fix case with 0x80000000
+ as dividend.
+
2013-02-16 Alan Modra <amodra@gmail.com>
PR target/55431
diff --git a/libgcc/config/microblaze/modsi3.S b/libgcc/config/microblaze/modsi3.S
index ed28acf8f63..93d0c30b688 100644
--- a/libgcc/config/microblaze/modsi3.S
+++ b/libgcc/config/microblaze/modsi3.S
@@ -55,6 +55,8 @@ $LaR5_Pos:
$LaR6_Pos:
ADDIK r3,r0,0 # Clear mod
ADDIK r30,r0,0 # clear div
+ BLTId r5,$LaDIV2 # If r5 is still negative (0x80000000), skip
+ # the first bit search.
ADDIK r29,r0,32 # Initialize the loop count
# First part try to find the first '1' in the r5
$LaDIV1:
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 1a42a8449a9..54ac5738c01 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,20 @@
+2013-02-21 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/30162
+ * io/open.c (test_endfile): Call stell only if size != 0.
+ * io/unix.c (raw_tell): Revert r194679.
+ (raw_size): Return size field only for regular files, otherwise 0.
+
+2013-02-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/56347
+ * acinclude.m4 (LIBGFOR_CHECK_FOR_BROKEN_POWF): Remove check for
+ broken powf.
+ * configure.ac (LIBGFOR_CHECK_FOR_BROKEN_POWF): Likewise.
+ * intrinsics/c99_functions.c: Likewise.
+ * configure: Rebuilt.
+ * config.h.in: Rebuilt.
+
2013-02-06 Janus Weil <janus@gcc.gnu.org>
PR fortran/55978
diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
index d10126150ea..35698ec00f6 100644
--- a/libgfortran/acinclude.m4
+++ b/libgfortran/acinclude.m4
@@ -257,18 +257,6 @@ __mingw_snprintf (NULL, 0, "%d\n", 1);
fi
])
-dnl Check whether we have a broken powf implementation
-AC_DEFUN([LIBGFOR_CHECK_FOR_BROKEN_POWF], [
- AC_CACHE_CHECK([whether powf is broken], libgfor_cv_have_broken_powf, [
-case "${target}" in
- hppa*64*-*-hpux*) libgfor_cv_have_broken_powf=yes ;;
- *) libgfor_cv_have_broken_powf=no;;
-esac])
- if test x"$libgfor_cv_have_broken_powf" = xyes; then
- AC_DEFINE(HAVE_BROKEN_POWF, 1, [Define if powf is broken.])
- fi
-])
-
dnl Check whether we have a __float128 type
AC_DEFUN([LIBGFOR_CHECK_FLOAT128], [
LIBQUADSPEC=
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index ee4c14f52c3..fb5026fc0da 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -81,9 +81,6 @@
/* Define to 1 if the target supports __attribute__((visibility(...))). */
#undef HAVE_ATTRIBUTE_VISIBILITY
-/* Define if powf is broken. */
-#undef HAVE_BROKEN_POWF
-
/* Define to 1 if you have the `cabs' function. */
#undef HAVE_CABS
diff --git a/libgfortran/configure b/libgfortran/configure
index 5ad56aa29b7..8385e968458 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -25592,28 +25592,6 @@ $as_echo "#define HAVE_MINGW_SNPRINTF 1" >>confdefs.h
fi
-# Check for a broken powf implementation
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether powf is broken" >&5
-$as_echo_n "checking whether powf is broken... " >&6; }
-if test "${libgfor_cv_have_broken_powf+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
-
-case "${target}" in
- hppa*64*-*-hpux*) libgfor_cv_have_broken_powf=yes ;;
- *) libgfor_cv_have_broken_powf=no;;
-esac
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_broken_powf" >&5
-$as_echo "$libgfor_cv_have_broken_powf" >&6; }
- if test x"$libgfor_cv_have_broken_powf" = xyes; then
-
-$as_echo "#define HAVE_BROKEN_POWF 1" >>confdefs.h
-
- fi
-
-
# Check whether libquadmath should be used
# Check whether --enable-libquadmath-support was given.
if test "${enable_libquadmath_support+set}" = set; then :
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 86cb330fee3..7d97fed1b0b 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -468,9 +468,6 @@ LIBGFOR_CHECK_WORKING_STAT
# Check whether __mingw_snprintf() is present
LIBGFOR_CHECK_MINGW_SNPRINTF
-# Check for a broken powf implementation
-LIBGFOR_CHECK_FOR_BROKEN_POWF
-
# Check whether libquadmath should be used
AC_ARG_ENABLE(libquadmath-support,
AS_HELP_STRING([--disable-libquadmath-support],
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c
index f6acf2d1d0f..ee74b115ea7 100644
--- a/libgfortran/intrinsics/c99_functions.c
+++ b/libgfortran/intrinsics/c99_functions.c
@@ -518,10 +518,8 @@ nextafterf (float x, float y)
#endif
-#if !defined(HAVE_POWF) || defined(HAVE_BROKEN_POWF)
#ifndef HAVE_POWF
#define HAVE_POWF 1
-#endif
float powf (float x, float y);
float
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
index 28957673eff..d9cfde853f5 100644
--- a/libgfortran/io/open.c
+++ b/libgfortran/io/open.c
@@ -152,8 +152,12 @@ static const st_option async_opt[] =
static void
test_endfile (gfc_unit * u)
{
- if (u->endfile == NO_ENDFILE && ssize (u->s) == stell (u->s))
- u->endfile = AT_ENDFILE;
+ if (u->endfile == NO_ENDFILE)
+ {
+ gfc_offset sz = ssize (u->s);
+ if (sz == 0 || sz == stell (u->s))
+ u->endfile = AT_ENDFILE;
+ }
}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index ba8392d21a1..8b9d7a77342 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -342,15 +342,7 @@ raw_seek (unix_stream * s, gfc_offset offset, int whence)
static gfc_offset
raw_tell (unix_stream * s)
{
- gfc_offset x;
- x = lseek (s->fd, 0, SEEK_CUR);
-
- /* Non-seekable files should always be assumed to be at
- current position. */
- if (x == -1 && errno == ESPIPE)
- x = 0;
-
- return x;
+ return lseek (s->fd, 0, SEEK_CUR);
}
static gfc_offset
@@ -360,7 +352,10 @@ raw_size (unix_stream * s)
int ret = fstat (s->fd, &statbuf);
if (ret == -1)
return ret;
- return statbuf.st_size;
+ if (S_ISREG (statbuf.st_mode))
+ return statbuf.st_size;
+ else
+ return 0;
}
static int
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index c153ae22227..ea90318cee1 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -1656,6 +1656,13 @@ endif
endif
endif
+# Define socket functions.
+if LIBGO_IS_SOLARIS
+syscall_socket_os_file = go/syscall/socket_xnet.go
+else
+syscall_socket_os_file = go/syscall/socket_posix.go
+endif
+
# Support for uname.
if LIBGO_IS_SOLARIS
if LIBGO_IS_386
@@ -1722,6 +1729,7 @@ go_base_syscall_files = \
$(syscall_errstr_file) \
$(syscall_size_file) \
$(syscall_socket_file) \
+ $(syscall_socket_os_file) \
$(syscall_uname_file) \
$(syscall_netlink_file) \
$(syscall_lsf_file) \
@@ -1746,13 +1754,20 @@ go_syscall_test_files = \
go/syscall/passfd_test.go
libcalls.go: s-libcalls; @true
-s-libcalls: Makefile go/syscall/mksyscall.awk $(go_base_syscall_files)
+s-libcalls: libcalls-list go/syscall/mksyscall.awk $(go_base_syscall_files)
rm -f libcalls.go.tmp
- files=`echo $^ | sed -e 's/Makefile//' -e 's|[^ ]*go/syscall/mksyscall.awk||'`; \
+ files=`echo $^ | sed -e 's/libcalls-list//' -e 's|[^ ]*go/syscall/mksyscall.awk||'`; \
$(AWK) -f $(srcdir)/go/syscall/mksyscall.awk $${files} > libcalls.go.tmp
$(SHELL) $(srcdir)/../move-if-change libcalls.go.tmp libcalls.go
$(STAMP) $@
+libcalls-list: s-libcalls-list; @true
+s-libcalls-list: Makefile
+ rm -f libcalls-list.tmp
+ echo $(go_base_syscall_files) > libcalls-list.tmp
+ $(SHELL) $(srcdir)/../move-if-change libcalls-list.tmp libcalls-list
+ $(STAMP) $@
+
syscall_arch.go: s-syscall_arch; @true
s-syscall_arch: Makefile
rm -f syscall_arch.go.tmp
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index fe780b13f22..c22a4ea47fc 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -1877,6 +1877,10 @@ go_unicode_utf8_files = \
# Define socket sizes and types.
@LIBGO_IS_LINUX_TRUE@syscall_socket_file = go/syscall/socket_linux.go epoll.go
+@LIBGO_IS_SOLARIS_FALSE@syscall_socket_os_file = go/syscall/socket_posix.go
+
+# Define socket functions.
+@LIBGO_IS_SOLARIS_TRUE@syscall_socket_os_file = go/syscall/socket_xnet.go
@LIBGO_IS_386_FALSE@@LIBGO_IS_SOLARIS_TRUE@syscall_uname_file = go/syscall/libcall_uname.go
# Support for uname.
@@ -1922,6 +1926,7 @@ go_base_syscall_files = \
$(syscall_errstr_file) \
$(syscall_size_file) \
$(syscall_socket_file) \
+ $(syscall_socket_os_file) \
$(syscall_uname_file) \
$(syscall_netlink_file) \
$(syscall_lsf_file) \
@@ -4512,13 +4517,20 @@ s-version: Makefile
$(STAMP) $@
libcalls.go: s-libcalls; @true
-s-libcalls: Makefile go/syscall/mksyscall.awk $(go_base_syscall_files)
+s-libcalls: libcalls-list go/syscall/mksyscall.awk $(go_base_syscall_files)
rm -f libcalls.go.tmp
- files=`echo $^ | sed -e 's/Makefile//' -e 's|[^ ]*go/syscall/mksyscall.awk||'`; \
+ files=`echo $^ | sed -e 's/libcalls-list//' -e 's|[^ ]*go/syscall/mksyscall.awk||'`; \
$(AWK) -f $(srcdir)/go/syscall/mksyscall.awk $${files} > libcalls.go.tmp
$(SHELL) $(srcdir)/../move-if-change libcalls.go.tmp libcalls.go
$(STAMP) $@
+libcalls-list: s-libcalls-list; @true
+s-libcalls-list: Makefile
+ rm -f libcalls-list.tmp
+ echo $(go_base_syscall_files) > libcalls-list.tmp
+ $(SHELL) $(srcdir)/../move-if-change libcalls-list.tmp libcalls-list
+ $(STAMP) $@
+
syscall_arch.go: s-syscall_arch; @true
s-syscall_arch: Makefile
rm -f syscall_arch.go.tmp
diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go
index fc83df123db..951bc18fcdf 100644
--- a/libgo/go/syscall/sockcmsg_unix.go
+++ b/libgo/go/syscall/sockcmsg_unix.go
@@ -8,7 +8,10 @@
package syscall
-import "unsafe"
+import (
+ "runtime"
+ "unsafe"
+)
// Round the length of a raw sockaddr up to align it propery.
func cmsgAlignOf(salen int) int {
@@ -18,6 +21,11 @@ func cmsgAlignOf(salen int) int {
if darwinAMD64 {
salign = 4
}
+ // NOTE: Solaris always uses 32-bit alignment,
+ // cf. _CMSG_DATA_ALIGNMENT in <sys/socket.h>.
+ if runtime.GOOS == "solaris" {
+ salign = 4
+ }
if salen == 0 {
return salign
}
diff --git a/libgo/go/syscall/socket.go b/libgo/go/syscall/socket.go
index 3aa92012f08..a625eb69851 100644
--- a/libgo/go/syscall/socket.go
+++ b/libgo/go/syscall/socket.go
@@ -177,9 +177,6 @@ func Getpeername(fd int) (sa Sockaddr, err error) {
return anyToSockaddr(&rsa)
}
-//sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error)
-//bind(fd _C_int, sa *RawSockaddrAny, len Socklen_t) _C_int
-
func Bind(fd int, sa Sockaddr) (err error) {
ptr, n, err := sa.sockaddr()
if err != nil {
@@ -188,9 +185,6 @@ func Bind(fd int, sa Sockaddr) (err error) {
return bind(fd, ptr, n)
}
-//sys connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) (err error)
-//connect(s _C_int, addr *RawSockaddrAny, addrlen Socklen_t) _C_int
-
func Connect(fd int, sa Sockaddr) (err error) {
ptr, n, err := sa.sockaddr()
if err != nil {
@@ -199,9 +193,6 @@ func Connect(fd int, sa Sockaddr) (err error) {
return connect(fd, ptr, n)
}
-//sysnb socket(domain int, typ int, proto int) (fd int, err error)
-//socket(domain _C_int, typ _C_int, protocol _C_int) _C_int
-
func Socket(domain, typ, proto int) (fd int, err error) {
if domain == AF_INET6 && SocketDisableIPv6 {
return -1, EAFNOSUPPORT
@@ -210,9 +201,6 @@ func Socket(domain, typ, proto int) (fd int, err error) {
return
}
-//sysnb socketpair(domain int, typ int, proto int, fd *[2]_C_int) (err error)
-//socketpair(domain _C_int, typ _C_int, protocol _C_int, fd *[2]_C_int) _C_int
-
func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
var fdx [2]_C_int
err = socketpair(domain, typ, proto, &fdx)
@@ -223,9 +211,6 @@ func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
return
}
-//sys getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
-//getsockopt(s _C_int, level _C_int, name _C_int, val *byte, vallen *Socklen_t) _C_int
-
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
var n byte
vallen := Socklen_t(1)
@@ -326,9 +311,6 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return
}
-//sys sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
-//sendto(s _C_int, buf *byte, len Size_t, flags _C_int, to *RawSockaddrAny, tolen Socklen_t) Ssize_t
-
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
ptr, n, err := to.sockaddr()
if err != nil {
@@ -337,9 +319,6 @@ func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
return sendto(fd, p, flags, ptr, n)
}
-//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
-//recvmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
-
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var msg Msghdr
var rsa RawSockaddrAny
@@ -374,9 +353,6 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
return
}
-//sys sendmsg(s int, msg *Msghdr, flags int) (err error)
-//sendmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
-
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
var ptr *RawSockaddrAny
var salen Socklen_t
diff --git a/libgo/go/syscall/socket_posix.go b/libgo/go/syscall/socket_posix.go
new file mode 100644
index 00000000000..06d7dab464a
--- /dev/null
+++ b/libgo/go/syscall/socket_posix.go
@@ -0,0 +1,31 @@
+// socket_posix.go -- Socket handling for generic POSIX systems.
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+//sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error)
+//bind(fd _C_int, sa *RawSockaddrAny, len Socklen_t) _C_int
+
+//sys connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) (err error)
+//connect(s _C_int, addr *RawSockaddrAny, addrlen Socklen_t) _C_int
+
+//sysnb socket(domain int, typ int, proto int) (fd int, err error)
+//socket(domain _C_int, typ _C_int, protocol _C_int) _C_int
+
+//sysnb socketpair(domain int, typ int, proto int, fd *[2]_C_int) (err error)
+//socketpair(domain _C_int, typ _C_int, protocol _C_int, fd *[2]_C_int) _C_int
+
+//sys getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
+//getsockopt(s _C_int, level _C_int, name _C_int, val *byte, vallen *Socklen_t) _C_int
+
+//sys sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
+//sendto(s _C_int, buf *byte, len Size_t, flags _C_int, to *RawSockaddrAny, tolen Socklen_t) Ssize_t
+
+//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//recvmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
+
+//sys sendmsg(s int, msg *Msghdr, flags int) (err error)
+//sendmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
diff --git a/libgo/go/syscall/socket_xnet.go b/libgo/go/syscall/socket_xnet.go
new file mode 100644
index 00000000000..8f86c622b9f
--- /dev/null
+++ b/libgo/go/syscall/socket_xnet.go
@@ -0,0 +1,32 @@
+// socket_xnet.go -- Socket handling specific to Solaris.
+// Enforce use of XPG 4.2 versions of socket functions.
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+//sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error)
+//__xnet_bind(fd _C_int, sa *RawSockaddrAny, len Socklen_t) _C_int
+
+//sys connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) (err error)
+//__xnet_connect(s _C_int, addr *RawSockaddrAny, addrlen Socklen_t) _C_int
+
+//sysnb socket(domain int, typ int, proto int) (fd int, err error)
+//__xnet_socket(domain _C_int, typ _C_int, protocol _C_int) _C_int
+
+//sysnb socketpair(domain int, typ int, proto int, fd *[2]_C_int) (err error)
+//__xnet_socketpair(domain _C_int, typ _C_int, protocol _C_int, fd *[2]_C_int) _C_int
+
+//sys getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
+//__xnet_getsockopt(s _C_int, level _C_int, name _C_int, val *byte, vallen *Socklen_t) _C_int
+
+//sys sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
+//__xnet_sendto(s _C_int, buf *byte, len Size_t, flags _C_int, to *RawSockaddrAny, tolen Socklen_t) Ssize_t
+
+//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//__xnet_recvmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
+
+//sys sendmsg(s int, msg *Msghdr, flags int) (err error)
+//__xnet_sendmsg(s _C_int, msg *Msghdr, flags _C_int) Ssize_t
diff --git a/libgo/runtime/lfstack.c b/libgo/runtime/lfstack.c
index 00b60081e88..230ed87c43f 100644
--- a/libgo/runtime/lfstack.c
+++ b/libgo/runtime/lfstack.c
@@ -17,9 +17,10 @@
#define PTR_MASK ((1ull<<PTR_BITS)-1)
#define CNT_MASK (0ull-1)
-#if __SIZEOF_POINTER__ == 8 && defined(__sparc__)
-// SPARC64 uses all 64 bits of virtual addresses. Use low-order three
-// bits as ABA counter.
+#if __SIZEOF_POINTER__ == 8 && (defined(__sparc__) || (defined(__sun__) && defined(__amd64__)))
+// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
+// Use low-order three bits as ABA counter.
+// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
#undef PTR_BITS
#undef CNT_MASK
#undef PTR_MASK
diff --git a/libjava/classpath/ChangeLog.gcj b/libjava/classpath/ChangeLog.gcj
index 98ce4382983..62105e26968 100644
--- a/libjava/classpath/ChangeLog.gcj
+++ b/libjava/classpath/ChangeLog.gcj
@@ -1,3 +1,9 @@
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/56258
+ * doc/cp-tools.texinfo (Virtual Machine Options): Use just
+ one @gccoptlist instead of 3 separate ones.
+
2013-01-03 Jakub Jelinek <jakub@redhat.com>
* gnu/java/rmi/registry/RegistryImpl.java (version): Update
diff --git a/libjava/classpath/doc/cp-tools.texinfo b/libjava/classpath/doc/cp-tools.texinfo
index ec186dee778..c3cc5ff8cdf 100644
--- a/libjava/classpath/doc/cp-tools.texinfo
+++ b/libjava/classpath/doc/cp-tools.texinfo
@@ -2025,7 +2025,7 @@ Doclet, grouped by type. Explanations are in the following sections.
@item Virtual Machine Options
@xref{Virtual Machine Options,,Options Controlling Gjdoc Behavior}.
-@gccoptlist{-classpath} @gccoptlist{-bootclasspath} @gccoptlist{-J}@var{vmopt}
+@gccoptlist{-classpath -bootclasspath -J @var{vmopt}}
@end table
diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog
index 3c293cfac5e..15c0739319d 100644
--- a/libquadmath/ChangeLog
+++ b/libquadmath/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR libquadmath/56379
+ * strtod/strtod_l.c (mpn_lshift_1): Rewritten as function-like
+ macro.
+
2013-02-17 Tobias Burnus <burnus@net-b.de>
* math/cacoshq.c (cacoshq): Call signbitq instead of signbit.
diff --git a/libquadmath/strtod/strtod_l.c b/libquadmath/strtod/strtod_l.c
index d1845a8039c..0b0e85a3cf7 100644
--- a/libquadmath/strtod/strtod_l.c
+++ b/libquadmath/strtod/strtod_l.c
@@ -421,28 +421,30 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
/* Shift {PTR, SIZE} COUNT bits to the left, and fill the vacated bits
with the COUNT most significant bits of LIMB.
- Tege doesn't like this function so I have to write it here myself. :)
+ Implemented as a macro, so that __builtin_constant_p works even at -O0.
+
+ Tege doesn't like this macro so I have to write it here myself. :)
--drepper */
-static inline void
-__attribute ((always_inline))
-mpn_lshift_1 (mp_limb_t *ptr, mp_size_t size, unsigned int count,
- mp_limb_t limb)
-{
- if (__builtin_constant_p (count) && count == BITS_PER_MP_LIMB)
- {
- /* Optimize the case of shifting by exactly a word:
- just copy words, with no actual bit-shifting. */
- mp_size_t i;
- for (i = size - 1; i > 0; --i)
- ptr[i] = ptr[i - 1];
- ptr[0] = limb;
- }
- else
- {
- (void) mpn_lshift (ptr, ptr, size, count);
- ptr[0] |= limb >> (BITS_PER_MP_LIMB - count);
- }
-}
+#define mpn_lshift_1(ptr, size, count, limb) \
+ do \
+ { \
+ mp_limb_t *__ptr = (ptr); \
+ if (__builtin_constant_p (count) && count == BITS_PER_MP_LIMB) \
+ { \
+ mp_size_t i; \
+ for (i = (size) - 1; i > 0; --i) \
+ __ptr[i] = __ptr[i - 1]; \
+ __ptr[0] = (limb); \
+ } \
+ else \
+ { \
+ /* We assume count > 0 && count < BITS_PER_MP_LIMB here. */ \
+ unsigned int __count = (count); \
+ (void) mpn_lshift (__ptr, __ptr, size, __count); \
+ __ptr[0] |= (limb) >> (BITS_PER_MP_LIMB - __count); \
+ } \
+ } \
+ while (0)
#define INTERNAL(x) INTERNAL1(x)
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index eb6a3456e47..7f8f6ad7758 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,21 @@
+2013-02-21 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ * asan/Makefile.am (libasan_la_SOURCES): Remove deprecated
+ dynamic/asan_interceptors_dynamic.cc.
+ * asan/Makefile.in: Regenerated.
+ * merge.sh: Remove merge of deprecated lib/asan/dynamic.
+
+2013-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ * asan/asan_rtl.cc (__asan_preinit): Don't add if PIC macro is
+ defined. Add used attribute.
+
+2013-02-21 Kostya Serebryany <kcc@google.com>
+
+ * All source files: Merge from upstream r175733.
+ * sanitizer_common/Makefile.am: Added a new file.
+ * sanitizer_common/Makefile.in: Regenerated.
+
2013-02-14 H.J. Lu <hongjiu.lu@intel.com>
PR bootstrap/56327
diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE
index 02d2bfcf512..28d1e49ab77 100644
--- a/libsanitizer/MERGE
+++ b/libsanitizer/MERGE
@@ -1,4 +1,4 @@
-175049
+175733
The first line of this file holds the svn revision number of the
last merge done from the master library sources.
diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index bfd9e2e5524..b3ca3df31e1 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -37,7 +37,6 @@ asan_files = \
libasan_la_SOURCES = $(asan_files)
if USING_MAC_INTERPOSE
-libasan_la_SOURCES += dynamic/asan_interceptors_dynamic.cc
libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la
else
libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index 848f0df1e83..28dad181415 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -53,7 +53,6 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
@USING_MAC_INTERPOSE_TRUE@am__append_1 = -DMAC_INTERPOSE_FUNCTIONS -DMISSING_BLOCKS_SUPPORT
-@USING_MAC_INTERPOSE_TRUE@am__append_2 = dynamic/asan_interceptors_dynamic.cc
subdir = asan
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -107,13 +106,6 @@ am__DEPENDENCIES_1 =
@USING_MAC_INTERPOSE_FALSE@ $(am__DEPENDENCIES_1)
@USING_MAC_INTERPOSE_TRUE@libasan_la_DEPENDENCIES = $(top_builddir)/sanitizer_common/libsanitizer_common.la \
@USING_MAC_INTERPOSE_TRUE@ $(am__DEPENDENCIES_1)
-am__libasan_la_SOURCES_DIST = asan_allocator.cc asan_allocator2.cc \
- asan_interceptors.cc asan_mac.cc asan_malloc_mac.cc \
- asan_new_delete.cc asan_posix.cc asan_rtl.cc asan_stats.cc \
- asan_thread_registry.cc asan_fake_stack.cc asan_globals.cc \
- asan_linux.cc asan_malloc_linux.cc asan_malloc_win.cc \
- asan_poisoning.cc asan_report.cc asan_stack.cc asan_thread.cc \
- asan_win.cc dynamic/asan_interceptors_dynamic.cc
am__objects_1 = asan_allocator.lo asan_allocator2.lo \
asan_interceptors.lo asan_mac.lo asan_malloc_mac.lo \
asan_new_delete.lo asan_posix.lo asan_rtl.lo asan_stats.lo \
@@ -121,9 +113,7 @@ am__objects_1 = asan_allocator.lo asan_allocator2.lo \
asan_linux.lo asan_malloc_linux.lo asan_malloc_win.lo \
asan_poisoning.lo asan_report.lo asan_stack.lo asan_thread.lo \
asan_win.lo
-@USING_MAC_INTERPOSE_TRUE@am__objects_2 = \
-@USING_MAC_INTERPOSE_TRUE@ asan_interceptors_dynamic.lo
-am_libasan_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+am_libasan_la_OBJECTS = $(am__objects_1)
libasan_la_OBJECTS = $(am_libasan_la_OBJECTS)
libasan_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
@@ -142,7 +132,7 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libasan_la_SOURCES)
-DIST_SOURCES = $(am__libasan_la_SOURCES_DIST)
+DIST_SOURCES = $(libasan_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -317,7 +307,7 @@ asan_files = \
asan_thread.cc \
asan_win.cc
-libasan_la_SOURCES = $(asan_files) $(am__append_2)
+libasan_la_SOURCES = $(asan_files)
@USING_MAC_INTERPOSE_FALSE@libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la \
@USING_MAC_INTERPOSE_FALSE@ $(top_builddir)/interception/libinterception.la \
@USING_MAC_INTERPOSE_FALSE@ $(LIBSTDCXX_RAW_CXX_LDFLAGS)
@@ -444,7 +434,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_fake_stack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_globals.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_dynamic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_linux.Plo@am__quote@
@@ -482,13 +471,6 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
-asan_interceptors_dynamic.lo: dynamic/asan_interceptors_dynamic.cc
-@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT asan_interceptors_dynamic.lo -MD -MP -MF $(DEPDIR)/asan_interceptors_dynamic.Tpo -c -o asan_interceptors_dynamic.lo `test -f 'dynamic/asan_interceptors_dynamic.cc' || echo '$(srcdir)/'`dynamic/asan_interceptors_dynamic.cc
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/asan_interceptors_dynamic.Tpo $(DEPDIR)/asan_interceptors_dynamic.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dynamic/asan_interceptors_dynamic.cc' object='asan_interceptors_dynamic.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o asan_interceptors_dynamic.lo `test -f 'dynamic/asan_interceptors_dynamic.cc' || echo '$(srcdir)/'`dynamic/asan_interceptors_dynamic.cc
-
mostlyclean-libtool:
-rm -f *.lo
diff --git a/libsanitizer/asan/asan_flags.h b/libsanitizer/asan/asan_flags.h
index b05fdc3acc6..b880896c7a3 100644
--- a/libsanitizer/asan/asan_flags.h
+++ b/libsanitizer/asan/asan_flags.h
@@ -15,11 +15,13 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
-// ASan flag values can be defined in three ways:
+// ASan flag values can be defined in four ways:
// 1) initialized with default values at startup.
-// 2) overriden from string returned by user-specified function
+// 2) overriden during compilation of ASan runtime by providing
+// compile definition ASAN_DEFAULT_OPTIONS.
+// 3) overriden from string returned by user-specified function
// __asan_default_options().
-// 3) overriden from env variable ASAN_OPTIONS.
+// 4) overriden from env variable ASAN_OPTIONS.
namespace __asan {
diff --git a/libsanitizer/asan/asan_intercepted_functions.h b/libsanitizer/asan/asan_intercepted_functions.h
index 45c913c1894..ed75c428439 100644
--- a/libsanitizer/asan/asan_intercepted_functions.h
+++ b/libsanitizer/asan/asan_intercepted_functions.h
@@ -77,9 +77,36 @@ using __sanitizer::uptr;
# define ASAN_INTERCEPT___CXA_THROW 0
#endif
+#define INTERPOSE_FUNCTION(function) \
+ { reinterpret_cast<const uptr>(WRAP(function)), \
+ reinterpret_cast<const uptr>(function) }
+
+#define INTERPOSE_FUNCTION_2(function, wrapper) \
+ { reinterpret_cast<const uptr>(wrapper), \
+ reinterpret_cast<const uptr>(function) }
+
+struct interpose_substitution {
+ const uptr replacement;
+ const uptr original;
+};
+
+#define INTERPOSER(func) __attribute__((used)) \
+const interpose_substitution substitution_##func[] \
+ __attribute__((section("__DATA, __interpose"))) = { \
+ INTERPOSE_FUNCTION(func), \
+}
+
+#define INTERPOSER_2(func, wrapper) __attribute__((used)) \
+const interpose_substitution substitution_##func[] \
+ __attribute__((section("__DATA, __interpose"))) = { \
+ INTERPOSE_FUNCTION_2(func, wrapper), \
+}
+
+
#define DECLARE_FUNCTION_AND_WRAPPER(ret_type, func, ...) \
ret_type func(__VA_ARGS__); \
- ret_type WRAP(func)(__VA_ARGS__)
+ ret_type WRAP(func)(__VA_ARGS__); \
+ INTERPOSER(func)
// Use extern declarations of intercepted functions on Mac and Windows
// to avoid including system headers.
@@ -139,7 +166,8 @@ DECLARE_FUNCTION_AND_WRAPPER(char*, strdup, const char *s);
DECLARE_FUNCTION_AND_WRAPPER(uptr, strnlen, const char *s, uptr maxlen);
# endif
# if ASAN_INTERCEPT_INDEX
-DECLARE_FUNCTION_AND_WRAPPER(char*, index, const char *string, int c);
+char* index(const char *string, int c);
+INTERPOSER_2(index, WRAP(strchr));
# endif
// stdlib.h
@@ -193,6 +221,20 @@ DECLARE_FUNCTION_AND_WRAPPER(int, pthread_create,
void *(*start_routine)(void*), void *arg);
# endif
+# if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
+DECLARE_FUNCTION_AND_WRAPPER(void *, localtime, unsigned long *timep);
+DECLARE_FUNCTION_AND_WRAPPER(void *, localtime_r, unsigned long *timep,
+ void *result);
+DECLARE_FUNCTION_AND_WRAPPER(void *, gmtime, unsigned long *timep);
+DECLARE_FUNCTION_AND_WRAPPER(void *, gmtime_r, unsigned long *timep,
+ void *result);
+DECLARE_FUNCTION_AND_WRAPPER(char *, ctime, unsigned long *timep);
+DECLARE_FUNCTION_AND_WRAPPER(char *, ctime_r, unsigned long *timep,
+ char *result);
+DECLARE_FUNCTION_AND_WRAPPER(char *, asctime, void *tm);
+DECLARE_FUNCTION_AND_WRAPPER(char *, asctime_r, void *tm, char *result);
+# endif
+
// stdio.h
# if SANITIZER_INTERCEPT_SCANF
DECLARE_FUNCTION_AND_WRAPPER(int, vscanf, const char *format, va_list ap);
@@ -205,17 +247,6 @@ DECLARE_FUNCTION_AND_WRAPPER(int, fscanf,
void* stream, const char *format, ...);
DECLARE_FUNCTION_AND_WRAPPER(int, sscanf, // NOLINT
const char *str, const char *format, ...);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_vscanf, const char *format,
- va_list ap);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_vsscanf, const char *str,
- const char *format, va_list ap);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_vfscanf, void *stream,
- const char *format, va_list ap);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_scanf, const char *format, ...);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_fscanf,
- void* stream, const char *format, ...);
-DECLARE_FUNCTION_AND_WRAPPER(int, __isoc99_sscanf, // NOLINT
- const char *str, const char *format, ...);
# endif
# if defined(__APPLE__)
@@ -278,9 +309,11 @@ DECLARE_FUNCTION_AND_WRAPPER(void *, valloc, size_t size);
DECLARE_FUNCTION_AND_WRAPPER(size_t, malloc_good_size, size_t size);
DECLARE_FUNCTION_AND_WRAPPER(int, posix_memalign,
void **memptr, size_t alignment, size_t size);
+#if 0
DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_prepare, void);
DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_parent, void);
DECLARE_FUNCTION_AND_WRAPPER(void, _malloc_fork_child, void);
+#endif
diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cc
index f4c56830d8a..064fc6261b0 100644
--- a/libsanitizer/asan/asan_interceptors.cc
+++ b/libsanitizer/asan/asan_interceptors.cc
@@ -24,6 +24,16 @@
namespace __asan {
+// Return true if we can quickly decide that the region is unpoisoned.
+static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
+ if (size == 0) return true;
+ if (size <= 32)
+ return !AddressIsPoisoned(beg) &&
+ !AddressIsPoisoned(beg + size - 1) &&
+ !AddressIsPoisoned(beg + size / 2);
+ return false;
+}
+
// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
// and ASAN_WRITE_RANGE as macro instead of function so
// that no extra frames are created, and stack trace contains
@@ -32,7 +42,8 @@ namespace __asan {
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
uptr __offset = (uptr)(offset); \
uptr __size = (uptr)(size); \
- if (__asan_region_is_poisoned(__offset, __size)) { \
+ if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \
+ __asan_region_is_poisoned(__offset, __size)) { \
GET_CURRENT_PC_BP_SP; \
__asan_report_error(pc, bp, sp, __offset, isWrite, __size); \
} \
diff --git a/libsanitizer/asan/asan_internal.h b/libsanitizer/asan/asan_internal.h
index 0fe620e2e4c..1ccbf108647 100644
--- a/libsanitizer/asan/asan_internal.h
+++ b/libsanitizer/asan/asan_internal.h
@@ -52,7 +52,7 @@
#define ASAN_POSIX (ASAN_LINUX || ASAN_MAC)
-#if __has_feature(address_sanitizer)
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# error "The AddressSanitizer run-time should not be"
" instrumented by AddressSanitizer"
#endif
@@ -89,6 +89,10 @@
# endif
#endif
+#ifndef ASAN_USE_PREINIT_ARRAY
+# define ASAN_USE_PREINIT_ARRAY (ASAN_LINUX && !ASAN_ANDROID)
+#endif
+
// All internal functions in asan reside inside the __asan namespace
// to avoid namespace collisions with the user programs.
// Seperate namespace also makes it simpler to distinguish the asan run-time
diff --git a/libsanitizer/asan/asan_mac.cc b/libsanitizer/asan/asan_mac.cc
index c5fc7de10c0..dd2657df1e2 100644
--- a/libsanitizer/asan/asan_mac.cc
+++ b/libsanitizer/asan/asan_mac.cc
@@ -86,6 +86,39 @@ extern "C"
void __asan_init();
static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
+LowLevelAllocator allocator_for_env;
+
+// Change the value of the env var |name|, leaking the original value.
+// If |name_value| is NULL, the variable is deleted from the environment,
+// otherwise the corresponding "NAME=value" string is replaced with
+// |name_value|.
+void LeakyResetEnv(const char *name, const char *name_value) {
+ char ***env_ptr = _NSGetEnviron();
+ CHECK(env_ptr);
+ char **environ = *env_ptr;
+ CHECK(environ);
+ uptr name_len = internal_strlen(name);
+ while (*environ != 0) {
+ uptr len = internal_strlen(*environ);
+ if (len > name_len) {
+ const char *p = *environ;
+ if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') {
+ // Match.
+ if (name_value) {
+ // Replace the old value with the new one.
+ *environ = const_cast<char*>(name_value);
+ } else {
+ // Shift the subsequent pointers back.
+ char **del = environ;
+ do {
+ del[0] = del[1];
+ } while (*del++);
+ }
+ }
+ }
+ environ++;
+ }
+}
void MaybeReexec() {
if (!flags()->allow_reexec) return;
@@ -94,7 +127,11 @@ void MaybeReexec() {
// ourselves.
Dl_info info;
CHECK(dladdr((void*)((uptr)__asan_init), &info));
- const char *dyld_insert_libraries = GetEnv(kDyldInsertLibraries);
+ char *dyld_insert_libraries =
+ const_cast<char*>(GetEnv(kDyldInsertLibraries));
+ uptr old_env_len = dyld_insert_libraries ?
+ internal_strlen(dyld_insert_libraries) : 0;
+ uptr fname_len = internal_strlen(info.dli_fname);
if (!dyld_insert_libraries ||
!REAL(strstr)(dyld_insert_libraries, info.dli_fname)) {
// DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
@@ -102,16 +139,79 @@ void MaybeReexec() {
char program_name[1024];
uint32_t buf_size = sizeof(program_name);
_NSGetExecutablePath(program_name, &buf_size);
- // Ok to use setenv() since the wrappers don't depend on the value of
- // asan_inited.
- setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
+ char *new_env = const_cast<char*>(info.dli_fname);
+ if (dyld_insert_libraries) {
+ // Append the runtime dylib name to the existing value of
+ // DYLD_INSERT_LIBRARIES.
+ new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
+ internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
+ new_env[old_env_len] = ':';
+ // Copy fname_len and add a trailing zero.
+ internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
+ fname_len + 1);
+ // Ok to use setenv() since the wrappers don't depend on the value of
+ // asan_inited.
+ setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
+ } else {
+ // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
+ setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
+ }
if (flags()->verbosity >= 1) {
Report("exec()-ing the program with\n");
- Report("%s=%s\n", kDyldInsertLibraries, info.dli_fname);
+ Report("%s=%s\n", kDyldInsertLibraries, new_env);
Report("to enable ASan wrappers.\n");
Report("Set ASAN_OPTIONS=allow_reexec=0 to disable this.\n");
}
execv(program_name, *_NSGetArgv());
+ } else {
+ // DYLD_INSERT_LIBRARIES is set and contains the runtime library.
+ if (old_env_len == fname_len) {
+ // It's just the runtime library name - fine to unset the variable.
+ LeakyResetEnv(kDyldInsertLibraries, NULL);
+ } else {
+ uptr env_name_len = internal_strlen(kDyldInsertLibraries);
+ // Allocate memory to hold the previous env var name, its value, the '='
+ // sign and the '\0' char.
+ char *new_env = (char*)allocator_for_env.Allocate(
+ old_env_len + 2 + env_name_len);
+ CHECK(new_env);
+ internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
+ internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
+ new_env[env_name_len] = '=';
+ char *new_env_pos = new_env + env_name_len + 1;
+
+ // Iterate over colon-separated pieces of |dyld_insert_libraries|.
+ char *piece_start = dyld_insert_libraries;
+ char *piece_end = NULL;
+ char *old_env_end = dyld_insert_libraries + old_env_len;
+ do {
+ if (piece_start[0] == ':') piece_start++;
+ piece_end = REAL(strchr)(piece_start, ':');
+ if (!piece_end) piece_end = dyld_insert_libraries + old_env_len;
+ if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
+ uptr piece_len = piece_end - piece_start;
+
+ // If the current piece isn't the runtime library name,
+ // append it to new_env.
+ if ((piece_len != fname_len) ||
+ (internal_strncmp(piece_start, info.dli_fname, fname_len) != 0)) {
+ if (new_env_pos != new_env + env_name_len + 1) {
+ new_env_pos[0] = ':';
+ new_env_pos++;
+ }
+ internal_strncpy(new_env_pos, piece_start, piece_len);
+ }
+ // Move on to the next piece.
+ new_env_pos += piece_len;
+ piece_start = piece_end;
+ } while (piece_start < old_env_end);
+
+ // Can't use setenv() here, because it requires the allocator to be
+ // initialized.
+ // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in
+ // a separate function called after InitializeAllocator().
+ LeakyResetEnv(kDyldInsertLibraries, new_env);
+ }
}
}
diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h
index 48b24545b99..df952363893 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -1,7 +1,5 @@
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
@@ -18,6 +16,37 @@
// The full explanation of the memory mapping could be found here:
// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
+//
+// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
+// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
+// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
+// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap ||
+// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
+// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
+//
+// When SHADOW_OFFSET is zero (-pie):
+// || `[0x100000000000, 0x7fffffffffff]` || HighMem ||
+// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
+// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap ||
+//
+// Special case when something is already mapped between
+// 0x003000000000 and 0x004000000000 (e.g. when prelink is installed):
+// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
+// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
+// || `[0x004000000000, 0x02008fff6fff]` || ShadowGap3 ||
+// || `[0x003000000000, 0x003fffffffff]` || MidMem ||
+// || `[0x00087fff8000, 0x002fffffffff]` || ShadowGap2 ||
+// || `[0x00067fff8000, 0x00087fff7fff]` || MidShadow ||
+// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap ||
+// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
+// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
+//
+// Default Linux/i386 mapping:
+// || `[0x40000000, 0xffffffff]` || HighMem ||
+// || `[0x28000000, 0x3fffffff]` || HighShadow ||
+// || `[0x24000000, 0x27ffffff]` || ShadowGap ||
+// || `[0x20000000, 0x23ffffff]` || LowShadow ||
+// || `[0x00000000, 0x1fffffff]` || LowMem ||
#if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1
extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale;
@@ -36,7 +65,11 @@ extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset;
# if defined(__powerpc64__)
# define SHADOW_OFFSET (1ULL << 41)
# else
-# define SHADOW_OFFSET (1ULL << 44)
+# if ASAN_MAC
+# define SHADOW_OFFSET (1ULL << 44)
+# else
+# define SHADOW_OFFSET 0x7fff8000ULL
+# endif
# endif
# endif
# endif
@@ -57,49 +90,105 @@ extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset;
#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
+# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
+# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
+
// With the zero shadow base we can not actually map pages starting from 0.
// This constant is somewhat arbitrary.
#define kZeroBaseShadowStart (1 << 18)
#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \
: kZeroBaseShadowStart)
-#define kShadowGapEnd (kHighShadowBeg - 1)
+#define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
+
+#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
+#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
+
+#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
+#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
+
+#define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below.
+
+#if DO_ASAN_MAPPING_PROFILE
+# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
+#else
+# define PROFILE_ASAN_MAPPING()
+#endif
+
+// If 1, all shadow boundaries are constants.
+// Don't set to 1 other than for testing.
+#define ASAN_FIXED_MAPPING 0
namespace __asan {
+extern uptr AsanMappingProfile[];
+
+#if ASAN_FIXED_MAPPING
+// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
+// with non-fixed mapping. As of r175253 (Feb 2013) the performance
+// difference between fixed and non-fixed mapping is below the noise level.
+static uptr kHighMemEnd = 0x7fffffffffffULL;
+static uptr kMidMemBeg = 0x3000000000ULL;
+static uptr kMidMemEnd = 0x3fffffffffULL;
+#else
SANITIZER_INTERFACE_ATTRIBUTE
-extern uptr kHighMemEnd; // Initialized in __asan_init.
+extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
+#endif
static inline bool AddrIsInLowMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a < kLowMemEnd;
}
static inline bool AddrIsInLowShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a >= kLowShadowBeg && a <= kLowShadowEnd;
}
static inline bool AddrIsInHighMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
return a >= kHighMemBeg && a <= kHighMemEnd;
}
+static inline bool AddrIsInMidMem(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
+}
+
static inline bool AddrIsInMem(uptr a) {
- return AddrIsInLowMem(a) || AddrIsInHighMem(a);
+ PROFILE_ASAN_MAPPING();
+ return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);
}
static inline uptr MemToShadow(uptr p) {
+ PROFILE_ASAN_MAPPING();
CHECK(AddrIsInMem(p));
return MEM_TO_SHADOW(p);
}
static inline bool AddrIsInHighShadow(uptr a) {
- return a >= kHighShadowBeg && a <= kHighMemEnd;
+ PROFILE_ASAN_MAPPING();
+ return a >= kHighShadowBeg && a <= kHighMemEnd;
+}
+
+static inline bool AddrIsInMidShadow(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;
}
static inline bool AddrIsInShadow(uptr a) {
- return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);
+ PROFILE_ASAN_MAPPING();
+ return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
}
static inline bool AddrIsInShadowGap(uptr a) {
+ PROFILE_ASAN_MAPPING();
+ if (kMidMemBeg) {
+ if (a <= kShadowGapEnd)
+ return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
+ return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
+ (a >= kShadowGap3Beg && a <= kShadowGap3End);
+ }
// In zero-based shadow mode we treat addresses near zero as addresses
// in shadow gap as well.
if (SHADOW_OFFSET == 0)
@@ -108,12 +197,14 @@ static inline bool AddrIsInShadowGap(uptr a) {
}
static inline bool AddrIsAlignedByGranularity(uptr a) {
+ PROFILE_ASAN_MAPPING();
return (a & (SHADOW_GRANULARITY - 1)) == 0;
}
static inline bool AddressIsPoisoned(uptr a) {
+ PROFILE_ASAN_MAPPING();
const uptr kAccessSize = 1;
- u8 *shadow_address = (u8*)MemToShadow(a);
+ u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
s8 shadow_value = *shadow_address;
if (shadow_value) {
u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
@@ -123,6 +214,9 @@ static inline bool AddressIsPoisoned(uptr a) {
return false;
}
+// Must be after all calls to PROFILE_ASAN_MAPPING().
+static const uptr kAsanMappingProfileSize = __LINE__;
+
} // namespace __asan
#endif // ASAN_MAPPING_H
diff --git a/libsanitizer/asan/asan_report.cc b/libsanitizer/asan/asan_report.cc
index 663e8f3b748..13e94c421b5 100644
--- a/libsanitizer/asan/asan_report.cc
+++ b/libsanitizer/asan/asan_report.cc
@@ -433,9 +433,9 @@ class ScopedInErrorReport {
// an error report will finish doing it.
SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
}
- // If we're still not dead for some reason, use raw Exit() instead of
+ // If we're still not dead for some reason, use raw _exit() instead of
// Die() to bypass any additional checks.
- Exit(flags()->exitcode);
+ internal__exit(flags()->exitcode);
}
ASAN_ON_ERROR();
reporting_thread_tid = asanThreadRegistry().GetCurrentTidOrInvalid();
diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc
index 175d37788c2..4b0afd2731a 100644
--- a/libsanitizer/asan/asan_rtl.cc
+++ b/libsanitizer/asan/asan_rtl.cc
@@ -25,6 +25,8 @@
namespace __asan {
+uptr AsanMappingProfile[kAsanMappingProfileSize];
+
static void AsanDie() {
static atomic_uint32_t num_calls;
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
@@ -35,13 +37,19 @@ static void AsanDie() {
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
SleepForSeconds(flags()->sleep_before_dying);
}
- if (flags()->unmap_shadow_on_exit)
- UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+ if (flags()->unmap_shadow_on_exit) {
+ if (kMidMemBeg) {
+ UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
+ UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
+ } else {
+ UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+ }
+ }
if (death_callback)
death_callback();
if (flags()->abort_on_error)
Abort();
- Exit(flags()->exitcode);
+ internal__exit(flags()->exitcode);
}
static void AsanCheckFailed(const char *file, int line, const char *cond,
@@ -66,6 +74,17 @@ static const char *MaybeCallAsanDefaultOptions() {
return (&__asan_default_options) ? __asan_default_options() : "";
}
+static const char *MaybeUseAsanDefaultOptionsCompileDefiniton() {
+#ifdef ASAN_DEFAULT_OPTIONS
+// Stringize the macro value.
+# define ASAN_STRINGIZE(x) #x
+# define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options)
+ return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS);
+#else
+ return "";
+#endif
+}
+
static void ParseFlagsFromString(Flags *f, const char *str) {
ParseFlag(str, &f->quarantine_size, "quarantine_size");
ParseFlag(str, &f->symbolize, "symbolize");
@@ -146,6 +165,9 @@ void InitializeFlags(Flags *f, const char *env) {
f->alloc_dealloc_mismatch = true;
f->use_stack_depot = true; // Only affects allocator2.
+ // Override from compile definition.
+ ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton());
+
// Override from user-specified string.
ParseFlagsFromString(f, MaybeCallAsanDefaultOptions());
if (flags()->verbosity) {
@@ -161,7 +183,10 @@ void InitializeFlags(Flags *f, const char *env) {
int asan_inited;
bool asan_init_is_running;
void (*death_callback)(void);
-uptr kHighMemEnd;
+
+#if !ASAN_FIXED_MAPPING
+uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
+#endif
// -------------------------- Misc ---------------- {{{1
void ShowStatsAndAbort() {
@@ -209,6 +234,17 @@ ASAN_REPORT_ERROR(store, true, 4)
ASAN_REPORT_ERROR(store, true, 8)
ASAN_REPORT_ERROR(store, true, 16)
+#define ASAN_REPORT_ERROR_N(type, is_write) \
+extern "C" NOINLINE INTERFACE_ATTRIBUTE \
+void __asan_report_ ## type ## _n(uptr addr, uptr size); \
+void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
+ GET_CALLER_PC_BP_SP; \
+ __asan_report_error(pc, bp, sp, addr, is_write, size); \
+}
+
+ASAN_REPORT_ERROR_N(load, false)
+ASAN_REPORT_ERROR_N(store, true)
+
// Force the linker to keep the symbols for various ASan interface functions.
// We want to keep those in the executable in order to let the instrumented
// dynamic libraries access the symbol even if it is not used by the executable
@@ -259,9 +295,15 @@ static NOINLINE void force_interface_symbols() {
static void asan_atexit() {
Printf("AddressSanitizer exit stats:\n");
__asan_print_accumulated_stats();
+ // Print AsanMappingProfile.
+ for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
+ if (AsanMappingProfile[i] == 0) continue;
+ Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
+ }
}
static void InitializeHighMemEnd() {
+#if !ASAN_FIXED_MAPPING
#if SANITIZER_WORDSIZE == 64
# if defined(__powerpc64__)
// FIXME:
@@ -277,6 +319,58 @@ static void InitializeHighMemEnd() {
#else // SANITIZER_WORDSIZE == 32
kHighMemEnd = (1ULL << 32) - 1; // 0xffffffff;
#endif // SANITIZER_WORDSIZE
+#endif // !ASAN_FIXED_MAPPING
+}
+
+static void ProtectGap(uptr a, uptr size) {
+ CHECK_EQ(a, (uptr)Mprotect(a, size));
+}
+
+static void PrintAddressSpaceLayout() {
+ Printf("|| `[%p, %p]` || HighMem ||\n",
+ (void*)kHighMemBeg, (void*)kHighMemEnd);
+ Printf("|| `[%p, %p]` || HighShadow ||\n",
+ (void*)kHighShadowBeg, (void*)kHighShadowEnd);
+ if (kMidMemBeg) {
+ Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
+ (void*)kShadowGap3Beg, (void*)kShadowGap3End);
+ Printf("|| `[%p, %p]` || MidMem ||\n",
+ (void*)kMidMemBeg, (void*)kMidMemEnd);
+ Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
+ (void*)kShadowGap2Beg, (void*)kShadowGap2End);
+ Printf("|| `[%p, %p]` || MidShadow ||\n",
+ (void*)kMidShadowBeg, (void*)kMidShadowEnd);
+ }
+ Printf("|| `[%p, %p]` || ShadowGap ||\n",
+ (void*)kShadowGapBeg, (void*)kShadowGapEnd);
+ if (kLowShadowBeg) {
+ Printf("|| `[%p, %p]` || LowShadow ||\n",
+ (void*)kLowShadowBeg, (void*)kLowShadowEnd);
+ Printf("|| `[%p, %p]` || LowMem ||\n",
+ (void*)kLowMemBeg, (void*)kLowMemEnd);
+ }
+ Printf("MemToShadow(shadow): %p %p %p %p",
+ (void*)MEM_TO_SHADOW(kLowShadowBeg),
+ (void*)MEM_TO_SHADOW(kLowShadowEnd),
+ (void*)MEM_TO_SHADOW(kHighShadowBeg),
+ (void*)MEM_TO_SHADOW(kHighShadowEnd));
+ if (kMidMemBeg) {
+ Printf(" %p %p",
+ (void*)MEM_TO_SHADOW(kMidShadowBeg),
+ (void*)MEM_TO_SHADOW(kMidShadowEnd));
+ }
+ Printf("\n");
+ Printf("red_zone=%zu\n", (uptr)flags()->redzone);
+ Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
+
+ Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
+ Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
+ Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
+ CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
+ if (kMidMemBeg)
+ CHECK(kMidShadowBeg > kLowShadowEnd &&
+ kMidMemBeg > kMidShadowEnd &&
+ kHighShadowBeg > kMidMemEnd);
}
} // namespace __asan
@@ -352,49 +446,48 @@ void __asan_init() {
ReplaceSystemMalloc();
ReplaceOperatorsNewAndDelete();
- if (flags()->verbosity) {
- Printf("|| `[%p, %p]` || HighMem ||\n",
- (void*)kHighMemBeg, (void*)kHighMemEnd);
- Printf("|| `[%p, %p]` || HighShadow ||\n",
- (void*)kHighShadowBeg, (void*)kHighShadowEnd);
- Printf("|| `[%p, %p]` || ShadowGap ||\n",
- (void*)kShadowGapBeg, (void*)kShadowGapEnd);
- Printf("|| `[%p, %p]` || LowShadow ||\n",
- (void*)kLowShadowBeg, (void*)kLowShadowEnd);
- Printf("|| `[%p, %p]` || LowMem ||\n",
- (void*)kLowMemBeg, (void*)kLowMemEnd);
- Printf("MemToShadow(shadow): %p %p %p %p\n",
- (void*)MEM_TO_SHADOW(kLowShadowBeg),
- (void*)MEM_TO_SHADOW(kLowShadowEnd),
- (void*)MEM_TO_SHADOW(kHighShadowBeg),
- (void*)MEM_TO_SHADOW(kHighShadowEnd));
- Printf("red_zone=%zu\n", (uptr)flags()->redzone);
- Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
-
- Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
- Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
- Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
- CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
+ uptr shadow_start = kLowShadowBeg;
+ if (kLowShadowBeg) shadow_start -= GetMmapGranularity();
+ uptr shadow_end = kHighShadowEnd;
+ bool full_shadow_is_available =
+ MemoryRangeIsAvailable(shadow_start, shadow_end);
+
+#if ASAN_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING
+ if (!full_shadow_is_available) {
+ kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
+ kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x3fffffffffULL : 0;
}
+#endif
+
+ if (flags()->verbosity)
+ PrintAddressSpaceLayout();
if (flags()->disable_core) {
DisableCoreDumper();
}
- uptr shadow_start = kLowShadowBeg;
- if (kLowShadowBeg > 0) shadow_start -= GetMmapGranularity();
- uptr shadow_end = kHighShadowEnd;
- if (MemoryRangeIsAvailable(shadow_start, shadow_end)) {
- if (kLowShadowBeg != kLowShadowEnd) {
- // mmap the low shadow plus at least one page.
- ReserveShadowMemoryRange(kLowShadowBeg - GetMmapGranularity(),
- kLowShadowEnd);
- }
+ if (full_shadow_is_available) {
+ // mmap the low shadow plus at least one page at the left.
+ if (kLowShadowBeg)
+ ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+ // mmap the high shadow.
+ ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
+ // protect the gap.
+ ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+ } else if (kMidMemBeg &&
+ MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
+ MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) {
+ CHECK(kLowShadowBeg != kLowShadowEnd);
+ // mmap the low shadow plus at least one page at the left.
+ ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
+ // mmap the mid shadow.
+ ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
// mmap the high shadow.
ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
- // protect the gap
- void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
- CHECK(prot == (void*)kShadowGapBeg);
+ // protect the gaps.
+ ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+ ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
+ ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
} else {
Report("Shadow memory range interleaves with an existing memory mapping. "
"ASan cannot proceed correctly. ABORTING.\n");
@@ -427,12 +520,12 @@ void __asan_init() {
}
}
-#if defined(ASAN_USE_PREINIT_ARRAY)
+#if ASAN_USE_PREINIT_ARRAY && !defined (PIC)
// On Linux, we force __asan_init to be called before anyone else
// by placing it into .preinit_array section.
// FIXME: do we have anything like this on Mac?
- __attribute__((section(".preinit_array")))
- typeof(__asan_init) *__asan_preinit =__asan_init;
+ __attribute__((section(".preinit_array"), used))
+ void (*__asan_preinit)(void) =__asan_init;
#elif defined(_WIN32) && defined(_DLL)
// On Windows, when using dynamic CRT (/MD), we can put a pointer
// to __asan_init into the global list of C initializers.
diff --git a/libsanitizer/asan/dynamic/asan_interceptors_dynamic.cc b/libsanitizer/asan/dynamic/asan_interceptors_dynamic.cc
deleted file mode 100644
index 727edf2b43b..00000000000
--- a/libsanitizer/asan/dynamic/asan_interceptors_dynamic.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-//===-- asan_interceptors_dynamic.cc --------------------------------------===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// __DATA,__interpose section of the dynamic runtime library for Mac OS.
-//===----------------------------------------------------------------------===//
-
-#if defined(__APPLE__)
-
-#include "../asan_interceptors.h"
-#include "../asan_intercepted_functions.h"
-
-namespace __asan {
-
-#define INTERPOSE_FUNCTION(function) \
- { reinterpret_cast<const uptr>(WRAP(function)), \
- reinterpret_cast<const uptr>(function) }
-
-#define INTERPOSE_FUNCTION_2(function, wrapper) \
- { reinterpret_cast<const uptr>(wrapper), \
- reinterpret_cast<const uptr>(function) }
-
-struct interpose_substitution {
- const uptr replacement;
- const uptr original;
-};
-
-__attribute__((used))
-const interpose_substitution substitutions[]
- __attribute__((section("__DATA, __interpose"))) = {
- INTERPOSE_FUNCTION(strlen),
- INTERPOSE_FUNCTION(memcmp),
- INTERPOSE_FUNCTION(memcpy),
- INTERPOSE_FUNCTION(memmove),
- INTERPOSE_FUNCTION(memset),
- INTERPOSE_FUNCTION(strchr),
- INTERPOSE_FUNCTION(strcat),
- INTERPOSE_FUNCTION(strncat),
- INTERPOSE_FUNCTION(strcpy),
- INTERPOSE_FUNCTION(strncpy),
- INTERPOSE_FUNCTION(pthread_create),
- INTERPOSE_FUNCTION(longjmp),
-#if ASAN_INTERCEPT__LONGJMP
- INTERPOSE_FUNCTION(_longjmp),
-#endif
-#if ASAN_INTERCEPT_SIGLONGJMP
- INTERPOSE_FUNCTION(siglongjmp),
-#endif
-#if ASAN_INTERCEPT_STRDUP
- INTERPOSE_FUNCTION(strdup),
-#endif
-#if ASAN_INTERCEPT_STRNLEN
- INTERPOSE_FUNCTION(strnlen),
-#endif
-#if ASAN_INTERCEPT_INDEX
- INTERPOSE_FUNCTION_2(index, WRAP(strchr)),
-#endif
- INTERPOSE_FUNCTION(strcmp),
- INTERPOSE_FUNCTION(strncmp),
-#if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP
- INTERPOSE_FUNCTION(strcasecmp),
- INTERPOSE_FUNCTION(strncasecmp),
-#endif
- INTERPOSE_FUNCTION(atoi),
- INTERPOSE_FUNCTION(atol),
- INTERPOSE_FUNCTION(strtol),
-#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
- INTERPOSE_FUNCTION(atoll),
- INTERPOSE_FUNCTION(strtoll),
-#endif
-#if ASAN_INTERCEPT_MLOCKX
- INTERPOSE_FUNCTION(mlock),
- INTERPOSE_FUNCTION(munlock),
- INTERPOSE_FUNCTION(mlockall),
- INTERPOSE_FUNCTION(munlockall),
-#endif
- INTERPOSE_FUNCTION(dispatch_async_f),
- INTERPOSE_FUNCTION(dispatch_sync_f),
- INTERPOSE_FUNCTION(dispatch_after_f),
- INTERPOSE_FUNCTION(dispatch_barrier_async_f),
- INTERPOSE_FUNCTION(dispatch_group_async_f),
-#ifndef MISSING_BLOCKS_SUPPORT
- INTERPOSE_FUNCTION(dispatch_group_async),
- INTERPOSE_FUNCTION(dispatch_async),
- INTERPOSE_FUNCTION(dispatch_after),
- INTERPOSE_FUNCTION(dispatch_source_set_event_handler),
- INTERPOSE_FUNCTION(dispatch_source_set_cancel_handler),
-#endif
- INTERPOSE_FUNCTION(signal),
- INTERPOSE_FUNCTION(sigaction),
-
- INTERPOSE_FUNCTION(malloc_create_zone),
- INTERPOSE_FUNCTION(malloc_default_zone),
- INTERPOSE_FUNCTION(malloc_default_purgeable_zone),
- INTERPOSE_FUNCTION(malloc_make_purgeable),
- INTERPOSE_FUNCTION(malloc_make_nonpurgeable),
- INTERPOSE_FUNCTION(malloc_set_zone_name),
- INTERPOSE_FUNCTION(malloc),
- INTERPOSE_FUNCTION(free),
- INTERPOSE_FUNCTION(realloc),
- INTERPOSE_FUNCTION(calloc),
- INTERPOSE_FUNCTION(valloc),
- INTERPOSE_FUNCTION(malloc_good_size),
- INTERPOSE_FUNCTION(posix_memalign),
-};
-
-} // namespace __asan
-
-#endif // __APPLE__
diff --git a/libsanitizer/include/sanitizer/asan_interface.h b/libsanitizer/include/sanitizer/asan_interface.h
index 18696a681ed..0016339e486 100644
--- a/libsanitizer/include/sanitizer/asan_interface.h
+++ b/libsanitizer/include/sanitizer/asan_interface.h
@@ -35,8 +35,8 @@ extern "C" {
// (un)poison memory in the same memory region simultaneously.
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
- // User code should use macro instead of functions.
-#if __has_feature(address_sanitizer)
+// User code should use macros instead of functions.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
#define ASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
diff --git a/libsanitizer/include/sanitizer/common_interface_defs.h b/libsanitizer/include/sanitizer/common_interface_defs.h
index b61b8a1a636..c218b5b5654 100644
--- a/libsanitizer/include/sanitizer/common_interface_defs.h
+++ b/libsanitizer/include/sanitizer/common_interface_defs.h
@@ -14,6 +14,11 @@
#include <stddef.h>
#include <stdint.h>
+// GCC does not understand __has_feature.
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh
index d2e622aeb1a..9c29b319829 100755
--- a/libsanitizer/merge.sh
+++ b/libsanitizer/merge.sh
@@ -66,7 +66,6 @@ CUR_REV=$(get_current_rev)
echo Current upstream revision: $CUR_REV
merge include/sanitizer include/sanitizer
merge lib/asan asan
-merge lib/asan/dynamic asan/dynamic
merge lib/tsan/rtl tsan
merge lib/sanitizer_common sanitizer_common
merge lib/interception interception
diff --git a/libsanitizer/sanitizer_common/Makefile.am b/libsanitizer/sanitizer_common/Makefile.am
index 79585e48ed2..c53a3c6bfc5 100644
--- a/libsanitizer/sanitizer_common/Makefile.am
+++ b/libsanitizer/sanitizer_common/Makefile.am
@@ -17,6 +17,7 @@ sanitizer_common_files = \
sanitizer_libc.cc \
sanitizer_linux.cc \
sanitizer_mac.cc \
+ sanitizer_platform_limits_posix.cc \
sanitizer_posix.cc \
sanitizer_printf.cc \
sanitizer_stackdepot.cc \
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index ce68d5e02f6..32e0dc8cac6 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -74,11 +74,12 @@ LTLIBRARIES = $(noinst_LTLIBRARIES)
libsanitizer_common_la_LIBADD =
am__objects_1 = sanitizer_allocator.lo sanitizer_common.lo \
sanitizer_flags.lo sanitizer_libc.lo sanitizer_linux.lo \
- sanitizer_mac.lo sanitizer_posix.lo sanitizer_printf.lo \
- sanitizer_stackdepot.lo sanitizer_stacktrace.lo \
- sanitizer_symbolizer.lo sanitizer_symbolizer_itanium.lo \
- sanitizer_symbolizer_linux.lo sanitizer_symbolizer_mac.lo \
- sanitizer_symbolizer_win.lo sanitizer_win.lo
+ sanitizer_mac.lo sanitizer_platform_limits_posix.lo \
+ sanitizer_posix.lo sanitizer_printf.lo sanitizer_stackdepot.lo \
+ sanitizer_stacktrace.lo sanitizer_symbolizer.lo \
+ sanitizer_symbolizer_itanium.lo sanitizer_symbolizer_linux.lo \
+ sanitizer_symbolizer_mac.lo sanitizer_symbolizer_win.lo \
+ sanitizer_win.lo
am_libsanitizer_common_la_OBJECTS = $(am__objects_1)
libsanitizer_common_la_OBJECTS = $(am_libsanitizer_common_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -252,6 +253,7 @@ sanitizer_common_files = \
sanitizer_libc.cc \
sanitizer_linux.cc \
sanitizer_mac.cc \
+ sanitizer_platform_limits_posix.cc \
sanitizer_posix.cc \
sanitizer_printf.cc \
sanitizer_stackdepot.cc \
@@ -362,6 +364,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_posix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_printf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stackdepot.Plo@am__quote@
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cc
index 4447c346eba..f8d2d0e3fe5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_common.cc
@@ -43,7 +43,7 @@ void NORETURN Die() {
if (DieCallback) {
DieCallback();
}
- Exit(1);
+ internal__exit(1);
}
static CheckFailedCallbackType CheckFailedCallback;
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h
index 109966ba360..302dc742769 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -124,6 +124,7 @@ void DumpProcessMap();
bool FileExists(const char *filename);
const char *GetEnv(const char *name);
const char *GetPwd();
+u32 GetUid();
void ReExec();
bool StackSizeIsUnlimited();
void SetStackSizeLimitInBytes(uptr limit);
@@ -137,7 +138,6 @@ void SortArray(uptr *array, uptr size);
// Exit
void NORETURN Abort();
-void NORETURN Exit(int exitcode);
void NORETURN Die();
void NORETURN SANITIZER_INTERFACE_ATTRIBUTE
CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
index 4ba7b8fee9f..af27603ebdd 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
@@ -124,8 +124,8 @@ INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
#endif
#if SANITIZER_INTERCEPT_PRCTL
-INTERCEPTOR(int, prctl, int option, unsigned long arg2,
- unsigned long arg3, // NOLINT
+INTERCEPTOR(int, prctl, int option,
+ unsigned long arg2, unsigned long arg3, // NOLINT
unsigned long arg4, unsigned long arg5) { // NOLINT
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
@@ -144,6 +144,100 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2,
#define INIT_PRCTL
#endif // SANITIZER_INTERCEPT_PRCTL
+#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
+INTERCEPTOR(void *, localtime, unsigned long *timep) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
+ void *res = REAL(localtime)(timep);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
+ }
+ return res;
+}
+INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
+ void *res = REAL(localtime_r)(timep, result);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
+ }
+ return res;
+}
+INTERCEPTOR(void *, gmtime, unsigned long *timep) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
+ void *res = REAL(gmtime)(timep);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
+ }
+ return res;
+}
+INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
+ void *res = REAL(gmtime_r)(timep, result);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
+ }
+ return res;
+}
+INTERCEPTOR(char *, ctime, unsigned long *timep) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
+ char *res = REAL(ctime)(timep);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ }
+ return res;
+}
+INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
+ char *res = REAL(ctime_r)(timep, result);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ }
+ return res;
+}
+INTERCEPTOR(char *, asctime, void *tm) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
+ char *res = REAL(asctime)(tm);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ }
+ return res;
+}
+INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
+ char *res = REAL(asctime_r)(tm, result);
+ if (res) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ }
+ return res;
+}
+#define INIT_LOCALTIME_AND_FRIENDS \
+ INTERCEPT_FUNCTION(localtime); \
+ INTERCEPT_FUNCTION(localtime_r); \
+ INTERCEPT_FUNCTION(gmtime); \
+ INTERCEPT_FUNCTION(gmtime_r); \
+ INTERCEPT_FUNCTION(ctime); \
+ INTERCEPT_FUNCTION(ctime_r); \
+ INTERCEPT_FUNCTION(asctime); \
+ INTERCEPT_FUNCTION(asctime_r);
+#else
+#define INIT_LOCALTIME_AND_FRIENDS
+#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
+
#if SANITIZER_INTERCEPT_SCANF
#include "sanitizer_common_interceptors_scanf.inc"
@@ -170,6 +264,7 @@ VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
+#if SANITIZER_INTERCEPT_ISOC99_SCANF
INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
@@ -179,6 +274,7 @@ VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
+#endif // SANITIZER_INTERCEPT_ISOC99_SCANF
#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \
{ \
@@ -200,6 +296,7 @@ SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
+#if SANITIZER_INTERCEPT_ISOC99_SCANF
INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
@@ -208,6 +305,7 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
+#endif
#define INIT_SCANF \
INTERCEPT_FUNCTION(scanf); \
@@ -235,4 +333,5 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
INIT_WRITE; \
INIT_PWRITE; \
INIT_PWRITE64; \
+ INIT_LOCALTIME_AND_FRIENDS; \
INIT_SCANF;
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.cc b/libsanitizer/sanitizer_common/sanitizer_flags.cc
index 837738ceb81..2152c7bdff4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.cc
@@ -36,7 +36,8 @@ static bool GetFlagValue(const char *env, const char *name,
pos += 1;
end = internal_strchr(pos, '\'');
} else {
- end = internal_strchr(pos, ' ');
+ // Read until the next space or colon.
+ end = pos + internal_strcspn(pos, " :");
}
if (end == 0)
end = pos + internal_strlen(pos);
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index 1a25b70c23e..577c9a9c17f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -29,7 +29,7 @@
# define SANITIZER_SUPPORTS_WEAK_HOOKS 0
#endif
-// __has_feature
+// GCC does not understand __has_feature
#if !defined(__has_feature)
# define __has_feature(x) 0
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h
index 7a9774406fa..16239413356 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libc.h
+++ b/libsanitizer/sanitizer_common/sanitizer_libc.h
@@ -43,6 +43,7 @@ char *internal_strrchr(const char *s, int c);
char *internal_strstr(const char *haystack, const char *needle);
// Works only for base=10 and doesn't set errno.
s64 internal_simple_strtoll(const char *nptr, char **endptr, int base);
+int internal_snprintf(char *buffer, uptr length, const char *format, ...);
// Return true if all bytes in [mem, mem+size) are zero.
// Optimized for the case when the result is true.
@@ -68,14 +69,15 @@ fd_t internal_open(const char *filename, int flags, u32 mode);
uptr internal_read(fd_t fd, void *buf, uptr count);
uptr internal_write(fd_t fd, const void *buf, uptr count);
+
+// OS
uptr internal_filesize(fd_t fd); // -1 on error.
int internal_stat(const char *path, void *buf);
int internal_lstat(const char *path, void *buf);
int internal_fstat(fd_t fd, void *buf);
-
int internal_dup2(int oldfd, int newfd);
uptr internal_readlink(const char *path, char *buf, uptr bufsize);
-int internal_snprintf(char *buffer, uptr length, const char *format, ...);
+void NORETURN internal__exit(int exitcode);
// Threading
int internal_sched_yield();
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index 3d3aa0b00bd..06e5a0a6441 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -138,6 +138,11 @@ int internal_sched_yield() {
return syscall(__NR_sched_yield);
}
+void internal__exit(int exitcode) {
+ syscall(__NR_exit_group, exitcode);
+ Die(); // Unreachable.
+}
+
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
@@ -232,6 +237,21 @@ const char *GetEnv(const char *name) {
return 0; // Not found.
}
+#ifdef __GLIBC__
+
+extern "C" {
+ extern void *__libc_stack_end;
+}
+
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ uptr *stack_end = (uptr *)__libc_stack_end;
+ int argc = *stack_end;
+ *argv = (char**)(stack_end + 1);
+ *envp = (char**)(stack_end + argc + 2);
+}
+
+#else // __GLIBC__
+
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -251,12 +271,20 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
(*arr)[count] = 0;
}
+static void GetArgsAndEnv(char ***argv, char ***envp) {
+ static const int kMaxArgv = 2000, kMaxEnvp = 2000;
+ ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
+ ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
+}
+
+#endif // __GLIBC__
+
void ReExec() {
- static const int kMaxArgv = 100, kMaxEnvp = 1000;
char **argv, **envp;
- ReadNullSepFileToArray("/proc/self/cmdline", &argv, kMaxArgv);
- ReadNullSepFileToArray("/proc/self/environ", &envp, kMaxEnvp);
- execve(argv[0], argv, envp);
+ GetArgsAndEnv(&argv, &envp);
+ execve("/proc/self/exe", argv, envp);
+ Printf("execve failed, errno %d\n", errno);
+ Die();
}
void PrepareForSandboxing() {
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_mac.cc
index 309b5a94005..d7885bb3509 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.cc
@@ -104,6 +104,10 @@ int internal_sched_yield() {
return sched_yield();
}
+void internal__exit(int exitcode) {
+ _exit(exitcode);
+}
+
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
struct stat st;
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
index 2c60253c533..9b40c0cc523 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
@@ -14,6 +14,7 @@
#if !defined(_WIN32)
# define SI_NOT_WINDOWS 1
+# include "sanitizer_platform_limits_posix.h"
#else
# define SI_NOT_WINDOWS 0
#endif
@@ -24,6 +25,12 @@
# define SI_LINUX_NOT_ANDROID 0
#endif
+#if defined(__linux__)
+# define SI_LINUX 1
+#else
+# define SI_LINUX 0
+#endif
+
# define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_PREAD SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_WRITE SI_NOT_WINDOWS
@@ -33,4 +40,7 @@
# define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID
# define SANITIZER_INTERCEPT_PRCTL SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS SI_NOT_WINDOWS
+
# define SANITIZER_INTERCEPT_SCANF SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_ISOC99_SCANF SI_LINUX
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
new file mode 100644
index 00000000000..c4be1aa42da
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -0,0 +1,68 @@
+//===-- sanitizer_platform_limits_posix.cc --------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific POSIX data structures.
+//===----------------------------------------------------------------------===//
+
+#if defined(__linux__) || defined(__APPLE__)
+
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform_limits_posix.h"
+
+#include <dirent.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <time.h>
+
+#if defined(__linux__)
+#include <sys/vfs.h>
+#include <sys/epoll.h>
+#endif // __linux__
+
+namespace __sanitizer {
+ unsigned struct_utsname_sz = sizeof(struct utsname);
+ unsigned struct_stat_sz = sizeof(struct stat);
+ unsigned struct_stat64_sz = sizeof(struct stat64);
+ unsigned struct_rusage_sz = sizeof(struct rusage);
+ unsigned struct_tm_sz = sizeof(struct tm);
+
+#if defined(__linux__)
+ unsigned struct_rlimit_sz = sizeof(struct rlimit);
+ unsigned struct_dirent_sz = sizeof(struct dirent);
+ unsigned struct_statfs_sz = sizeof(struct statfs);
+ unsigned struct_epoll_event_sz = sizeof(struct epoll_event);
+#endif // __linux__
+
+#if defined(__linux__) && !defined(__ANDROID__)
+ unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
+ unsigned struct_statfs64_sz = sizeof(struct statfs64);
+#endif // __linux__ && !__ANDROID__
+
+ void* __sanitizer_get_msghdr_iov_iov_base(void* msg, int idx) {
+ return ((struct msghdr *)msg)->msg_iov[idx].iov_base;
+ }
+
+ uptr __sanitizer_get_msghdr_iov_iov_len(void* msg, int idx) {
+ return ((struct msghdr *)msg)->msg_iov[idx].iov_len;
+ }
+
+ uptr __sanitizer_get_msghdr_iovlen(void* msg) {
+ return ((struct msghdr *)msg)->msg_iovlen;
+ }
+
+ uptr __sanitizer_get_socklen_t(void* socklen_ptr) {
+ return *(socklen_t*)socklen_ptr;
+ }
+} // namespace __sanitizer
+
+#endif // __linux__ || __APPLE__
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
new file mode 100644
index 00000000000..dd53da94be6
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -0,0 +1,41 @@
+//===-- sanitizer_platform_limits_posix.h ---------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific POSIX data structures.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H
+#define SANITIZER_PLATFORM_LIMITS_POSIX_H
+
+namespace __sanitizer {
+ extern unsigned struct_utsname_sz;
+ extern unsigned struct_stat_sz;
+ extern unsigned struct_stat64_sz;
+ extern unsigned struct_rusage_sz;
+ extern unsigned struct_tm_sz;
+
+#if defined(__linux__)
+ extern unsigned struct_rlimit_sz;
+ extern unsigned struct_dirent_sz;
+ extern unsigned struct_statfs_sz;
+ extern unsigned struct_epoll_event_sz;
+#endif // __linux__
+
+#if defined(__linux__) && !defined(__ANDROID__)
+ extern unsigned struct_rlimit64_sz;
+ extern unsigned struct_statfs64_sz;
+#endif // __linux__ && !__ANDROID__
+
+ void* __sanitizer_get_msghdr_iov_iov_base(void* msg, int idx);
+ uptr __sanitizer_get_msghdr_iov_iov_len(void* msg, int idx);
+ uptr __sanitizer_get_msghdr_iovlen(void* msg);
+ uptr __sanitizer_get_socklen_t(void* socklen_ptr);
+} // namespace __sanitizer
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cc
index 48c5ebaef3e..1c6ff0a2ebb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.cc
@@ -42,6 +42,10 @@ int GetPid() {
return getpid();
}
+u32 GetUid() {
+ return getuid();
+}
+
uptr GetThreadSelf() {
return (uptr)pthread_self();
}
@@ -203,10 +207,6 @@ void SleepForMillis(int millis) {
usleep(millis * 1000);
}
-void Exit(int exitcode) {
- _exit(exitcode);
-}
-
void Abort() {
abort();
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
index 259da0082e3..e14ea447264 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
@@ -129,8 +129,9 @@ void StackTrace::FastUnwindStack(uptr pc, uptr bp,
CHECK(size == 0 && trace[0] == pc);
size = 1;
uhwptr *frame = (uhwptr *)bp;
- uhwptr *prev_frame = frame;
- while (frame >= prev_frame &&
+ uhwptr *prev_frame = frame - 1;
+ // Avoid infinite loop when frame == frame[0] by using frame > prev_frame.
+ while (frame > prev_frame &&
frame < (uhwptr *)stack_top - 2 &&
frame > (uhwptr *)stack_bottom &&
size < max_size) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
index bb1c40f9613..01f1e4588da 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_linux.cc
@@ -97,7 +97,7 @@ bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
for (int fd = getdtablesize(); fd > 2; fd--)
internal_close(fd);
execl(path_to_symbolizer, path_to_symbolizer, (char*)0);
- Exit(1);
+ internal__exit(1);
}
// Continue execution in parent process.
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cc
index 3d5cde11cf8..695265594b3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win.cc
@@ -129,6 +129,10 @@ const char *GetPwd() {
UNIMPLEMENTED();
}
+u32 GetUid() {
+ UNIMPLEMENTED();
+}
+
void DumpProcessMap() {
UNIMPLEMENTED();
}
@@ -161,10 +165,6 @@ void SleepForMillis(int millis) {
Sleep(millis);
}
-void Exit(int exitcode) {
- _exit(exitcode);
-}
-
void Abort() {
abort();
_exit(-1); // abort is not NORETURN on Windows.
@@ -251,6 +251,10 @@ int internal_sched_yield() {
return 0;
}
+void internal__exit(int exitcode) {
+ _exit(exitcode);
+}
+
// ---------------------- BlockingMutex ---------------- {{{1
const uptr LOCK_UNINITIALIZED = 0;
const uptr LOCK_READY = (uptr)-1;
diff --git a/libsanitizer/tsan/tsan_platform_linux.cc b/libsanitizer/tsan/tsan_platform_linux.cc
index def91559d5e..f7b05f2bf8f 100644
--- a/libsanitizer/tsan/tsan_platform_linux.cc
+++ b/libsanitizer/tsan/tsan_platform_linux.cc
@@ -241,7 +241,7 @@ const char *InitializePlatform() {
g_tls_size = (uptr)InitTlsSize();
InitDataSeg();
#endif
- return getenv(kTsanOptionsEnv);
+ return GetEnv(kTsanOptionsEnv);
}
void FinalizePlatform() {
diff --git a/libsanitizer/tsan/tsan_platform_mac.cc b/libsanitizer/tsan/tsan_platform_mac.cc
index 808d99c0207..b247468c829 100644
--- a/libsanitizer/tsan/tsan_platform_mac.cc
+++ b/libsanitizer/tsan/tsan_platform_mac.cc
@@ -80,7 +80,7 @@ const char *InitializePlatform() {
setrlimit(RLIMIT_CORE, (rlimit*)&lim);
}
- return getenv(kTsanOptionsEnv);
+ return GetEnv(kTsanOptionsEnv);
}
void FinalizePlatform() {
diff --git a/libsanitizer/tsan/tsan_platform_windows.cc b/libsanitizer/tsan/tsan_platform_windows.cc
index 74b9020d077..376dc08688b 100644
--- a/libsanitizer/tsan/tsan_platform_windows.cc
+++ b/libsanitizer/tsan/tsan_platform_windows.cc
@@ -32,7 +32,7 @@ void FlushShadowMemory() {
}
const char *InitializePlatform() {
- return getenv(kTsanOptionsEnv);
+ return GetEnv(kTsanOptionsEnv);
}
void FinalizePlatform() {
diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h
index 717f4599705..e939921049a 100644
--- a/libsanitizer/tsan/tsan_rtl.h
+++ b/libsanitizer/tsan/tsan_rtl.h
@@ -590,6 +590,8 @@ void MemoryAccessImpl(ThreadState *thr, uptr addr,
u64 *shadow_mem, Shadow cur);
void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
uptr size, bool is_write);
+void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,
+ uptr size, uptr step, bool is_write);
const int kSizeLog1 = 0;
const int kSizeLog2 = 1;
diff --git a/libsanitizer/tsan/tsan_rtl_thread.cc b/libsanitizer/tsan/tsan_rtl_thread.cc
index 9c89417ad68..e30916dc627 100644
--- a/libsanitizer/tsan/tsan_rtl_thread.cc
+++ b/libsanitizer/tsan/tsan_rtl_thread.cc
@@ -420,4 +420,26 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
shadow_mem, cur);
}
}
+
+void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,
+ uptr size, uptr step, bool is_write) {
+ if (size == 0)
+ return;
+ FastState fast_state = thr->fast_state;
+ if (fast_state.GetIgnoreBit())
+ return;
+ StatInc(thr, StatMopRange);
+ fast_state.IncrementEpoch();
+ thr->fast_state = fast_state;
+ TraceAddEvent(thr, fast_state, EventTypeMop, pc);
+
+ for (uptr addr_end = addr + size; addr < addr_end; addr += step) {
+ u64 *shadow_mem = (u64*)MemToShadow(addr);
+ Shadow cur(fast_state);
+ cur.SetWrite(is_write);
+ cur.SetAddr0AndSizeLog(addr & (kShadowCell - 1), kSizeLog1);
+ MemoryAccessImpl(thr, addr, kSizeLog1, is_write, false,
+ shadow_mem, cur);
+ }
+}
} // namespace __tsan
diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cc
index cd88d2df928..fbec4225d9c 100644
--- a/libsanitizer/tsan/tsan_stat.cc
+++ b/libsanitizer/tsan/tsan_stat.cc
@@ -263,6 +263,14 @@ void StatOutput(u64 *stat) {
name[StatInt___isoc99_fscanf] = " fscanf ";
name[StatInt_on_exit] = " on_exit ";
name[StatInt___cxa_atexit] = " __cxa_atexit ";
+ name[StatInt_localtime] = " localtime ";
+ name[StatInt_localtime_r] = " localtime_r ";
+ name[StatInt_gmtime] = " gmtime ";
+ name[StatInt_gmtime_r] = " gmtime_r ";
+ name[StatInt_ctime] = " ctime ";
+ name[StatInt_ctime_r] = " ctime_r ";
+ name[StatInt_asctime] = " asctime ";
+ name[StatInt_asctime_r] = " asctime_r ";
name[StatAnnotation] = "Dynamic annotations ";
name[StatAnnotateHappensBefore] = " HappensBefore ";
diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h
index 1d6c54cdd4f..8b08a024be2 100644
--- a/libsanitizer/tsan/tsan_stat.h
+++ b/libsanitizer/tsan/tsan_stat.h
@@ -262,6 +262,14 @@ enum StatType {
StatInt___isoc99_fscanf,
StatInt_on_exit,
StatInt___cxa_atexit,
+ StatInt_localtime,
+ StatInt_localtime_r,
+ StatInt_gmtime,
+ StatInt_gmtime_r,
+ StatInt_ctime,
+ StatInt_ctime_r,
+ StatInt_asctime,
+ StatInt_asctime_r,
// Dynamic annotations.
StatAnnotation,
diff --git a/libsanitizer/tsan/tsan_suppressions.cc b/libsanitizer/tsan/tsan_suppressions.cc
index b6c54db2c51..8ee8de7c278 100644
--- a/libsanitizer/tsan/tsan_suppressions.cc
+++ b/libsanitizer/tsan/tsan_suppressions.cc
@@ -138,7 +138,7 @@ void InitializeSuppressions() {
g_suppressions = SuppressionParse(0, supp);
#ifndef TSAN_GO
supp = __tsan_default_suppressions();
- g_suppressions = SuppressionParse(0, supp);
+ g_suppressions = SuppressionParse(g_suppressions, supp);
#endif
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8d61a2d6e7d..8e4d68f77b5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,41 @@
+2013-02-20 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/streambuf (basic_streambuf): Use injected class name
+ instead of non-standard __streambuf_type typedef. Fix unclosed Doxygen
+ group.
+
+2013-02-20 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * doc/html/faq.html: Fix spelling.
+ * doc/xml/faq.xml: Likewise.
+ * include/bits/basic_ios.h: Likewise.
+ * include/bits/regex.h: Likewise.
+ * include/std/istream: Likewise.
+ * include/std/streambuf: Likewise.
+
+2013-02-20 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * testsuite/23_containers/unordered_set/55043.cc: Add missing
+ namespace qualification.
+ * testsuite/23_containers/unordered_multiset/55043.cc: Likewise.
+
+2013-02-19 Benjamin Kosnik <bkoz@redhat.com>
+
+ * doc/doxygen/user.cfg.in: Set __cplusplus to 201103L. Change to
+ _GLIBCXX_INCLUDE_AS_CXX11. DIRECTORY_GRAPH, MARKDOWN_SUPPORT,
+ AUTOLINK_SUPPORT to NO. Update to doxygen 1.8.3.1.
+ * include/bits/stl_pair.h: Add to utilities group.
+ * include/std/tuple: Same.
+ * include/std/typeindex: Same.
+
+ * include/bits/stringfwd.h: Fix markup.
+ * include/std/limits: Same.
+ * include/std/type_traits: Same.
+ * include/tr1/memory: Same.
+ * include/tr1/regex: Same.
+ * scripts/run_doxygen: Comment.
+ * testsuite/20_util/uses_allocator/cons_neg.cc: Fixup line numbers.
+
2013-02-14 Jason Merrill <jason@redhat.com>
* testsuite/18_support/quick_exit/quick_exit.cc: #if out the whole
diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 5af636bfe92..4a3afc4de93 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.2
+# Doxyfile 1.8.3.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -252,14 +252,15 @@ EXTENSION_MAPPING =
# can mix doxygen, HTML, and XML commands with Markdown formatting.
# Disable only in case of backward compatibilities issues.
-MARKDOWN_SUPPORT = YES
+MARKDOWN_SUPPORT = NO
-# When enabled doxygen tries to link words that correspond to documented classes,
-# or namespaces to their corresponding documentation. Such a link can be
-# prevented in individual cases by by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
+# When enabled doxygen tries to link words that correspond to
+# documented classes, or namespaces to their corresponding
+# documentation. Such a link can be prevented in individual cases by
+# by putting a % sign in front of the word or globally by setting
+# AUTOLINK_SUPPORT to NO.
-AUTOLINK_SUPPORT = YES
+AUTOLINK_SUPPORT = NO
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
@@ -281,7 +282,12 @@ CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
-# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT = NO
@@ -305,8 +311,7 @@ SUBGROUPING = YES
# @ingroup) instead of on a separate page (for HTML and Man pages) or
# section (for LaTeX and RTF).
-#INLINE_GROUPED_CLASSES = NO
-INLINE_GROUPED_CLASSES = YES
+INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
# unions with only public data fields will be shown inline in the documentation
@@ -314,7 +319,7 @@ INLINE_GROUPED_CLASSES = YES
# documentation), provided this scope is documented. If set to NO (the default),
# structs, classes, and unions are shown on a separate page (for HTML and Man
# pages) or section (for LaTeX and RTF).
-
+
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
@@ -542,7 +547,8 @@ GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
ENABLED_SECTIONS = @enabled_sections@
@@ -600,7 +606,8 @@ LAYOUT_FILE =
# requires the bibtex tool to be installed. See also
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
-# feature you need bibtex and perl available in the search path.
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
CITE_BIB_FILES =
@@ -952,6 +959,13 @@ FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page (index.html).
+# This can be useful if you have a project on for instance GitHub and want reuse
+# the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -1134,7 +1148,7 @@ HTML_TIMESTAMP = NO
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
-HTML_DYNAMIC_SECTIONS = YES
+HTML_DYNAMIC_SECTIONS = NO
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
# entries shown in the various tree structured indices initially; the user
@@ -1145,7 +1159,7 @@ HTML_DYNAMIC_SECTIONS = YES
# default. 0 is a special value representing an infinite number of entries
# and will result in a full expanded tree by default.
-HTML_INDEX_NUM_ENTRIES = 100
+HTML_INDEX_NUM_ENTRIES = 0
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
@@ -1361,6 +1375,13 @@ FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
+# When MathJax is enabled you can set the default output format to be used for
+# thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT = HTML-CSS
+
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
@@ -1389,15 +1410,55 @@ MATHJAX_EXTENSIONS =
SEARCHENGINE = NO
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvantages are that it is more difficult to setup
-# and does not have live searching capabilities.
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
SERVER_BASED_SEARCH = NO
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search engine
+# library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
+# of to a relative location where the documentation can be found.
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS =
+
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
@@ -1431,7 +1492,7 @@ MAKEINDEX_CMD_NAME = makeindex
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
-COMPACT_LATEX = YES
+COMPACT_LATEX = YES
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
@@ -1698,10 +1759,10 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = __cplusplus \
+PREDEFINED = __cplusplus=201103L \
__GTHREADS \
_GLIBCXX_HAS_GTHREADS \
- _GLIBCXX_INCLUDE_AS_CXX0X \
+ _GLIBCXX_INCLUDE_AS_CXX11 \
"_GLIBCXX_PURE= " \
"_GLIBCXX_CONST= " \
"_GLIBCXX_NORETURN= " \
@@ -1938,7 +1999,7 @@ GRAPHICAL_HIERARCHY = YES
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.
-DIRECTORY_GRAPH = YES
+DIRECTORY_GRAPH = NO
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are svg, png, jpg, or gif.
diff --git a/libstdc++-v3/doc/html/faq.html b/libstdc++-v3/doc/html/faq.html
index 0c1d3280a85..91952071e87 100644
--- a/libstdc++-v3/doc/html/faq.html
+++ b/libstdc++-v3/doc/html/faq.html
@@ -503,7 +503,7 @@
Short answer: Pretty much everything <span class="emphasis"><em>works</em></span>
except for some corner cases. Support for localization
in <code class="classname">locale</code> may be incomplete on non-GNU
- platforms. Also dependant on the underlying platform is support
+ platforms. Also dependent on the underlying platform is support
for <span class="type">wchar_t</span> and <span class="type">long
long</span> specializations, and details of thread support.
</p><p>
diff --git a/libstdc++-v3/doc/xml/faq.xml b/libstdc++-v3/doc/xml/faq.xml
index 1408bd24610..4e3339260ee 100644
--- a/libstdc++-v3/doc/xml/faq.xml
+++ b/libstdc++-v3/doc/xml/faq.xml
@@ -685,7 +685,7 @@
Short answer: Pretty much everything <emphasis>works</emphasis>
except for some corner cases. Support for localization
in <classname>locale</classname> may be incomplete on non-GNU
- platforms. Also dependant on the underlying platform is support
+ platforms. Also dependent on the underlying platform is support
for <type>wchar_t</type> and <type>long
long</type> specializations, and details of thread support.
</para>
diff --git a/libstdc++-v3/include/bits/basic_ios.h b/libstdc++-v3/include/bits/basic_ios.h
index b78b464ba02..5325800df90 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
//@{
/**
* These are standard types. They permit a standardized way of
- * referring to names of (or names dependant on) the template
+ * referring to names of (or names dependent on) the template
* parameters, which are specific to the implementation.
*/
typedef _CharT char_type;
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 39704bee716..101925a66f8 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -135,7 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/**
- * @brief Gets a sort key for a character sequence, independant of case.
+ * @brief Gets a sort key for a character sequence, independent of case.
*
* @param __first beginning of the character sequence.
* @param __last one-past-the-end of the character sequence.
@@ -185,7 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the returned mask identifies the classification regardless of
* the case of the characters to be matched (for example,
* [[:lower:]] is the same as [[:alpha:]]), otherwise a
- * case-dependant classification is returned. The value
+ * case-dependent classification is returned. The value
* returned shall be independent of the case of the characters
* in the character sequence. If the name is not recognized then
* returns a value that compares equal to 0.
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 967951cfecc..92250166b40 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -66,6 +66,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /**
+ * @addtogroup utilities
+ * @{
+ */
+
#if __cplusplus >= 201103L
/// piecewise_construct_t
struct piecewise_construct_t { };
@@ -282,7 +287,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return pair<_T1, _T2>(__x, __y); }
#endif
+ /// @}
+
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif /* _STL_PAIR_H */
diff --git a/libstdc++-v3/include/bits/stringfwd.h b/libstdc++-v3/include/bits/stringfwd.h
index e204b08940e..5d5b83f5e96 100644
--- a/libstdc++-v3/include/bits/stringfwd.h
+++ b/libstdc++-v3/include/bits/stringfwd.h
@@ -60,12 +60,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<> struct char_traits<char>;
- typedef basic_string<char> string; /// A string of @c char
+ /// A string of @c char
+ typedef basic_string<char> string;
#ifdef _GLIBCXX_USE_WCHAR_T
template<> struct char_traits<wchar_t>;
- typedef basic_string<wchar_t> wstring; /// A string of @c wchar_t
+ /// A string of @c wchar_t
+ typedef basic_string<wchar_t> wstring;
#endif
#if ((__cplusplus >= 201103L) \
@@ -74,13 +76,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<> struct char_traits<char16_t>;
template<> struct char_traits<char32_t>;
- typedef basic_string<char16_t> u16string; /// A string of @c char16_t
- typedef basic_string<char32_t> u32string; /// A string of @c char32_t
+ /// A string of @c char16_t
+ typedef basic_string<char16_t> u16string;
+
+ /// A string of @c char32_t
+ typedef basic_string<char32_t> u32string;
#endif
/** @} */
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // _STRINGFWD_H
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index ae1485f5f43..861bca53adf 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -660,7 +660,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _M_ok;
public:
- /// Easy access to dependant types.
+ /// Easy access to dependent types.
typedef _Traits traits_type;
typedef basic_streambuf<_CharT, _Traits> __streambuf_type;
typedef basic_istream<_CharT, _Traits> __istream_type;
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits
index 13ad660aeca..a137d0b1210 100644
--- a/libstdc++-v3/include/std/limits
+++ b/libstdc++-v3/include/std/limits
@@ -211,14 +211,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** True if the type is signed. */
static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
- /** True if the type is integer.
- * Is this supposed to be <em>if the type is integral?</em> */
+ /** True if the type is integer. */
static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
- /** True if the type uses an exact representation. <em>All integer types are
+ /** True if the type uses an exact representation. All integer types are
exact, but not all exact types are integer. For example, rational and
- fixed-exponent representations are exact but not integer.</em>
- [18.2.1.2]/15 */
+ fixed-exponent representations are exact but not integer. */
static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
/** For integer types, specifies the base of the representation. For
@@ -246,27 +244,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
/** True if the type has a representation for a quiet (non-signaling)
- <em>Not a Number</em>. */
+ Not a Number. */
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
/** True if the type has a representation for a signaling
- <em>Not a Number</em>. */
+ Not a Number. */
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
/** See std::float_denorm_style for more information. */
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
- /** <em>True if loss of accuracy is detected as a denormalization loss,
- rather than as an inexact result.</em> [18.2.1.2]/42 */
+ /** True if loss of accuracy is detected as a denormalization loss,
+ rather than as an inexact result. */
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
/** True if-and-only-if the type adheres to the IEC 559 standard, also
known as IEEE 754. (Only makes sense for floating point types.) */
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
- /** <em>True if the set of values representable by the type is
+ /** True if the set of values representable by the type is
finite. All built-in types are bounded, this member would be
- false for arbitrary precision types.</em> [18.2.1.2]/54 */
+ false for arbitrary precision types. */
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = false;
/** True if the type is @e modulo. A type is modulo if, for any
@@ -334,12 +332,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static _GLIBCXX_CONSTEXPR _Tp
infinity() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
- /** The representation of a quiet <em>Not a Number</em>,
+ /** The representation of a quiet Not a Number,
if @c has_quiet_NaN. */
static _GLIBCXX_CONSTEXPR _Tp
quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
- /** The representation of a signaling <em>Not a Number</em>, if
+ /** The representation of a signaling Not a Number, if
@c has_signaling_NaN. */
static _GLIBCXX_CONSTEXPR _Tp
signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf
index 0fb2f07cc90..26a3871471c 100644
--- a/libstdc++-v3/include/std/streambuf
+++ b/libstdc++-v3/include/std/streambuf
@@ -123,7 +123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
//@{
/**
* These are standard types. They permit a standardized way of
- * referring to names of (or names dependant on) the template
+ * referring to names of (or names dependent on) the template
* parameters, which are specific to the implementation.
*/
typedef _CharT char_type;
@@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
friend class ostreambuf_iterator<char_type, traits_type>;
friend streamsize
- __copy_streambufs_eof<>(__streambuf_type*, __streambuf_type*, bool&);
+ __copy_streambufs_eof<>(basic_streambuf*, basic_streambuf*, bool&);
template<bool _IsMove, typename _CharT2>
friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value,
@@ -174,20 +174,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
basic_string<_CharT2, _Traits2, _Alloc>&, _CharT2);
protected:
- //@{
- /**
+ /*
* This is based on _IO_FILE, just reordered to be more consistent,
* and is intended to be the most minimal abstraction for an
* internal buffer.
* - get == input == read
* - put == output == write
*/
- char_type* _M_in_beg; // Start of get area.
- char_type* _M_in_cur; // Current read area.
- char_type* _M_in_end; // End of get area.
- char_type* _M_out_beg; // Start of put area.
- char_type* _M_out_cur; // Current put area.
- char_type* _M_out_end; // End of put area.
+ char_type* _M_in_beg; ///< Start of get area.
+ char_type* _M_in_cur; ///< Current read area.
+ char_type* _M_in_end; ///< End of get area.
+ char_type* _M_out_beg; ///< Start of put area.
+ char_type* _M_out_cur; ///< Current put area.
+ char_type* _M_out_end; ///< End of put area.
/// Current locale setting.
locale _M_buf_locale;
@@ -236,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* derived @c foo member functions, passing the arguments (if any)
* and returning the result unchanged.
*/
- __streambuf_type*
+ basic_streambuf*
pubsetbuf(char_type* __s, streamsize __n)
{ return this->setbuf(__s, __n); }
@@ -800,15 +799,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// Side effect of DR 50.
- basic_streambuf(const __streambuf_type& __sb)
+ basic_streambuf(const basic_streambuf& __sb)
: _M_in_beg(__sb._M_in_beg), _M_in_cur(__sb._M_in_cur),
_M_in_end(__sb._M_in_end), _M_out_beg(__sb._M_out_beg),
_M_out_cur(__sb._M_out_cur), _M_out_end(__sb._M_out_cur),
_M_buf_locale(__sb._M_buf_locale)
{ }
- __streambuf_type&
- operator=(const __streambuf_type&) { return *this; };
+ basic_streambuf&
+ operator=(const basic_streambuf&) { return *this; };
};
// Explicit specialization declarations, defined in src/streambuf.cc.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 80b136a2c61..ee2b2e1d4c2 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -43,6 +43,11 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /**
+ * @addtogroup utilities
+ * @{
+ */
+
// Adds a const reference to a non-reference type.
template<typename _Tp>
struct __add_c_ref
@@ -1018,6 +1023,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ /// tuple_cat
template<typename... _Tpls, typename = typename
enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
constexpr auto
@@ -1030,11 +1036,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
}
+ /// tie
template<typename... _Elements>
inline tuple<_Elements&...>
tie(_Elements&... __args) noexcept
{ return tuple<_Elements&...>(__args...); }
+ /// swap
template<typename... _Elements>
inline void
swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
@@ -1080,8 +1088,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
{ }
+ /// @}
+
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // C++11
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index cfc45390454..62d59128f9f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1,4 +1,4 @@
-// C++11 type_traits -*- C++ -*-
+// C++11 <type_traits> -*- C++ -*-
// Copyright (C) 2007-2013 Free Software Foundation, Inc.
//
@@ -42,7 +42,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
- * @defgroup metaprogramming Metaprogramming and type traits
+ * @defgroup metaprogramming Metaprogramming
* @ingroup utilities
*
* Template utilities for compile-time introspection and modification,
@@ -62,15 +62,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr operator value_type() { return value; }
};
+ template<typename _Tp, _Tp __v>
+ constexpr _Tp integral_constant<_Tp, __v>::value;
+
/// The type used as a compile-time boolean with true value.
typedef integral_constant<bool, true> true_type;
/// The type used as a compile-time boolean with false value.
typedef integral_constant<bool, false> false_type;
- template<typename _Tp, _Tp __v>
- constexpr _Tp integral_constant<_Tp, __v>::value;
-
// Meta programming helper types.
template<bool, typename, typename>
@@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __failure_type
{ };
- // primary type categories.
+ // Primary type categories.
template<typename>
struct remove_cv;
@@ -426,7 +426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
remove_cv<_Tp>::type>::value)>
{ };
- // composite type categories.
+ // Composite type categories.
/// is_reference
template<typename _Tp>
@@ -484,7 +484,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename remove_cv<_Tp>::type>::value)>
{ };
- // type properties.
+ // Type properties.
/// is_const
template<typename>
@@ -577,7 +577,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
- // destructible and constructible type properties
+ // Destructible and constructible type properties.
template<typename>
struct add_rvalue_reference;
@@ -1271,7 +1271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
- // type relations.
+ // Type relations.
/// is_same
template<typename, typename>
@@ -1320,7 +1320,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
- // const-volatile modifications.
+ // Const-volatile modifications.
/// remove_const
template<typename _Tp>
@@ -1420,7 +1420,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
- // sign modifications.
+ // Sign modifications.
// Utility for constructing identically cv-qualified types.
template<typename _Unqualified, bool _IsConst, bool _IsVol>
@@ -1617,7 +1617,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct make_signed<bool>;
- // array modifications.
+ // Array modifications.
/// remove_extent
template<typename _Tp>
@@ -1646,7 +1646,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ typedef typename remove_all_extents<_Tp>::type type; };
- // pointer modifications.
+ // Pointer modifications.
template<typename _Tp, typename>
struct __remove_pointer_helper
@@ -1789,7 +1789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename... _Tp>
struct common_type;
- // sfinae-friendly common_type implementation:
+ // Sfinae-friendly common_type implementation:
struct __do_common_type_impl
{
@@ -1877,7 +1877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Signature>
class result_of;
- // sfinae-friendly result_of implementation:
+ // Sfinae-friendly result_of implementation:
// [func.require] paragraph 1 bullet 1:
struct __result_of_memfun_ref_impl
@@ -2034,6 +2034,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Functor, _ArgTypes...
>::type
{ };
+
+ /// @} group metaprogramming
/**
* Use SFINAE to determine if the type _Tp has a publicly-accessible
@@ -2064,9 +2066,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
<typename remove_cv<_Tp>::type>::value> \
{ };
- /// @} group metaprogramming
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // C++11
diff --git a/libstdc++-v3/include/std/typeindex b/libstdc++-v3/include/std/typeindex
index 793894f3f80..9e6db30a72a 100644
--- a/libstdc++-v3/include/std/typeindex
+++ b/libstdc++-v3/include/std/typeindex
@@ -1,4 +1,4 @@
-// C++0x typeindex -*- C++ -*-
+// C++11 <typeindex> -*- C++ -*-
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
@@ -42,9 +42,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
- @brief The class type_index provides a simple wrapper for type_info
- which can be used as an index type in associative containers (23.6)
- and in unordered associative containers (23.7).
+ * @brief Class type_index
+ * @ingroup utilities
+ *
+ * The class type_index provides a simple wrapper for type_info
+ * which can be used as an index type in associative containers
+ * (23.6) and in unordered associative containers (23.7).
*/
struct type_index
{
@@ -102,7 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // C++11
diff --git a/libstdc++-v3/include/tr1/memory b/libstdc++-v3/include/tr1/memory
index d04f86b8030..7f4ce513777 100644
--- a/libstdc++-v3/include/tr1/memory
+++ b/libstdc++-v3/include/tr1/memory
@@ -32,8 +32,8 @@
#pragma GCC system_header
-#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
-# error TR1 header cannot be included from C++0x header
+#if defined(_GLIBCXX_INCLUDE_AS_CXX11)
+# error TR1 header cannot be included from C++11 header
#endif
#include <memory>
diff --git a/libstdc++-v3/include/tr1/regex b/libstdc++-v3/include/tr1/regex
index 15f56af41c9..dfcc3a90467 100644
--- a/libstdc++-v3/include/tr1/regex
+++ b/libstdc++-v3/include/tr1/regex
@@ -847,7 +847,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_flags(__f), _M_pattern(__first, __last), _M_mark_count(0)
{ _M_compile(); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+#ifdef _GLIBCXX_INCLUDE_AS_CXX11
/**
* @brief Constructs a basic regular expression from an initializer list.
*
@@ -986,7 +986,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
flag_type __flags = regex_constants::ECMAScript)
{ return this->assign(string_type(__first, __last), __flags); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+#ifdef _GLIBCXX_INCLUDE_AS_CXX11
/**
* @brief Assigns a new regular expression to a regex object.
*
@@ -1966,7 +1966,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
begin() const
{ return _Base_type::begin(); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+#ifdef _GLIBCXX_INCLUDE_AS_CXX11
/**
* @brief Gets an iterator to the start of the %sub_match collection.
*/
@@ -1982,7 +1982,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
end() const
{ return _Base_type::end(); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+#ifdef _GLIBCXX_INCLUDE_AS_CXX11
/**
* @brief Gets an iterator to one-past-the-end of the collection.
*/
diff --git a/libstdc++-v3/scripts/run_doxygen b/libstdc++-v3/scripts/run_doxygen
index 0f65d3af05c..75b2f4f9758 100644
--- a/libstdc++-v3/scripts/run_doxygen
+++ b/libstdc++-v3/scripts/run_doxygen
@@ -205,6 +205,8 @@ if $do_html; then
cd ${outdir}/${mode}
#doxytag -t libstdc++.tag . > /dev/null 2>&1
+
+ # Strip pathnames from tag file.
sed -e '/<path>/d' libstdc++.tag > TEMP
mv TEMP libstdc++.tag
diff --git a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
index 2fbc4568123..e5f015fa146 100644
--- a/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc
@@ -44,4 +44,4 @@ void test01()
tuple<Type> t(allocator_arg, a, 1);
}
-// { dg-error "no matching function" "" { target *-*-* } 113 }
+// { dg-error "no matching function" "" { target *-*-* } 118 }
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
index 445e4e48bc3..9d71cff8583 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc
@@ -33,7 +33,7 @@ struct equal {
bool operator()(const MoveOnly&, const MoveOnly) const { return true; }
};
struct hash {
- size_t operator()(const MoveOnly&) const { return 0; }
+ std::size_t operator()(const MoveOnly&) const { return 0; }
};
template<typename Alloc>
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
index e5ba065f5d5..152489042f7 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc
@@ -33,7 +33,7 @@ struct equal {
bool operator()(const MoveOnly&, const MoveOnly) const { return true; }
};
struct hash {
- size_t operator()(const MoveOnly&) const { return 0; }
+ std::size_t operator()(const MoveOnly&) const { return 0; }
};
template<typename Alloc>