aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-04-04 21:38:30 +0200
committerYvan Roux <yvan.roux@linaro.org>2017-04-04 21:38:30 +0200
commit8888e7889696a6323bf711c5cae0815d5856450a (patch)
treeb5376881a614e2d8dc38e471d31a7a1e6d1d07cd
parenta3f228934d965534672908b4d3571aa637b5fede (diff)
Merge branches/gcc-6-branch rev 246668.
Change-Id: If1d4497c52a1bdde1390c2377e3f2c16ac2e73b4
-rw-r--r--gcc/ChangeLog354
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in21
-rw-r--r--gcc/ada/ChangeLog15
-rw-r--r--gcc/ada/gcc-interface/Makefile.in17
-rw-r--r--gcc/ada/system-linux-aarch64-ilp32.ads157
-rw-r--r--gcc/c-family/ChangeLog13
-rw-r--r--gcc/c-family/c-ada-spec.c2
-rw-r--r--gcc/c-family/c-common.c7
-rw-r--r--gcc/config/i386/cpuid.h2
-rw-r--r--gcc/config/i386/i386.c38
-rw-r--r--gcc/config/rs6000/constraints.md3
-rw-r--r--gcc/config/rs6000/dfp.md8
-rw-r--r--gcc/config/rs6000/rs6000.c14
-rw-r--r--gcc/config/rs6000/rs6000.h4
-rw-r--r--gcc/config/rs6000/rs6000.md178
-rw-r--r--gcc/config/rs6000/vsx.md23
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/init.c8
-rw-r--r--gcc/cp/lambda.c5
-rw-r--r--gcc/data-streamer-in.c1
-rw-r--r--gcc/data-streamer-out.c1
-rw-r--r--gcc/doc/extend.texi8
-rw-r--r--gcc/doc/gcc.texi3
-rw-r--r--gcc/doc/gcov-dump.texi93
-rw-r--r--gcc/doc/invoke.texi7
-rw-r--r--gcc/doc/md.texi3
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/fortran/ChangeLog29
-rw-r--r--gcc/fortran/module.c21
-rw-r--r--gcc/fortran/parse.c31
-rw-r--r--gcc/fortran/symbol.c16
-rw-r--r--gcc/gcov-dump.c2
-rw-r--r--gcc/gcse.c32
-rw-r--r--gcc/ipa-devirt.c17
-rw-r--r--gcc/ipa-pure-const.c8
-rw-r--r--gcc/multiple_target.c79
-rw-r--r--gcc/params.def2
-rw-r--r--gcc/passes.def3
-rw-r--r--gcc/testsuite/ChangeLog282
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-10.c10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr80091.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/flexary12.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/flexary20.C49
-rw-r--r--gcc/testsuite/g++.dg/ext/flexary21.C15
-rw-r--r--gcc/testsuite/g++.dg/ext/mv8.C2
-rw-r--r--gcc/testsuite/g++.dg/pr71294.C60
-rw-r--r--gcc/testsuite/g++.dg/pr79761.C34
-rw-r--r--gcc/testsuite/g++.dg/pr79769.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-var-26.C147
-rw-r--r--gcc/testsuite/gcc.dg/pr78644-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/pr78644-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr79574-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr79574.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr80218.c28
-rw-r--r--gcc/testsuite/gcc.dg/tls/emutls-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71881.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr78742.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr79732.c5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr80181.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr66295.c35
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr79587.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr79803.c60
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/pr78339.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/pr79631.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/pr79753.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/pr79770.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/mvc9.c28
-rw-r--r--gcc/testsuite/gcc.target/i386/pr65044.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr71458.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr80019.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr78543.c60
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr79947.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr79951.c10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr80246.c37
-rw-r--r--gcc/testsuite/gfortran.dg/submodule_25.f0843
-rw-r--r--gcc/testsuite/gfortran.dg/submodule_26.f0846
-rw-r--r--gcc/testsuite/gfortran.dg/submodule_27.f0844
-rw-r--r--gcc/testsuite/gfortran.dg/submodule_28.f0852
-rw-r--r--gcc/toplev.c29
-rw-r--r--gcc/tree-call-cdce.c68
-rw-r--r--gcc/tree-chkp-opt.c4
-rw-r--r--gcc/tree-chkp.c19
-rw-r--r--gcc/tree-inline.c7
-rw-r--r--gcc/tree-ssa-ccp.c26
-rw-r--r--gcc/tree-ssa-loop-prefetch.c19
-rw-r--r--gcc/value-prof.c12
-rw-r--r--libstdc++-v3/ChangeLog136
-rw-r--r--libstdc++-v3/include/bits/locale_conv.h5
-rw-r--r--libstdc++-v3/include/bits/random.tcc25
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h10
-rw-r--r--libstdc++-v3/include/experimental/iterator5
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp21
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp1
-rw-r--r--libstdc++-v3/src/c++11/codecvt.cc606
-rw-r--r--libstdc++-v3/testsuite/20_util/pair/79141.cc25
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc142
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/80041.cc87
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/members.cc81
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc289
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/79980.cc94
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/members.cc81
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc60
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc76
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc16
-rw-r--r--libstdc++-v3/testsuite/experimental/iterator/requirements.cc12
-rw-r--r--libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc51
-rw-r--r--libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues.cc2
111 files changed, 4032 insertions, 529 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a9858ce86e..0c45f5c2333 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,357 @@
+2017-04-03 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from the trunk
+ 2017-03-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/79947
+ * config/rs6000/rs6000.h (TARGET_FRSQRTES): Add check for
+ -mpowerpc-gfxopt.
+
+2017-03-31 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/80218
+ * tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds):
+ Update block frequencies and counts.
+
+2017-03-30 Peter Bergner <bergner@vnet.ibm.com>
+
+ Backport from mainline
+ 2017-03-30 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR target/80246
+ * config/rs6000/dfp.md (dfp_dxex_<mode>): Update mode of operand 0.
+ (dfp_diex_<mode>): Update mode of operand 1.
+ * doc/extend.texi (dxex, dxexq): Document change to return type.
+ (diex, diexq): Document change to argument type.
+
+2017-03-29 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from trunk
+ 2017-03-21 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
+
+ PR target/80123
+ * doc/md.texi (Constraints): Document wA constraint.
+ * config/rs6000/constraints.md (wA): New.
+ * config/rs6000/rs6000.c (rs6000_debug_reg_global): Add wA reg_class.
+ (rs6000_init_hard_regno_mode_ok): Init wA constraint.
+ * config/rs6000/rs6000.h (RS6000_CONSTRAINT_wA): New.
+ * config/rs6000/vsx.md (vsx_splat_<mode>): Use wA constraint.
+
+ 2017-03-16 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/71294
+ * config/rs6000/vsx.md (vsx_splat_<mode>, VSX_D iterator): Allow a
+ SPLAT operation on ISA 2.07 64-bit systems that have direct move,
+ but no MTVSRDD support, by doing MTVSRD and XXPERMDI.
+
+2017-03-29 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-03-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/78644
+ * tree-ssa-ccp.c (evaluate_stmt): When we may not use the value
+ of a simplification result we may not use it at all.
+
+ 2017-03-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/80181
+ * tree-ssa-ccp.c (likely_value): UNDEFINED ^ X is UNDEFINED.
+
+2017-03-28 Marek Polacek <polacek@redhat.com>
+
+ Backport from mainline
+ 2017-03-28 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/80067
+ * fold-const.c (fold_comparison): Use protected_set_expr_location
+ instead of SET_EXPR_LOCATION.
+
+2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from trunk
+ 2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/78543
+ * config/rs6000/rs6000.md (bswaphi2_extenddi): Combine bswap
+ HImode and SImode with zero extend to DImode to one insn.
+ (bswap<mode>2_extenddi): Likewise.
+ (bswapsi2_extenddi): Likewise.
+ (bswaphi2_extendsi): Likewise.
+ (bswaphi2): Combine bswap HImode and SImode into one insn.
+ Separate memory insns from swapping register.
+ (bswapsi2): Likewise.
+ (bswap<mode>2): Likewise.
+ (bswaphi2_internal): Delete, no longer used.
+ (bswapsi2_internal): Likewise.
+ (bswap<mode>2_load): Split bswap HImode/SImode into separate load,
+ store, and gpr<-gpr swap insns.
+ (bswap<mode>2_store): Likewise.
+ (bswaphi2_reg): Register only splitter, combine with the splitter.
+ (bswaphi2 splitter): Likewise.
+ (bswapsi2_reg): Likewise.
+ (bswapsi2 splitter): Likewise.
+ (bswapdi2): If we have the LDBRX and STDBRX instructions, split
+ the insns into load, store, and register/register insns.
+ (bswapdi2_ldbrx): Likewise.
+ (bswapdi2_load): Likewise.
+ (bswapdi2_store): Likewise.
+ (bswapdi2_reg): Likewise.
+
+2017-03-25 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/80180
+ * config/i386/i386.c (ix86_expand_builtin)
+ <IX86_BUILTIN_RDSEED{16,32,64}_STEP>: Do not expand arg0 between
+ flags reg setting and flags reg using instructions.
+ <IX86_BUILTIN_RDRAND{16,32,64}_STEP>: Ditto. Use non-flags reg
+ clobbering instructions to zero extend op2.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-14 Martin Liska <mliska@suse.cz>
+
+ PR lto/66295
+ * multiple_target.c (expand_target_clones): Drop local.local
+ flag for default implementation.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-22 Martin Liska <mliska@suse.cz>
+
+ PR lto/79587
+ * data-streamer-in.c (streamer_read_gcov_count): Remove assert.
+ * data-streamer-out.c (streamer_write_gcov_count_stream):
+ Likewise.
+ * value-prof.c (stream_out_histogram_value): Make assert more
+ precise based on type of counter.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-03 Martin Liska <mliska@suse.cz>
+
+ PR lto/66295
+ * multiple_target.c (create_dispatcher_calls): Redirect edge
+ from a caller of a dispatcher.
+ (expand_target_clones): Make the clones local.
+ (ipa_target_clone): Do both target clones and resolvers.
+ (ipa_dispatcher_calls): Remove the pass.
+ (pass_dispatcher_calls::gate): Likewise.
+ (make_pass_dispatcher_calls): Likewise.
+ * passes.def (pass_target_clone): Put as very first IPA early
+ pass.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-22 Martin Liska <mliska@suse.cz>
+
+ PR target/79906
+ * config/rs6000/rs6000.c (rs6000_inner_target_options): Show
+ error message instead of an ICE.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-21 Martin Liska <mliska@suse.cz>
+
+ PR gcov-profile/80081
+ * Makefile.in: Add gcov-dump and fix installation of gcov-tool.
+ * doc/gcc.texi: Include gcov-dump stuff.
+ * doc/gcov-dump.texi: New file.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-20 Martin Liska <mliska@suse.cz>
+
+ PR middle-end/79753
+ * tree-chkp.c (chkp_build_returned_bound): Do not build
+ returned bounds for a LHS that's not a BOUNDED_P type.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-20 Martin Liska <mliska@suse.cz>
+
+ PR target/79769
+ PR target/79770
+ * tree-chkp.c (chkp_find_bounds_1): Handle REAL_CST,
+ COMPLEX_CST and VECTOR_CST.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-14 Martin Liska <mliska@suse.cz>
+
+ PR middle-end/79831
+ * doc/invoke.texi (-Wchkp): Document the option.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-14 Martin Liska <mliska@suse.cz>
+
+ PR target/79892
+ * multiple_target.c (create_dispatcher_calls): Check that
+ a target can create a function dispatcher.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-13 Martin Liska <mliska@suse.cz>
+
+ PR middle-end/78339
+ * ipa-pure-const.c (warn_function_noreturn): If the declarations
+ is a CHKP clone, use original declaration.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-10 Martin Liska <mliska@suse.cz>
+
+ PR target/65705
+ PR target/69804
+ * toplev.c (process_options): Enable MPX with LSAN and UBSAN.
+ * tree-chkp.c (chkp_walk_pointer_assignments): Verify that
+ FIELD != NULL.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/79631
+ * tree-chkp-opt.c (chkp_is_constant_addr): Call
+ tree_int_cst_sign_bit just for INTEGER constants.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR target/65705
+ PR target/69804
+ * toplev.c (process_options): Disable -fcheck-pointer-bounds with
+ sanitizers.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR ipa/79761
+ * tree-chkp.c (chkp_get_bound_for_parm): Get bounds for a param.
+ (chkp_find_bounds_1): Remove gcc_unreachable.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-03 Jan Hubicka <jh@suse.cz>
+
+ PR lto/79760
+ * ipa-devirt.c (maybe_record_node): Properly handle
+ __cxa_pure_virtual visibility.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-03 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/79803
+ * tree-ssa-loop-prefetch.c (tree_ssa_prefetch_arrays): Remove
+ assert.
+ (pass_loop_prefetch::execute): Disabled optimization if an
+ assumption about L1 cache size is not met.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-03 Martin Liska <mliska@suse.cz>
+
+ PR rtl-optimization/79574
+ * gcse.c (struct gcse_expr): Use HOST_WIDE_INT instead of int.
+ (hash_scan_set): Likewise.
+ (dump_hash_table): Likewise.
+ (hoist_code): Likewise.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-17 Martin Liska <mliska@suse.cz>
+
+ PR rtl-optimization/79574
+ * gcse.c (want_to_gcse_p): Prevent integer overflow.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-17 Martin Liska <mliska@suse.cz>
+
+ PR rtl-optimization/79577
+ * params.def (selsched-max-sched-times): Increase minimum to 1.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2016-06-13 Martin Liska <mliska@suse.cz>
+
+ PR sanitizer/71458
+ * toplev.c (process_options): Do not enable -fcheck-pointer-bounds
+ w/ -fsanitize=bounds.
+
+2017-03-21 Pat Haugen <pthaugen@us.ibm.com>
+
+ Backport from mainline:
+ 2017-03-17 Pat Haugen <pthaugen@us.ibm.com>
+
+ PR target/79951
+ * config/rs6000/rs6000.md (copysign<mode>3_fcpsgn): Test
+ for VECTOR_UNIT_VSX_P (<MODE>mode) too.
+
+2017-03-21 Tamar Christina <tamar.christina@arm.com>
+
+ * config/aarch64/aarch64-simd.md (*aarch64_simd_mov<mode>)
+ Change ins into fmov.
+
+2017-03-19 Dominique d'Humieres <dominiq@lps.ens.fr>
+
+ PR target/71017
+ * config/i386/cpuid.h: Fix another undefined behavior.
+
+2017-03-17 Tom de Vries <tom@codesourcery.com>
+
+ backport from trunk:
+ 2017-03-17 Tom de Vries <tom@codesourcery.com>
+
+ * gcov-dump.c (print_usage): Print bug_report_url.
+
+2017-03-16 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-02-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/79732
+ * tree-inline.c (expand_call_inline): Handle anonymous
+ SSA lhs properly when inlining a function without return
+ value.
+
+2017-03-15 Matthias Klose <doko@ubuntu.com>
+
+ Backport from mainline
+ 2017-03-14 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Install gcov-dump.
+
+2017-03-15 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/80019
+ * config/i386/i386.c (ix86_vector_duplicate_value): Create
+ subreg of inner mode for values already in registers.
+
2017-03-14 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
Backport from mainline
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 2e38bf7671a..7c3b057f980 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20170315
+20170404
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 46aaac4fe7b..9b3574c778b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -787,6 +787,7 @@ GCC_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcc|sed '$(progra
CPP_INSTALL_NAME := $(shell echo cpp|sed '$(program_transform_name)')
GCOV_INSTALL_NAME := $(shell echo gcov|sed '$(program_transform_name)')
GCOV_TOOL_INSTALL_NAME := $(shell echo gcov-tool|sed '$(program_transform_name)')
+GCOV_DUMP_INSTALL_NAME := $(shell echo gcov-dump|sed '$(program_transform_name)')
# Setup the testing framework, if you have one
EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
@@ -2980,7 +2981,7 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi \
gcov.texi trouble.texi bugreport.texi service.texi \
contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi \
fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi \
- implement-c.texi implement-cxx.texi gcov-tool.texi
+ implement-c.texi implement-cxx.texi gcov-tool.texi gcov-dump.texi
# we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with
# the generated tm.texi; the latter might have a more recent timestamp,
@@ -3103,7 +3104,7 @@ $(build_htmldir)/gccinstall/index.html: $(TEXI_GCCINSTALL_FILES)
$(SHELL) $(srcdir)/doc/install.texi2html
MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 \
- doc/fsf-funding.7 doc/gcov-tool.1
+ doc/fsf-funding.7 doc/gcov-tool.1 doc/gcov-dump.1
generated-manpages: man
@@ -3412,6 +3413,15 @@ install-common: native lang.install-common installdirs
gcov-tool$(exeext) $(DESTDIR)$(bindir)/$(GCOV_TOOL_INSTALL_NAME)$(exeext); \
fi; \
fi
+# Install gcov-dump if it was compiled.
+ -if test "$(enable_as_accelerator)" != "yes" ; then \
+ if [ -f gcov-dump$(exeext) ]; \
+ then \
+ rm -f $(DESTDIR)$(bindir)/$(GCOV_DUMP_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) \
+ gcov-dump$(exeext) $(DESTDIR)$(bindir)/$(GCOV_DUMP_INSTALL_NAME)$(exeext); \
+ fi; \
+ fi
# Install the driver program as $(target_noncanonical)-gcc,
# $(target_noncanonical)-gcc-$(version), and also as gcc if native.
@@ -3495,6 +3505,8 @@ install-man: lang.install-man \
$(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) \
$(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext) \
$(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext) \
+ $(DESTDIR)$(man1dir)/$(GCOV_TOOL_INSTALL_NAME)$(man1ext) \
+ $(DESTDIR)$(man1dir)/$(GCOV_DUMP_INSTALL_NAME)$(man1ext) \
$(DESTDIR)$(man7dir)/fsf-funding$(man7ext) \
$(DESTDIR)$(man7dir)/gfdl$(man7ext) \
$(DESTDIR)$(man7dir)/gpl$(man7ext)
@@ -3524,6 +3536,11 @@ $(DESTDIR)$(man1dir)/$(GCOV_TOOL_INSTALL_NAME)$(man1ext): doc/gcov-tool.1 instal
-$(INSTALL_DATA) $< $@
-chmod a-x $@
+$(DESTDIR)$(man1dir)/$(GCOV_DUMP_INSTALL_NAME)$(man1ext): doc/gcov-dump.1 installdirs
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
# Install all the header files built in the include subdirectory.
install-headers: $(INSTALL_HEADERS_DIR)
# Fix symlinks to absolute paths in the installed include directory to
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 46ce3934d12..e1e94597628 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,18 @@
+2017-03-28 Andreas Schwab <schwab@suse.de>
+
+ Backport from trunk
+
+ 2017-03-28 Andreas Schwab <schwab@suse.de>
+
+ PR ada/80117
+ * system-linux-aarch64-ilp32.ads: New file.
+ * gcc-interface/Makefile.in (LIBGNAT_TARGET_PAIRS_COMMON): Rename
+ from LIBGNAT_TARGET_PAIRS.
+ (LIBGNAT_TARGET_PAIRS_32, LIBGNAT_TARGET_PAIRS_64): Define.
+ (LIBGNAT_TARGET_PAIRS): Use LIBGNAT_TARGET_PAIRS_COMMON, and
+ LIBGNAT_TARGET_PAIRS_64 or LIBGNAT_TARGET_PAIRS_32 for -mabi=lp64
+ or -mabi=ilp32, resp.
+
2017-03-08 Thanassis Tsiodras <ttsiodras@gmail.com>
PR ada/79903
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index b1b7e9ac447..598b262d914 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -2013,7 +2013,7 @@ endif
# AArch64 Linux
ifeq ($(strip $(filter-out aarch64% linux%,$(target_cpu) $(target_os))),)
- LIBGNAT_TARGET_PAIRS = \
+ LIBGNAT_TARGET_PAIRS_COMMON = \
a-exetim.adb<a-exetim-posix.adb \
a-exetim.ads<a-exetim-default.ads \
a-intnam.ads<a-intnam-linux.ads \
@@ -2033,10 +2033,23 @@ ifeq ($(strip $(filter-out aarch64% linux%,$(target_cpu) $(target_os))),)
s-taspri.ads<s-taspri-posix.ads \
g-sercom.adb<g-sercom-linux.adb \
$(ATOMICS_TARGET_PAIRS) \
- $(ATOMICS_BUILTINS_TARGET_PAIRS) \
+ $(ATOMICS_BUILTINS_TARGET_PAIRS)
+
+ LIBGNAT_TARGET_PAIRS_32 = \
+ system.ads<system-linux-aarch64-ilp32.ads
+
+ LIBGNAT_TARGET_PAIRS_64 = \
system.ads<system-linux-x86_64.ads
## ^^ Note the above is a pretty-close placeholder.
+ ifneq (,$(or $(filter aarch64-linux-gnu, $(shell $(GCC_FOR_TARGET) $(GNATLIBCFLAGS) -print-multiarch)), $(filter ../lib64, $(shell $(GCC_FOR_TARGET) $(GNATLIBCFLAGS) -print-multi-os-directory))))
+ LIBGNAT_TARGET_PAIRS = \
+ $(LIBGNAT_TARGET_PAIRS_COMMON) $(LIBGNAT_TARGET_PAIRS_64)
+ else
+ LIBGNAT_TARGET_PAIRS = \
+ $(LIBGNAT_TARGET_PAIRS_COMMON) $(LIBGNAT_TARGET_PAIRS_32)
+ endif
+
TOOLS_TARGET_PAIRS = \
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \
indepsw.adb<indepsw-gnu.adb
diff --git a/gcc/ada/system-linux-aarch64-ilp32.ads b/gcc/ada/system-linux-aarch64-ilp32.ads
new file mode 100644
index 00000000000..496bccf3fcf
--- /dev/null
+++ b/gcc/ada/system-linux-aarch64-ilp32.ads
@@ -0,0 +1,157 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M --
+-- --
+-- S p e c --
+-- (GNU-Linux/ARM Version) --
+-- --
+-- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
+-- --
+-- This specification is derived from the Ada Reference Manual for use with --
+-- GNAT. The copyright notice above, and the license provisions that follow --
+-- apply solely to the contents of the part following the private keyword. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package System is
+ pragma Pure;
+ -- Note that we take advantage of the implementation permission to make
+ -- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
+ -- 2005, this is Pure in any case (AI-362).
+
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
+ type Name is (SYSTEM_NAME_GNAT);
+ System_Name : constant Name := SYSTEM_NAME_GNAT;
+
+ -- System-Dependent Named Numbers
+
+ Min_Int : constant := Long_Long_Integer'First;
+ Max_Int : constant := Long_Long_Integer'Last;
+
+ Max_Binary_Modulus : constant := 2 ** Long_Long_Integer'Size;
+ Max_Nonbinary_Modulus : constant := 2 ** Integer'Size - 1;
+
+ Max_Base_Digits : constant := Long_Long_Float'Digits;
+ Max_Digits : constant := Long_Long_Float'Digits;
+
+ Max_Mantissa : constant := 63;
+ Fine_Delta : constant := 2.0 ** (-Max_Mantissa);
+
+ Tick : constant := 0.000_001;
+
+ -- Storage-related Declarations
+
+ type Address is private;
+ pragma Preelaborable_Initialization (Address);
+ Null_Address : constant Address;
+
+ Storage_Unit : constant := 8;
+ Word_Size : constant := 32;
+ Memory_Size : constant := 2 ** Word_Size;
+
+ -- Address comparison
+
+ function "<" (Left, Right : Address) return Boolean;
+ function "<=" (Left, Right : Address) return Boolean;
+ function ">" (Left, Right : Address) return Boolean;
+ function ">=" (Left, Right : Address) return Boolean;
+ function "=" (Left, Right : Address) return Boolean;
+
+ pragma Import (Intrinsic, "<");
+ pragma Import (Intrinsic, "<=");
+ pragma Import (Intrinsic, ">");
+ pragma Import (Intrinsic, ">=");
+ pragma Import (Intrinsic, "=");
+
+ -- Other System-Dependent Declarations
+
+ type Bit_Order is (High_Order_First, Low_Order_First);
+ Default_Bit_Order : constant Bit_Order :=
+ Bit_Order'Val (Standard'Default_Bit_Order);
+ pragma Warnings (Off, Default_Bit_Order); -- kill constant condition warning
+
+ -- Priority-related Declarations (RM D.1)
+
+ -- 0 .. 98 corresponds to the system priority range 1 .. 99.
+ --
+ -- If the scheduling policy is SCHED_FIFO or SCHED_RR the runtime makes use
+ -- of the entire range provided by the system.
+ --
+ -- If the scheduling policy is SCHED_OTHER the only valid system priority
+ -- is 1 and other values are simply ignored.
+
+ Max_Priority : constant Positive := 97;
+ Max_Interrupt_Priority : constant Positive := 98;
+
+ subtype Any_Priority is Integer range 0 .. 98;
+ subtype Priority is Any_Priority range 0 .. 97;
+ subtype Interrupt_Priority is Any_Priority range 98 .. 98;
+
+ Default_Priority : constant Priority := 48;
+
+private
+
+ type Address is mod Memory_Size;
+ Null_Address : constant Address := 0;
+
+ --------------------------------------
+ -- System Implementation Parameters --
+ --------------------------------------
+
+ -- These parameters provide information about the target that is used
+ -- by the compiler. They are in the private part of System, where they
+ -- can be accessed using the special circuitry in the Targparm unit
+ -- whose source should be consulted for more detailed descriptions
+ -- of the individual switch values.
+
+ Backend_Divide_Checks : constant Boolean := False;
+ Backend_Overflow_Checks : constant Boolean := True;
+ Command_Line_Args : constant Boolean := True;
+ Configurable_Run_Time : constant Boolean := False;
+ Denorm : constant Boolean := True;
+ Duration_32_Bits : constant Boolean := False;
+ Exit_Status_Supported : constant Boolean := True;
+ Fractional_Fixed_Ops : constant Boolean := False;
+ Frontend_Layout : constant Boolean := False;
+ Machine_Overflows : constant Boolean := False;
+ Machine_Rounds : constant Boolean := True;
+ Preallocated_Stacks : constant Boolean := False;
+ Signed_Zeros : constant Boolean := True;
+ Stack_Check_Default : constant Boolean := False;
+ Stack_Check_Probes : constant Boolean := True;
+ Stack_Check_Limits : constant Boolean := False;
+ Support_Aggregates : constant Boolean := True;
+ Support_Atomic_Primitives : constant Boolean := True;
+ Support_Composite_Assign : constant Boolean := True;
+ Support_Composite_Compare : constant Boolean := True;
+ Support_Long_Shifts : constant Boolean := True;
+ Always_Compatible_Rep : constant Boolean := False;
+ Suppress_Standard_Library : constant Boolean := False;
+ Use_Ada_Main_Program_Name : constant Boolean := False;
+ Frontend_Exceptions : constant Boolean := False;
+ ZCX_By_Default : constant Boolean := True;
+
+end System;
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index b5ae22d9a17..2a8d42eb5ee 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,16 @@
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ * c-ada-spec.c (macro_length): Increment value instead of a pointer.
+
+2017-03-21 Martin Sebor <msebor@redhat.com>
+
+ PR c++/79548
+ * c-common.c (set_underlying_type): Mark type used only when
+ original del is declared unused.
+
2017-03-14 Marek Polacek <polacek@redhat.com>
PR c++/79962
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 75a25ccbc63..d6aa78a7952 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -72,7 +72,7 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
if (macro->fun_like)
{
- param_len++;
+ (*param_len)++;
for (i = 0; i < macro->paramc; i++)
{
cpp_hashnode *param = macro->params[i];
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index f900dfaf8fd..69c1229ea2f 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -12029,7 +12029,12 @@ set_underlying_type (tree x)
tt = build_variant_type_copy (tt);
TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
TYPE_NAME (tt) = x;
- TREE_USED (tt) = TREE_USED (x);
+
+ /* Mark the type as used only when its type decl is decorated
+ with attribute unused. */
+ if (lookup_attribute ("unused", DECL_ATTRIBUTES (x)))
+ TREE_USED (tt) = 1;
+
TREE_TYPE (x) = tt;
}
}
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 3cf9b18edfa..af7226dd11f 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -63,7 +63,7 @@
#define bit_MMXEXT (1 << 22)
#define bit_LM (1 << 29)
#define bit_3DNOWP (1 << 30)
-#define bit_3DNOW (1 << 31)
+#define bit_3DNOW (1u << 31)
/* %ebx. */
#define bit_CLZERO (1 << 0)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 371b84e3f6f..e3201e404e9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -41323,9 +41323,6 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
mode0 = DImode;
rdrand_step:
- op0 = gen_reg_rtx (mode0);
- emit_insn (GEN_FCN (icode) (op0));
-
arg0 = CALL_EXPR_ARG (exp, 0);
op1 = expand_normal (arg0);
if (!address_operand (op1, VOIDmode))
@@ -41333,6 +41330,10 @@ rdrand_step:
op1 = convert_memory_address (Pmode, op1);
op1 = copy_addr_to_reg (op1);
}
+
+ op0 = gen_reg_rtx (mode0);
+ emit_insn (GEN_FCN (icode) (op0));
+
emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
op1 = gen_reg_rtx (SImode);
@@ -41341,8 +41342,20 @@ rdrand_step:
/* Emit SImode conditional move. */
if (mode0 == HImode)
{
- op2 = gen_reg_rtx (SImode);
- emit_insn (gen_zero_extendhisi2 (op2, op0));
+ if (TARGET_ZERO_EXTEND_WITH_AND
+ && optimize_function_for_speed_p (cfun))
+ {
+ op2 = force_reg (SImode, const0_rtx);
+
+ emit_insn (gen_movstricthi
+ (gen_lowpart (HImode, op2), op0));
+ }
+ else
+ {
+ op2 = gen_reg_rtx (SImode);
+
+ emit_insn (gen_zero_extendhisi2 (op2, op0));
+ }
}
else if (mode0 == SImode)
op2 = op0;
@@ -41374,9 +41387,6 @@ rdrand_step:
mode0 = DImode;
rdseed_step:
- op0 = gen_reg_rtx (mode0);
- emit_insn (GEN_FCN (icode) (op0));
-
arg0 = CALL_EXPR_ARG (exp, 0);
op1 = expand_normal (arg0);
if (!address_operand (op1, VOIDmode))
@@ -41384,6 +41394,10 @@ rdseed_step:
op1 = convert_memory_address (Pmode, op1);
op1 = copy_addr_to_reg (op1);
}
+
+ op0 = gen_reg_rtx (mode0);
+ emit_insn (GEN_FCN (icode) (op0));
+
emit_move_insn (gen_rtx_MEM (mode0, op1), op0);
op2 = gen_reg_rtx (QImode);
@@ -45939,10 +45953,16 @@ ix86_vector_duplicate_value (machine_mode mode, rtx target, rtx val)
if (recog_memoized (insn) < 0)
{
rtx_insn *seq;
+ machine_mode innermode = GET_MODE_INNER (mode);
+ rtx reg;
+
/* If that fails, force VAL into a register. */
start_sequence ();
- XEXP (dup, 0) = force_reg (GET_MODE_INNER (mode), val);
+ reg = force_reg (innermode, val);
+ if (GET_MODE (reg) != innermode)
+ reg = gen_lowpart (innermode, reg);
+ XEXP (dup, 0) = reg;
seq = get_insns ();
end_sequence ();
if (seq)
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index 465ad6d9210..4277394a3a7 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -135,6 +135,9 @@
(define_register_constraint "wz" "rs6000_constraints[RS6000_CONSTRAINT_wz]"
"Floating point register if the LFIWZX instruction is enabled or NO_REGS.")
+(define_register_constraint "wA" "rs6000_constraints[RS6000_CONSTRAINT_wA]"
+ "BASE_REGS if 64-bit instructions are enabled or NO_REGS.")
+
(define_constraint "wD"
"Int constant that is the element number of the 64-bit scalar in a vector."
(and (match_code "const_int")
diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
index e6ed70ed8ec..c84b43d75bb 100644
--- a/gcc/config/rs6000/dfp.md
+++ b/gcc/config/rs6000/dfp.md
@@ -347,16 +347,16 @@
[(set_attr "type" "dfp")])
(define_insn "dfp_dxex_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
- UNSPEC_DXEX))]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+ (unspec:DI [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
"TARGET_DFP"
"dxex<dfp_suffix> %0,%1"
[(set_attr "type" "dfp")])
(define_insn "dfp_diex_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d")
(match_operand:D64_D128 2 "gpc_reg_operand" "d")]
UNSPEC_DXEX))]
"TARGET_DFP"
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7df09a3cab0..5a48f06face 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2406,6 +2406,7 @@ rs6000_debug_reg_global (void)
"wx reg_class = %s\n"
"wy reg_class = %s\n"
"wz reg_class = %s\n"
+ "wA reg_class = %s\n"
"\n",
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
@@ -2433,7 +2434,8 @@ rs6000_debug_reg_global (void)
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ww]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]],
reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wy]],
- reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]]);
+ reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]],
+ reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]]);
nl = "\n";
for (m = 0; m < NUM_MACHINE_MODES; ++m)
@@ -3120,7 +3122,10 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
}
if (TARGET_POWERPC64)
- rs6000_constraints[RS6000_CONSTRAINT_wr] = GENERAL_REGS;
+ {
+ rs6000_constraints[RS6000_CONSTRAINT_wr] = GENERAL_REGS;
+ rs6000_constraints[RS6000_CONSTRAINT_wA] = BASE_REGS;
+ }
if (TARGET_P8_VECTOR && TARGET_UPPER_REGS_SF) /* SFmode */
{
@@ -36169,7 +36174,10 @@ rs6000_inner_target_options (tree args, bool attr_p)
}
else
- gcc_unreachable ();
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
return ret;
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9f6f6851db9..9aba7529e86 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -744,7 +744,8 @@ extern int rs6000_vector_align[];
&& (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)))
#define TARGET_FRSQRTES (TARGET_HARD_FLOAT && TARGET_POPCNTB \
- && TARGET_FPRS && TARGET_SINGLE_FLOAT)
+ && TARGET_PPC_GFXOPT && TARGET_FPRS \
+ && TARGET_SINGLE_FLOAT)
#define TARGET_FRSQRTE (TARGET_HARD_FLOAT && TARGET_FPRS \
&& TARGET_DOUBLE_FLOAT \
@@ -1589,6 +1590,7 @@ enum r6000_reg_class_enum {
RS6000_CONSTRAINT_wx, /* FPR register for STFIWX */
RS6000_CONSTRAINT_wy, /* VSX register for SF */
RS6000_CONSTRAINT_wz, /* FPR register for LFIWZX */
+ RS6000_CONSTRAINT_wA, /* BASE_REGS if 64-bit. */
RS6000_CONSTRAINT_MAX
};
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index c54e7271302..0f1e9a45823 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2252,12 +2252,12 @@
;; Since the hardware zeros the upper part of the register, save generating the
;; AND immediate if we are converting to unsigned
-(define_insn "*bswaphi2_extenddi"
+(define_insn "*bswap<mode>2_extenddi"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extend:DI
- (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
+ (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
"TARGET_POWERPC64"
- "lhbrx %0,%y1"
+ "l<wd>brx %0,%y1"
[(set_attr "length" "4")
(set_attr "type" "load")])
@@ -2270,34 +2270,52 @@
[(set_attr "length" "4")
(set_attr "type" "load")])
-(define_expand "bswaphi2"
- [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
- (bswap:HI
- (match_operand:HI 1 "reg_or_mem_operand" "")))
- (clobber (match_scratch:SI 2 ""))])]
+;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
+;; the register allocator from converting a gpr<-gpr swap into a store and then
+;; load with byte swap, which can be slower than doing it in the registers. It
+;; also prevents certain failures with the RELOAD register allocator.
+
+(define_expand "bswap<mode>2"
+ [(use (match_operand:HSI 0 "reg_or_mem_operand"))
+ (use (match_operand:HSI 1 "reg_or_mem_operand"))]
""
{
- if (!REG_P (operands[0]) && !REG_P (operands[1]))
- operands[1] = force_reg (HImode, operands[1]);
+ rtx dest = operands[0];
+ rtx src = operands[1];
+
+ if (!REG_P (dest) && !REG_P (src))
+ src = force_reg (<MODE>mode, src);
+
+ if (MEM_P (src))
+ emit_insn (gen_bswap<mode>2_load (dest, src));
+ else if (MEM_P (dest))
+ emit_insn (gen_bswap<mode>2_store (dest, src));
+ else
+ emit_insn (gen_bswap<mode>2_reg (dest, src));
+ DONE;
})
-(define_insn "bswaphi2_internal"
- [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
- (bswap:HI
- (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
- (clobber (match_scratch:SI 2 "=X,X,&r"))]
+(define_insn "bswap<mode>2_load"
+ [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
+ (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
""
- "@
- lhbrx %0,%y1
- sthbrx %1,%y0
- #"
- [(set_attr "length" "4,4,12")
- (set_attr "type" "load,store,*")])
+ "l<wd>brx %0,%y1"
+ [(set_attr "type" "load")])
-(define_split
- [(set (match_operand:HI 0 "gpc_reg_operand" "")
- (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
- (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
+(define_insn "bswap<mode>2_store"
+ [(set (match_operand:HSI 0 "memory_operand" "=Z")
+ (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
+ ""
+ "st<wd>brx %1,%y0"
+ [(set_attr "type" "store")])
+
+(define_insn_and_split "bswaphi2_reg"
+ [(set (match_operand:HI 0 "gpc_reg_operand" "=&r")
+ (bswap:HI
+ (match_operand:HI 1 "gpc_reg_operand" "r")))
+ (clobber (match_scratch:SI 2 "=&r"))]
+ ""
+ "#"
"reload_completed"
[(set (match_dup 3)
(and:SI (lshiftrt:SI (match_dup 4)
@@ -2310,48 +2328,21 @@
(set (match_dup 3)
(ior:SI (match_dup 3)
(match_dup 2)))]
- "
{
operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
-}")
-
-(define_insn "*bswapsi2_extenddi"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (zero_extend:DI
- (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
- "TARGET_POWERPC64"
- "lwbrx %0,%y1"
- [(set_attr "length" "4")
- (set_attr "type" "load")])
-
-(define_expand "bswapsi2"
- [(set (match_operand:SI 0 "reg_or_mem_operand" "")
- (bswap:SI
- (match_operand:SI 1 "reg_or_mem_operand" "")))]
- ""
-{
- if (!REG_P (operands[0]) && !REG_P (operands[1]))
- operands[1] = force_reg (SImode, operands[1]);
-})
-
-(define_insn "*bswapsi2_internal"
- [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
- (bswap:SI
- (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
- ""
- "@
- lwbrx %0,%y1
- stwbrx %1,%y0
- #"
- [(set_attr "length" "4,4,12")
- (set_attr "type" "load,store,*")])
+}
+ [(set_attr "length" "12")
+ (set_attr "type" "*")])
;; We are always BITS_BIG_ENDIAN, so the bit positions below in
;; zero_extract insns do not change for -mlittle.
-(define_split
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
+(define_insn_and_split "bswapsi2_reg"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
+ (bswap:SI
+ (match_operand:SI 1 "gpc_reg_operand" "r")))]
+ ""
+ "#"
"reload_completed"
[(set (match_dup 0) ; DABC
(rotate:SI (match_dup 1)
@@ -2367,11 +2358,13 @@
(const_int 24))
(const_int 255))
(and:SI (match_dup 0)
- (const_int -256))))
-
- ]
+ (const_int -256))))]
"")
+;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
+;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
+;; complex code.
+
(define_expand "bswapdi2"
[(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
(bswap:DI
@@ -2380,33 +2373,56 @@
(clobber (match_scratch:DI 3 ""))])]
""
{
- if (!REG_P (operands[0]) && !REG_P (operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
+ rtx dest = operands[0];
+ rtx src = operands[1];
+
+ if (!REG_P (dest) && !REG_P (src))
+ operands[1] = src = force_reg (DImode, src);
+
+ if (TARGET_POWERPC64 && TARGET_LDBRX)
+ {
+ if (MEM_P (src))
+ emit_insn (gen_bswapdi2_load (dest, src));
+ else if (MEM_P (dest))
+ emit_insn (gen_bswapdi2_store (dest, src));
+ else
+ emit_insn (gen_bswapdi2_reg (dest, src));
+ DONE;
+ }
if (!TARGET_POWERPC64)
{
/* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
that uses 64-bit registers needs the same scratch registers as 64-bit
mode. */
- emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
+ emit_insn (gen_bswapdi2_32bit (dest, src));
DONE;
}
})
;; Power7/cell has ldbrx/stdbrx, so use it directly
-(define_insn "*bswapdi2_ldbrx"
- [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
- (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
- (clobber (match_scratch:DI 2 "=X,X,&r"))
- (clobber (match_scratch:DI 3 "=X,X,&r"))]
- "TARGET_POWERPC64 && TARGET_LDBRX
- && (REG_P (operands[0]) || REG_P (operands[1]))"
- "@
- ldbrx %0,%y1
- stdbrx %1,%y0
- #"
- [(set_attr "length" "4,4,36")
- (set_attr "type" "load,store,*")])
+(define_insn "bswapdi2_load"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
+ "TARGET_POWERPC64 && TARGET_LDBRX"
+ "ldbrx %0,%y1"
+ [(set_attr "type" "load")])
+
+(define_insn "bswapdi2_store"
+ [(set (match_operand:DI 0 "memory_operand" "=Z")
+ (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+ "TARGET_POWERPC64 && TARGET_LDBRX"
+ "stdbrx %1,%y0"
+ [(set_attr "type" "store")])
+
+(define_insn "bswapdi2_reg"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
+ (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (clobber (match_scratch:DI 2 "=&r"))
+ (clobber (match_scratch:DI 3 "=&r"))]
+ "TARGET_POWERPC64 && TARGET_LDBRX"
+ "#"
+ [(set_attr "length" "36")])
;; Non-power7/cell, fall back to use lwbrx/stwbrx
(define_insn "*bswapdi2_64bit"
@@ -4663,7 +4679,7 @@
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_COPYSIGN))]
- "TARGET_<MODE>_FPR && TARGET_CMPB"
+ "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
"@
fcpsgn %0,%2,%1
xscpsgndp %x0,%x2,%x1"
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 2745e445ff4..4ea8bc52edd 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -2429,16 +2429,29 @@
})
;; V2DF/V2DI splat
-(define_insn "vsx_splat_<mode>"
- [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSa>,<VSa>,we")
+(define_insn_and_split "vsx_splat_<mode>"
+ [(set (match_operand:VSX_D 0 "vsx_register_operand"
+ "=<VSa>, <VSa>,we,<VS_64dm>")
(vec_duplicate:VSX_D
- (match_operand:<VS_scalar> 1 "splat_input_operand" "<VS_64reg>,Z,b")))]
+ (match_operand:<VS_scalar> 1 "splat_input_operand"
+ "<VS_64reg>,Z, b, wA")))]
"VECTOR_MEM_VSX_P (<MODE>mode)"
"@
xxpermdi %x0,%x1,%x1,0
lxvdsx %x0,%y1
- mtvsrdd %x0,%1,%1"
- [(set_attr "type" "vecperm,vecload,mftgpr")])
+ mtvsrdd %x0,%1,%1
+ #"
+ "&& reload_completed && TARGET_POWERPC64 && !TARGET_P9_VECTOR
+ && int_reg_operand (operands[1], <VS_scalar>mode)"
+ [(set (match_dup 2)
+ (match_dup 1))
+ (set (match_dup 0)
+ (vec_duplicate:VSX_D (match_dup 2)))]
+{
+ operands[2] = gen_rtx_REG (<VS_scalar>mode, reg_or_subregno (operands[0]));
+}
+ [(set_attr "type" "vecperm,vecload,vecperm,vecperm")
+ (set_attr "length" "4,4,4,8")])
;; V4SI splat (ISA 3.0)
;; When SI's are allowed in VSX registers, add XXSPLTW support
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 81583850b01..0aae8fc82a9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2017-03-20 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/80091
+ * lambda.c (maybe_generic_this_capture): Capture when fn
+ is an identifier node.
+
+2017-03-15 Marek Polacek <polacek@redhat.com>
+
+ Backported from mainline
+ 2016-12-14 Marek Polacek <polacek@redhat.com>
+
+ PR c++/72775
+ * init.c (perform_member_init): Diagnose member initializer for
+ flexible array member.
+
2017-03-14 Marek Polacek <polacek@redhat.com>
Backported from mainline
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1cd6a866d3d..0236e78eccc 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -796,6 +796,14 @@ perform_member_init (tree member, tree init)
in that case. */
init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
tf_warning_or_error);
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE
+ && init != NULL_TREE)
+ {
+ error_at (DECL_SOURCE_LOCATION (current_function_decl),
+ "member initializer for flexible array member");
+ inform (DECL_SOURCE_LOCATION (member), "%q#D initialized", member);
+ }
if (init)
finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 7c57d67a150..603b69b4876 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -809,8 +809,9 @@ maybe_generic_this_capture (tree object, tree fns)
{
tree fn = OVL_CURRENT (fns);
- if ((!id_expr || TREE_CODE (fn) == TEMPLATE_DECL)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ if (identifier_p (fns)
+ || ((!id_expr || TREE_CODE (fn) == TEMPLATE_DECL)
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)))
{
/* Found a non-static member. Capture this. */
lambda_expr_this_capture (lam, true);
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index 2625af6470e..787688d9c3e 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -181,6 +181,5 @@ gcov_type
streamer_read_gcov_count (struct lto_input_block *ib)
{
gcov_type ret = streamer_read_hwi (ib);
- gcc_assert (ret >= 0);
return ret;
}
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index e476530579d..47b5fec49d5 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -340,7 +340,6 @@ streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
void
streamer_write_gcov_count_stream (struct lto_output_stream *obs, gcov_type work)
{
- gcc_assert (work >= 0);
gcc_assert ((HOST_WIDE_INT) work == work);
streamer_write_hwi_stream (obs, work);
}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 04b93934e25..73ffddfc240 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -14003,14 +14003,14 @@ The following built-in functions are available for the PowerPC family
of processors when hardware decimal floating point
(@option{-mhard-dfp}) is available:
@smallexample
-_Decimal64 __builtin_dxex (_Decimal64);
-_Decimal128 __builtin_dxexq (_Decimal128);
+long long __builtin_dxex (_Decimal64);
+long long __builtin_dxexq (_Decimal128);
_Decimal64 __builtin_ddedpd (int, _Decimal64);
_Decimal128 __builtin_ddedpdq (int, _Decimal128);
_Decimal64 __builtin_denbcd (int, _Decimal64);
_Decimal128 __builtin_denbcdq (int, _Decimal128);
-_Decimal64 __builtin_diex (_Decimal64, _Decimal64);
-_Decimal128 _builtin_diexq (_Decimal128, _Decimal128);
+_Decimal64 __builtin_diex (long long, _Decimal64);
+_Decimal128 _builtin_diexq (long long, _Decimal128);
_Decimal64 __builtin_dscli (_Decimal64, int);
_Decimal128 __builtin_dscliq (_Decimal128, int);
_Decimal64 __builtin_dscri (_Decimal64, int);
diff --git a/gcc/doc/gcc.texi b/gcc/doc/gcc.texi
index 629365aeb12..b5a93764806 100644
--- a/gcc/doc/gcc.texi
+++ b/gcc/doc/gcc.texi
@@ -67,6 +67,7 @@ Texts being (a) (see below), and with the Back-Cover Texts being (b)
* g++: (gcc). The GNU C++ compiler.
* gcov: (gcc) Gcov. @command{gcov}---a test coverage program.
* gcov-tool: (gcc) Gcov-tool. @command{gcov-tool}---an offline gcda profile processing program.
+* gcov-dump: (gcc) Gcov-dump. @command{gcov-dump}---an offline gcda and gcno profile dump tool.
@end direntry
This file documents the use of the GNU compilers.
@sp 1
@@ -140,6 +141,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
* Compatibility:: Binary Compatibility
* Gcov:: @command{gcov}---a test coverage program.
* Gcov-tool:: @command{gcov-tool}---an offline gcda profile processing program.
+* Gcov-dump:: @command{gcov-dump}---an offline gcda and gcno profile dump tool.
* Trouble:: If you have trouble using GCC.
* Bugs:: How, why and where to report bugs.
* Service:: How To Get Help with GCC
@@ -167,6 +169,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
@include compat.texi
@include gcov.texi
@include gcov-tool.texi
+@include gcov-dump.texi
@include trouble.texi
@include bugreport.texi
@include service.texi
diff --git a/gcc/doc/gcov-dump.texi b/gcc/doc/gcov-dump.texi
new file mode 100644
index 00000000000..d7931fd3a19
--- /dev/null
+++ b/gcc/doc/gcov-dump.texi
@@ -0,0 +1,93 @@
+@c Copyright (C) 2017 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@ignore
+@c man begin COPYRIGHT
+Copyright @copyright{} 2017 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover texts being (a) (see below), and with
+the Back-Cover Texts being (b) (see below). A copy of the license is
+included in the gfdl(7) man page.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@c man end
+@c Set file name and title for the man page.
+@setfilename gcov-dump
+@settitle offline gcda and gcno profile dump tool
+@end ignore
+
+@node Gcov-dump
+@chapter @command{gcov-dump}---an Offline Gcda and Gcno Profile Dump Tool
+
+@menu
+* Gcov-dump Intro:: Introduction to gcov-dump.
+* Invoking Gcov-dump:: How to use gcov-dump.
+@end menu
+
+@node Gcov-dump Intro
+@section Introduction to @command{gcov-dump}
+@c man begin DESCRIPTION
+
+@command{gcov-dump} is a tool you can use in conjunction with GCC to
+dump content of gcda and gcno profile files offline.
+
+@c man end
+
+@node Invoking Gcov-dump
+@section Invoking @command{gcov-dump}
+
+@smallexample
+Usage: gcov-dump @r{[}@var{OPTION}@r{]} ... @var{gcovfiles}
+@end smallexample
+
+@command{gcov-dump} accepts the following options:
+
+@ignore
+@c man begin SYNOPSIS
+gcov-dump [@option{-v}|@option{--version}]
+ [@option{-h}|@option{--help}]
+ [@option{-l}|@option{--long}]
+ [@option{-p}|@option{--positions}]
+ [@option{-w}|@option{--working-sets}] @var{gcovfiles}
+@c man end
+@end ignore
+
+@c man begin OPTIONS
+@table @gcctabopt
+@item -h
+@itemx --help
+Display help about using @command{gcov-dump} (on the standard output), and
+exit without doing any further processing.
+
+@item -v
+@itemx --version
+Display the @command{gcov-dump} version number (on the standard output),
+and exit without doing any further processing.
+
+@item -l
+@itemx --long
+Dump content of records.
+
+@item -p
+@itemx --positions
+Dump positions of records.
+
+@item -w
+@itemx --working-sets
+Dump working set computed from summary.
+@end table
+
+@c man end
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 996b63965c4..ace8f63544e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -256,7 +256,7 @@ Objective-C and Objective-C++ Dialects}.
-Wno-attributes -Wbool-compare -Wno-builtin-macro-redefined @gol
-Wc90-c99-compat -Wc99-c11-compat @gol
-Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol
--Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
+-Wchar-subscripts -Wchkp -Wclobbered -Wcomment -Wconditionally-supported @gol
-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdate-time -Wdelete-incomplete @gol
-Wno-deprecated -Wno-deprecated-declarations -Wno-designated-init @gol
-Wdisabled-optimization @gol
@@ -3652,6 +3652,11 @@ Warn whenever a comment-start sequence @samp{/*} appears in a @samp{/*}
comment, or whenever a Backslash-Newline appears in a @samp{//} comment.
This warning is enabled by @option{-Wall}.
+@item -Wchkp
+@opindex Wchkp
+Warn about an invalid memory access that is found by Pointer Bounds Checker
+(@option{-fcheck-pointer-bounds}).
+
@item -Wno-coverage-mismatch
@opindex Wno-coverage-mismatch
Warn if feedback profiles do not match when using the
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index d12c7b1674e..44c441bc57c 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3211,6 +3211,9 @@ FP or VSX register to perform ISA 2.07 float ops or NO_REGS.
@item wz
Floating point register if the LFIWZX instruction is enabled or NO_REGS.
+@item wA
+Address base register if 64-bit instructions are enabled or NO_REGS.
+
@item wD
Int constant that is the element number of the 64-bit scalar in a vector.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 4f2f8417e7d..e7170496dc5 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8887,7 +8887,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
if (save_p)
{
tem = save_expr (build2 (code, type, cval1, cval2));
- SET_EXPR_LOCATION (tem, loc);
+ protected_set_expr_location (tem, loc);
return tem;
}
return fold_build2_loc (loc, code, type, cval1, cval2);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index d2db3c7f8c5..8083787f8a6 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,32 @@
+2017-04-01 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/71838
+ * symbol.c (check_conflict): A dummy procedure in a submodule,
+ module procedure is not an error.
+ (gfc_add_flavor): Ditto.
+
+2017-04-01 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/79676
+ * module.c (mio_symbol_attribute): Remove reset of the flag
+ 'no_module_procedures'.
+ (check_for_module_procedures): New function. Move declaration
+ of 'no_module_procedures' to above it.
+ (gfc_dump_module): Traverse namespace calling new function.
+
+2017-03-26 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/79434
+ * parse.c (check_component, parse_union): Whitespace.
+ (set_syms_host_assoc): For a derived type, check if the module
+ in which it was declared is one of the submodule ancestors. If
+ it is, make the components public. Otherwise, reset attribute
+ 'host_assoc' and set 'use-assoc' so that encapsulation is
+ preserved.
+
2017-03-14 Richard Biener <rguenther@suse.de>
Backport from mainline
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 8ebd3e08569..29bcaf37bf9 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -193,10 +193,6 @@ static const char *module_name;
/* The name of the .smod file that the submodule will write to. */
static const char *submodule_name;
-/* Suppress the output of a .smod file by module, if no module
- procedures have been seen. */
-static bool no_module_procedures;
-
static gfc_use_list *module_list;
/* If we're reading an intrinsic module, this is its ID. */
@@ -2240,10 +2236,7 @@ mio_symbol_attribute (symbol_attribute *attr)
if (attr->array_outer_dependency)
MIO_NAME (ab_attribute) (AB_ARRAY_OUTER_DEPENDENCY, attr_bits);
if (attr->module_procedure)
- {
MIO_NAME (ab_attribute) (AB_MODULE_PROCEDURE, attr_bits);
- no_module_procedures = false;
- }
if (attr->oacc_declare_create)
MIO_NAME (ab_attribute) (AB_OACC_DECLARE_CREATE, attr_bits);
if (attr->oacc_declare_copyin)
@@ -6129,6 +6122,18 @@ dump_module (const char *name, int dump_flag)
}
+/* Suppress the output of a .smod file by module, if no module
+ procedures have been seen. */
+static bool no_module_procedures;
+
+static void
+check_for_module_procedures (gfc_symbol *sym)
+{
+ if (sym && sym->attr.module_procedure)
+ no_module_procedures = false;
+}
+
+
void
gfc_dump_module (const char *name, int dump_flag)
{
@@ -6138,6 +6143,8 @@ gfc_dump_module (const char *name, int dump_flag)
dump_smod =false;
no_module_procedures = true;
+ gfc_traverse_ns (gfc_current_ns, check_for_module_procedures);
+
dump_module (name, dump_flag);
if (no_module_procedures || dump_smod)
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 49da3d44b1c..3afdf4df5e5 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -2795,7 +2795,7 @@ check_component (gfc_symbol *sym, gfc_component *c, gfc_component **lockp,
coarray = true;
sym->attr.coarray_comp = 1;
}
-
+
if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.coarray_comp
&& !c->attr.pointer)
{
@@ -2959,7 +2959,7 @@ parse_union (void)
/* Add a component to the union for each map. */
if (!gfc_add_component (un, gfc_new_block->name, &c))
{
- gfc_internal_error ("failed to create map component '%s'",
+ gfc_internal_error ("failed to create map component '%s'",
gfc_new_block->name);
reject_statement ();
return;
@@ -5668,6 +5668,9 @@ static void
set_syms_host_assoc (gfc_symbol *sym)
{
gfc_component *c;
+ const char dot[2] = ".";
+ char parent1[GFC_MAX_SYMBOL_LEN + 1];
+ char parent2[GFC_MAX_SYMBOL_LEN + 1];
if (sym == NULL)
return;
@@ -5675,16 +5678,32 @@ set_syms_host_assoc (gfc_symbol *sym)
if (sym->attr.module_procedure)
sym->attr.external = 0;
-/* sym->attr.access = ACCESS_PUBLIC; */
-
sym->attr.use_assoc = 0;
sym->attr.host_assoc = 1;
sym->attr.used_in_submodule =1;
if (sym->attr.flavor == FL_DERIVED)
{
- for (c = sym->components; c; c = c->next)
- c->attr.access = ACCESS_PUBLIC;
+ /* Derived types with PRIVATE components that are declared in
+ modules other than the parent module must not be changed to be
+ PUBLIC. The 'use-assoc' attribute must be reset so that the
+ test in symbol.c(gfc_find_component) works correctly. This is
+ not necessary for PRIVATE symbols since they are not read from
+ the module. */
+ memset(parent1, '\0', sizeof(parent1));
+ memset(parent2, '\0', sizeof(parent2));
+ strcpy (parent1, gfc_new_block->name);
+ strcpy (parent2, sym->module);
+ if (strcmp (strtok (parent1, dot), strtok (parent2, dot)) == 0)
+ {
+ for (c = sym->components; c; c = c->next)
+ c->attr.access = ACCESS_PUBLIC;
+ }
+ else
+ {
+ sym->attr.use_assoc = 1;
+ sym->attr.host_assoc = 0;
+ }
}
}
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 050c281335f..98f4127bb9b 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -464,8 +464,13 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
}
}
- if (attr->dummy && ((attr->function || attr->subroutine) &&
- gfc_current_state () == COMP_CONTAINS))
+ /* The copying of procedure dummy arguments for module procedures in
+ a submodule occur whilst the current state is COMP_CONTAINS. It
+ is necessary, therefore, to let this through. */
+ if (attr->dummy
+ && (attr->function || attr->subroutine)
+ && gfc_current_state () == COMP_CONTAINS
+ && !(gfc_new_block && gfc_new_block->abr_modproc_decl))
gfc_error_now ("internal procedure %qs at %L conflicts with "
"DUMMY argument", name, where);
@@ -1587,6 +1592,13 @@ gfc_add_flavor (symbol_attribute *attr, sym_flavor f, const char *name,
if (attr->flavor == f && f == FL_VARIABLE)
return true;
+ /* Copying a procedure dummy argument for a module procedure in a
+ submodule results in the flavor being copied and would result in
+ an error without this. */
+ if (gfc_new_block && gfc_new_block->abr_modproc_decl
+ && attr->flavor == f && f == FL_PROCEDURE)
+ return true;
+
if (attr->flavor != FL_UNKNOWN)
{
if (where == NULL)
diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c
index 0f8ae993d50..e16fd9d6a3a 100644
--- a/gcc/gcov-dump.c
+++ b/gcc/gcov-dump.c
@@ -136,6 +136,8 @@ print_usage (void)
printf (" -l, --long Dump record contents too\n");
printf (" -p, --positions Dump record positions\n");
printf (" -w, --working-sets Dump working set computed from summary\n");
+ printf ("\nFor bug reporting instructions, please see:\n%s.\n",
+ bug_report_url);
}
static void
diff --git a/gcc/gcse.c b/gcc/gcse.c
index a3a7dc31353..5b2c96ecb5a 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -279,7 +279,7 @@ struct gcse_expr
to keep register pressure under control.
A value of "0" removes restrictions on how far the expression can
travel. */
- int max_distance;
+ HOST_WIDE_INT max_distance;
};
/* Occurrence of an expression.
@@ -457,7 +457,7 @@ static int oprs_unchanged_p (const_rtx, const rtx_insn *, int);
static int oprs_anticipatable_p (const_rtx, const rtx_insn *);
static int oprs_available_p (const_rtx, const rtx_insn *);
static void insert_expr_in_table (rtx, machine_mode, rtx_insn *, int, int,
- int, struct gcse_hash_table_d *);
+ HOST_WIDE_INT, struct gcse_hash_table_d *);
static unsigned int hash_expr (const_rtx, machine_mode, int *, int);
static void record_last_reg_set_info (rtx_insn *, int);
static void record_last_mem_set_info (rtx_insn *);
@@ -487,8 +487,10 @@ static void alloc_code_hoist_mem (int, int);
static void free_code_hoist_mem (void);
static void compute_code_hoist_vbeinout (void);
static void compute_code_hoist_data (void);
-static int should_hoist_expr_to_dom (basic_block, struct gcse_expr *, basic_block,
- sbitmap, int, int *, enum reg_class,
+static int should_hoist_expr_to_dom (basic_block, struct gcse_expr *,
+ basic_block,
+ sbitmap, HOST_WIDE_INT, int *,
+ enum reg_class,
int *, bitmap, rtx_insn *);
static int hoist_code (void);
static enum reg_class get_regno_pressure_class (int regno, int *nregs);
@@ -742,7 +744,7 @@ static basic_block current_bb;
GCSE. */
static int
-want_to_gcse_p (rtx x, machine_mode mode, int *max_distance_ptr)
+want_to_gcse_p (rtx x, machine_mode mode, HOST_WIDE_INT *max_distance_ptr)
{
#ifdef STACK_REGS
/* On register stack architectures, don't GCSE constants from the
@@ -789,7 +791,7 @@ want_to_gcse_p (rtx x, machine_mode mode, int *max_distance_ptr)
/* PRE doesn't implement max_distance restriction. */
{
int cost;
- int max_distance;
+ HOST_WIDE_INT max_distance;
gcc_assert (!optimize_function_for_speed_p (cfun)
&& optimize_function_for_size_p (cfun));
@@ -797,7 +799,8 @@ want_to_gcse_p (rtx x, machine_mode mode, int *max_distance_ptr)
if (cost < COSTS_N_INSNS (GCSE_UNRESTRICTED_COST))
{
- max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
+ max_distance
+ = ((HOST_WIDE_INT)GCSE_COST_DISTANCE_RATIO * cost) / 10;
if (max_distance == 0)
return 0;
@@ -1113,7 +1116,8 @@ expr_equiv_p (const_rtx x, const_rtx y)
static void
insert_expr_in_table (rtx x, machine_mode mode, rtx_insn *insn,
int antic_p,
- int avail_p, int max_distance, struct gcse_hash_table_d *table)
+ int avail_p, HOST_WIDE_INT max_distance,
+ struct gcse_hash_table_d *table)
{
int found, do_not_record_p;
unsigned int hash;
@@ -1229,7 +1233,7 @@ hash_scan_set (rtx set, rtx_insn *insn, struct gcse_hash_table_d *table)
else if (REG_P (dest))
{
unsigned int regno = REGNO (dest);
- int max_distance = 0;
+ HOST_WIDE_INT max_distance = 0;
/* See if a REG_EQUAL note shows this equivalent to a simpler expression.
@@ -1298,7 +1302,7 @@ hash_scan_set (rtx set, rtx_insn *insn, struct gcse_hash_table_d *table)
else if (flag_gcse_las && REG_P (src) && MEM_P (dest))
{
unsigned int regno = REGNO (src);
- int max_distance = 0;
+ HOST_WIDE_INT max_distance = 0;
/* Only record sets of pseudo-regs in the hash table. */
if (regno >= FIRST_PSEUDO_REGISTER
@@ -1410,7 +1414,8 @@ dump_hash_table (FILE *file, const char *name, struct gcse_hash_table_d *table)
if (flat_table[i] != 0)
{
expr = flat_table[i];
- fprintf (file, "Index %d (hash value %d; max distance %d)\n ",
+ fprintf (file, "Index %d (hash value %d; max distance "
+ HOST_WIDE_INT_PRINT_DEC ")\n ",
expr->bitmap_index, hash_val[i], expr->max_distance);
print_rtl (file, expr->expr);
fprintf (file, "\n");
@@ -2874,7 +2879,8 @@ update_bb_reg_pressure (basic_block bb, rtx_insn *from)
static int
should_hoist_expr_to_dom (basic_block expr_bb, struct gcse_expr *expr,
- basic_block bb, sbitmap visited, int distance,
+ basic_block bb, sbitmap visited,
+ HOST_WIDE_INT distance,
int *bb_size, enum reg_class pressure_class,
int *nregs, bitmap hoisted_bbs, rtx_insn *from)
{
@@ -3151,7 +3157,7 @@ hoist_code (void)
computes the expression. */
FOR_EACH_VEC_ELT (domby, j, dominated)
{
- int max_distance;
+ HOST_WIDE_INT max_distance;
/* Ignore self dominance. */
if (bb == dominated)
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 2cf018bdf39..981fabf6dc6 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2462,10 +2462,19 @@ maybe_record_node (vec <cgraph_node *> &nodes,
nodes.safe_push (target_node);
}
}
- else if (completep
- && (!type_in_anonymous_namespace_p
- (DECL_CONTEXT (target))
- || flag_ltrans))
+ else if (!completep)
+ ;
+ /* We have definition of __cxa_pure_virtual that is not accessible (it is
+ optimized out or partitioned to other unit) so we can not add it. When
+ not sanitizing, there is nothing to do.
+ Otherwise declare the list incomplete. */
+ else if (pure_virtual)
+ {
+ if (flag_sanitize & SANITIZE_UNREACHABLE)
+ *completep = false;
+ }
+ else if (flag_ltrans
+ || !type_in_anonymous_namespace_p (DECL_CONTEXT (target)))
*completep = false;
}
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 5421ee31268..75d3ddf91cc 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -218,11 +218,17 @@ warn_function_const (tree decl, bool known_finite)
static void
warn_function_noreturn (tree decl)
{
+ tree original_decl = decl;
+
+ cgraph_node *node = cgraph_node::get (decl);
+ if (node->instrumentation_clone)
+ decl = node->instrumented_version->decl;
+
static hash_set<tree> *warned_about;
if (!lang_hooks.missing_noreturn_ok_p (decl)
&& targetm.warn_func_return (decl))
warned_about
- = suggest_attribute (OPT_Wsuggest_attribute_noreturn, decl,
+ = suggest_attribute (OPT_Wsuggest_attribute_noreturn, original_decl,
true, warned_about, "noreturn");
}
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index 59880a390d0..a314fae41f2 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -68,6 +68,13 @@ create_dispatcher_calls (struct cgraph_node *node)
" supported by this target");
break;
}
+ else if (!targetm.get_function_versions_dispatcher)
+ {
+ error_at (gimple_location (call),
+ "target does not support function version dispatcher");
+ break;
+ }
+
e_next = e->next_caller;
idecl = targetm.get_function_versions_dispatcher (decl);
if (!idecl)
@@ -87,6 +94,7 @@ create_dispatcher_calls (struct cgraph_node *node)
inode->resolve_alias (cgraph_node::get (resolver_decl));
e->redirect_callee (inode);
+ e->redirect_call_stmt_to_callee ();
/* Since REDIRECT_CALLEE modifies NEXT_CALLER field we move to
previously set NEXT_CALLER. */
e = NULL;
@@ -283,6 +291,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
create_new_asm_name (attr, suffix);
/* Create new target clone. */
cgraph_node *new_node = create_target_clone (node, definition, suffix);
+ new_node->local.local = false;
XDELETEVEC (suffix);
/* Set new attribute for the clone. */
@@ -325,6 +334,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
tree attributes = make_attribute ("target", "default",
DECL_ATTRIBUTES (node->decl));
DECL_ATTRIBUTES (node->decl) = attributes;
+ node->local.local = false;
location_t saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (node->decl);
bool ret
@@ -334,17 +344,19 @@ expand_target_clones (struct cgraph_node *node, bool definition)
return ret;
}
-static bool target_clone_pass;
-
static unsigned int
ipa_target_clone (void)
{
struct cgraph_node *node;
- target_clone_pass = false;
+ bool target_clone_pass = false;
FOR_EACH_FUNCTION (node)
- if (node->definition)
- target_clone_pass |= expand_target_clones (node, true);
+ target_clone_pass |= expand_target_clones (node, node->definition);
+
+ if (target_clone_pass)
+ FOR_EACH_FUNCTION (node)
+ create_dispatcher_calls (node);
+
return 0;
}
@@ -360,7 +372,7 @@ const pass_data pass_data_target_clone =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0 /* todo_flags_finish */
+ TODO_update_ssa /* todo_flags_finish */
};
class pass_target_clone : public simple_ipa_opt_pass
@@ -388,58 +400,3 @@ make_pass_target_clone (gcc::context *ctxt)
{
return new pass_target_clone (ctxt);
}
-
-static unsigned int
-ipa_dispatcher_calls (void)
-{
- struct cgraph_node *node;
-
- FOR_EACH_FUNCTION (node)
- if (!node->definition)
- target_clone_pass |= expand_target_clones (node, false);
- if (target_clone_pass)
- FOR_EACH_FUNCTION (node)
- create_dispatcher_calls (node);
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_dispatcher_calls =
-{
- SIMPLE_IPA_PASS, /* type */
- "dispachercalls", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- ( PROP_ssa | PROP_cfg ), /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
-};
-
-class pass_dispatcher_calls : public simple_ipa_opt_pass
-{
-public:
- pass_dispatcher_calls (gcc::context *ctxt)
- : simple_ipa_opt_pass (pass_data_dispatcher_calls, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *);
- virtual unsigned int execute (function *) { return ipa_dispatcher_calls (); }
-};
-
-bool
-pass_dispatcher_calls::gate (function *)
-{
- return true;
-}
-
-} // anon namespace
-
-simple_ipa_opt_pass *
-make_pass_dispatcher_calls (gcc::context *ctxt)
-{
- return new pass_dispatcher_calls (ctxt);
-}
diff --git a/gcc/params.def b/gcc/params.def
index 7ae89243b48..de39827f230 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -634,7 +634,7 @@ DEFPARAM(PARAM_SELSCHED_MAX_LOOKAHEAD,
DEFPARAM(PARAM_SELSCHED_MAX_SCHED_TIMES,
"selsched-max-sched-times",
"Maximum number of times that an insn could be scheduled.",
- 2, 0, 0)
+ 2, 1, 0)
DEFPARAM(PARAM_SELSCHED_INSNS_TO_RENAME,
"selsched-insns-to-rename",
diff --git a/gcc/passes.def b/gcc/passes.def
index 7aed1444542..7db9c9577cf 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -132,6 +132,7 @@ along with GCC; see the file COPYING3. If not see
POP_INSERT_PASSES ()
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_target_clone);
NEXT_PASS (pass_ipa_chkp_produce_thunks);
NEXT_PASS (pass_ipa_auto_profile);
NEXT_PASS (pass_ipa_free_inline_summary);
@@ -151,7 +152,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_ipa_devirt);
NEXT_PASS (pass_ipa_cp);
NEXT_PASS (pass_ipa_cdtor_merge);
- NEXT_PASS (pass_target_clone);
NEXT_PASS (pass_ipa_hsa);
NEXT_PASS (pass_ipa_inline);
NEXT_PASS (pass_ipa_pure_const);
@@ -169,7 +169,6 @@ along with GCC; see the file COPYING3. If not see
compiled unit. */
INSERT_PASSES_AFTER (all_late_ipa_passes)
NEXT_PASS (pass_ipa_pta);
- NEXT_PASS (pass_dispatcher_calls);
NEXT_PASS (pass_omp_simd_clone);
TERMINATE_PASS_LIST ()
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e9572b10dcd..bff83e1c22f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,285 @@
+2017-04-03 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from the trunk
+ 2017-03-14 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/79947
+ * gcc.target/powerpc/pr79947.c: New test.
+
+2017-04-03 Peter Bergner <bergner@vnet.ibm.com>
+
+ Backport from mainline
+ 2017-04-03 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR target/80246
+ * gcc.target/powerpc/dfp-builtin-1.c: Require hard_dfp, not
+ powerpc_vsx_ok.
+ (std, ld): Limit scan-assembler-times check to lp64.
+ (stwu, stw, lwz): Add scan-assembler-times check for ilp32.
+ * gcc.target/powerpc/dfp-builtin-2.c: Require hard_dfp, not
+ powerpc_vsx_ok.
+
+ PR target/80246
+ * gcc.target/powerpc/pr80246.c: Require hard_dfp.
+
+2017-04-01 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/71838
+ * gfortran.dg/submodule_26.f08 : New test.
+ * gfortran.dg/submodule_27.f08 : New test.
+
+2017-04-01 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/79676
+ * gfortran.dg/submodule_28.f08 : New test.
+
+2017-03-31 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/80218
+ * gcc.dg/pr80218.c: New test.
+
+2017-03-30 Peter Bergner <bergner@vnet.ibm.com>
+
+ Backport from mainline
+ 2017-03-30 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR target/80246
+ * gcc.target/powerpc/dfp-builtin-1.c: Remove unneeded dg-skip-if for
+ Darwin and SPE.
+ (dxex, dxexq): Update return type.
+ (diex, diexq): Update argument type.
+ * gcc.target/powerpc/pr80246.c: New test.
+
+2017-03-29 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from trunk
+ 2017-03-16 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/71294
+ * g++.dg/pr71294.C: New test.
+
+2017-03-29 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-03-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/78644
+ * gcc.dg/pr78644-1.c: New testcase.
+ * gcc.dg/pr78644-2.c: Likewise.
+
+ 2017-03-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/80181
+ * gcc.dg/torture/pr80181.c: New testcase.
+
+2017-03-28 Marek Polacek <polacek@redhat.com>
+
+ Backport from mainline
+ 2017-03-28 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/80067
+ * c-c++-common/ubsan/shift-10.c: New test.
+
+2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ Back port from trunk
+ 2017-03-27 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/78543
+ * gcc.target/powerpc/pr78543.c: New test.
+
+2017-03-27 Tom de Vries <tom@codesourcery.com>
+
+ backport from trunk:
+ 2017-03-24 Tom de Vries <tom@codesourcery.com>
+
+ PR testsuite/80092
+ * gcc.dg/tls/emutls-2.c: Add dg-require-effective-target
+ global_constructor.
+
+2017-03-26 Paul Thomas <pault@gcc.gnu.org>
+
+ Backport from trunk
+ PR fortran/79434
+ * gfortran.dg/submodule_25.f08 : New test.
+
+2017-03-24 Tom de Vries <tom@codesourcery.com>
+
+ backport from trunk:
+ 2017-03-24 Tom de Vries <tom@codesourcery.com>
+
+ PR testsuite/80092
+ * gcc.dg/torture/pr71881.c: Add dg-require-effective-target alloca.
+ * gcc.dg/torture/pr78742.c: Same.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-16 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * gcc.dg/tree-prof/pr66295.c: Skip unless on an x86 target.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-14 Martin Liska <mliska@suse.cz>
+
+ PR lto/66295
+ * gcc.dg/tree-prof/pr66295.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-22 Martin Liska <mliska@suse.cz>
+
+ PR lto/79587
+ * gcc.dg/tree-prof/pr79587.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-03 Martin Liska <mliska@suse.cz>
+
+ PR lto/66295
+ * gcc.target/i386/mvc9.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-22 Martin Liska <mliska@suse.cz>
+
+ PR target/79906
+ * g++.dg/ext/mv8.C: Add power* targets.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-21 Martin Liska <mliska@suse.cz>
+
+ * gcc.target/i386/pr65044.c: Add '.' in order to catch
+ apostrophes.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-20 Martin Liska <mliska@suse.cz>
+
+ PR middle-end/79753
+ * gcc.target/i386/mpx/pr79753.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-20 Martin Liska <mliska@suse.cz>
+
+ PR target/79769
+ PR target/79770
+ * g++.dg/pr79769.C: New test.
+ * gcc.target/i386/mpx/pr79770.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-13 Martin Liska <mliska@suse.cz>
+
+ PR middle-end/78339
+ * gcc.target/i386/mpx/pr78339.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/79631
+ * gcc.target/i386/mpx/pr79631.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR target/65705
+ PR target/69804
+ * gcc.target/i386/pr71458.c: Update scanned pattern.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-09 Martin Liska <mliska@suse.cz>
+
+ PR ipa/79761
+ * g++.dg/pr79761.C: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-03 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/79803
+ * gcc.dg/tree-ssa/pr79803.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-03-03 Martin Liska <mliska@suse.cz>
+
+ PR rtl-optimization/79574
+ * gcc.dg/pr79574-2.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2017-02-17 Martin Liska <mliska@suse.cz>
+
+ PR rtl-optimization/79574
+ * gcc.dg/pr79574.c: New test.
+
+2017-03-22 Martin Liska <mliska@suse.cz>
+
+ Backport from mainline
+ 2016-06-13 Martin Liska <mliska@suse.cz>
+
+ PR sanitizer/71458
+ * gcc.target/i386/pr71458.c: New test.
+
+2017-03-21 Martin Sebor <msebor@redhat.com>
+
+ PR c++/79548
+ * g++.dg/warn/Wunused-var-26.C: New test.
+
+2017-03-21 Pat Haugen <pthaugen@us.ibm.com>
+
+ Backport from mainline:
+ 2017-03-17 Pat Haugen <pthaugen@us.ibm.com>
+
+ PR target/79951
+ * gcc.target/powerpc/pr79951.c: New.
+
+2017-03-16 Richard Biener <rguenther@suse.de>
+
+ Backport from mainline
+ 2017-02-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/79732
+ * gcc.dg/torture/pr79732.c: New testcase.
+
+2017-03-15 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/80019
+ * gcc.target/i386/pr80019.c: New test.
+
+2017-03-15 Marek Polacek <polacek@redhat.com>
+
+ Backported from mainline
+ 2016-12-14 Marek Polacek <polacek@redhat.com>
+
+ PR c++/72775
+ * g++.dg/ext/flexary12.C: Adjust dg-error.
+ * g++.dg/ext/flexary20.C: New.
+ * g++.dg/ext/flexary21.C: New.
+
2017-03-14 Marek Polacek <polacek@redhat.com>
Backported from mainline
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-10.c b/gcc/testsuite/c-c++-common/ubsan/shift-10.c
new file mode 100644
index 00000000000..9202fccc465
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-10.c
@@ -0,0 +1,10 @@
+/* PR sanitizer/80067 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift" } */
+
+extern signed char a;
+void
+foo ()
+{
+ 0 << ((647 > a) - 1);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr80091.C b/gcc/testsuite/g++.dg/cpp0x/pr80091.C
new file mode 100644
index 00000000000..46c36e9f9ea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr80091.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+
+// PR 80091 ICE with member fn call from lambda in template
+
+struct A {
+ void m_fn1();
+};
+template <int> struct B : A {
+ void m_fn2() {
+ [&] { m_fn1(); };
+ }
+};
diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C
index 3d8c8059223..db80bf408f5 100644
--- a/gcc/testsuite/g++.dg/ext/flexary12.C
+++ b/gcc/testsuite/g++.dg/ext/flexary12.C
@@ -44,7 +44,7 @@ struct D {
D ();
};
-D::D ():
+D::D (): // { dg-error "member initializer for flexible array member" }
a ("c") // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
{ }
diff --git a/gcc/testsuite/g++.dg/ext/flexary20.C b/gcc/testsuite/g++.dg/ext/flexary20.C
new file mode 100644
index 00000000000..2c8ab2960f7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary20.C
@@ -0,0 +1,49 @@
+// PR c++/72775
+// { dg-do compile { target c++11 } }
+// { dg-options -Wno-pedantic }
+
+struct S {
+ int i;
+ char a[] = "foo";
+ S () {} // { dg-error "member initializer for flexible array member" }
+};
+
+struct T { // { dg-error "member initializer for flexible array member" }
+ int i;
+ char a[] = "foo";
+};
+
+struct U {
+ int i;
+ char a[] = "foo";
+ U ();
+};
+
+U::U() {} // { dg-error "member initializer for flexible array member" }
+
+int
+main ()
+{
+ struct T t;
+}
+
+struct V {
+ int i;
+ struct W { // { dg-error "member initializer for flexible array member" }
+ int j;
+ char a[] = "foo";
+ } w;
+ V () {}
+};
+
+template <class T>
+struct X { // { dg-error "member initializer for flexible array member" }
+ int i;
+ T a[] = "foo";
+};
+
+void
+fn ()
+{
+ struct X<char> x;
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary21.C b/gcc/testsuite/g++.dg/ext/flexary21.C
new file mode 100644
index 00000000000..5675bf6f0d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary21.C
@@ -0,0 +1,15 @@
+// PR c++/72775
+// { dg-do compile { target c++11 } }
+// { dg-options -Wno-pedantic }
+
+struct S {
+ int i;
+ char a[];
+ S () : a("bob") {} // { dg-error "member initializer for flexible array member" }
+};
+
+struct T {
+ int i;
+ char a[] = "bob";
+ T () : a("bob") {} // { dg-error "member initializer for flexible array member" }
+};
diff --git a/gcc/testsuite/g++.dg/ext/mv8.C b/gcc/testsuite/g++.dg/ext/mv8.C
index 2e98dd7ad85..bbf90b5a328 100644
--- a/gcc/testsuite/g++.dg/ext/mv8.C
+++ b/gcc/testsuite/g++.dg/ext/mv8.C
@@ -1,4 +1,4 @@
-// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-do compile { target i?86-*-* x86_64-*-* powerpc*-*-* } }
// { dg-options "" }
__attribute__((target (11,12)))
diff --git a/gcc/testsuite/g++.dg/pr71294.C b/gcc/testsuite/g++.dg/pr71294.C
new file mode 100644
index 00000000000..55dd01e5ccf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr71294.C
@@ -0,0 +1,60 @@
+// { dg-do compile { target { powerpc64*-*-* && lp64 } } }
+// { dg-require-effective-target powerpc_p8vector_ok } */
+// { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } }
+// { dg-options "-mcpu=power8 -O3 -fstack-protector -mno-lra" }
+
+// PAR target/71294 failed because RELOAD could not figure how create a V2DI
+// vector that auto vectorization created with each element being the same
+// stack address, with stack-protector turned on.
+
+class A;
+template <typename _Tp, int m, int n> class B {
+public:
+ _Tp val[m * n];
+};
+class C {
+public:
+ C(A);
+};
+struct D {
+ D();
+ unsigned long &operator[](int);
+ unsigned long *p;
+};
+class A {
+public:
+ template <typename _Tp, int m, int n> A(const B<_Tp, m, n> &, bool);
+ int rows, cols;
+ unsigned char *data;
+ unsigned char *datastart;
+ unsigned char *dataend;
+ unsigned char *datalimit;
+ D step;
+};
+template <typename _Tp, int m, int n>
+A::A(const B<_Tp, m, n> &p1, bool)
+ : rows(m), cols(n) {
+ step[0] = cols * sizeof(_Tp);
+ datastart = data = (unsigned char *)p1.val;
+ datalimit = dataend = datastart + rows * step[0];
+}
+class F {
+public:
+ static void compute(C);
+ template <typename _Tp, int m, int n, int nm>
+ static void compute(const B<_Tp, m, n> &, B<_Tp, nm, 1> &, B<_Tp, m, nm> &,
+ B<_Tp, n, nm> &);
+};
+D::D() {}
+unsigned long &D::operator[](int p1) { return p[p1]; }
+template <typename _Tp, int m, int n, int nm>
+void F::compute(const B<_Tp, m, n> &, B<_Tp, nm, 1> &, B<_Tp, m, nm> &,
+ B<_Tp, n, nm> &p4) {
+ A a(p4, false);
+ compute(a);
+}
+void fn1() {
+ B<double, 4, 4> b, c, e;
+ B<double, 4, 1> d;
+ F::compute(b, d, c, e);
+}
diff --git a/gcc/testsuite/g++.dg/pr79761.C b/gcc/testsuite/g++.dg/pr79761.C
new file mode 100644
index 00000000000..a97325a1fc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr79761.C
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && { ! x32 } } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -mabi=ms" } */
+
+struct Foo
+{
+ Foo() : a(1), b(1), c('a') {}
+ int a;
+ int b;
+ char c;
+};
+
+static Foo copy_foo(Foo) __attribute__((noinline, noclone));
+
+static Foo copy_foo(Foo A)
+{
+ return A;
+}
+
+struct Bar : Foo
+{
+ Bar(Foo t) : Foo(copy_foo(t)) {}
+};
+
+Foo F;
+
+int main (void)
+{
+ Bar B (F);
+
+ if (B.a != 1 || B.b != 1 || B.c != 'a')
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/pr79769.C b/gcc/testsuite/g++.dg/pr79769.C
new file mode 100644
index 00000000000..c3186877f60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr79769.C
@@ -0,0 +1,4 @@
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && { ! x32 } } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -mabi=ms" } */
+
+void a (_Complex) { a (3); }
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
new file mode 100644
index 00000000000..b3e020b6007
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
@@ -0,0 +1,147 @@
+// PR c++/79548 - missing -Wunused-variable on a typedef'd variable
+// in a function template
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+
+#define UNUSED __attribute__ ((unused))
+
+template <class T>
+void f_int ()
+{
+ T t; // { dg-warning "unused variable" }
+
+ typedef T U;
+ U u; // { dg-warning "unused variable" }
+}
+
+template void f_int<int>();
+
+
+template <class T>
+void f_intptr ()
+{
+ T *t = 0; // { dg-warning "unused variable" }
+
+ typedef T U;
+ U *u = 0; // { dg-warning "unused variable" }
+}
+
+template void f_intptr<int>();
+
+
+template <class T>
+void f_var_unused ()
+{
+ // The variable is marked unused.
+ T t UNUSED;
+
+ typedef T U;
+ U u UNUSED;
+}
+
+template void f_var_unused<int>();
+
+
+template <class T>
+void f_var_type_unused ()
+{
+ // The variable's type is marked unused.
+ T* UNUSED t = new T; // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+
+ typedef T U;
+ U* UNUSED u = new U; // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+
+ typedef T UNUSED U;
+ U v = U (); // { dg-bogus "unused variable" "bug 79585" }
+}
+
+template void f_var_type_unused<int>();
+
+
+struct A { int i; };
+
+template <class T>
+void f_A ()
+{
+ T t; // { dg-warning "unused variable" }
+
+ typedef T U;
+ U u; // { dg-warning "unused variable" }
+}
+
+template void f_A<A>();
+
+
+template <class T>
+void f_A_unused ()
+{
+ T t UNUSED;
+
+ typedef T U;
+ U u UNUSED;
+}
+
+template void f_A_unused<A>();
+
+
+struct B { B (); };
+
+template <class T>
+void f_B ()
+{
+ T t;
+
+ typedef T U;
+ U u;
+}
+
+template void f_B<B>();
+
+
+struct NonTrivialDtor { ~NonTrivialDtor (); };
+
+template <class T>
+void f_with_NonTrivialDtor ()
+{
+ // Expect no warnings when instantiated on a type with a non-trivial
+ // destructor.
+ T t;
+
+ typedef T U;
+ U u;
+}
+
+template void f_with_NonTrivialDtor<NonTrivialDtor>();
+
+
+struct D { NonTrivialDtor b; };
+
+template <class T>
+void f_D ()
+{
+ // Same as f_with_NonTrivialDtor but with a class that has a member
+ // with a non-trivial dtor.
+ T t;
+
+ typedef T U;
+ U u;
+}
+
+template void f_D<D>();
+
+
+struct UNUSED DeclaredUnused { };
+
+template <class T>
+void f_with_unused ()
+{
+ // Expect no warnings when instantiatiated on a type declared
+ // with attribute unused.
+ T t;
+
+ typedef T U;
+ U u;
+}
+
+template void f_with_unused<DeclaredUnused>();
diff --git a/gcc/testsuite/gcc.dg/pr78644-1.c b/gcc/testsuite/gcc.dg/pr78644-1.c
new file mode 100644
index 00000000000..d6aafeb7c63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr78644-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-Og -fipa-cp -w -Wno-psabi" } */
+
+typedef unsigned __int128 u128;
+typedef unsigned __int128 V __attribute__ ((vector_size (64)));
+
+V x4;
+
+static V
+bar (u128 x2, u128 x3)
+{
+ while (x4[0]--)
+ x2 /= x3 >>= 1;
+ return x2 + x3 + x4;
+}
+
+void
+foo (void)
+{
+ bar (0, 0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr78644-2.c b/gcc/testsuite/gcc.dg/pr78644-2.c
new file mode 100644
index 00000000000..3395ddee952
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr78644-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-Og -finline-functions-called-once -w -Wno-psabi" } */
+
+typedef unsigned V __attribute__ ((vector_size (64)));
+typedef unsigned __int128 U __attribute__ ((vector_size (64)));
+
+U
+bar4 (U u0, U u1)
+{
+ if (u1[0])
+ u1 <<= 1;
+ return u0 + u1;
+}
+
+V
+foo (U u, V v)
+{
+ v |= (unsigned)bar4(u, (U){})[0];
+ return v;
+}
diff --git a/gcc/testsuite/gcc.dg/pr79574-2.c b/gcc/testsuite/gcc.dg/pr79574-2.c
new file mode 100644
index 00000000000..995dff40174
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr79574-2.c
@@ -0,0 +1,33 @@
+/* PR rtl-optimization/79574 */
+/* { dg-do compile } */
+/* { dg-options "-Os --param gcse-cost-distance-ratio=2147483647" } */
+
+#include "stdarg.h"
+
+int buf[100];
+int buf1[10];
+
+int rd (int *pppp, int n, ...)
+{
+ va_list argp;
+ int *p;
+ int i;
+ int res;
+
+ va_start (argp, n);
+ for (; n > 0; n--)
+ va_arg (argp, double);
+ p = va_arg (argp, int *);
+ i = va_arg (argp, int);
+
+ res = p[i];
+ __builtin_printf ("%d\n", res);
+
+ return res;
+}
+
+int mpx_test (int argc, const char **argv)
+{
+ rd (buf1, 2, 10.0d, 10.0d, buf, 100, buf1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr79574.c b/gcc/testsuite/gcc.dg/pr79574.c
new file mode 100644
index 00000000000..1b666e20d21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr79574.c
@@ -0,0 +1,10 @@
+/* PR rtl-optimization/79574 */
+/* { dg-do compile } */
+/* { dg-options "-Os --param gcse-cost-distance-ratio=2147483647" } */
+
+void a (void)
+{
+ volatile int b;
+ for (;; b)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr80218.c b/gcc/testsuite/gcc.dg/pr80218.c
new file mode 100644
index 00000000000..8669ee12751
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr80218.c
@@ -0,0 +1,28 @@
+/* { dg-options "-O2 -fdump-rtl-ira-details-blocks" } */
+/* { dg-require-effective-target c99_runtime } */
+
+#include <math.h>
+
+void foo (float *);
+
+void
+f1 (float *x)
+{
+ x[0] = sqrtf (x[0]);
+}
+
+void
+f2 (float *x)
+{
+ sqrtf (x[0]);
+ foo (x);
+}
+
+void
+f3 (float *x)
+{
+ acosf (x[0]);
+ foo (x);
+}
+
+/* { dg-final { scan-rtl-dump-not "Invalid sum" "ira" } } */
diff --git a/gcc/testsuite/gcc.dg/tls/emutls-2.c b/gcc/testsuite/gcc.dg/tls/emutls-2.c
index 1e26d5fe116..3b94dc7e45c 100644
--- a/gcc/testsuite/gcc.dg/tls/emutls-2.c
+++ b/gcc/testsuite/gcc.dg/tls/emutls-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target tls } */
+/* { dg-require-effective-target global_constructor } */
/* { dg-options "-O2" } */
/* With emulated TLS, the constructor generated during IPA
diff --git a/gcc/testsuite/gcc.dg/torture/pr71881.c b/gcc/testsuite/gcc.dg/torture/pr71881.c
index b17db1b21c1..34325ba164a 100644
--- a/gcc/testsuite/gcc.dg/torture/pr71881.c
+++ b/gcc/testsuite/gcc.dg/torture/pr71881.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target alloca } */
/* { dg-additional-options "-g" } */
int a, b, c, d, *e, f, g;
diff --git a/gcc/testsuite/gcc.dg/torture/pr78742.c b/gcc/testsuite/gcc.dg/torture/pr78742.c
index c83ecbcb7d7..75601d4392f 100644
--- a/gcc/testsuite/gcc.dg/torture/pr78742.c
+++ b/gcc/testsuite/gcc.dg/torture/pr78742.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target alloca } */
void foo();
diff --git a/gcc/testsuite/gcc.dg/torture/pr79732.c b/gcc/testsuite/gcc.dg/torture/pr79732.c
new file mode 100644
index 00000000000..7231ba4f139
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr79732.c
@@ -0,0 +1,5 @@
+/* { dg-do link } */
+
+int bar () __attribute__ ((alias ("foo")));
+void foo () { }
+int main () { return bar(); }
diff --git a/gcc/testsuite/gcc.dg/torture/pr80181.c b/gcc/testsuite/gcc.dg/torture/pr80181.c
new file mode 100644
index 00000000000..896ca4fe0bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr80181.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+int
+nr (void)
+{
+}
+
+void
+it (int dl)
+{
+ int vp = 0;
+
+ for (;;)
+ {
+ dl = vp ^ nr ();
+ dl ^= vp;
+ vp = 1;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr66295.c b/gcc/testsuite/gcc.dg/tree-prof/pr66295.c
new file mode 100644
index 00000000000..e83e821387f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr66295.c
@@ -0,0 +1,35 @@
+/* { dg-require-ifunc "" } */
+/* { dg-skip-if "" { ! { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2" } */
+
+static double bar (double *__restrict, double *__restrict, int)
+__attribute__ ((target_clones("avx,avx2,avx512f,default")));
+
+double
+foo (double *__restrict a, double *__restrict b, int n)
+{
+ return bar (a,b,n);
+}
+
+double
+bar (double *__restrict a, double *__restrict b, int n) /* { dg-error "attribute\[^\n\r]*foo\[^\n\r]* is unknown" } */
+{
+ double s;
+ int i;
+ s = 0.0;
+ for (i=0; i<n; i++)
+ s += a[i] + b[i];
+
+ return s;
+}
+
+#define N 5
+
+int main ()
+{
+ double a[N] = {1.2f, 1.2f, 1.2f, 1.2f, 1.2f };
+ double b[N] = {1.2f, 1.2f, 1.2f, 1.2f, 1.2f };
+
+ __builtin_printf ("value: %.5f\n", foo (a, b, N));
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr79587.c b/gcc/testsuite/gcc.dg/tree-prof/pr79587.c
new file mode 100644
index 00000000000..517e0819919
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr79587.c
@@ -0,0 +1,26 @@
+/* { dg-require-effective-target lto } */
+/* { dg-options "-O2 -flto" } */
+
+unsigned long global = -12345;
+
+unsigned long
+__attribute__((noinline))
+test(unsigned long v, unsigned long v2)
+{
+ unsigned long x = v % v2;
+
+ return x;
+}
+
+int main(int argc, char **argv)
+{
+ unsigned long r = 0;
+
+ for (int i = 0; i < 100; i++)
+ r += test(argc, global);
+
+ if (r != 100)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr79803.c b/gcc/testsuite/gcc.dg/tree-ssa/pr79803.c
new file mode 100644
index 00000000000..51b245d4d5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr79803.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { x86_64-*-* } } } */
+/* { dg-options "-march=opteron-sse3 -Ofast --param l1-cache-line-size=3 -Wdisabled-optimization" } */
+/* { dg-require-effective-target indirect_jumps } */
+
+#include <setjmp.h>
+
+extern void abort (void);
+
+jmp_buf buf;
+
+void raise0(void)
+{
+ __builtin_longjmp (buf, 1);
+}
+
+int execute(int cmd) /* { dg-warning "'l1-cache-size' parameter is not a power of two 3" } */
+{
+ int last = 0;
+
+ if (__builtin_setjmp (buf) == 0)
+ while (1)
+ {
+ last = 1;
+ raise0 ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+int execute2(int cmd, int cmd2)
+{
+ int last = 0;
+
+ if (__builtin_setjmp (buf) == 0)
+ while (1)
+ {
+ last = 1;
+ raise0 ();
+ }
+
+ if (last == 0)
+ return 0;
+ else
+ return cmd;
+}
+
+
+int main(void)
+{
+ if (execute (1) == 0)
+ abort ();
+
+ if (execute2 (1, 2) == 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr78339.c b/gcc/testsuite/gcc.target/i386/mpx/pr78339.c
new file mode 100644
index 00000000000..3dd04240e8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr78339.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -Wsuggest-attribute=noreturn" } */
+
+extern _Noreturn void exit (int);
+int main (void) { exit (1); }
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr79631.c b/gcc/testsuite/gcc.target/i386/mpx/pr79631.c
new file mode 100644
index 00000000000..075d46b835f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr79631.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -O2" } */
+
+typedef struct { int _mp_size; } mpz_t[1];
+int a, b;
+void fn1()
+{
+ mpz_t c[1][b];
+ for (;;) {
+ int d = 0 >= 0 ? 0 == 0 ? c[0][0]->_mp_size ? -1 : 0 : 0 : 0,
+ e = 0 >= 0 ? 0 == 0 ? c[1][1]->_mp_size ? -1 : 0 : 0 : 0;
+ if (d != e)
+ a++;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr79753.c b/gcc/testsuite/gcc.target/i386/mpx/pr79753.c
new file mode 100644
index 00000000000..9b7bc52e1ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr79753.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -O2" } */
+
+int
+foo (void)
+{
+ return 0;
+}
+
+void
+bar (int **p)
+{
+ *p = (int *) (__UINTPTR_TYPE__) foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr79770.c b/gcc/testsuite/gcc.target/i386/mpx/pr79770.c
new file mode 100644
index 00000000000..0890fcc7bf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr79770.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -mabi=ms -Wno-psabi" } */
+
+typedef unsigned U __attribute__ ((vector_size (64)));
+typedef unsigned __int128 V __attribute__ ((vector_size (64)));
+
+static inline V
+bar (U u, U x, V v)
+{
+ v = (V)(U) { 0, ~0 };
+ v[x[0]] <<= u[-63];
+ return v;
+}
+
+V
+foo (U u)
+{
+ return bar (u, (U) {}, (V) {});
+}
diff --git a/gcc/testsuite/gcc.target/i386/mvc9.c b/gcc/testsuite/gcc.target/i386/mvc9.c
new file mode 100644
index 00000000000..69e3cefb7d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc9.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-flto -O2" { target lto } } */
+
+__attribute__((target_clones("avx","arch=slm","arch=core-avx2","default")))
+int
+foo ()
+{
+ return -2;
+}
+
+int
+bar ()
+{
+ return 2;
+}
+
+int
+main ()
+{
+ int r = 0;
+ r += bar ();
+ r += foo ();
+ r += bar ();
+ r += foo ();
+ r += bar ();
+ return r - 2;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr65044.c b/gcc/testsuite/gcc.target/i386/pr65044.c
index 9b0636339e5..d5cfecd15a9 100644
--- a/gcc/testsuite/gcc.target/i386/pr65044.c
+++ b/gcc/testsuite/gcc.target/i386/pr65044.c
@@ -1,6 +1,6 @@
/* { dg-do compile { target { ! x32 } } } */
/* { dg-options "-fcheck-pointer-bounds -mmpx -fsanitize=address" } */
-/* { dg-error "-fcheck-pointer-bounds is not supported with Address Sanitizer" "" { target *-*-* } 0 } */
+/* { dg-error ".-fcheck-pointer-bounds. is not supported with Address Sanitizer" "" { target *-*-* } 0 } */
extern int x[];
diff --git a/gcc/testsuite/gcc.target/i386/pr71458.c b/gcc/testsuite/gcc.target/i386/pr71458.c
new file mode 100644
index 00000000000..d36b61cbe02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr71458.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -fsanitize=bounds" } */
+/* { dg-error "'-fcheck-pointer-bounds' is not supported with '-fsanitize=bounds'" "" { target *-*-* } 0 } */
+
+enum {} a[0];
+void fn1(int);
+void fn2() { fn1(a[-1]); }
diff --git a/gcc/testsuite/gcc.target/i386/pr80019.c b/gcc/testsuite/gcc.target/i386/pr80019.c
new file mode 100644
index 00000000000..35ec9608a80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr80019.c
@@ -0,0 +1,13 @@
+/* PR target/80019 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mxop -mavx2" } */
+
+typedef char v16qi __attribute__ ((vector_size (16)));
+
+extern v16qi b, c;
+
+void
+foo (int e)
+{
+ b = c << e;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
index c776d139dc5..e4addedd59c 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
@@ -1,7 +1,5 @@
/* { dg-do compile { target { powerpc*-*-linux* } } } */
-/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
-/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-require-effective-target hard_dfp } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-mcpu=power7 -O2" } */
/* { dg-final { scan-assembler-times "ddedpd " 4 } } */
@@ -10,11 +8,17 @@
/* { dg-final { scan-assembler-times "diex " 1 } } */
/* { dg-final { scan-assembler-times "dscli " 2 } } */
/* { dg-final { scan-assembler-times "dscri " 2 } } */
+/* { dg-final { scan-assembler-times "std " 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "ld " 1 { target lp64 } } } */
+/* 32-bit needs a stack frame, and needs two GPR mem insns per _Decimal64. */
+/* { dg-final { scan-assembler-times "stwu " 2 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "stw " 2 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "lwz " 2 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "stfd " 1 } } */
+/* { dg-final { scan-assembler-times "lfd " 1 } } */
/* { dg-final { scan-assembler-not "bl __builtin" } } */
/* { dg-final { scan-assembler-not "dctqpq" } } */
/* { dg-final { scan-assembler-not "drdpq" } } */
-/* { dg-final { scan-assembler-not "stfd" } } */
-/* { dg-final { scan-assembler-not "lfd" } } */
_Decimal64
do_dedpd_0 (_Decimal64 a)
@@ -52,14 +56,14 @@ do_enbcd_1 (_Decimal64 a)
return __builtin_denbcd (1, a);
}
-_Decimal64
+long long
do_xex (_Decimal64 a)
{
return __builtin_dxex (a);
}
_Decimal64
-do_iex (_Decimal64 a, _Decimal64 b)
+do_iex (long long a, _Decimal64 b)
{
return __builtin_diex (a, b);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
index 1c1a4b34be7..b3b7c990f83 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
@@ -1,7 +1,5 @@
/* { dg-do compile { target { powerpc*-*-linux* } } } */
-/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
-/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
-/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-require-effective-target hard_dfp } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-mcpu=power7 -O2" } */
/* { dg-final { scan-assembler-times "ddedpdq " 4 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr78543.c b/gcc/testsuite/gcc.target/powerpc/pr78543.c
new file mode 100644
index 00000000000..0421344d3ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr78543.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O1 -mno-lra" } */
+
+typedef long a;
+enum c { e, f, g, h, i, ab } j();
+int l, n, o, p;
+a q, r;
+void *memcpy();
+void b();
+static int k(int *s) {
+ int m;
+ if (j(&m))
+ *s = m;
+ return !0;
+}
+void d(char s) {
+ int af[4];
+ int ag;
+ enum c ah;
+ char ai[24 << 11];
+ unsigned aj;
+ if (!k(&aj))
+ goto ak;
+ for (;;) {
+ if (!k(&ag))
+ goto ak;
+ switch (ah) {
+ case e:
+ b("");
+ b("bad length %d for GUID in fileinfo v%u for \"%s\"");
+ case i:
+ b("bad length %d for TTH in fileinfo v%u for \"%s\"", aj);
+ case ab:
+ if (ag % 24)
+ b("for \"%s\"", s);
+ case f:
+ if (20 == ag)
+ case h:
+ if (20 == ag)
+ o = 0;
+ break;
+ case g:
+ memcpy(af, ai, sizeof af);
+ b();
+ if (p) {
+ a al, am;
+ r = al << 2 | am;
+ n = af[2];
+ al = n;
+ l = __builtin_bswap32(af[3]);
+ am = q = n | l;
+ }
+ default:
+ b("%s0 unhandled field ID %u 0", __func__);
+ }
+ }
+ak:;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr79947.c b/gcc/testsuite/gcc.target/powerpc/pr79947.c
new file mode 100644
index 00000000000..970e8c0ca89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr79947.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-Ofast -mno-powerpc-gfxopt -mcmpb -mno-vsx" } */
+
+/* PR 79949: Compiler segmentation fault due to not having conditional move
+ support for the target if the -mno-powerpc-gfxopt option is used. */
+
+float a, b;
+void
+c ()
+{
+ a = __builtin_sqrtf (b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr79951.c b/gcc/testsuite/gcc.target/powerpc/pr79951.c
new file mode 100644
index 00000000000..67837444b20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr79951.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -S -mno-cmpb" } */
+
+float testf (float x, float y)
+{
+ return __builtin_copysignf (x, y);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80246.c b/gcc/testsuite/gcc.target/powerpc/pr80246.c
new file mode 100644
index 00000000000..b43d8314b8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr80246.c
@@ -0,0 +1,37 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target hard_dfp } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times "dxex " 1 } } */
+/* { dg-final { scan-assembler-times "dxexq " 1 } } */
+/* { dg-final { scan-assembler-times "diex " 1 } } */
+/* { dg-final { scan-assembler-times "diexq " 1 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* Verify we don't generate any drintn., drintnq., dctfix, dctfixq, dcffix
+ or dcffixq instructions, as they imply we are getting unwanted casting. */
+/* { dg-final { scan-assembler-not "drintn\[q\]\." } } */
+/* { dg-final { scan-assembler-not "dctfix\[q\]" } } */
+/* { dg-final { scan-assembler-not "dcffix\[q\]" } } */
+
+long long
+do_xex (_Decimal64 arg)
+{
+ return __builtin_dxex (arg);
+}
+
+long long
+do_xexq (_Decimal128 arg)
+{
+ return __builtin_dxexq (arg);
+}
+
+_Decimal64
+do_iex (long long exp, _Decimal64 arg)
+{
+ return __builtin_diex (exp, arg);
+}
+
+_Decimal128
+do_iexq (long long exp, _Decimal128 arg)
+{
+ return __builtin_diexq (exp, arg);
+}
diff --git a/gcc/testsuite/gfortran.dg/submodule_25.f08 b/gcc/testsuite/gfortran.dg/submodule_25.f08
new file mode 100644
index 00000000000..0581ce3ca76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/submodule_25.f08
@@ -0,0 +1,43 @@
+! { dg-do compile }
+! Test the fix for PR79434 in which the PRIVATE attribute of the
+! component 'i' of the derived type 't' was not respected in the
+! submodule 's_u'.
+!
+! Contributed by Reinhold Bader <Bader@lrz.de>
+!
+module mod_encap_t
+ implicit none
+ type, public :: t
+ private
+ integer :: i
+ end type
+end module
+module mod_encap_u
+ use mod_encap_t
+ type, public, extends(t) :: u
+ private
+ integer :: j
+ end type
+ interface
+ module subroutine fu(this)
+ type(u), intent(inout) :: this
+ end subroutine
+ end interface
+end module
+submodule (mod_encap_u) s_u
+contains
+ module procedure fu
+! the following statement should cause the compiler to
+! abort, pointing out a private component defined in
+! a USED module is being accessed
+ this%i = 2 ! { dg-error "is a PRIVATE component" }
+ this%j = 1
+ write(*, *) 'FAIL'
+ end procedure
+end submodule
+program p
+ use mod_encap_u
+ implicit none
+ type(u) :: x
+ call fu(x)
+end program
diff --git a/gcc/testsuite/gfortran.dg/submodule_26.f08 b/gcc/testsuite/gfortran.dg/submodule_26.f08
new file mode 100644
index 00000000000..6e0ec9a8f39
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/submodule_26.f08
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=single" }
+!
+! Tests the fix for PR71838 in which the PROCEDURE dummy argument caused
+! an ICE in the submodule. This is the reduced test in comment #9.
+!
+! Contributed by Anton Shterenlikht <mexas@bristol.ac.uk>
+! Test reduced by Dominique d'Humieres <dominiq@lps.ens.fr>
+!
+module cgca_m3clvg
+ abstract interface
+ subroutine cgca_clvgs_abstract( farr, marr, n, cstate, debug, &
+ newstate )
+ integer, parameter :: iarr = 4, idef = 4, rdef = 4, ldef = 4
+ integer, parameter :: l=-1, centre=l+1, u=centre+1
+ integer( kind=iarr ), intent(in) :: farr(l:u,l:u,l:u), &
+ marr(l:u,l:u,l:u), cstate
+ real( kind=rdef ), intent(in) :: n(3)
+ logical( kind=ldef ), intent(in) :: debug
+ integer( kind=iarr ), intent(out) :: newstate
+ end subroutine cgca_clvgs_abstract
+ end interface
+
+ interface
+ module subroutine cgca_clvgp( coarray, rt, t, scrit, sub, gcus, &
+ periodicbc, iter, heartbeat, debug )
+ integer, parameter :: iarr = 4, idef = 4, rdef = 4, ldef = 4
+ integer( kind=iarr ), allocatable, intent(inout) :: &
+ coarray(:,:,:,:)[:,:,:]
+ real( kind=rdef ), allocatable, intent(inout) :: rt(:,:,:)[:,:,:]
+ real( kind=rdef ), intent(in) :: t(3,3), scrit(3)
+ procedure( cgca_clvgs_abstract ) :: sub
+ logical( kind=ldef ), intent(in) :: periodicbc
+ integer( kind=idef ), intent(in) :: iter, heartbeat
+ logical( kind=ldef ), intent(in) :: debug
+ end subroutine cgca_clvgp
+ end interface
+end module cgca_m3clvg
+
+
+submodule ( cgca_m3clvg ) m3clvg_sm3
+ implicit none
+contains
+ module procedure cgca_clvgp
+ end procedure cgca_clvgp
+end submodule m3clvg_sm3
diff --git a/gcc/testsuite/gfortran.dg/submodule_27.f08 b/gcc/testsuite/gfortran.dg/submodule_27.f08
new file mode 100644
index 00000000000..1439c38cb9a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/submodule_27.f08
@@ -0,0 +1,44 @@
+! { dg-do run }
+!
+! Tests the fix for PR71838 in which the PROCEDURE dummy argument caused
+! an ICE in the submodule. This an executable version of the reduced test
+! in comment #11.
+!
+! Contributed by Anton Shterenlikht <mexas@bristol.ac.uk>
+! Test reduced by Dominique d'Humieres <dominiq@lps.ens.fr>
+!
+subroutine hello (message)
+ character (7), intent(inout) :: message
+ message = "hello "
+end
+
+module cgca_m3clvg
+ interface
+ subroutine cgca_clvgs_abstract(message)
+ character (7), intent(inout) :: message
+ end subroutine cgca_clvgs_abstract
+ end interface
+
+ interface
+ module subroutine cgca_clvgp(sub)
+ procedure( cgca_clvgs_abstract ) :: sub
+ end subroutine cgca_clvgp
+ end interface
+
+ character (7) :: greeting
+end module cgca_m3clvg
+
+submodule ( cgca_m3clvg ) m3clvg_sm3
+ implicit none
+contains
+ module procedure cgca_clvgp
+ call sub (greeting)
+ end procedure cgca_clvgp
+end submodule m3clvg_sm3
+
+ use cgca_m3clvg
+ external hello
+ greeting = "goodbye"
+ call cgca_clvgp (hello)
+ if (trim (greeting) .ne. "hello") call abort
+end
diff --git a/gcc/testsuite/gfortran.dg/submodule_28.f08 b/gcc/testsuite/gfortran.dg/submodule_28.f08
new file mode 100644
index 00000000000..f7b10a6ed83
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/submodule_28.f08
@@ -0,0 +1,52 @@
+! { dg-do run }
+!
+! Tests the fix for PR79676 in which submod_test was private even to the
+! submodule 'my_submod'.
+!
+! Contributed by Adam Hirst <adam@aphirst.karoo.co.uk>
+!
+module my_mod
+ private ! This hid 'submod_test'.
+ interface
+ module subroutine submod_test(x)
+ integer :: x
+ end subroutine
+ end interface
+ integer answer
+ public routine1, print_two, answer
+contains
+ subroutine routine1(x)
+ integer :: x
+ call submod_test(x)
+ end subroutine
+ subroutine print_two()
+ integer, parameter :: two = 2
+ answer = answer * two
+ end subroutine
+end module
+
+module my_mod_2
+ use my_mod
+contains
+ subroutine circular_dependency()
+ call print_two()
+ end subroutine
+end module
+
+submodule (my_mod) my_submod
+ use my_mod_2
+contains
+module subroutine submod_test(x)
+ integer :: x
+ answer = x
+ call circular_dependency()
+end subroutine
+
+end submodule
+
+program hello
+ use my_mod
+ implicit none
+ call routine1(2)
+ if (answer .ne. 4) call abort
+end program
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 8979d263426..59604e56195 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1263,17 +1263,42 @@ process_options (void)
if (targetm.chkp_bound_mode () == VOIDmode)
{
error_at (UNKNOWN_LOCATION,
- "-fcheck-pointer-bounds is not supported for this target");
+ "%<-fcheck-pointer-bounds%> is not supported for this "
+ "target");
+ flag_check_pointer_bounds = 0;
+ }
+
+ if (flag_sanitize & SANITIZE_BOUNDS_STRICT)
+ {
+ error_at (UNKNOWN_LOCATION,
+ "%<-fcheck-pointer-bounds%> is not supported with "
+ "%<-fsanitize=bounds-strict%>");
+ flag_check_pointer_bounds = 0;
+ }
+ else if (flag_sanitize & SANITIZE_BOUNDS)
+ {
+ error_at (UNKNOWN_LOCATION,
+ "%<-fcheck-pointer-bounds%> is not supported with "
+ "%<-fsanitize=bounds%>");
flag_check_pointer_bounds = 0;
}
if (flag_sanitize & SANITIZE_ADDRESS)
{
error_at (UNKNOWN_LOCATION,
- "-fcheck-pointer-bounds is not supported with "
+ "%<-fcheck-pointer-bounds%> is not supported with "
"Address Sanitizer");
flag_check_pointer_bounds = 0;
}
+
+ if (flag_sanitize & SANITIZE_THREAD)
+ {
+ error_at (UNKNOWN_LOCATION,
+ "%<-fcheck-pointer-bounds%> is not supported with "
+ "Thread Sanitizer");
+
+ flag_check_pointer_bounds = 0;
+ }
}
/* One region RA really helps to decrease the code size. */
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index a7fa3cdb908..51b9296cdb1 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -841,10 +841,12 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
- nconds--;
ci++;
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
+ typedef std::pair<edge, edge> edge_pair;
+ auto_vec<edge_pair, 8> edges;
+
bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
bi_call_in_edge0->flags |= EDGE_FALSE_VALUE;
@@ -853,17 +855,11 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
join_tgt_in_edge_fall_thru = make_edge (guard_bb, join_tgt_bb,
EDGE_TRUE_VALUE);
- bi_call_in_edge0->probability = REG_BR_PROB_BASE * ERR_PROB;
- bi_call_in_edge0->count =
- apply_probability (guard_bb->count,
- bi_call_in_edge0->probability);
- join_tgt_in_edge_fall_thru->probability =
- inverse_probability (bi_call_in_edge0->probability);
- join_tgt_in_edge_fall_thru->count =
- guard_bb->count - bi_call_in_edge0->count;
+ edges.reserve (nconds);
+ edges.quick_push (edge_pair (bi_call_in_edge0, join_tgt_in_edge_fall_thru));
/* Code generation for the rest of the conditions */
- while (nconds > 0)
+ for (unsigned int i = 1; i < nconds; ++i)
{
unsigned ci0;
edge bi_call_in_edge;
@@ -879,7 +875,6 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
- nconds--;
ci++;
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
guard_bb_in_edge = split_block (guard_bb, cond_expr);
@@ -887,14 +882,51 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
guard_bb_in_edge->flags |= EDGE_TRUE_VALUE;
bi_call_in_edge = make_edge (guard_bb, bi_call_bb, EDGE_FALSE_VALUE);
+ edges.quick_push (edge_pair (bi_call_in_edge, guard_bb_in_edge));
+ }
+
+ /* Now update the probability and profile information, processing the
+ guards in order of execution.
+
+ There are two approaches we could take here. On the one hand we
+ could assign a probability of X to the call block and distribute
+ that probability among its incoming edges. On the other hand we
+ could assign a probability of X to each individual call edge.
+
+ The choice only affects calls that have more than one condition.
+ In those cases, the second approach would give the call block
+ a greater probability than the first. However, the difference
+ is only small, and our chosen X is a pure guess anyway.
+
+ Here we take the second approach because it's slightly simpler
+ and because it's easy to see that it doesn't lose profile counts. */
+ bi_call_bb->count = 0;
+ bi_call_bb->frequency = 0;
+ while (!edges.is_empty ())
+ {
+ edge_pair e = edges.pop ();
+ edge call_edge = e.first;
+ edge nocall_edge = e.second;
+ basic_block src_bb = call_edge->src;
+ gcc_assert (src_bb == nocall_edge->src);
+
+ call_edge->probability = REG_BR_PROB_BASE * ERR_PROB;
+ call_edge->count = apply_probability (src_bb->count,
+ call_edge->probability);
+ nocall_edge->probability = inverse_probability (call_edge->probability);
+ nocall_edge->count = src_bb->count - call_edge->count;
+
+ unsigned int call_frequency = apply_probability (src_bb->frequency,
+ call_edge->probability);
- bi_call_in_edge->probability = REG_BR_PROB_BASE * ERR_PROB;
- bi_call_in_edge->count =
- apply_probability (guard_bb->count,
- bi_call_in_edge->probability);
- guard_bb_in_edge->probability =
- inverse_probability (bi_call_in_edge->probability);
- guard_bb_in_edge->count = guard_bb->count - bi_call_in_edge->count;
+ bi_call_bb->count += call_edge->count;
+ bi_call_bb->frequency += call_frequency;
+
+ if (nocall_edge->dest != join_tgt_bb)
+ {
+ nocall_edge->dest->count = nocall_edge->count;
+ nocall_edge->dest->frequency = src_bb->frequency - call_frequency;
+ }
}
if (dom_info_available_p (CDI_DOMINATORS))
diff --git a/gcc/tree-chkp-opt.c b/gcc/tree-chkp-opt.c
index 52d127c26f9..7beaac96d2b 100644
--- a/gcc/tree-chkp-opt.c
+++ b/gcc/tree-chkp-opt.c
@@ -239,9 +239,11 @@ chkp_is_constant_addr (const address_t &addr, int *sign)
return false;
else if (addr.pol[0].var)
return false;
+ else if (TREE_CODE (addr.pol[0].cst) != INTEGER_CST)
+ return false;
else if (integer_zerop (addr.pol[0].cst))
*sign = 0;
- else if (tree_int_cst_sign_bit (addr.pol[0].cst))
+ else if (tree_int_cst_sign_bit (addr.pol[0].cst))
*sign = -1;
else
*sign = 1;
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 4ca2d34607c..2901e8b354d 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -2215,6 +2215,7 @@ chkp_build_returned_bound (gcall *call)
gimple *stmt;
tree fndecl = gimple_call_fndecl (call);
unsigned int retflags;
+ tree lhs = gimple_call_lhs (call);
/* To avoid fixing alloca expands in targets we handle
it separately. */
@@ -2224,9 +2225,8 @@ chkp_build_returned_bound (gcall *call)
|| DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA_WITH_ALIGN))
{
tree size = gimple_call_arg (call, 0);
- tree lb = gimple_call_lhs (call);
gimple_stmt_iterator iter = gsi_for_stmt (call);
- bounds = chkp_make_bounds (lb, size, &iter, true);
+ bounds = chkp_make_bounds (lhs, size, &iter, true);
}
/* We know bounds returned by set_bounds builtin call. */
else if (fndecl
@@ -2279,9 +2279,10 @@ chkp_build_returned_bound (gcall *call)
bounds = chkp_find_bounds (gimple_call_arg (call, argno), &iter);
}
- else if (chkp_call_returns_bounds_p (call))
+ else if (chkp_call_returns_bounds_p (call)
+ && BOUNDED_P (lhs))
{
- gcc_assert (TREE_CODE (gimple_call_lhs (call)) == SSA_NAME);
+ gcc_assert (TREE_CODE (lhs) == SSA_NAME);
/* In general case build checker builtin call to
obtain returned bounds. */
@@ -2308,7 +2309,7 @@ chkp_build_returned_bound (gcall *call)
print_gimple_stmt (dump_file, call, 0, TDF_VOPS|TDF_MEMSYMS);
}
- bounds = chkp_maybe_copy_and_register_bounds (gimple_call_lhs (call), bounds);
+ bounds = chkp_maybe_copy_and_register_bounds (lhs, bounds);
return bounds;
}
@@ -3599,8 +3600,8 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
break;
case PARM_DECL:
- gcc_unreachable ();
- bounds = chkp_get_bound_for_parm (ptr_src);
+ /* Handled above but failed. */
+ bounds = chkp_get_invalid_op_bounds ();
break;
case TARGET_MEM_REF:
@@ -3662,6 +3663,8 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
break;
case INTEGER_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
if (integer_zerop (ptr_src))
bounds = chkp_get_none_bounds ();
else
@@ -3734,7 +3737,7 @@ chkp_walk_pointer_assignments (tree lhs, tree rhs, void *arg,
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs), cnt, field, val)
{
- if (chkp_type_has_pointer (TREE_TYPE (field)))
+ if (field && chkp_type_has_pointer (TREE_TYPE (field)))
{
tree lhs_field = chkp_build_component_ref (lhs, field);
chkp_walk_pointer_assignments (lhs_field, val, arg, handler);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index cbb393efef2..d08a96d3f7b 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4721,7 +4721,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
{
tree name = gimple_call_lhs (stmt);
tree var = SSA_NAME_VAR (name);
- tree def = ssa_default_def (cfun, var);
+ tree def = var ? ssa_default_def (cfun, var) : NULL;
if (def)
{
@@ -4732,6 +4732,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
}
else
{
+ if (!var)
+ {
+ var = create_tmp_reg_fn (cfun, TREE_TYPE (name), NULL);
+ SET_SSA_NAME_VAR_OR_IDENTIFIER (name, var);
+ }
/* Otherwise make this variable undefined. */
gsi_remove (&stmt_gsi, true);
set_ssa_default_def (cfun, var, name);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 89556e1be0e..4abefd6fc68 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -728,9 +728,11 @@ likely_value (gimple *stmt)
case PLUS_EXPR:
case MINUS_EXPR:
case POINTER_PLUS_EXPR:
+ case BIT_XOR_EXPR:
/* Not MIN_EXPR, MAX_EXPR. One VARYING operand may be selected.
Not bitwise operators, one VARYING operand may specify the
- result completely. Not logical operators for the same reason.
+ result completely.
+ Not logical operators for the same reason, apart from XOR.
Not COMPLEX_EXPR as one VARYING operand makes the result partly
not UNDEFINED. Not *DIV_EXPR, comparisons and shifts because
the undefined operand may be promoted. */
@@ -1732,18 +1734,24 @@ evaluate_stmt (gimple *stmt)
fold_defer_overflow_warnings ();
simplified = ccp_fold (stmt);
if (simplified
- && TREE_CODE (simplified) == SSA_NAME
+ && TREE_CODE (simplified) == SSA_NAME)
+ {
/* We may not use values of something that may be simulated again,
see valueize_op_1. */
- && (SSA_NAME_IS_DEFAULT_DEF (simplified)
- || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified))))
- {
- val = *get_value (simplified);
- if (val.lattice_val != VARYING)
+ if (SSA_NAME_IS_DEFAULT_DEF (simplified)
+ || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (simplified)))
{
- fold_undefer_overflow_warnings (true, stmt, 0);
- return val;
+ val = *get_value (simplified);
+ if (val.lattice_val != VARYING)
+ {
+ fold_undefer_overflow_warnings (true, stmt, 0);
+ return val;
+ }
}
+ else
+ /* We may also not place a non-valueized copy in the lattice
+ as that might become stale if we never re-visit this stmt. */
+ simplified = NULL_TREE;
}
is_constant = simplified && is_gimple_min_invariant (simplified);
fold_undefer_overflow_warnings (is_constant, stmt, 0);
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index c054c60203c..f3299237bd4 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "tree-inline.h"
#include "tree-data-ref.h"
+#include "diagnostic-core.h"
/* FIXME: Needed for optabs, but this should all be moved to a TBD interface
@@ -1965,10 +1966,6 @@ tree_ssa_prefetch_arrays (void)
set_builtin_decl (BUILT_IN_PREFETCH, decl, false);
}
- /* We assume that size of cache line is a power of two, so verify this
- here. */
- gcc_assert ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) == 0);
-
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2026,6 +2023,20 @@ pass_loop_prefetch::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
+ if ((PREFETCH_BLOCK & (PREFETCH_BLOCK - 1)) != 0)
+ {
+ static bool warned = false;
+
+ if (!warned)
+ {
+ warning (OPT_Wdisabled_optimization,
+ "%<l1-cache-size%> parameter is not a power of two %d",
+ PREFETCH_BLOCK);
+ warned = true;
+ }
+ return 0;
+ }
+
return tree_ssa_prefetch_arrays ();
}
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 89f6b865766..2e423954db1 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -384,7 +384,17 @@ stream_out_histogram_value (struct output_block *ob, histogram_value hist)
break;
}
for (i = 0; i < hist->n_counters; i++)
- streamer_write_gcov_count (ob, hist->hvalue.counters[i]);
+ {
+ /* When user uses an unsigned type with a big value, constant converted
+ to gcov_type (a signed type) can be negative. */
+ gcov_type value = hist->hvalue.counters[i];
+ if (hist->type == HIST_TYPE_SINGLE_VALUE && i == 0)
+ ;
+ else
+ gcc_assert (value >= 0);
+
+ streamer_write_gcov_count (ob, value);
+ }
if (hist->hvalue.next)
stream_out_histogram_value (ob, hist->hvalue.next);
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 67bf7fb83a7..165d3a2ec1d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,139 @@
+2017-04-03 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Backport from mainline
+ 2017-04-03 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ PR libstdc++/79141
+ * include/bits/stl_pair.h (__nonesuch_no_braces): New.
+ (operator=(typename conditional<
+ __and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>::value,
+ const pair&, const __nonesuch&>::type)): Change __nonesuch
+ to __nonesuch_no_braces.
+ (operator=(typename conditional<
+ __not_<__and_<is_copy_assignable<_T1>,
+ is_copy_assignable<_T2>>>::value,
+ const pair&, const __nonesuch&>::type)): Likewise.
+ (operator=(typename conditional<
+ __and_<is_move_assignable<_T1>,
+ is_move_assignable<_T2>>::value,
+ pair&&, __nonesuch&&>::type)): Likewise.
+ * testsuite/20_util/pair/79141.cc: New.
+
+2017-03-28 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/80137
+ * include/bits/random.tcc (generate_canonical): Use std::nextafter
+ or numeric_limits::epsilon() to reduce out-of-range values.
+ * testsuite/26_numerics/random/uniform_real_distribution/operators/
+ 64351.cc: Verify complexity requirement is met.
+
+ Backport from mainline
+ 2017-03-15  Xi Ruoyao  <ryxi@stu.xidian.edu.cn>
+
+ PR libstdc++/62045
+ * include/ext/pb_ds/qdetail/binary_heap_/binary_heap_.hpp
+ (is_heap): Remove.
+ (push_heap): Remove the wrong checking using is_heap.
+ (make_heap): Remove the assertion using is_heap.
+ * include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp
+ (modify): Ditto.
+ (resize_for_insert_if_needed): Add PB_DS_ASSERT_VALID after
+ calling make_heap.
+
+ Backport from mainline
+ 2017-03-15 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/62045
+ * testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc:
+ New test.
+ * testsuite/ext/pb_ds/regression/priority_queues.cc: Fix copy&paste
+ error in comment.
+
+ Backport from mainline
+ 2017-02-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/experimental/iterator: Include <iterator>.
+ * testsuite/experimental/iterator/requirements.cc: Check for contents
+ of <iterator>.
+
+2017-03-17 Jonathan Wakely <jwakely@redhat.com>
+
+ Backport from mainline
+ 2017-03-17 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++11/codecvt.cc (range): Add non-type template parameter and
+ define oerloaded operators for reading and writing code units.
+ (range<Elem, false>): Define partial specialization for accessing
+ wide characters in potentially unaligned byte ranges.
+ (ucs2_span(const char16_t*, const char16_t*, ...))
+ (ucs4_span(const char16_t*, const char16_t*, ...)): Change parameters
+ to range<const char16_t, false> in order to avoid unaligned reads.
+ (__codecvt_utf16_base<char16_t>::do_out)
+ (__codecvt_utf16_base<char32_t>::do_out)
+ (__codecvt_utf16_base<wchar_t>::do_out): Use range specialization for
+ unaligned data to avoid unaligned writes.
+ (__codecvt_utf16_base<char16_t>::do_in)
+ (__codecvt_utf16_base<char32_t>::do_in)
+ (__codecvt_utf16_base<wchar_t>::do_in): Likewise for writes. Return
+ error if there are unprocessable trailing bytes.
+ (__codecvt_utf16_base<char16_t>::do_length)
+ (__codecvt_utf16_base<char32_t>::do_length)
+ (__codecvt_utf16_base<wchar_t>::do_length): Pass arguments of type
+ range<const char16_t, false> to span functions.
+ * testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc: New test.
+
+ Backport from mainline
+ 2017-03-16 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/79980
+ * src/c++11/codecvt.cc (to_integer(codecvt_mode)): Fix target type.
+
+ PR libstdc++/80041
+ * src/c++11/codecvt.cc (__codecvt_utf16_base<wchar_t>::do_out)
+ (__codecvt_utf16_base<wchar_t>::do_in): Convert char arguments to
+ char16_t to work with UTF-16 instead of UTF-8.
+ * testsuite/22_locale/codecvt/codecvt_utf16/80041.cc: New test.
+
+ * src/c++11/codecvt.cc (codecvt<char16_t, char, mbstate_t>)
+ (codecvt<char32_t, char, mbstate_t>, __codecvt_utf8_base<char16_t>)
+ (__codecvt_utf8_base<char32_t>, __codecvt_utf8_base<wchar_t>)
+ (__codecvt_utf16_base<char16_t>, __codecvt_utf16_base<char32_t>)
+ (__codecvt_utf16_base<wchar_t>, __codecvt_utf8_utf16_base<char16_t>)
+ (__codecvt_utf8_utf16_base<char32_t>)
+ (__codecvt_utf8_utf16_base<wchar_t>): Fix do_encoding() and
+ do_max_length() return values.
+ * testsuite/22_locale/codecvt/codecvt_utf16/members.cc: New test.
+ * testsuite/22_locale/codecvt/codecvt_utf8/members.cc: New test.
+ * testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc: New test.
+
+ PR libstdc++/79980
+ * include/bits/locale_conv.h (__do_str_codecvt): Set __count on
+ error path.
+ * src/c++11/codecvt.cc (operator&=, operator|=, operator~): Overloads
+ for manipulating codecvt_mode values.
+ (read_utf16_bom): Compare input to BOM constants instead of integral
+ constants that depend on endianness. Take mode parameter by
+ reference and adjust it, to distinguish between no BOM present and
+ UTF-16BE BOM present.
+ (ucs4_in, ucs2_span, ucs4_span): Adjust calls to read_utf16_bom.
+ (surrogates): New enumeration type.
+ (utf16_in, utf16_out): Add surrogates parameter to choose between
+ UTF-16 and UCS2 behaviour.
+ (utf16_span, ucs2_span): Use std::min not std::max.
+ (ucs2_out): Use std::min not std::max. Disallow surrogate pairs.
+ (ucs2_in): Likewise. Adjust calls to read_utf16_bom.
+ * testsuite/22_locale/codecvt/codecvt_utf16/79980.cc: New test.
+ * testsuite/22_locale/codecvt/codecvt_utf8/79980.cc: New test.
+
+ PR libstdc++/79511
+ * src/c++11/codecvt.cc (write_utf16_code_point): Don't write 0xffff
+ as a surrogate pair.
+ (__codecvt_utf8_utf16_base<char32_t>::do_in): Use native endianness
+ for internal representation.
+ (__codecvt_utf8_utf16_base<wchar_t>::do_in): Likewise.
+ * testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc: New test.
+
2017-03-14 Jonathan Wakely <jwakely@redhat.com>
* testsuite/17_intro/names.cc: Undefine macros that clash with
diff --git a/libstdc++-v3/include/bits/locale_conv.h b/libstdc++-v3/include/bits/locale_conv.h
index d4bec2fa8b9..ba04824ebdd 100644
--- a/libstdc++-v3/include/bits/locale_conv.h
+++ b/libstdc++-v3/include/bits/locale_conv.h
@@ -81,7 +81,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& (__outstr.size() - __outchars) < __maxlen);
if (__result == codecvt_base::error)
- return false;
+ {
+ __count = __next - __first;
+ return false;
+ }
if (__result == codecvt_base::noconv)
{
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 7dfc721e55f..a61e9c1813e 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -3323,18 +3323,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const size_t __m = std::max<size_t>(1UL,
(__b + __log2r - 1UL) / __log2r);
_RealType __ret;
- do
+ _RealType __sum = _RealType(0);
+ _RealType __tmp = _RealType(1);
+ for (size_t __k = __m; __k != 0; --__k)
{
- _RealType __sum = _RealType(0);
- _RealType __tmp = _RealType(1);
- for (size_t __k = __m; __k != 0; --__k)
- {
- __sum += _RealType(__urng() - __urng.min()) * __tmp;
- __tmp *= __r;
- }
- __ret = __sum / __tmp;
+ __sum += _RealType(__urng() - __urng.min()) * __tmp;
+ __tmp *= __r;
+ }
+ __ret = __sum / __tmp;
+ if (__builtin_expect(__ret >= _RealType(1), 0))
+ {
+#if _GLIBCXX_USE_C99_MATH_TR1
+ __ret = std::nextafter(_RealType(1), _RealType(0));
+#else
+ __ret = _RealType(1)
+ - std::numeric_limits<_RealType>::epsilon() / _RealType(2);
+#endif
}
- while (__builtin_expect(__ret >= _RealType(1), 0));
return __ret;
}
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 87824f0c1bd..0d9d0c37b7c 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -178,6 +178,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
+ struct __wrap_nonesuch : std::__nonesuch {
+ explicit __wrap_nonesuch(const __nonesuch&) = delete;
+ };
+
#endif
/**
@@ -359,7 +363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(typename conditional<
__and_<is_copy_assignable<_T1>,
is_copy_assignable<_T2>>::value,
- const pair&, const __nonesuch&>::type __p)
+ const pair&, const __wrap_nonesuch&>::type __p)
{
first = __p.first;
second = __p.second;
@@ -370,13 +374,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(typename conditional<
__not_<__and_<is_copy_assignable<_T1>,
is_copy_assignable<_T2>>>::value,
- const pair&, const __nonesuch&>::type __p) = delete;
+ const pair&, const __wrap_nonesuch&>::type __p) = delete;
pair&
operator=(typename conditional<
__and_<is_move_assignable<_T1>,
is_move_assignable<_T2>>::value,
- pair&&, __nonesuch&&>::type __p)
+ pair&&, __wrap_nonesuch&&>::type __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
diff --git a/libstdc++-v3/include/experimental/iterator b/libstdc++-v3/include/experimental/iterator
index e6ec421f054..be365826f8e 100644
--- a/libstdc++-v3/include/experimental/iterator
+++ b/libstdc++-v3/include/experimental/iterator
@@ -39,10 +39,9 @@
# include <bits/c++14_warning.h>
#else
-#include <experimental/type_traits>
+#include <iterator>
#include <iosfwd>
-#include <bits/move.h>
-#include <bits/stl_iterator_base_types.h>
+#include <experimental/type_traits>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
index 3ce7e45c9c3..bfba1234f86 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/binary_heap_.hpp
@@ -266,20 +266,14 @@ namespace __gnu_pbds
const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
entry_pointer end = m_a_entries + m_size;
std::make_heap(m_a_entries, end, m_cmp);
- _GLIBCXX_DEBUG_ASSERT(is_heap());
}
void
push_heap()
{
- if (!is_heap())
- make_heap();
- else
- {
- const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
- entry_pointer end = m_a_entries + m_size;
- std::push_heap(m_a_entries, end, m_cmp);
- }
+ const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
+ entry_pointer end = m_a_entries + m_size;
+ std::push_heap(m_a_entries, end, m_cmp);
}
void
@@ -290,15 +284,6 @@ namespace __gnu_pbds
std::pop_heap(m_a_entries, end, m_cmp);
}
- bool
- is_heap()
- {
- const entry_cmp& m_cmp = static_cast<entry_cmp&>(*this);
- entry_pointer end = m_a_entries + m_size;
- bool p = std::__is_heap(m_a_entries, end, m_cmp);
- return p;
- }
-
#ifdef _GLIBCXX_DEBUG
void
assert_valid(const char*, int) const;
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp
index 8ccb2a88e9c..97a463ad8ef 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/binary_heap_/insert_fn_imps.hpp
@@ -103,7 +103,6 @@ modify(point_iterator it, const_reference r_new_val)
swap_value_imp(it.m_p_e, r_new_val, s_no_throw_copies_ind);
fix(it.m_p_e);
PB_DS_ASSERT_VALID((*this))
- _GLIBCXX_DEBUG_ASSERT(is_heap());
}
PB_DS_CLASS_T_DEC
diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc
index b60691cf2a6..11873397341 100644
--- a/libstdc++-v3/src/c++11/codecvt.cc
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -1,6 +1,6 @@
// Locale support (codecvt) -*- C++ -*-
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2015-2017 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -24,13 +24,27 @@
#include <codecvt>
#include <cstring> // std::memcpy, std::memcmp
-#include <bits/stl_algobase.h> // std::max
+#include <bits/stl_algobase.h> // std::min
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ // The standard doesn't define these operators, which is annoying.
+ static underlying_type<codecvt_mode>::type
+ to_integer(codecvt_mode m)
+ { return static_cast<underlying_type<codecvt_mode>::type>(m); }
+
+ static codecvt_mode& operator&=(codecvt_mode& m, codecvt_mode n)
+ { return m = codecvt_mode(to_integer(m) & to_integer(n)); }
+
+ static codecvt_mode& operator|=(codecvt_mode& m, codecvt_mode n)
+ { return m = codecvt_mode(to_integer(m) | to_integer(n)); }
+
+ static codecvt_mode operator~(codecvt_mode m)
+ { return codecvt_mode(~to_integer(m)); }
+
namespace
{
// Largest code point that fits in a single UTF-16 code unit.
@@ -43,35 +57,142 @@ namespace
const char32_t incomplete_mb_character = char32_t(-2);
const char32_t invalid_mb_sequence = char32_t(-1);
- template<typename Elem>
+ // Utility type for reading and writing code units of type Elem from
+ // a range defined by a pair of pointers.
+ template<typename Elem, bool Aligned = true>
struct range
{
Elem* next;
Elem* end;
+ // Write a code unit.
+ range& operator=(Elem e)
+ {
+ *next++ = e;
+ return *this;
+ }
+
+ // Read the next code unit.
Elem operator*() const { return *next; }
- range& operator++() { ++next; return *this; }
+ // Read the Nth code unit.
+ Elem operator[](size_t n) const { return next[n]; }
+ // Move to the next code unit.
+ range& operator++()
+ {
+ ++next;
+ return *this;
+ }
+
+ // Move to the Nth code unit.
+ range& operator+=(size_t n)
+ {
+ next += n;
+ return *this;
+ }
+
+ // The number of code units remaining.
size_t size() const { return end - next; }
+
+ // The number of bytes remaining.
+ size_t nbytes() const { return (const char*)end - (const char*)next; }
+ };
+
+ // This specialization is used when accessing char16_t values through
+ // pointers to char, which might not be correctly aligned for char16_t.
+ template<typename Elem>
+ struct range<Elem, false>
+ {
+ using value_type = typename remove_const<Elem>::type;
+
+ using char_pointer = typename
+ conditional<is_const<Elem>::value, const char*, char*>::type;
+
+ char_pointer next;
+ char_pointer end;
+
+ // Write a code unit.
+ range& operator=(Elem e)
+ {
+ memcpy(next, &e, sizeof(Elem));
+ ++*this;
+ return *this;
+ }
+
+ // Read the next code unit.
+ Elem operator*() const
+ {
+ value_type e;
+ memcpy(&e, next, sizeof(Elem));
+ return e;
+ }
+
+ // Read the Nth code unit.
+ Elem operator[](size_t n) const
+ {
+ value_type e;
+ memcpy(&e, next + n * sizeof(Elem), sizeof(Elem));
+ return e;
+ }
+
+ // Move to the next code unit.
+ range& operator++()
+ {
+ next += sizeof(Elem);
+ return *this;
+ }
+
+ // Move to the Nth code unit.
+ range& operator+=(size_t n)
+ {
+ next += n * sizeof(Elem);
+ return *this;
+ }
+
+ // The number of code units remaining.
+ size_t size() const { return nbytes() / sizeof(Elem); }
+
+ // The number of bytes remaining.
+ size_t nbytes() const { return end - next; }
};
// Multibyte sequences can have "header" consisting of Byte Order Mark
const unsigned char utf8_bom[3] = { 0xEF, 0xBB, 0xBF };
- const unsigned char utf16_bom[4] = { 0xFE, 0xFF };
- const unsigned char utf16le_bom[4] = { 0xFF, 0xFE };
+ const unsigned char utf16_bom[2] = { 0xFE, 0xFF };
+ const unsigned char utf16le_bom[2] = { 0xFF, 0xFE };
- template<size_t N>
- inline bool
- write_bom(range<char>& to, const unsigned char (&bom)[N])
+ // Write a BOM (space permitting).
+ template<typename C, bool A, size_t N>
+ bool
+ write_bom(range<C, A>& to, const unsigned char (&bom)[N])
{
- if (to.size() < N)
+ static_assert( (N / sizeof(C)) != 0, "" );
+ static_assert( (N % sizeof(C)) == 0, "" );
+
+ if (to.nbytes() < N)
return false;
memcpy(to.next, bom, N);
- to.next += N;
+ to += (N / sizeof(C));
return true;
}
+ // Try to read a BOM.
+ template<typename C, bool A, size_t N>
+ bool
+ read_bom(range<C, A>& from, const unsigned char (&bom)[N])
+ {
+ static_assert( (N / sizeof(C)) != 0, "" );
+ static_assert( (N % sizeof(C)) == 0, "" );
+
+ if (from.nbytes() >= N && !memcmp(from.next, bom, N))
+ {
+ from += (N / sizeof(C));
+ return true;
+ }
+ return false;
+ }
+
// If generate_header is set in mode write out UTF-8 BOM.
bool
write_utf8_bom(range<char>& to, codecvt_mode mode)
@@ -83,32 +204,20 @@ namespace
// If generate_header is set in mode write out the UTF-16 BOM indicated
// by whether little_endian is set in mode.
+ template<bool Aligned>
bool
- write_utf16_bom(range<char16_t>& to, codecvt_mode mode)
+ write_utf16_bom(range<char16_t, Aligned>& to, codecvt_mode mode)
{
if (mode & generate_header)
{
- if (!to.size())
- return false;
- auto* bom = (mode & little_endian) ? utf16le_bom : utf16_bom;
- std::memcpy(to.next, bom, 2);
- ++to.next;
+ if (mode & little_endian)
+ return write_bom(to, utf16le_bom);
+ else
+ return write_bom(to, utf16_bom);
}
return true;
}
- template<size_t N>
- inline bool
- read_bom(range<const char>& from, const unsigned char (&bom)[N])
- {
- if (from.size() >= N && !memcmp(from.next, bom, N))
- {
- from.next += N;
- return true;
- }
- return false;
- }
-
// If consume_header is set in mode update from.next to after any BOM.
void
read_utf8_bom(range<const char>& from, codecvt_mode mode)
@@ -117,22 +226,21 @@ namespace
read_bom(from, utf8_bom);
}
- // If consume_header is set in mode update from.next to after any BOM.
- // Return little_endian iff the UTF-16LE BOM was present.
- codecvt_mode
- read_utf16_bom(range<const char16_t>& from, codecvt_mode mode)
+ // If consume_header is not set in mode, no effects.
+ // Otherwise, if *from.next is a UTF-16 BOM increment from.next and then:
+ // - if the UTF-16BE BOM was found unset little_endian in mode, or
+ // - if the UTF-16LE BOM was found set little_endian in mode.
+ template<bool Aligned>
+ void
+ read_utf16_bom(range<const char16_t, Aligned>& from, codecvt_mode& mode)
{
- if (mode & consume_header && from.size())
+ if (mode & consume_header)
{
- if (*from.next == 0xFEFF)
- ++from.next;
- else if (*from.next == 0xFFFE)
- {
- ++from.next;
- return little_endian;
- }
+ if (read_bom(from, utf16_bom))
+ mode &= ~little_endian;
+ else if (read_bom(from, utf16le_bom))
+ mode |= little_endian;
}
- return {};
}
// Read a codepoint from a UTF-8 multibyte sequence.
@@ -144,11 +252,11 @@ namespace
const size_t avail = from.size();
if (avail == 0)
return incomplete_mb_character;
- unsigned char c1 = from.next[0];
+ unsigned char c1 = from[0];
// https://en.wikipedia.org/wiki/UTF-8#Sample_code
if (c1 < 0x80)
{
- ++from.next;
+ ++from;
return c1;
}
else if (c1 < 0xC2) // continuation or overlong 2-byte sequence
@@ -157,51 +265,51 @@ namespace
{
if (avail < 2)
return incomplete_mb_character;
- unsigned char c2 = from.next[1];
+ unsigned char c2 = from[1];
if ((c2 & 0xC0) != 0x80)
return invalid_mb_sequence;
char32_t c = (c1 << 6) + c2 - 0x3080;
if (c <= maxcode)
- from.next += 2;
+ from += 2;
return c;
}
else if (c1 < 0xF0) // 3-byte sequence
{
if (avail < 3)
return incomplete_mb_character;
- unsigned char c2 = from.next[1];
+ unsigned char c2 = from[1];
if ((c2 & 0xC0) != 0x80)
return invalid_mb_sequence;
if (c1 == 0xE0 && c2 < 0xA0) // overlong
return invalid_mb_sequence;
- unsigned char c3 = from.next[2];
+ unsigned char c3 = from[2];
if ((c3 & 0xC0) != 0x80)
return invalid_mb_sequence;
char32_t c = (c1 << 12) + (c2 << 6) + c3 - 0xE2080;
if (c <= maxcode)
- from.next += 3;
+ from += 3;
return c;
}
else if (c1 < 0xF5) // 4-byte sequence
{
if (avail < 4)
return incomplete_mb_character;
- unsigned char c2 = from.next[1];
+ unsigned char c2 = from[1];
if ((c2 & 0xC0) != 0x80)
return invalid_mb_sequence;
if (c1 == 0xF0 && c2 < 0x90) // overlong
return invalid_mb_sequence;
if (c1 == 0xF4 && c2 >= 0x90) // > U+10FFFF
return invalid_mb_sequence;
- unsigned char c3 = from.next[2];
+ unsigned char c3 = from[2];
if ((c3 & 0xC0) != 0x80)
return invalid_mb_sequence;
- unsigned char c4 = from.next[3];
+ unsigned char c4 = from[3];
if ((c4 & 0xC0) != 0x80)
return invalid_mb_sequence;
char32_t c = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4 - 0x3C82080;
if (c <= maxcode)
- from.next += 4;
+ from += 4;
return c;
}
else // > U+10FFFF
@@ -215,31 +323,31 @@ namespace
{
if (to.size() < 1)
return false;
- *to.next++ = code_point;
+ to = code_point;
}
else if (code_point <= 0x7FF)
{
if (to.size() < 2)
return false;
- *to.next++ = (code_point >> 6) + 0xC0;
- *to.next++ = (code_point & 0x3F) + 0x80;
+ to = (code_point >> 6) + 0xC0;
+ to = (code_point & 0x3F) + 0x80;
}
else if (code_point <= 0xFFFF)
{
if (to.size() < 3)
return false;
- *to.next++ = (code_point >> 12) + 0xE0;
- *to.next++ = ((code_point >> 6) & 0x3F) + 0x80;
- *to.next++ = (code_point & 0x3F) + 0x80;
+ to = (code_point >> 12) + 0xE0;
+ to = ((code_point >> 6) & 0x3F) + 0x80;
+ to = (code_point & 0x3F) + 0x80;
}
else if (code_point <= 0x10FFFF)
{
if (to.size() < 4)
return false;
- *to.next++ = (code_point >> 18) + 0xF0;
- *to.next++ = ((code_point >> 12) & 0x3F) + 0x80;
- *to.next++ = ((code_point >> 6) & 0x3F) + 0x80;
- *to.next++ = (code_point & 0x3F) + 0x80;
+ to = (code_point >> 18) + 0xF0;
+ to = ((code_point >> 12) & 0x3F) + 0x80;
+ to = ((code_point >> 6) & 0x3F) + 0x80;
+ to = (code_point & 0x3F) + 0x80;
}
else
return false;
@@ -280,47 +388,47 @@ namespace
// The sequence's endianness is indicated by (mode & little_endian).
// Updates from.next if the codepoint is not greater than maxcode.
// Returns invalid_mb_sequence, incomplete_mb_character or the code point.
- char32_t
- read_utf16_code_point(range<const char16_t>& from, unsigned long maxcode,
- codecvt_mode mode)
- {
- const size_t avail = from.size();
- if (avail == 0)
- return incomplete_mb_character;
- int inc = 1;
- char32_t c = adjust_byte_order(from.next[0], mode);
- if (is_high_surrogate(c))
- {
- if (avail < 2)
- return incomplete_mb_character;
- const char16_t c2 = adjust_byte_order(from.next[1], mode);
- if (is_low_surrogate(c2))
- {
- c = surrogate_pair_to_code_point(c, c2);
- inc = 2;
- }
- else
- return invalid_mb_sequence;
- }
- else if (is_low_surrogate(c))
- return invalid_mb_sequence;
- if (c <= maxcode)
- from.next += inc;
- return c;
- }
+ template<bool Aligned>
+ char32_t
+ read_utf16_code_point(range<const char16_t, Aligned>& from,
+ unsigned long maxcode, codecvt_mode mode)
+ {
+ const size_t avail = from.size();
+ if (avail == 0)
+ return incomplete_mb_character;
+ int inc = 1;
+ char32_t c = adjust_byte_order(from[0], mode);
+ if (is_high_surrogate(c))
+ {
+ if (avail < 2)
+ return incomplete_mb_character;
+ const char16_t c2 = adjust_byte_order(from[1], mode);
+ if (is_low_surrogate(c2))
+ {
+ c = surrogate_pair_to_code_point(c, c2);
+ inc = 2;
+ }
+ else
+ return invalid_mb_sequence;
+ }
+ else if (is_low_surrogate(c))
+ return invalid_mb_sequence;
+ if (c <= maxcode)
+ from += inc;
+ return c;
+ }
- template<typename C>
+ template<typename C, bool A>
bool
- write_utf16_code_point(range<C>& to, char32_t codepoint, codecvt_mode mode)
+ write_utf16_code_point(range<C, A>& to, char32_t codepoint, codecvt_mode mode)
{
static_assert(sizeof(C) >= 2, "a code unit must be at least 16-bit");
- if (codepoint < max_single_utf16_unit)
+ if (codepoint <= max_single_utf16_unit)
{
if (to.size() > 0)
{
- *to.next = adjust_byte_order(codepoint, mode);
- ++to.next;
+ to = adjust_byte_order(codepoint, mode);
return true;
}
}
@@ -330,9 +438,8 @@ namespace
const char32_t LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
char16_t lead = LEAD_OFFSET + (codepoint >> 10);
char16_t trail = 0xDC00 + (codepoint & 0x3FF);
- to.next[0] = adjust_byte_order(lead, mode);
- to.next[1] = adjust_byte_order(trail, mode);
- to.next += 2;
+ to = adjust_byte_order(lead, mode);
+ to = adjust_byte_order(trail, mode);
return true;
}
return false;
@@ -351,7 +458,7 @@ namespace
return codecvt_base::partial;
if (codepoint > maxcode)
return codecvt_base::error;
- *to.next++ = codepoint;
+ to = codepoint;
}
return from.size() ? codecvt_base::partial : codecvt_base::ok;
}
@@ -365,23 +472,22 @@ namespace
return codecvt_base::partial;
while (from.size())
{
- const char32_t c = from.next[0];
+ const char32_t c = from[0];
if (c > maxcode)
return codecvt_base::error;
if (!write_utf8_code_point(to, c))
return codecvt_base::partial;
- ++from.next;
+ ++from;
}
return codecvt_base::ok;
}
// utf16 -> ucs4
codecvt_base::result
- ucs4_in(range<const char16_t>& from, range<char32_t>& to,
+ ucs4_in(range<const char16_t, false>& from, range<char32_t>& to,
unsigned long maxcode = max_code_point, codecvt_mode mode = {})
{
- if (read_utf16_bom(from, mode) == little_endian)
- mode = codecvt_mode(mode & little_endian);
+ read_utf16_bom(from, mode);
while (from.size() && to.size())
{
const char32_t codepoint = read_utf16_code_point(from, maxcode, mode);
@@ -389,72 +495,85 @@ namespace
return codecvt_base::partial;
if (codepoint > maxcode)
return codecvt_base::error;
- *to.next++ = codepoint;
+ to = codepoint;
}
return from.size() ? codecvt_base::partial : codecvt_base::ok;
}
// ucs4 -> utf16
codecvt_base::result
- ucs4_out(range<const char32_t>& from, range<char16_t>& to,
+ ucs4_out(range<const char32_t>& from, range<char16_t, false>& to,
unsigned long maxcode = max_code_point, codecvt_mode mode = {})
{
if (!write_utf16_bom(to, mode))
return codecvt_base::partial;
while (from.size())
{
- const char32_t c = from.next[0];
+ const char32_t c = from[0];
if (c > maxcode)
return codecvt_base::error;
if (!write_utf16_code_point(to, c, mode))
return codecvt_base::partial;
- ++from.next;
+ ++from;
}
return codecvt_base::ok;
}
- // utf8 -> utf16
+ // Flag indicating whether to process UTF-16 or UCS2
+ enum class surrogates { allowed, disallowed };
+
+ // utf8 -> utf16 (or utf8 -> ucs2 if s == surrogates::disallowed)
template<typename C>
codecvt_base::result
utf16_in(range<const char>& from, range<C>& to,
- unsigned long maxcode = max_code_point, codecvt_mode mode = {})
+ unsigned long maxcode = max_code_point, codecvt_mode mode = {},
+ surrogates s = surrogates::allowed)
{
read_utf8_bom(from, mode);
while (from.size() && to.size())
{
- const char* const first = from.next;
+ auto orig = from;
const char32_t codepoint = read_utf8_code_point(from, maxcode);
if (codepoint == incomplete_mb_character)
- return codecvt_base::partial;
+ {
+ if (s == surrogates::allowed)
+ return codecvt_base::partial;
+ else
+ return codecvt_base::error; // No surrogates in UCS2
+ }
if (codepoint > maxcode)
return codecvt_base::error;
if (!write_utf16_code_point(to, codepoint, mode))
{
- from.next = first;
+ from = orig; // rewind to previous position
return codecvt_base::partial;
}
}
return codecvt_base::ok;
}
- // utf16 -> utf8
+ // utf16 -> utf8 (or ucs2 -> utf8 if s == surrogates::disallowed)
template<typename C>
codecvt_base::result
utf16_out(range<const C>& from, range<char>& to,
- unsigned long maxcode = max_code_point, codecvt_mode mode = {})
+ unsigned long maxcode = max_code_point, codecvt_mode mode = {},
+ surrogates s = surrogates::allowed)
{
if (!write_utf8_bom(to, mode))
return codecvt_base::partial;
while (from.size())
{
- char32_t c = from.next[0];
+ char32_t c = from[0];
int inc = 1;
if (is_high_surrogate(c))
{
+ if (s == surrogates::disallowed)
+ return codecvt_base::error; // No surrogates in UCS-2
+
if (from.size() < 2)
return codecvt_base::ok; // stop converting at this point
- const char32_t c2 = from.next[1];
+ const char32_t c2 = from[1];
if (is_low_surrogate(c2))
{
c = surrogate_pair_to_code_point(c, c2);
@@ -469,7 +588,7 @@ namespace
return codecvt_base::error;
if (!write_utf8_code_point(to, c))
return codecvt_base::partial;
- from.next += inc;
+ from += inc;
}
return codecvt_base::ok;
}
@@ -492,7 +611,7 @@ namespace
++count;
}
if (count+1 == max) // take one more character if it fits in a single unit
- read_utf8_code_point(from, std::max(max_single_utf16_unit, maxcode));
+ read_utf8_code_point(from, std::min(max_single_utf16_unit, maxcode));
return from.next;
}
@@ -501,7 +620,9 @@ namespace
ucs2_in(range<const char>& from, range<char16_t>& to,
char32_t maxcode = max_code_point, codecvt_mode mode = {})
{
- return utf16_in(from, to, std::max(max_single_utf16_unit, maxcode), mode);
+ // UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
+ maxcode = std::min(max_single_utf16_unit, maxcode);
+ return utf16_in(from, to, maxcode, mode, surrogates::disallowed);
}
// ucs2 -> utf8
@@ -509,61 +630,62 @@ namespace
ucs2_out(range<const char16_t>& from, range<char>& to,
char32_t maxcode = max_code_point, codecvt_mode mode = {})
{
- return utf16_out(from, to, std::max(max_single_utf16_unit, maxcode), mode);
+ // UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
+ maxcode = std::min(max_single_utf16_unit, maxcode);
+ return utf16_out(from, to, maxcode, mode, surrogates::disallowed);
}
// ucs2 -> utf16
codecvt_base::result
- ucs2_out(range<const char16_t>& from, range<char16_t>& to,
+ ucs2_out(range<const char16_t>& from, range<char16_t, false>& to,
char32_t maxcode = max_code_point, codecvt_mode mode = {})
{
if (!write_utf16_bom(to, mode))
return codecvt_base::partial;
while (from.size() && to.size())
{
- char16_t c = from.next[0];
+ char16_t c = from[0];
if (is_high_surrogate(c))
return codecvt_base::error;
if (c > maxcode)
return codecvt_base::error;
- *to.next++ = adjust_byte_order(c, mode);
- ++from.next;
+ to = adjust_byte_order(c, mode);
+ ++from;
}
return from.size() == 0 ? codecvt_base::ok : codecvt_base::partial;
}
// utf16 -> ucs2
codecvt_base::result
- ucs2_in(range<const char16_t>& from, range<char16_t>& to,
+ ucs2_in(range<const char16_t, false>& from, range<char16_t>& to,
char32_t maxcode = max_code_point, codecvt_mode mode = {})
{
- if (read_utf16_bom(from, mode) == little_endian)
- mode = codecvt_mode(mode & little_endian);
- maxcode = std::max(max_single_utf16_unit, maxcode);
+ read_utf16_bom(from, mode);
+ // UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
+ maxcode = std::min(max_single_utf16_unit, maxcode);
while (from.size() && to.size())
{
const char32_t c = read_utf16_code_point(from, maxcode, mode);
if (c == incomplete_mb_character)
- return codecvt_base::partial;
+ return codecvt_base::error; // UCS-2 only supports single units.
if (c > maxcode)
return codecvt_base::error;
- *to.next++ = c;
+ to = c;
}
return from.size() == 0 ? codecvt_base::ok : codecvt_base::partial;
}
const char16_t*
- ucs2_span(const char16_t* begin, const char16_t* end, size_t max,
+ ucs2_span(range<const char16_t, false>& from, size_t max,
char32_t maxcode, codecvt_mode mode)
{
- range<const char16_t> from{ begin, end };
- if (read_utf16_bom(from, mode) == little_endian)
- mode = codecvt_mode(mode & little_endian);
- maxcode = std::max(max_single_utf16_unit, maxcode);
+ read_utf16_bom(from, mode);
+ // UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
+ maxcode = std::min(max_single_utf16_unit, maxcode);
char32_t c = 0;
while (max-- && c <= maxcode)
c = read_utf16_code_point(from, maxcode, mode);
- return from.next;
+ return reinterpret_cast<const char16_t*>(from.next);
}
const char*
@@ -572,7 +694,8 @@ namespace
{
range<const char> from{ begin, end };
read_utf8_bom(from, mode);
- maxcode = std::max(max_single_utf16_unit, maxcode);
+ // UCS-2 only supports characters in the BMP, i.e. one UTF-16 code unit:
+ maxcode = std::min(max_single_utf16_unit, maxcode);
char32_t c = 0;
while (max-- && c <= maxcode)
c = read_utf8_code_point(from, maxcode);
@@ -594,16 +717,14 @@ namespace
// return pos such that [begin,pos) is valid UCS-4 string no longer than max
const char16_t*
- ucs4_span(const char16_t* begin, const char16_t* end, size_t max,
+ ucs4_span(range<const char16_t, false>& from, size_t max,
char32_t maxcode = max_code_point, codecvt_mode mode = {})
{
- range<const char16_t> from{ begin, end };
- if (read_utf16_bom(from, mode) == little_endian)
- mode = codecvt_mode(mode & little_endian);
+ read_utf16_bom(from, mode);
char32_t c = 0;
while (max-- && c <= maxcode)
c = read_utf16_code_point(from, maxcode, mode);
- return from.next;
+ return reinterpret_cast<const char16_t*>(from.next);
}
}
@@ -661,7 +782,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
codecvt<char16_t, char, mbstate_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
codecvt<char16_t, char, mbstate_t>::do_always_noconv() const throw()
@@ -679,9 +800,9 @@ do_length(state_type&, const extern_type* __from,
int
codecvt<char16_t, char, mbstate_t>::do_max_length() const throw()
{
- // Any valid UTF-8 sequence of 3 bytes fits in a single 16-bit code unit,
- // whereas 4 byte sequences require two 16-bit code units.
- return 3;
+ // A single character (one or two UTF-16 code units) requires
+ // up to four UTF-8 code units.
+ return 4;
}
// Define members of codecvt<char32_t, char, mbstate_t> specialization.
@@ -732,7 +853,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
codecvt<char32_t, char, mbstate_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
codecvt<char32_t, char, mbstate_t>::do_always_noconv() const throw()
@@ -749,7 +870,11 @@ do_length(state_type&, const extern_type* __from,
int
codecvt<char32_t, char, mbstate_t>::do_max_length() const throw()
-{ return 4; }
+{
+ // A single character (one UTF-32 code unit) requires
+ // up to 4 UTF-8 code units.
+ return 4;
+}
// Define members of codecvt_utf8<char16_t> base class implementation.
// Converts from UTF-8 to UCS-2.
@@ -801,7 +926,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_base<char16_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_base<char16_t>::do_always_noconv() const throw()
@@ -818,7 +943,14 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_base<char16_t>::do_max_length() const throw()
-{ return 3; }
+{
+ // A single UCS-2 character requires up to three UTF-8 code units.
+ // (UCS-2 cannot represent characters that use four UTF-8 code units).
+ int max = 3;
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
+}
// Define members of codecvt_utf8<char32_t> base class implementation.
// Converts from UTF-8 to UTF-32 (aka UCS-4).
@@ -866,7 +998,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_base<char32_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_base<char32_t>::do_always_noconv() const throw()
@@ -883,9 +1015,22 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_base<char32_t>::do_max_length() const throw()
-{ return 4; }
+{
+ // A single UCS-4 character requires up to four UTF-8 code units.
+ int max = 4;
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
+}
#ifdef _GLIBCXX_USE_WCHAR_T
+
+#if __SIZEOF_WCHAR_T__ == 2
+static_assert(sizeof(wchar_t) == sizeof(char16_t), "");
+#elif __SIZEOF_WCHAR_T__ == 4
+static_assert(sizeof(wchar_t) == sizeof(char32_t), "");
+#endif
+
// Define members of codecvt_utf8<wchar_t> base class implementation.
// Converts from UTF-8 to UCS-2 or UCS-4 depending on sizeof(wchar_t).
@@ -958,7 +1103,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_base<wchar_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_base<wchar_t>::do_always_noconv() const throw()
@@ -981,7 +1126,16 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_base<wchar_t>::do_max_length() const throw()
-{ return 4; }
+{
+#if __SIZEOF_WCHAR_T__ == 2
+ int max = 3; // See __codecvt_utf8_base<char16_t>::do_max_length()
+#else
+ int max = 4; // See __codecvt_utf8_base<char32_t>::do_max_length()
+#endif
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
+}
#endif
// Define members of codecvt_utf16<char16_t> base class implementation.
@@ -997,10 +1151,7 @@ do_out(state_type&, const intern_type* __from, const intern_type* __from_end,
extern_type*& __to_next) const
{
range<const char16_t> from{ __from, __from_end };
- range<char16_t> to{
- reinterpret_cast<char16_t*>(__to),
- reinterpret_cast<char16_t*>(__to_end)
- };
+ range<char16_t, false> to{ __to, __to_end };
auto res = ucs2_out(from, to, _M_maxcode, _M_mode);
__from_next = from.next;
__to_next = reinterpret_cast<char*>(to.next);
@@ -1023,20 +1174,19 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const
{
- range<const char16_t> from{
- reinterpret_cast<const char16_t*>(__from),
- reinterpret_cast<const char16_t*>(__from_end)
- };
+ range<const char16_t, false> from{ __from, __from_end };
range<char16_t> to{ __to, __to_end };
auto res = ucs2_in(from, to, _M_maxcode, _M_mode);
__from_next = reinterpret_cast<const char*>(from.next);
__to_next = to.next;
+ if (res == codecvt_base::ok && __from_next != __from_end)
+ res = codecvt_base::error;
return res;
}
int
__codecvt_utf16_base<char16_t>::do_encoding() const throw()
-{ return 1; }
+{ return 0; } // UTF-16 is not a fixed-width encoding
bool
__codecvt_utf16_base<char16_t>::do_always_noconv() const throw()
@@ -1047,15 +1197,21 @@ __codecvt_utf16_base<char16_t>::
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const
{
- auto next = reinterpret_cast<const char16_t*>(__from);
- next = ucs2_span(next, reinterpret_cast<const char16_t*>(__end), __max,
- _M_maxcode, _M_mode);
+ range<const char16_t, false> from{ __from, __end };
+ const char16_t* next = ucs2_span(from, __max, _M_maxcode, _M_mode);
return reinterpret_cast<const char*>(next) - __from;
}
int
__codecvt_utf16_base<char16_t>::do_max_length() const throw()
-{ return 3; }
+{
+ // A single UCS-2 character requires one UTF-16 code unit (so two chars).
+ // (UCS-2 cannot represent characters that use multiple UTF-16 code units).
+ int max = 2;
+ if (_M_mode & consume_header)
+ max += sizeof(utf16_bom);
+ return max;
+}
// Define members of codecvt_utf16<char32_t> base class implementation.
// Converts from UTF-16 to UTF-32 (aka UCS-4).
@@ -1070,10 +1226,7 @@ do_out(state_type&, const intern_type* __from, const intern_type* __from_end,
extern_type*& __to_next) const
{
range<const char32_t> from{ __from, __from_end };
- range<char16_t> to{
- reinterpret_cast<char16_t*>(__to),
- reinterpret_cast<char16_t*>(__to_end)
- };
+ range<char16_t, false> to{ __to, __to_end };
auto res = ucs4_out(from, to, _M_maxcode, _M_mode);
__from_next = from.next;
__to_next = reinterpret_cast<char*>(to.next);
@@ -1096,20 +1249,19 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const
{
- range<const char16_t> from{
- reinterpret_cast<const char16_t*>(__from),
- reinterpret_cast<const char16_t*>(__from_end)
- };
+ range<const char16_t, false> from{ __from, __from_end };
range<char32_t> to{ __to, __to_end };
auto res = ucs4_in(from, to, _M_maxcode, _M_mode);
__from_next = reinterpret_cast<const char*>(from.next);
__to_next = to.next;
+ if (res == codecvt_base::ok && __from_next != __from_end)
+ res = codecvt_base::error;
return res;
}
int
__codecvt_utf16_base<char32_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-16 is not a fixed-width encoding
bool
__codecvt_utf16_base<char32_t>::do_always_noconv() const throw()
@@ -1120,15 +1272,21 @@ __codecvt_utf16_base<char32_t>::
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const
{
- auto next = reinterpret_cast<const char16_t*>(__from);
- next = ucs4_span(next, reinterpret_cast<const char16_t*>(__end), __max,
- _M_maxcode, _M_mode);
+ range<const char16_t, false> from{ __from, __end };
+ const char16_t* next = ucs4_span(from, __max, _M_maxcode, _M_mode);
return reinterpret_cast<const char*>(next) - __from;
}
int
__codecvt_utf16_base<char32_t>::do_max_length() const throw()
-{ return 4; }
+{
+ // A single UCS-4 character requires one or two UTF-16 code units
+ // (so up to four chars).
+ int max = 4;
+ if (_M_mode & consume_header)
+ max += sizeof(utf16_bom);
+ return max;
+}
#ifdef _GLIBCXX_USE_WCHAR_T
// Define members of codecvt_utf16<wchar_t> base class implementation.
@@ -1143,24 +1301,24 @@ do_out(state_type&, const intern_type* __from, const intern_type* __from_end,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const
{
- range<char> to{ __to, __to_end };
+ range<char16_t, false> to{ __to, __to_end };
#if __SIZEOF_WCHAR_T__ == 2
range<const char16_t> from{
reinterpret_cast<const char16_t*>(__from),
- reinterpret_cast<const char16_t*>(__from_end)
+ reinterpret_cast<const char16_t*>(__from_end),
};
auto res = ucs2_out(from, to, _M_maxcode, _M_mode);
#elif __SIZEOF_WCHAR_T__ == 4
range<const char32_t> from{
reinterpret_cast<const char32_t*>(__from),
- reinterpret_cast<const char32_t*>(__from_end)
+ reinterpret_cast<const char32_t*>(__from_end),
};
auto res = ucs4_out(from, to, _M_maxcode, _M_mode);
#else
return codecvt_base::error;
#endif
__from_next = reinterpret_cast<const wchar_t*>(from.next);
- __to_next = to.next;
+ __to_next = reinterpret_cast<char*>(to.next);
return res;
}
@@ -1180,30 +1338,32 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const
{
- range<const char> from{ __from, __from_end };
+ range<const char16_t, false> from{ __from, __from_end };
#if __SIZEOF_WCHAR_T__ == 2
range<char16_t> to{
reinterpret_cast<char16_t*>(__to),
- reinterpret_cast<char16_t*>(__to_end)
+ reinterpret_cast<char16_t*>(__to_end),
};
auto res = ucs2_in(from, to, _M_maxcode, _M_mode);
#elif __SIZEOF_WCHAR_T__ == 4
range<char32_t> to{
reinterpret_cast<char32_t*>(__to),
- reinterpret_cast<char32_t*>(__to_end)
+ reinterpret_cast<char32_t*>(__to_end),
};
auto res = ucs4_in(from, to, _M_maxcode, _M_mode);
#else
return codecvt_base::error;
#endif
- __from_next = from.next;
+ __from_next = reinterpret_cast<const char*>(from.next);
__to_next = reinterpret_cast<wchar_t*>(to.next);
+ if (res == codecvt_base::ok && __from_next != __from_end)
+ res = codecvt_base::error;
return res;
}
int
__codecvt_utf16_base<wchar_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-16 is not a fixed-width encoding
bool
__codecvt_utf16_base<wchar_t>::do_always_noconv() const throw()
@@ -1214,20 +1374,27 @@ __codecvt_utf16_base<wchar_t>::
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const
{
- auto next = reinterpret_cast<const char16_t*>(__from);
+ range<const char16_t, false> from{ __from, __end };
#if __SIZEOF_WCHAR_T__ == 2
- next = ucs2_span(next, reinterpret_cast<const char16_t*>(__end), __max,
- _M_maxcode, _M_mode);
+ const char16_t* next = ucs2_span(from, __max, _M_maxcode, _M_mode);
#elif __SIZEOF_WCHAR_T__ == 4
- next = ucs4_span(next, reinterpret_cast<const char16_t*>(__end), __max,
- _M_maxcode, _M_mode);
+ const char16_t* next = ucs4_span(from, __max, _M_maxcode, _M_mode);
#endif
return reinterpret_cast<const char*>(next) - __from;
}
int
__codecvt_utf16_base<wchar_t>::do_max_length() const throw()
-{ return 4; }
+{
+#if __SIZEOF_WCHAR_T__ == 2
+ int max = 2; // See __codecvt_utf16_base<char16_t>::do_max_length()
+#else
+ int max = 4; // See __codecvt_utf16_base<char32_t>::do_max_length()
+#endif
+ if (_M_mode & consume_header)
+ max += sizeof(utf16_bom);
+ return max;
+}
#endif
// Define members of codecvt_utf8_utf16<char16_t> base class implementation.
@@ -1280,7 +1447,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_utf16_base<char16_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_utf16_base<char16_t>::do_always_noconv() const throw()
@@ -1298,9 +1465,12 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_utf16_base<char16_t>::do_max_length() const throw()
{
- // Any valid UTF-8 sequence of 3 bytes fits in a single 16-bit code unit,
- // whereas 4 byte sequences require two 16-bit code units.
- return 3;
+ // A single character can be 1 or 2 UTF-16 code units,
+ // requiring up to 4 UTF-8 code units.
+ int max = 4;
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
}
// Define members of codecvt_utf8_utf16<char32_t> base class implementation.
@@ -1341,7 +1511,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
{
range<const char> from{ __from, __from_end };
range<char32_t> to{ __to, __to_end };
- auto res = utf16_in(from, to, _M_maxcode, _M_mode);
+ codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header));
+#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
+ mode = codecvt_mode(mode | little_endian);
+#endif
+ auto res = utf16_in(from, to, _M_maxcode, mode);
__from_next = from.next;
__to_next = to.next;
return res;
@@ -1349,7 +1523,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_utf16_base<char32_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_utf16_base<char32_t>::do_always_noconv() const throw()
@@ -1367,9 +1541,12 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_utf16_base<char32_t>::do_max_length() const throw()
{
- // Any valid UTF-8 sequence of 3 bytes fits in a single 16-bit code unit,
- // whereas 4 byte sequences require two 16-bit code units.
- return 3;
+ // A single character can be 1 or 2 UTF-16 code units,
+ // requiring up to 4 UTF-8 code units.
+ int max = 4;
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
}
#ifdef _GLIBCXX_USE_WCHAR_T
@@ -1411,7 +1588,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
{
range<const char> from{ __from, __from_end };
range<wchar_t> to{ __to, __to_end };
- auto res = utf16_in(from, to, _M_maxcode, _M_mode);
+ codecvt_mode mode = codecvt_mode(_M_mode & (consume_header|generate_header));
+#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
+ mode = codecvt_mode(mode | little_endian);
+#endif
+ auto res = utf16_in(from, to, _M_maxcode, mode);
__from_next = from.next;
__to_next = to.next;
return res;
@@ -1419,7 +1600,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
int
__codecvt_utf8_utf16_base<wchar_t>::do_encoding() const throw()
-{ return 0; }
+{ return 0; } // UTF-8 is not a fixed-width encoding
bool
__codecvt_utf8_utf16_base<wchar_t>::do_always_noconv() const throw()
@@ -1437,9 +1618,12 @@ do_length(state_type&, const extern_type* __from,
int
__codecvt_utf8_utf16_base<wchar_t>::do_max_length() const throw()
{
- // Any valid UTF-8 sequence of 3 bytes fits in a single 16-bit code unit,
- // whereas 4 byte sequences require two 16-bit code units.
- return 3;
+ // A single character can be 1 or 2 UTF-16 code units,
+ // requiring up to 4 UTF-8 code units.
+ int max = 4;
+ if (_M_mode & consume_header)
+ max += sizeof(utf8_bom);
+ return max;
}
#endif
diff --git a/libstdc++-v3/testsuite/20_util/pair/79141.cc b/libstdc++-v3/testsuite/20_util/pair/79141.cc
new file mode 100644
index 00000000000..d4b5c9443f2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/79141.cc
@@ -0,0 +1,25 @@
+// { dg-do compile { target c++11 } }
+
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <utility>
+
+int main() {
+ std::pair<int,int> p;
+ p = {};
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc b/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc
index 012ccf5a4b8..92f5884735a 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc
@@ -34,7 +34,7 @@ test01()
const codecvt_c16* const cvt = &use_facet<codecvt_c16>(loc_c);
VERIFY(!cvt->always_noconv());
- VERIFY(cvt->max_length() == 3);
+ VERIFY(cvt->max_length() == 4);
VERIFY(cvt->encoding() == 0);
const char u8dat[] = u8"H\U000000E4ll\U000000F6 \U0001F63F \U000056FD "
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc
new file mode 100644
index 00000000000..d8b9729ed5b
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc
@@ -0,0 +1,142 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <locale>
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/79980
+
+constexpr std::codecvt_mode mode(std::codecvt_mode m)
+{ return static_cast<std::codecvt_mode>(m | std::consume_header); }
+
+template<typename WCh, unsigned long Max = 0x10FFFF,
+ std::codecvt_mode Mode = std::consume_header>
+ using Conv
+ = std::wstring_convert<std::codecvt_utf16<WCh, Max, mode(Mode)>, WCh>;
+
+void
+test01()
+{
+ const char src[] = "\xFE\xFF\xAB\xCD";
+ Conv<char16_t> conv;
+ auto dst = conv.from_bytes(src, src+4);
+ VERIFY( dst[0] == 0xabcd );
+}
+
+void
+test02()
+{
+ const char src[] = "\xFF\xFE\xAB\xCD";
+ Conv<char16_t> conv;
+ auto dst = conv.from_bytes(src, src+4);
+ VERIFY( dst[0] == 0xcdab );
+}
+
+void
+test03()
+{
+ const char src[] = "\xFE\xFF\xAB\xCD";
+ Conv<char16_t, 0x10FFFF, std::little_endian> conv;
+ auto dst = conv.from_bytes(src, src+4);
+ VERIFY( dst[0] == 0xabcd );
+}
+
+void
+test04()
+{
+ const char src[] = "\xFF\xFE\xAB\xCD";
+ Conv<char16_t, 0x10FFFF, std::little_endian> conv;
+ auto dst = conv.from_bytes(src, src+4);
+ VERIFY( dst[0] == 0xcdab );
+}
+
+void
+test05()
+{
+ const char src[] = "\0\x61\xAB\xCD"; // character greater than 0x00FF
+ Conv<char16_t, 0xFF> conv("to_bytes failed", u"from_bytes failed");
+ std::u16string result = conv.from_bytes(src, src+4);
+ VERIFY( result == u"from_bytes failed" );
+ VERIFY( conv.converted() == 2 );
+}
+
+void
+test06()
+{
+ const char src[] = "\0\x61\xAB\xCD";
+ Conv<char16_t> conv("to_bytes failed", u"from_bytes failed");
+ std::u16string result = conv.from_bytes(src, src+3); // incomplete character
+ VERIFY( result == u"from_bytes failed" );
+ VERIFY( conv.converted() == 2 );
+}
+
+void
+test07()
+{
+ Conv<char16_t> conv("to_bytes failed", u"from_bytes failed");
+ // ucs2 to utf-16 conversion should fail on invalid ucs2 input:
+ std::u16string utf16 = u"1234\U00001111\U0001ffff";
+ auto out = conv.to_bytes(utf16);
+ VERIFY( out == "to_bytes failed" );
+ VERIFY( conv.converted() == 5 );
+
+ // And should also fail on incomplete surrogate pair (not return partial):
+ out = conv.to_bytes(utf16.substr(0, utf16.size()-1));
+ VERIFY( out == "to_bytes failed" );
+ VERIFY( conv.converted() == 5 );
+}
+
+void
+test08()
+{
+ // Read/write UTF-16 code units from data not correctly aligned for char16_t
+ Conv<char16_t, 0x10FFFF, std::generate_header> conv;
+ const char src[] = "-\xFE\xFF\0\x61\xAB\xCD";
+ auto out = conv.from_bytes(src + 1, src + 7);
+ VERIFY( out[0] == 0x0061 );
+ VERIFY( out[1] == 0xabcd );
+ auto bytes = conv.to_bytes(out);
+ VERIFY( bytes == std::string(src + 1, 6) );
+}
+
+void
+test09()
+{
+ // Read/write UTF-16 code units from data not correctly aligned for char16_t
+ Conv<char32_t, 0x10FFFF, std::generate_header> conv;
+ const char src[] = "-\xFE\xFF\xD8\x08\xDF\x45";
+ auto out = conv.from_bytes(src + 1, src + 7);
+ VERIFY( out == U"\U00012345" );
+ auto bytes = conv.to_bytes(out);
+ VERIFY( bytes == std::string(src + 1, 6) );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ test05();
+ test06();
+ test07();
+ test08();
+ test09();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/80041.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/80041.cc
new file mode 100644
index 00000000000..a78b194212d
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/80041.cc
@@ -0,0 +1,87 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ std::codecvt_utf16<wchar_t> conv;
+ const wchar_t wc = 0x6557;
+ char bytes[2] = {0};
+ const wchar_t* wcnext;
+ std::mbstate_t st{};
+ char* next = nullptr;
+ auto res = conv.out(st, &wc, &wc+ 1, wcnext, bytes, std::end(bytes), next);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( wcnext == &wc + 1 );
+ VERIFY( next == std::end(bytes) );
+ VERIFY( bytes[0] == 0x65 );
+ VERIFY( bytes[1] == 0x57 );
+ VERIFY( conv.length(st, bytes, next, 1) == (next - bytes) );
+
+ wchar_t w;
+ wchar_t* wnext;
+ const char* cnext;
+ st = {};
+ res = conv.in(st, bytes, next, cnext, &w, &w + 1, wnext);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( wnext == &w + 1 );
+ VERIFY( cnext == next );
+ VERIFY( w == wc );
+#endif
+}
+
+void
+test02()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ std::codecvt_utf16<wchar_t, 0x10FFFF, std::little_endian> conv;
+ wchar_t wc = 0x6557;
+ char bytes[2] = {0};
+ const wchar_t* wcnext;
+ std::mbstate_t st{};
+ char* next = nullptr;
+ auto res = conv.out(st, &wc, &wc+ 1, wcnext, bytes, std::end(bytes), next);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( wcnext == &wc + 1 );
+ VERIFY( next == std::end(bytes) );
+ VERIFY( bytes[0] == 0x57 );
+ VERIFY( bytes[1] == 0x65 );
+ VERIFY( conv.length(st, bytes, next, 1) == (next - bytes) );
+
+ wchar_t w;
+ wchar_t* wnext;
+ const char* cnext;
+ st = {};
+ res = conv.in(st, bytes, next, cnext, &w, &w + 1, wnext);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( wnext == &w + 1 );
+ VERIFY( cnext == next );
+ VERIFY( w == wc );
+#endif
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/members.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/members.cc
new file mode 100644
index 00000000000..993c86082c1
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/members.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+const int bomlen = 2; // UTF-16 BOM is 16 bits
+
+void
+test01()
+{
+ const int maxlen = 2;
+
+ std::codecvt_utf16<char16_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf16<char16_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test02()
+{
+ const int maxlen = 4;
+
+ std::codecvt_utf16<char32_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf16<char32_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test03()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ const int maxlen = sizeof(wchar_t) == 4 ? 4 : 2;
+
+ std::codecvt_utf16<wchar_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+#endif
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc
new file mode 100644
index 00000000000..0179c184c20
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc
@@ -0,0 +1,289 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <locale>
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+using std::codecvt_base;
+using std::codecvt_mode;
+using std::codecvt_utf16;
+using std::wstring_convert;
+using std::mbstate_t;
+
+constexpr codecvt_mode
+operator|(codecvt_mode m1, codecvt_mode m2)
+{
+ using underlying = std::underlying_type<codecvt_mode>::type;
+ return static_cast<codecvt_mode>(static_cast<underlying>(m1) | m2);
+}
+
+// Read/write UTF-16 code units from data not correctly aligned for char16_t
+
+void
+test01()
+{
+ mbstate_t st;
+ constexpr codecvt_mode m = std::consume_header|std::generate_header;
+ codecvt_utf16<char16_t, 0x10FFFF, m> conv;
+ const char src[] = "-\xFE\xFF\0\x61\xAB\xCD";
+ const char* const src_end = src + 7;
+
+ int len = conv.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+
+ char16_t dst[2];
+ char16_t* const dst_end = dst + 2;
+ char16_t* dst_next;
+ const char* src_cnext;
+ auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ char out[sizeof(src)] = { src[0] };
+ char* const out_end = out + 7;
+ char* out_next;
+ const char16_t* dst_cnext;
+ res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[1] );
+ VERIFY( out[2] == src[2] );
+ VERIFY( out[3] == src[3] );
+ VERIFY( out[4] == src[4] );
+ VERIFY( out[5] == src[5] );
+ VERIFY( out[6] == src[6] );
+
+ codecvt_utf16<char16_t, 0x10FFFF, m|std::little_endian> conv_le;
+
+ len = conv_le.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv_le.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+
+ res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[2] );
+ VERIFY( out[2] == src[1] );
+ VERIFY( out[3] == src[4] );
+ VERIFY( out[4] == src[3] );
+ VERIFY( out[5] == src[6] );
+ VERIFY( out[6] == src[5] );
+}
+
+void
+test02()
+{
+ mbstate_t st;
+ constexpr codecvt_mode m = std::consume_header|std::generate_header;
+ codecvt_utf16<char32_t, 0x10FFFF, m> conv;
+ const char src[] = "-\xFE\xFF\0\x61\xAB\xCD\xD8\x08\xDF\x45";
+ const char* const src_end = src + 11;
+
+ int len = conv.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+ len = conv.length(st, src + 1, src_end, -1ul);
+ VERIFY( len == 10 );
+
+ char32_t dst[3];
+ char32_t* const dst_end = dst + 3;
+ char32_t* dst_next;
+ const char* src_cnext;
+ auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ VERIFY( dst[2] == 0x012345 );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ char out[sizeof(src)] = { src[0] };
+ char* const out_end = out + 11;
+ char* out_next;
+ const char32_t* dst_cnext;
+ res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[1] );
+ VERIFY( out[2] == src[2] );
+ VERIFY( out[3] == src[3] );
+ VERIFY( out[4] == src[4] );
+ VERIFY( out[5] == src[5] );
+ VERIFY( out[6] == src[6] );
+ VERIFY( out[7] == src[7] );
+ VERIFY( out[8] == src[8] );
+ VERIFY( out[9] == src[9] );
+ VERIFY( out[10] == src[10] );
+
+ codecvt_utf16<char32_t, 0x10FFFF, m|std::little_endian> conv_le;
+
+ len = conv_le.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv_le.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+ len = conv.length(st, src + 1, src_end, -1ul);
+ VERIFY( len == 10 );
+
+ res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ VERIFY( dst[2] == 0x012345 );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[2] );
+ VERIFY( out[2] == src[1] );
+ VERIFY( out[3] == src[4] );
+ VERIFY( out[4] == src[3] );
+ VERIFY( out[5] == src[6] );
+ VERIFY( out[6] == src[5] );
+ VERIFY( out[7] == src[8] );
+ VERIFY( out[8] == src[7] );
+ VERIFY( out[9] == src[10] );
+ VERIFY( out[10] == src[9] );
+}
+
+void
+test03()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ mbstate_t st;
+ constexpr codecvt_mode m = std::consume_header|std::generate_header;
+ codecvt_utf16<wchar_t, 0x10FFFF, m> conv;
+ const char src[] = "-\xFE\xFF\0\x61\xAB\xCD\xD8\x08\xDF\x45";
+ const size_t in_len = sizeof(wchar_t) == 4 ? 11 : 7;
+ const size_t out_len = sizeof(wchar_t) == 4 ? 3 : 2;
+ const char* const src_end = src + in_len;
+
+ int len = conv.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+ if (sizeof(wchar_t) == 4)
+ {
+ len = conv.length(st, src + 1, src_end, -1ul);
+ VERIFY( len == 10 );
+ }
+
+ wchar_t dst[out_len];
+ wchar_t* const dst_end = dst + out_len;
+ wchar_t* dst_next;
+ const char* src_cnext;
+ auto res = conv.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ if (sizeof(wchar_t) == 4)
+ VERIFY( dst[2] == 0x012345 );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ char out[sizeof(src)] = { src[0] };
+ char* const out_end = out + in_len;
+ char* out_next;
+ const wchar_t* dst_cnext;
+ res = conv.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[1] );
+ VERIFY( out[2] == src[2] );
+ VERIFY( out[3] == src[3] );
+ VERIFY( out[4] == src[4] );
+ VERIFY( out[5] == src[5] );
+ VERIFY( out[6] == src[6] );
+ if (sizeof(wchar_t) == 4)
+ {
+ VERIFY( out[7] == src[7] );
+ VERIFY( out[8] == src[8] );
+ VERIFY( out[9] == src[9] );
+ VERIFY( out[10] == src[10] );
+ }
+
+ codecvt_utf16<wchar_t, 0x10FFFF, m|std::little_endian> conv_le;
+
+ len = conv_le.length(st, src + 1, src_end, 1);
+ VERIFY( len == 4 );
+ len = conv_le.length(st, src + 1, src_end, 2);
+ VERIFY( len == 6 );
+ if (sizeof(wchar_t) == 4)
+ {
+ len = conv.length(st, src + 1, src_end, -1ul);
+ VERIFY( len == 10 );
+ }
+
+ res = conv_le.in(st, src + 1, src_end, src_cnext, dst, dst_end, dst_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( dst[0] == 0x0061 );
+ VERIFY( dst[1] == 0xabcd );
+ if (sizeof(wchar_t) == 4)
+ VERIFY( dst[2] == 0x012345 );
+ VERIFY( src_cnext == src_end );
+ VERIFY( dst_next == dst_end );
+
+ res = conv_le.out(st, dst, dst_end, dst_cnext, out + 1, out_end, out_next);
+ VERIFY( res == codecvt_base::ok );
+ VERIFY( out_next == out_end );
+ VERIFY( dst_cnext == dst_end );
+ VERIFY( out[1] == src[2] );
+ VERIFY( out[2] == src[1] );
+ VERIFY( out[3] == src[4] );
+ VERIFY( out[4] == src[3] );
+ VERIFY( out[5] == src[6] );
+ VERIFY( out[6] == src[5] );
+ if (sizeof(wchar_t) == 4)
+ {
+ VERIFY( out[7] == src[8] );
+ VERIFY( out[8] == src[7] );
+ VERIFY( out[9] == src[10] );
+ VERIFY( out[10] == src[9] );
+ }
+#endif
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/79980.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/79980.cc
new file mode 100644
index 00000000000..1251acb85be
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/79980.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <codecvt>
+#include <locale>
+#include <string>
+#include <testsuite_hooks.h>
+
+using std::wstring_convert;
+using std::codecvt_utf8;
+
+void
+test01()
+{
+ std::string src = u8"1234\U00001111\U0001ffff";
+ wstring_convert<codecvt_utf8<char16_t>, char16_t> c("bad", u"BAD");
+
+ // utf-8 to ucs2 conversion should fail on character outside BMP
+ auto ucs2 = c.from_bytes(src);
+ VERIFY( ucs2 == u"BAD" );
+ VERIFY( c.converted() == 7 );
+
+ // ucs2 to utf-8 conversion should fail on invalid ucs2 input:
+ std::u16string utf16 = u"1234\U00001111\U0001ffff";
+ auto out = c.to_bytes(utf16);
+ VERIFY( out == "bad" );
+ VERIFY( c.converted() == 5 );
+
+ // And should also fail on incomplete surrogate pair (not return partial):
+ out = c.to_bytes(utf16.substr(0, utf16.size()-1));
+ VERIFY( out == "bad" );
+ VERIFY( c.converted() == 5 );
+}
+
+void
+test02()
+{
+ std::string src = u8"1234\U00001111\U0001ffff";
+ wstring_convert<codecvt_utf8<char16_t, 0x1000>, char16_t> c("bad", u"BAD");
+
+ // utf-8 to ucs2 conversion should fail on character above Maxcode=0x1000
+ auto ucs2 = c.from_bytes(src);
+ VERIFY( ucs2 == u"BAD" );
+ VERIFY( c.converted() == 4 );
+}
+
+void
+test03()
+{
+ std::string src = u8"1234\U00001111\U0001ffff";
+ wstring_convert<codecvt_utf8<char32_t, 0x10000>, char32_t> c("bad", U"BAD");
+
+ // utf-8 to ucs4 conversion should fail on character above Maxcode=0x10000
+ auto ucs4 = c.from_bytes(src);
+ VERIFY( ucs4 == U"BAD" );
+ VERIFY( c.converted() == 7 );
+}
+
+void
+test04()
+{
+ std::string src = u8"1234\U00001111\U0001ffff";
+ wstring_convert<codecvt_utf8<char32_t, 0x1000>, char32_t> c("bad", U"BAD");
+
+ // utf-8 to ucs4 conversion should fail on character above Maxcode=0x1000
+ auto ucs4 = c.from_bytes(src);
+ VERIFY( ucs4 == U"BAD" );
+ VERIFY( c.converted() == 4 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/members.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/members.cc
new file mode 100644
index 00000000000..baeb049861a
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/members.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+const int bomlen = 3; // UTF-8 BOM is 24 bits
+
+void
+test01()
+{
+ const int maxlen = 3;
+
+ std::codecvt_utf8<char16_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8<char16_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test02()
+{
+ const int maxlen = 4;
+
+ std::codecvt_utf8<char32_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8<char32_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test03()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ const int maxlen = sizeof(wchar_t) == 4 ? 4 : 3;
+
+ std::codecvt_utf8<wchar_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8<wchar_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+#endif
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc
new file mode 100644
index 00000000000..5555bcba6fe
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc
@@ -0,0 +1,60 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <locale>
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/79511
+
+template<typename ElemT>
+ std::basic_string<ElemT> conv(const char* src)
+ {
+ std::wstring_convert<std::codecvt_utf8_utf16<ElemT>, ElemT> conv;
+ return conv.from_bytes(src);
+ }
+
+void
+test01()
+{
+ static char const src[] = "\xEF\xBF\xBF";
+ VERIFY( conv<char16_t>(src) == u"\xffff" );
+ VERIFY( conv<char32_t>(src) == U"\xffff" );
+#ifdef _GLIBCXX_USE_WCHAR_T
+ VERIFY( conv<wchar_t>(src) == L"\xffff" );
+#endif
+}
+
+void
+test02()
+{
+ static char const src[] = "\xE2\x82\xAC";
+ VERIFY( conv<char16_t>(src) == u"\x20ac" );
+ VERIFY( conv<char32_t>(src) == U"\x20ac" );
+#ifdef _GLIBCXX_USE_WCHAR_T
+ VERIFY( conv<wchar_t>(src) == L"\x20ac" );
+#endif
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc
new file mode 100644
index 00000000000..8fcdfff2cc1
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <codecvt>
+#include <testsuite_hooks.h>
+
+const int bomlen = 3; // UTF-8 BOM is 24 bits
+const int maxlen = 4;
+
+void
+test01()
+{
+ std::codecvt_utf8_utf16<char16_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test02()
+{
+ std::codecvt_utf8_utf16<char32_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8_utf16<char32_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+}
+
+void
+test03()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ std::codecvt_utf8_utf16<wchar_t> c;
+ VERIFY( c.always_noconv() == false );
+ VERIFY( c.encoding() == 0 );
+ VERIFY( c.max_length() == maxlen );
+
+ std::codecvt_utf8_utf16<wchar_t, 0x10ffff, std::consume_header> c_bom;
+ VERIFY( c_bom.always_noconv() == false );
+ VERIFY( c_bom.encoding() == 0 );
+ VERIFY( c_bom.max_length() == (maxlen + bomlen) );
+#endif
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc
index 28c8eb5b7c4..c4175208a02 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/uniform_real_distribution/operators/64351.cc
@@ -43,10 +43,18 @@ test02()
std::mt19937 rng(8890);
std::seed_seq sequence{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
rng.seed(sequence);
- rng.discard(12 * 629143 + 6);
- float n =
- std::generate_canonical<float, std::numeric_limits<float>::digits>(rng);
- VERIFY( n != 1.f );
+ rng.discard(12 * 629143);
+ std::mt19937 rng2{rng};
+ for (int i = 0; i < 20; ++i)
+ {
+ float n =
+ std::generate_canonical<float, std::numeric_limits<float>::digits>(rng);
+ VERIFY( n != 1.f );
+
+ // PR libstdc++/80137
+ rng2.discard(1);
+ VERIFY( rng == rng2 );
+ }
}
int
diff --git a/libstdc++-v3/testsuite/experimental/iterator/requirements.cc b/libstdc++-v3/testsuite/experimental/iterator/requirements.cc
index 846ccde2da3..e17acdda692 100644
--- a/libstdc++-v3/testsuite/experimental/iterator/requirements.cc
+++ b/libstdc++-v3/testsuite/experimental/iterator/requirements.cc
@@ -20,7 +20,7 @@
// This is a compile-only test with minimal includes
#include <experimental/iterator>
-#include <iosfwd>
+#include <iosfwd> // No guarantee that <experimental/iterator> includes this!
using namespace std::experimental;
@@ -56,3 +56,13 @@ tester<int, char> ic;
tester<wchar_t, wchar_t> ww;
tester<int, wchar_t> iw;
#endif
+
+std::ostream& os();
+
+// Ensure that contents of <iterator> are defined by <experimental/iterator>:
+std::reverse_iterator<int*> ii;
+std::move_iterator<int*> mi;
+std::istream_iterator<int> isi;
+std::ostream_iterator<int> osi(os());
+std::istreambuf_iterator<char> isbi;
+std::ostreambuf_iterator<char> osbi(os());
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc
new file mode 100644
index 00000000000..a61d36f67b3
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc
@@ -0,0 +1,51 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run }
+
+#include <ext/pb_ds/priority_queue.hpp>
+#include <testsuite_hooks.h>
+
+int count = 0;
+
+struct less
+{
+ bool operator()(int i, int j) const
+ {
+ ++count;
+ return i < j;
+ }
+};
+
+void
+test01()
+{
+ __gnu_pbds::priority_queue<int, less, __gnu_pbds::binary_heap_tag> c;
+ c.push(1);
+ c.push(2);
+ c.push(3);
+ c.push(4);
+ count = 0;
+ c.push(5);
+ VERIFY( count < c.size() );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues.cc b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues.cc
index 330c3331fff..7802fbd3f09 100644
--- a/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues.cc
+++ b/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queues.cc
@@ -108,7 +108,7 @@ priority_queue_link_regression_test_0()
{
/*
- * Perform operations on a binomial-heap queue.
+ * Perform operations on a binary-heap queue.
*/
cout << "Binary heap" << endl;
__gnu_pbds::priority_queue<int, less<int>, binary_heap_tag> c;