From 8888e7889696a6323bf711c5cae0815d5856450a Mon Sep 17 00:00:00 2001 From: Yvan Roux Date: Tue, 4 Apr 2017 21:38:30 +0200 Subject: Merge branches/gcc-6-branch rev 246668. Change-Id: If1d4497c52a1bdde1390c2377e3f2c16ac2e73b4 --- gcc/ChangeLog | 354 ++++++++++++ gcc/DATESTAMP | 2 +- gcc/Makefile.in | 21 +- gcc/ada/ChangeLog | 15 + gcc/ada/gcc-interface/Makefile.in | 17 +- gcc/ada/system-linux-aarch64-ilp32.ads | 157 ++++++ gcc/c-family/ChangeLog | 13 + gcc/c-family/c-ada-spec.c | 2 +- gcc/c-family/c-common.c | 7 +- gcc/config/i386/cpuid.h | 2 +- gcc/config/i386/i386.c | 38 +- gcc/config/rs6000/constraints.md | 3 + gcc/config/rs6000/dfp.md | 8 +- gcc/config/rs6000/rs6000.c | 14 +- gcc/config/rs6000/rs6000.h | 4 +- gcc/config/rs6000/rs6000.md | 178 +++--- gcc/config/rs6000/vsx.md | 23 +- gcc/cp/ChangeLog | 15 + gcc/cp/init.c | 8 + gcc/cp/lambda.c | 5 +- gcc/data-streamer-in.c | 1 - gcc/data-streamer-out.c | 1 - gcc/doc/extend.texi | 8 +- gcc/doc/gcc.texi | 3 + gcc/doc/gcov-dump.texi | 93 ++++ gcc/doc/invoke.texi | 7 +- gcc/doc/md.texi | 3 + gcc/fold-const.c | 2 +- gcc/fortran/ChangeLog | 29 + gcc/fortran/module.c | 21 +- gcc/fortran/parse.c | 31 +- gcc/fortran/symbol.c | 16 +- gcc/gcov-dump.c | 2 + gcc/gcse.c | 32 +- gcc/ipa-devirt.c | 17 +- gcc/ipa-pure-const.c | 8 +- gcc/multiple_target.c | 79 +-- gcc/params.def | 2 +- gcc/passes.def | 3 +- gcc/testsuite/ChangeLog | 282 ++++++++++ gcc/testsuite/c-c++-common/ubsan/shift-10.c | 10 + gcc/testsuite/g++.dg/cpp0x/pr80091.C | 12 + gcc/testsuite/g++.dg/ext/flexary12.C | 2 +- gcc/testsuite/g++.dg/ext/flexary20.C | 49 ++ gcc/testsuite/g++.dg/ext/flexary21.C | 15 + gcc/testsuite/g++.dg/ext/mv8.C | 2 +- gcc/testsuite/g++.dg/pr71294.C | 60 ++ gcc/testsuite/g++.dg/pr79761.C | 34 ++ gcc/testsuite/g++.dg/pr79769.C | 4 + gcc/testsuite/g++.dg/warn/Wunused-var-26.C | 147 +++++ gcc/testsuite/gcc.dg/pr78644-1.c | 21 + gcc/testsuite/gcc.dg/pr78644-2.c | 20 + gcc/testsuite/gcc.dg/pr79574-2.c | 33 ++ gcc/testsuite/gcc.dg/pr79574.c | 10 + gcc/testsuite/gcc.dg/pr80218.c | 28 + gcc/testsuite/gcc.dg/tls/emutls-2.c | 1 + gcc/testsuite/gcc.dg/torture/pr71881.c | 1 + gcc/testsuite/gcc.dg/torture/pr78742.c | 1 + gcc/testsuite/gcc.dg/torture/pr79732.c | 5 + gcc/testsuite/gcc.dg/torture/pr80181.c | 19 + gcc/testsuite/gcc.dg/tree-prof/pr66295.c | 35 ++ gcc/testsuite/gcc.dg/tree-prof/pr79587.c | 26 + gcc/testsuite/gcc.dg/tree-ssa/pr79803.c | 60 ++ gcc/testsuite/gcc.target/i386/mpx/pr78339.c | 5 + gcc/testsuite/gcc.target/i386/mpx/pr79631.c | 15 + gcc/testsuite/gcc.target/i386/mpx/pr79753.c | 14 + gcc/testsuite/gcc.target/i386/mpx/pr79770.c | 19 + gcc/testsuite/gcc.target/i386/mvc9.c | 28 + gcc/testsuite/gcc.target/i386/pr65044.c | 2 +- gcc/testsuite/gcc.target/i386/pr71458.c | 7 + gcc/testsuite/gcc.target/i386/pr80019.c | 13 + gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c | 18 +- gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c | 4 +- gcc/testsuite/gcc.target/powerpc/pr78543.c | 60 ++ gcc/testsuite/gcc.target/powerpc/pr79947.c | 12 + gcc/testsuite/gcc.target/powerpc/pr79951.c | 10 + gcc/testsuite/gcc.target/powerpc/pr80246.c | 37 ++ gcc/testsuite/gfortran.dg/submodule_25.f08 | 43 ++ gcc/testsuite/gfortran.dg/submodule_26.f08 | 46 ++ gcc/testsuite/gfortran.dg/submodule_27.f08 | 44 ++ gcc/testsuite/gfortran.dg/submodule_28.f08 | 52 ++ gcc/toplev.c | 29 +- gcc/tree-call-cdce.c | 68 ++- gcc/tree-chkp-opt.c | 4 +- gcc/tree-chkp.c | 19 +- gcc/tree-inline.c | 7 +- gcc/tree-ssa-ccp.c | 26 +- gcc/tree-ssa-loop-prefetch.c | 19 +- gcc/value-prof.c | 12 +- libstdc++-v3/ChangeLog | 136 +++++ libstdc++-v3/include/bits/locale_conv.h | 5 +- libstdc++-v3/include/bits/random.tcc | 25 +- libstdc++-v3/include/bits/stl_pair.h | 10 +- libstdc++-v3/include/experimental/iterator | 5 +- .../ext/pb_ds/detail/binary_heap_/binary_heap_.hpp | 21 +- .../pb_ds/detail/binary_heap_/insert_fn_imps.hpp | 1 - libstdc++-v3/src/c++11/codecvt.cc | 606 ++++++++++++++------- libstdc++-v3/testsuite/20_util/pair/79141.cc | 25 + .../testsuite/22_locale/codecvt/char16_t.cc | 2 +- .../22_locale/codecvt/codecvt_utf16/79980.cc | 142 +++++ .../22_locale/codecvt/codecvt_utf16/80041.cc | 87 +++ .../22_locale/codecvt/codecvt_utf16/members.cc | 81 +++ .../22_locale/codecvt/codecvt_utf16/misaligned.cc | 289 ++++++++++ .../22_locale/codecvt/codecvt_utf8/79980.cc | 94 ++++ .../22_locale/codecvt/codecvt_utf8/members.cc | 81 +++ .../22_locale/codecvt/codecvt_utf8_utf16/79511.cc | 60 ++ .../codecvt/codecvt_utf8_utf16/members.cc | 76 +++ .../uniform_real_distribution/operators/64351.cc | 16 +- .../experimental/iterator/requirements.cc | 12 +- .../regression/priority_queue_binary_heap-62045.cc | 51 ++ .../ext/pb_ds/regression/priority_queues.cc | 2 +- 111 files changed, 4032 insertions(+), 529 deletions(-) create mode 100644 gcc/ada/system-linux-aarch64-ilp32.ads create mode 100644 gcc/doc/gcov-dump.texi create mode 100644 gcc/testsuite/c-c++-common/ubsan/shift-10.c create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr80091.C create mode 100644 gcc/testsuite/g++.dg/ext/flexary20.C create mode 100644 gcc/testsuite/g++.dg/ext/flexary21.C create mode 100644 gcc/testsuite/g++.dg/pr71294.C create mode 100644 gcc/testsuite/g++.dg/pr79761.C create mode 100644 gcc/testsuite/g++.dg/pr79769.C create mode 100644 gcc/testsuite/g++.dg/warn/Wunused-var-26.C create mode 100644 gcc/testsuite/gcc.dg/pr78644-1.c create mode 100644 gcc/testsuite/gcc.dg/pr78644-2.c create mode 100644 gcc/testsuite/gcc.dg/pr79574-2.c create mode 100644 gcc/testsuite/gcc.dg/pr79574.c create mode 100644 gcc/testsuite/gcc.dg/pr80218.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr79732.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr80181.c create mode 100644 gcc/testsuite/gcc.dg/tree-prof/pr66295.c create mode 100644 gcc/testsuite/gcc.dg/tree-prof/pr79587.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr79803.c create mode 100644 gcc/testsuite/gcc.target/i386/mpx/pr78339.c create mode 100644 gcc/testsuite/gcc.target/i386/mpx/pr79631.c create mode 100644 gcc/testsuite/gcc.target/i386/mpx/pr79753.c create mode 100644 gcc/testsuite/gcc.target/i386/mpx/pr79770.c create mode 100644 gcc/testsuite/gcc.target/i386/mvc9.c create mode 100644 gcc/testsuite/gcc.target/i386/pr71458.c create mode 100644 gcc/testsuite/gcc.target/i386/pr80019.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr78543.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr79947.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr79951.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr80246.c create mode 100644 gcc/testsuite/gfortran.dg/submodule_25.f08 create mode 100644 gcc/testsuite/gfortran.dg/submodule_26.f08 create mode 100644 gcc/testsuite/gfortran.dg/submodule_27.f08 create mode 100644 gcc/testsuite/gfortran.dg/submodule_28.f08 create mode 100644 libstdc++-v3/testsuite/20_util/pair/79141.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/80041.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/members.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/79980.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8/members.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc create mode 100644 libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf8_utf16/members.cc create mode 100644 libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_binary_heap-62045.cc 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 + + Back port from the trunk + 2017-03-14 Michael Meissner + + PR target/79947 + * config/rs6000/rs6000.h (TARGET_FRSQRTES): Add check for + -mpowerpc-gfxopt. + +2017-03-31 Richard Sandiford + + 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 + + Backport from mainline + 2017-03-30 Peter Bergner + + PR target/80246 + * config/rs6000/dfp.md (dfp_dxex_): Update mode of operand 0. + (dfp_diex_): 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 + + Back port from trunk + 2017-03-21 Aaron Sawdey + + 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_): Use wA constraint. + + 2017-03-16 Michael Meissner + + PR target/71294 + * config/rs6000/vsx.md (vsx_splat_, 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 + + Backport from mainline + 2017-03-28 Richard Biener + + 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 + + PR tree-optimization/80181 + * tree-ssa-ccp.c (likely_value): UNDEFINED ^ X is UNDEFINED. + +2017-03-28 Marek Polacek + + Backport from mainline + 2017-03-28 Marek Polacek + + PR sanitizer/80067 + * fold-const.c (fold_comparison): Use protected_set_expr_location + instead of SET_EXPR_LOCATION. + +2017-03-27 Michael Meissner + + Back port from trunk + 2017-03-27 Michael Meissner + + PR target/78543 + * config/rs6000/rs6000.md (bswaphi2_extenddi): Combine bswap + HImode and SImode with zero extend to DImode to one insn. + (bswap2_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. + (bswap2): Likewise. + (bswaphi2_internal): Delete, no longer used. + (bswapsi2_internal): Likewise. + (bswap2_load): Split bswap HImode/SImode into separate load, + store, and gpr<-gpr swap insns. + (bswap2_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 + + PR target/80180 + * config/i386/i386.c (ix86_expand_builtin) + : Do not expand arg0 between + flags reg setting and flags reg using instructions. + : Ditto. Use non-flags reg + clobbering instructions to zero extend op2. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-14 Martin Liska + + PR lto/66295 + * multiple_target.c (expand_target_clones): Drop local.local + flag for default implementation. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-02-22 Martin Liska + + 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 + + Backport from mainline + 2017-02-03 Martin Liska + + 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 + + Backport from mainline + 2017-03-22 Martin Liska + + PR target/79906 + * config/rs6000/rs6000.c (rs6000_inner_target_options): Show + error message instead of an ICE. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-21 Martin Liska + + 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 + + Backport from mainline + 2017-03-20 Martin Liska + + 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 + + Backport from mainline + 2017-03-20 Martin Liska + + 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 + + Backport from mainline + 2017-03-14 Martin Liska + + PR middle-end/79831 + * doc/invoke.texi (-Wchkp): Document the option. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-14 Martin Liska + + PR target/79892 + * multiple_target.c (create_dispatcher_calls): Check that + a target can create a function dispatcher. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-13 Martin Liska + + 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 + + Backport from mainline + 2017-03-10 Martin Liska + + 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 + + Backport from mainline + 2017-03-09 Martin Liska + + 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 + + Backport from mainline + 2017-03-09 Martin Liska + + PR target/65705 + PR target/69804 + * toplev.c (process_options): Disable -fcheck-pointer-bounds with + sanitizers. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-09 Martin Liska + + 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 + + Backport from mainline + 2017-03-03 Jan Hubicka + + PR lto/79760 + * ipa-devirt.c (maybe_record_node): Properly handle + __cxa_pure_virtual visibility. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-03 Martin Liska + + 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 + + Backport from mainline + 2017-03-03 Martin Liska + + 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 + + Backport from mainline + 2017-02-17 Martin Liska + + PR rtl-optimization/79574 + * gcse.c (want_to_gcse_p): Prevent integer overflow. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-02-17 Martin Liska + + PR rtl-optimization/79577 + * params.def (selsched-max-sched-times): Increase minimum to 1. + +2017-03-22 Martin Liska + + Backport from mainline + 2016-06-13 Martin Liska + + PR sanitizer/71458 + * toplev.c (process_options): Do not enable -fcheck-pointer-bounds + w/ -fsanitize=bounds. + +2017-03-21 Pat Haugen + + Backport from mainline: + 2017-03-17 Pat Haugen + + PR target/79951 + * config/rs6000/rs6000.md (copysign3_fcpsgn): Test + for VECTOR_UNIT_VSX_P (mode) too. + +2017-03-21 Tamar Christina + + * config/aarch64/aarch64-simd.md (*aarch64_simd_mov) + Change ins into fmov. + +2017-03-19 Dominique d'Humieres + + PR target/71017 + * config/i386/cpuid.h: Fix another undefined behavior. + +2017-03-17 Tom de Vries + + backport from trunk: + 2017-03-17 Tom de Vries + + * gcov-dump.c (print_usage): Print bug_report_url. + +2017-03-16 Richard Biener + + Backport from mainline + 2017-02-28 Richard Biener + + 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 + + Backport from mainline + 2017-03-14 Martin Liska + + * Makefile.in: Install gcov-dump. + +2017-03-15 Uros Bizjak + + 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 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 + + Backport from trunk + + 2017-03-28 Andreas Schwab + + 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 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. -- +-- -- +-- 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 + + Backport from mainline + 2017-03-09 Martin Liska + + * c-ada-spec.c (macro_length): Increment value instead of a pointer. + +2017-03-21 Martin Sebor + + PR c++/79548 + * c-common.c (set_underlying_type): Mark type used only when + original del is declared unused. + 2017-03-14 Marek Polacek 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_" - [(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 %0,%1" [(set_attr "type" "dfp")]) (define_insn "dfp_diex_" [(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 % 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 "*bswap2_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" + "lbrx %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 "bswap2" + [(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, src); + + if (MEM_P (src)) + emit_insn (gen_bswap2_load (dest, src)); + else if (MEM_P (dest)) + emit_insn (gen_bswap2_store (dest, src)); + else + emit_insn (gen_bswap2_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 "bswap2_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,*")]) + "lbrx %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 "bswap2_store" + [(set (match_operand:HSI 0 "memory_operand" "=Z") + (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] + "" + "stbrx %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" ",") (match_operand:SFDF 2 "gpc_reg_operand" ",")] UNSPEC_COPYSIGN))] - "TARGET__FPR && TARGET_CMPB" + "TARGET__FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (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_" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=,,we") +(define_insn_and_split "vsx_splat_" + [(set (match_operand:VSX_D 0 "vsx_register_operand" + "=, ,we,") (vec_duplicate:VSX_D - (match_operand: 1 "splat_input_operand" ",Z,b")))] + (match_operand: 1 "splat_input_operand" + ",Z, b, wA")))] "VECTOR_MEM_VSX_P (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], mode)" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (vec_duplicate:VSX_D (match_dup 2)))] +{ + operands[2] = gen_rtx_REG (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 + + PR c++/80091 + * lambda.c (maybe_generic_this_capture): Capture when fn + is an identifier node. + +2017-03-15 Marek Polacek + + Backported from mainline + 2016-12-14 Marek Polacek + + PR c++/72775 + * init.c (perform_member_init): Diagnose member initializer for + flexible array member. + 2017-03-14 Marek Polacek 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 + + 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 + + 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 + + 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 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 &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 *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 + + Back port from the trunk + 2017-03-14 Michael Meissner + + PR target/79947 + * gcc.target/powerpc/pr79947.c: New test. + +2017-04-03 Peter Bergner + + Backport from mainline + 2017-04-03 Peter Bergner + + 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 + + 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 + + Backport from trunk + PR fortran/79676 + * gfortran.dg/submodule_28.f08 : New test. + +2017-03-31 Richard Sandiford + + PR tree-optimization/80218 + * gcc.dg/pr80218.c: New test. + +2017-03-30 Peter Bergner + + Backport from mainline + 2017-03-30 Peter Bergner + + 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 + + Back port from trunk + 2017-03-16 Michael Meissner + + PR target/71294 + * g++.dg/pr71294.C: New test. + +2017-03-29 Richard Biener + + Backport from mainline + 2017-03-28 Richard Biener + + PR tree-optimization/78644 + * gcc.dg/pr78644-1.c: New testcase. + * gcc.dg/pr78644-2.c: Likewise. + + 2017-03-27 Richard Biener + + PR tree-optimization/80181 + * gcc.dg/torture/pr80181.c: New testcase. + +2017-03-28 Marek Polacek + + Backport from mainline + 2017-03-28 Marek Polacek + + PR sanitizer/80067 + * c-c++-common/ubsan/shift-10.c: New test. + +2017-03-27 Michael Meissner + + Back port from trunk + 2017-03-27 Michael Meissner + + PR target/78543 + * gcc.target/powerpc/pr78543.c: New test. + +2017-03-27 Tom de Vries + + backport from trunk: + 2017-03-24 Tom de Vries + + PR testsuite/80092 + * gcc.dg/tls/emutls-2.c: Add dg-require-effective-target + global_constructor. + +2017-03-26 Paul Thomas + + Backport from trunk + PR fortran/79434 + * gfortran.dg/submodule_25.f08 : New test. + +2017-03-24 Tom de Vries + + backport from trunk: + 2017-03-24 Tom de Vries + + 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 + + Backport from mainline + 2017-03-16 Segher Boessenkool + + * gcc.dg/tree-prof/pr66295.c: Skip unless on an x86 target. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-14 Martin Liska + + PR lto/66295 + * gcc.dg/tree-prof/pr66295.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-02-22 Martin Liska + + PR lto/79587 + * gcc.dg/tree-prof/pr79587.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-02-03 Martin Liska + + PR lto/66295 + * gcc.target/i386/mvc9.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-22 Martin Liska + + PR target/79906 + * g++.dg/ext/mv8.C: Add power* targets. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-21 Martin Liska + + * gcc.target/i386/pr65044.c: Add '.' in order to catch + apostrophes. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-20 Martin Liska + + PR middle-end/79753 + * gcc.target/i386/mpx/pr79753.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-20 Martin Liska + + 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 + + Backport from mainline + 2017-03-13 Martin Liska + + PR middle-end/78339 + * gcc.target/i386/mpx/pr78339.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-09 Martin Liska + + PR tree-optimization/79631 + * gcc.target/i386/mpx/pr79631.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-09 Martin Liska + + PR target/65705 + PR target/69804 + * gcc.target/i386/pr71458.c: Update scanned pattern. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-09 Martin Liska + + PR ipa/79761 + * g++.dg/pr79761.C: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-03 Martin Liska + + PR tree-optimization/79803 + * gcc.dg/tree-ssa/pr79803.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-03-03 Martin Liska + + PR rtl-optimization/79574 + * gcc.dg/pr79574-2.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2017-02-17 Martin Liska + + PR rtl-optimization/79574 + * gcc.dg/pr79574.c: New test. + +2017-03-22 Martin Liska + + Backport from mainline + 2016-06-13 Martin Liska + + PR sanitizer/71458 + * gcc.target/i386/pr71458.c: New test. + +2017-03-21 Martin Sebor + + PR c++/79548 + * g++.dg/warn/Wunused-var-26.C: New test. + +2017-03-21 Pat Haugen + + Backport from mainline: + 2017-03-17 Pat Haugen + + PR target/79951 + * gcc.target/powerpc/pr79951.c: New. + +2017-03-16 Richard Biener + + Backport from mainline + 2017-02-28 Richard Biener + + PR tree-optimization/79732 + * gcc.dg/torture/pr79732.c: New testcase. + +2017-03-15 Uros Bizjak + + PR target/80019 + * gcc.target/i386/pr80019.c: New test. + +2017-03-15 Marek Polacek + + Backported from mainline + 2016-12-14 Marek Polacek + + 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 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 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 +struct X { // { dg-error "member initializer for flexible array member" } + int i; + T a[] = "foo"; +}; + +void +fn () +{ + struct X 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 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 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 +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 + 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 +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 b, c, e; + B 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 +void f_int () +{ + T t; // { dg-warning "unused variable" } + + typedef T U; + U u; // { dg-warning "unused variable" } +} + +template void f_int(); + + +template +void f_intptr () +{ + T *t = 0; // { dg-warning "unused variable" } + + typedef T U; + U *u = 0; // { dg-warning "unused variable" } +} + +template void f_intptr(); + + +template +void f_var_unused () +{ + // The variable is marked unused. + T t UNUSED; + + typedef T U; + U u UNUSED; +} + +template void f_var_unused(); + + +template +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(); + + +struct A { int i; }; + +template +void f_A () +{ + T t; // { dg-warning "unused variable" } + + typedef T U; + U u; // { dg-warning "unused variable" } +} + +template void f_A(); + + +template +void f_A_unused () +{ + T t UNUSED; + + typedef T U; + U u UNUSED; +} + +template void f_A_unused(); + + +struct B { B (); }; + +template +void f_B () +{ + T t; + + typedef T U; + U u; +} + +template void f_B(); + + +struct NonTrivialDtor { ~NonTrivialDtor (); }; + +template +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(); + + +struct D { NonTrivialDtor b; }; + +template +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(); + + +struct UNUSED DeclaredUnused { }; + +template +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(); 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 + +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 + +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 +! +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 +! Test reduced by Dominique d'Humieres +! +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 +! Test reduced by Dominique d'Humieres +! +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 +! +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 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_pair; + auto_vec 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 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 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 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, + "% 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 + + Backport from mainline + 2017-04-03 Ville Voutilainen + + PR libstdc++/79141 + * include/bits/stl_pair.h (__nonesuch_no_braces): New. + (operator=(typename conditional< + __and_, + is_copy_assignable<_T2>>::value, + const pair&, const __nonesuch&>::type)): Change __nonesuch + to __nonesuch_no_braces. + (operator=(typename conditional< + __not_<__and_, + is_copy_assignable<_T2>>>::value, + const pair&, const __nonesuch&>::type)): Likewise. + (operator=(typename conditional< + __and_, + is_move_assignable<_T2>>::value, + pair&&, __nonesuch&&>::type)): Likewise. + * testsuite/20_util/pair/79141.cc: New. + +2017-03-28 Jonathan Wakely + + 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   + + 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 + + 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 + + * include/experimental/iterator: Include . + * testsuite/experimental/iterator/requirements.cc: Check for contents + of . + +2017-03-17 Jonathan Wakely + + Backport from mainline + 2017-03-17 Jonathan Wakely + + * src/c++11/codecvt.cc (range): Add non-type template parameter and + define oerloaded operators for reading and writing code units. + (range): 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 in order to avoid unaligned reads. + (__codecvt_utf16_base::do_out) + (__codecvt_utf16_base::do_out) + (__codecvt_utf16_base::do_out): Use range specialization for + unaligned data to avoid unaligned writes. + (__codecvt_utf16_base::do_in) + (__codecvt_utf16_base::do_in) + (__codecvt_utf16_base::do_in): Likewise for writes. Return + error if there are unprocessable trailing bytes. + (__codecvt_utf16_base::do_length) + (__codecvt_utf16_base::do_length) + (__codecvt_utf16_base::do_length): Pass arguments of type + range to span functions. + * testsuite/22_locale/codecvt/codecvt_utf16/misaligned.cc: New test. + + Backport from mainline + 2017-03-16 Jonathan Wakely + + 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::do_out) + (__codecvt_utf16_base::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) + (codecvt, __codecvt_utf8_base) + (__codecvt_utf8_base, __codecvt_utf8_base) + (__codecvt_utf16_base, __codecvt_utf16_base) + (__codecvt_utf16_base, __codecvt_utf8_utf16_base) + (__codecvt_utf8_utf16_base) + (__codecvt_utf8_utf16_base): 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::do_in): Use native endianness + for internal representation. + (__codecvt_utf8_utf16_base::do_in): Likewise. + * testsuite/22_locale/codecvt/codecvt_utf8_utf16/79511.cc: New test. + 2017-03-14 Jonathan Wakely * 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(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<_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<_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<_T2>>::value, - pair&&, __nonesuch&&>::type __p) + pair&&, __wrap_nonesuch&&>::type __p) noexcept(__and_, 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 #else -#include +#include #include -#include -#include +#include 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(*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(*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(*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(*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 #include // std::memcpy, std::memcmp -#include // std::max +#include // 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::type + to_integer(codecvt_mode m) + { return static_cast::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 + // Utility type for reading and writing code units of type Elem from + // a range defined by a pair of pointers. + template 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 + struct range + { + using value_type = typename remove_const::type; + + using char_pointer = typename + conditional::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 - inline bool - write_bom(range& to, const unsigned char (&bom)[N]) + // Write a BOM (space permitting). + template + bool + write_bom(range& 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 + bool + read_bom(range& 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& 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 - write_utf16_bom(range& to, codecvt_mode mode) + write_utf16_bom(range& 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 - inline bool - read_bom(range& 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& 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& 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 + void + read_utf16_bom(range& 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& 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 + char32_t + read_utf16_code_point(range& 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 + template bool - write_utf16_code_point(range& to, char32_t codepoint, codecvt_mode mode) + write_utf16_code_point(range& 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& from, range& to, + ucs4_in(range& from, range& 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& from, range& to, + ucs4_out(range& from, range& 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 codecvt_base::result utf16_in(range& from, range& 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 codecvt_base::result utf16_out(range& from, range& 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& from, range& 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& from, range& 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& from, range& to, + ucs2_out(range& from, range& 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& from, range& to, + ucs2_in(range& from, range& 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& from, size_t max, char32_t maxcode, codecvt_mode mode) { - range 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(from.next); } const char* @@ -572,7 +694,8 @@ namespace { range 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& from, size_t max, char32_t maxcode = max_code_point, codecvt_mode mode = {}) { - range 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(from.next); } } @@ -661,7 +782,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, int codecvt::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool codecvt::do_always_noconv() const throw() @@ -679,9 +800,9 @@ do_length(state_type&, const extern_type* __from, int codecvt::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 specialization. @@ -732,7 +853,7 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, int codecvt::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool codecvt::do_always_noconv() const throw() @@ -749,7 +870,11 @@ do_length(state_type&, const extern_type* __from, int codecvt::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 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_base::do_always_noconv() const throw() @@ -818,7 +943,14 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_base::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 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_base::do_always_noconv() const throw() @@ -883,9 +1015,22 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_base::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 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_base::do_always_noconv() const throw() @@ -981,7 +1126,16 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_base::do_max_length() const throw() -{ return 4; } +{ +#if __SIZEOF_WCHAR_T__ == 2 + int max = 3; // See __codecvt_utf8_base::do_max_length() +#else + int max = 4; // See __codecvt_utf8_base::do_max_length() +#endif + if (_M_mode & consume_header) + max += sizeof(utf8_bom); + return max; +} #endif // Define members of codecvt_utf16 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 from{ __from, __from_end }; - range to{ - reinterpret_cast(__to), - reinterpret_cast(__to_end) - }; + range to{ __to, __to_end }; auto res = ucs2_out(from, to, _M_maxcode, _M_mode); __from_next = from.next; __to_next = reinterpret_cast(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 from{ - reinterpret_cast(__from), - reinterpret_cast(__from_end) - }; + range from{ __from, __from_end }; range to{ __to, __to_end }; auto res = ucs2_in(from, to, _M_maxcode, _M_mode); __from_next = reinterpret_cast(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::do_encoding() const throw() -{ return 1; } +{ return 0; } // UTF-16 is not a fixed-width encoding bool __codecvt_utf16_base::do_always_noconv() const throw() @@ -1047,15 +1197,21 @@ __codecvt_utf16_base:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { - auto next = reinterpret_cast(__from); - next = ucs2_span(next, reinterpret_cast(__end), __max, - _M_maxcode, _M_mode); + range from{ __from, __end }; + const char16_t* next = ucs2_span(from, __max, _M_maxcode, _M_mode); return reinterpret_cast(next) - __from; } int __codecvt_utf16_base::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 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 from{ __from, __from_end }; - range to{ - reinterpret_cast(__to), - reinterpret_cast(__to_end) - }; + range to{ __to, __to_end }; auto res = ucs4_out(from, to, _M_maxcode, _M_mode); __from_next = from.next; __to_next = reinterpret_cast(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 from{ - reinterpret_cast(__from), - reinterpret_cast(__from_end) - }; + range from{ __from, __from_end }; range to{ __to, __to_end }; auto res = ucs4_in(from, to, _M_maxcode, _M_mode); __from_next = reinterpret_cast(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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-16 is not a fixed-width encoding bool __codecvt_utf16_base::do_always_noconv() const throw() @@ -1120,15 +1272,21 @@ __codecvt_utf16_base:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { - auto next = reinterpret_cast(__from); - next = ucs4_span(next, reinterpret_cast(__end), __max, - _M_maxcode, _M_mode); + range from{ __from, __end }; + const char16_t* next = ucs4_span(from, __max, _M_maxcode, _M_mode); return reinterpret_cast(next) - __from; } int __codecvt_utf16_base::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 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 to{ __to, __to_end }; + range to{ __to, __to_end }; #if __SIZEOF_WCHAR_T__ == 2 range from{ reinterpret_cast(__from), - reinterpret_cast(__from_end) + reinterpret_cast(__from_end), }; auto res = ucs2_out(from, to, _M_maxcode, _M_mode); #elif __SIZEOF_WCHAR_T__ == 4 range from{ reinterpret_cast(__from), - reinterpret_cast(__from_end) + reinterpret_cast(__from_end), }; auto res = ucs4_out(from, to, _M_maxcode, _M_mode); #else return codecvt_base::error; #endif __from_next = reinterpret_cast(from.next); - __to_next = to.next; + __to_next = reinterpret_cast(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 from{ __from, __from_end }; + range from{ __from, __from_end }; #if __SIZEOF_WCHAR_T__ == 2 range to{ reinterpret_cast(__to), - reinterpret_cast(__to_end) + reinterpret_cast(__to_end), }; auto res = ucs2_in(from, to, _M_maxcode, _M_mode); #elif __SIZEOF_WCHAR_T__ == 4 range to{ reinterpret_cast(__to), - reinterpret_cast(__to_end) + reinterpret_cast(__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(from.next); __to_next = reinterpret_cast(to.next); + if (res == codecvt_base::ok && __from_next != __from_end) + res = codecvt_base::error; return res; } int __codecvt_utf16_base::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-16 is not a fixed-width encoding bool __codecvt_utf16_base::do_always_noconv() const throw() @@ -1214,20 +1374,27 @@ __codecvt_utf16_base:: do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { - auto next = reinterpret_cast(__from); + range from{ __from, __end }; #if __SIZEOF_WCHAR_T__ == 2 - next = ucs2_span(next, reinterpret_cast(__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(__end), __max, - _M_maxcode, _M_mode); + const char16_t* next = ucs4_span(from, __max, _M_maxcode, _M_mode); #endif return reinterpret_cast(next) - __from; } int __codecvt_utf16_base::do_max_length() const throw() -{ return 4; } +{ +#if __SIZEOF_WCHAR_T__ == 2 + int max = 2; // See __codecvt_utf16_base::do_max_length() +#else + int max = 4; // See __codecvt_utf16_base::do_max_length() +#endif + if (_M_mode & consume_header) + max += sizeof(utf16_bom); + return max; +} #endif // Define members of codecvt_utf8_utf16 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_utf16_base::do_always_noconv() const throw() @@ -1298,9 +1465,12 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_utf16_base::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 base class implementation. @@ -1341,7 +1511,11 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end, { range from{ __from, __from_end }; range 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_utf16_base::do_always_noconv() const throw() @@ -1367,9 +1541,12 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_utf16_base::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 from{ __from, __from_end }; range 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::do_encoding() const throw() -{ return 0; } +{ return 0; } // UTF-8 is not a fixed-width encoding bool __codecvt_utf8_utf16_base::do_always_noconv() const throw() @@ -1437,9 +1618,12 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf8_utf16_base::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 +// . + +#include + +int main() { + std::pair 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(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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +// PR libstdc++/79980 + +constexpr std::codecvt_mode mode(std::codecvt_mode m) +{ return static_cast(m | std::consume_header); } + +template + using Conv + = std::wstring_convert, WCh>; + +void +test01() +{ + const char src[] = "\xFE\xFF\xAB\xCD"; + Conv conv; + auto dst = conv.from_bytes(src, src+4); + VERIFY( dst[0] == 0xabcd ); +} + +void +test02() +{ + const char src[] = "\xFF\xFE\xAB\xCD"; + Conv conv; + auto dst = conv.from_bytes(src, src+4); + VERIFY( dst[0] == 0xcdab ); +} + +void +test03() +{ + const char src[] = "\xFE\xFF\xAB\xCD"; + Conv conv; + auto dst = conv.from_bytes(src, src+4); + VERIFY( dst[0] == 0xabcd ); +} + +void +test04() +{ + const char src[] = "\xFF\xFE\xAB\xCD"; + Conv 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 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 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 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 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 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +void +test01() +{ +#ifdef _GLIBCXX_USE_WCHAR_T + std::codecvt_utf16 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 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +const int bomlen = 2; // UTF-16 BOM is 16 bits + +void +test01() +{ + const int maxlen = 2; + + std::codecvt_utf16 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf16 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf16 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf16 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +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::type; + return static_cast(static_cast(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 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 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 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 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 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 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include +#include + +using std::wstring_convert; +using std::codecvt_utf8; + +void +test01() +{ + std::string src = u8"1234\U00001111\U0001ffff"; + wstring_convert, 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, 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, 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, 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +const int bomlen = 3; // UTF-8 BOM is 24 bits + +void +test01() +{ + const int maxlen = 3; + + std::codecvt_utf8 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +// PR libstdc++/79511 + +template + std::basic_string conv(const char* src) + { + std::wstring_convert, ElemT> conv; + return conv.from_bytes(src); + } + +void +test01() +{ + static char const src[] = "\xEF\xBF\xBF"; + VERIFY( conv(src) == u"\xffff" ); + VERIFY( conv(src) == U"\xffff" ); +#ifdef _GLIBCXX_USE_WCHAR_T + VERIFY( conv(src) == L"\xffff" ); +#endif +} + +void +test02() +{ + static char const src[] = "\xE2\x82\xAC"; + VERIFY( conv(src) == u"\x20ac" ); + VERIFY( conv(src) == U"\x20ac" ); +#ifdef _GLIBCXX_USE_WCHAR_T + VERIFY( conv(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 +// . + +// { dg-do run { target c++11 } } + +#include +#include + +const int bomlen = 3; // UTF-8 BOM is 24 bits +const int maxlen = 4; + +void +test01() +{ + std::codecvt_utf8_utf16 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8_utf16 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8_utf16 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 c; + VERIFY( c.always_noconv() == false ); + VERIFY( c.encoding() == 0 ); + VERIFY( c.max_length() == maxlen ); + + std::codecvt_utf8_utf16 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::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::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 -#include +#include // No guarantee that includes this! using namespace std::experimental; @@ -56,3 +56,13 @@ tester ic; tester ww; tester iw; #endif + +std::ostream& os(); + +// Ensure that contents of are defined by : +std::reverse_iterator ii; +std::move_iterator mi; +std::istream_iterator isi; +std::ostream_iterator osi(os()); +std::istreambuf_iterator isbi; +std::ostreambuf_iterator 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 +// . + +// { dg-do run } + +#include +#include + +int count = 0; + +struct less +{ + bool operator()(int i, int j) const + { + ++count; + return i < j; + } +}; + +void +test01() +{ + __gnu_pbds::priority_queue 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, binary_heap_tag> c; -- cgit v1.2.3