aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-26 21:05:44 +0200
committerMartin Liska <mliska@suse.cz>2022-09-26 21:05:44 +0200
commit3c527a35fa428b727807c81f1225a5e0025446c1 (patch)
tree787e21d7bf8a1d85ac7b9ccee784909e85ebf61b
parentc9c59aa19c0b7159636763294b7b0c87c696d675 (diff)
parent7701ea4a70a5a5c0fd977da90a30ffc4f3f87617 (diff)
downloadgcc-3c527a35fa428b727807c81f1225a5e0025446c1.zip
gcc-3c527a35fa428b727807c81f1225a5e0025446c1.tar.gz
gcc-3c527a35fa428b727807c81f1225a5e0025446c1.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS4
-rw-r--r--contrib/ChangeLog5
-rw-r--r--gcc/ChangeLog513
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in1
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/adaint.c13
-rw-r--r--gcc/ada/bindgen.adb9
-rw-r--r--gcc/ada/cal.c2
-rw-r--r--gcc/ada/contracts.adb2
-rw-r--r--gcc/ada/cstreams.c8
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst8
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst30
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst1120
-rw-r--r--gcc/ada/expect.c8
-rw-r--r--gcc/ada/gnat_rm.texi22
-rw-r--r--gcc/ada/gnat_ugn.texi12
-rw-r--r--gcc/ada/gsocket.h6
-rw-r--r--gcc/ada/mingw32.h28
-rw-r--r--gcc/ada/rtsfind.ads111
-rw-r--r--gcc/ada/s-oscons-tmplt.c3
-rw-r--r--gcc/ada/sem_ch12.adb7
-rw-r--r--gcc/ada/sem_ch5.adb8
-rw-r--r--gcc/ada/sem_util.adb24
-rw-r--r--gcc/ada/sem_warn.ads9
-rw-r--r--gcc/ada/sysdep.c6
-rw-r--r--gcc/attribs.cc3
-rw-r--r--gcc/c-family/ChangeLog14
-rw-r--r--gcc/c-family/c-common.cc2
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-cppbuiltin.cc2
-rw-r--r--gcc/c-family/c-warn.cc9
-rw-r--r--gcc/c/ChangeLog26
-rw-r--r--gcc/c/c-parser.cc12
-rw-r--r--gcc/c/c-tree.h3
-rw-r--r--gcc/c/c-typeck.cc23
-rw-r--r--gcc/c/gimple-parser.cc5
-rw-r--r--gcc/cfgcleanup.cc2
-rw-r--r--gcc/cfgcleanup.h1
-rw-r--r--gcc/cfgrtl.cc29
-rw-r--r--gcc/common.opt2
-rw-r--r--gcc/common/config/riscv/riscv-common.cc2
-rw-r--r--gcc/config.gcc24
-rw-r--r--gcc/config/aarch64/aarch64-arches.def3
-rw-r--r--gcc/config/aarch64/aarch64-cores.def3
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/aarch64/aarch64.cc40
-rw-r--r--gcc/config/aarch64/aarch64.h68
-rw-r--r--gcc/config/i386/constraints.md8
-rw-r--r--gcc/config/i386/i386-expand.cc116
-rw-r--r--gcc/config/i386/i386.cc26
-rw-r--r--gcc/config/i386/mmx.md2
-rw-r--r--gcc/config/i386/predicates.md49
-rw-r--r--gcc/config/i386/sse.md8
-rwxr-xr-xgcc/config/nvptx/gen-multilib-matches.sh60
-rw-r--r--gcc/config/nvptx/nvptx.cc4
-rw-r--r--gcc/config/nvptx/nvptx.h8
-rw-r--r--gcc/config/nvptx/nvptx.opt2
-rw-r--r--gcc/config/nvptx/t-nvptx31
-rw-r--r--gcc/config/riscv/predicates.md3
-rw-r--r--gcc/config/riscv/riscv-modes.def141
-rw-r--r--gcc/config/riscv/riscv-protos.h9
-rw-r--r--gcc/config/riscv/riscv-selftests.cc241
-rw-r--r--gcc/config/riscv/riscv.cc298
-rw-r--r--gcc/config/riscv/riscv.h13
-rw-r--r--gcc/config/riscv/t-riscv4
-rw-r--r--gcc/config/rs6000/rs6000-logue.cc2
-rw-r--r--gcc/config/rs6000/vector.md2
-rw-r--r--gcc/config/s390/s390.cc15
-rw-r--r--gcc/config/xtensa/xtensa.cc119
-rwxr-xr-xgcc/configure49
-rw-r--r--gcc/configure.ac49
-rw-r--r--gcc/cp/ChangeLog52
-rw-r--r--gcc/cp/constraint.cc6
-rw-r--r--gcc/cp/cp-objcp-common.cc2
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/cxx-pretty-print.cc6
-rw-r--r--gcc/cp/decl.cc6
-rw-r--r--gcc/cp/method.cc38
-rw-r--r--gcc/cp/module.cc49
-rw-r--r--gcc/cp/parser.cc10
-rw-r--r--gcc/cp/pt.cc2
-rw-r--r--gcc/cp/semantics.cc8
-rw-r--r--gcc/cp/typeck2.cc11
-rw-r--r--gcc/doc/install.texi9
-rw-r--r--gcc/doc/invoke.texi22
-rw-r--r--gcc/doc/sourcebuild.texi2
-rw-r--r--gcc/fortran/ChangeLog116
-rw-r--r--gcc/fortran/expr.cc3
-rw-r--r--gcc/fortran/interface.cc11
-rw-r--r--gcc/fortran/simplify.cc1
-rw-r--r--gcc/fortran/trans-array.cc4
-rw-r--r--gcc/fortran/trans-decl.cc1
-rw-r--r--gcc/fortran/trans-expr.cc83
-rw-r--r--gcc/fortran/trans-types.cc15
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/gcc.cc26
-rw-r--r--gcc/gimple-range-edge.cc2
-rw-r--r--gcc/gimple-range-fold.cc556
-rw-r--r--gcc/gimple-range-fold.h16
-rw-r--r--gcc/gimple-range-gori.cc134
-rw-r--r--gcc/gimple-range-gori.h27
-rw-r--r--gcc/gimple-range-op.cc820
-rw-r--r--gcc/gimple-range-op.h52
-rw-r--r--gcc/gimple-range.cc11
-rw-r--r--gcc/gimple-range.h2
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/omp-expand.cc17
-rw-r--r--gcc/omp-low.cc20
-rw-r--r--gcc/opts.cc2
-rw-r--r--gcc/passes.def2
-rw-r--r--gcc/po/ChangeLog4
-rw-r--r--gcc/po/fr.po19
-rw-r--r--gcc/range-op-float.cc298
-rw-r--r--gcc/range-op.cc254
-rw-r--r--gcc/range-op.h17
-rw-r--r--gcc/real.cc8
-rw-r--r--gcc/testsuite/ChangeLog258
-rw-r--r--gcc/testsuite/c-c++-common/goacc/reduction-7.c22
-rw-r--r--gcc/testsuite/c-c++-common/goacc/reduction-8.c12
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr106981.c9
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr107001.c14
-rw-r--r--gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/char8_t3.C37
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/char8_t4.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/char8_t-init-2.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/has-builtin-1.C6
-rw-r--r--gcc/testsuite/g++.dg/ext/is_convertible1.C269
-rw-r--r--gcc/testsuite/g++.dg/ext/is_convertible2.C46
-rw-r--r--gcc/testsuite/g++.dg/ext/is_convertible3.C9
-rw-r--r--gcc/testsuite/g++.dg/ext/is_nothrow_convertible1.C270
-rw-r--r--gcc/testsuite/g++.dg/ext/is_nothrow_convertible2.C19
-rw-r--r--gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C9
-rw-r--r--gcc/testsuite/g++.dg/modules/auto-3.h10
-rw-r--r--gcc/testsuite/g++.dg/modules/auto-3_a.H4
-rw-r--r--gcc/testsuite/g++.dg/modules/auto-3_b.C4
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2.cc17
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2.h38
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_a.C6
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_b.C5
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_c.H5
-rw-r--r--gcc/testsuite/g++.dg/modules/partial-2_d.C8
-rw-r--r--gcc/testsuite/g++.dg/modules/xtreme-header-2.h3
-rw-r--r--gcc/testsuite/g++.dg/modules/xtreme-header-6.h10
-rw-r--r--gcc/testsuite/g++.dg/modules/xtreme-header.h59
-rw-r--r--gcc/testsuite/g++.dg/other/error36.C13
-rw-r--r--gcc/testsuite/g++.dg/torture/pr106922.C48
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr106922.C5
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-33.C55
-rw-r--r--gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c6
-rw-r--r--gcc/testsuite/gcc.dg/c2x-complit-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/c2x-concat-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/cpp/c2x-ucn-1.c996
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr106967.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107009.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c25
-rw-r--r--gcc/testsuite/gcc.dg/tsan/pr106984.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x2.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x3.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/pr106963.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr106994.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-1.c70
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-2.c59
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-3.c69
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53346-4.c59
-rw-r--r--gcc/testsuite/gcc.target/i386/pr94962-1.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr94962-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr94962-3.c64
-rw-r--r--gcc/testsuite/gcc.target/i386/pr94962-4.c49
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr100645.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr96072.c14
-rw-r--r--gcc/testsuite/gcc.target/riscv/ret-1.c41
-rw-r--r--gcc/testsuite/gfortran.dg/PR100103.f9076
-rw-r--r--gcc/testsuite/gfortran.dg/PR100132.f9075
-rw-r--r--gcc/testsuite/gfortran.dg/associate_26a.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_type_16.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_type_17.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/c-interop/c407b-2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/ieee/rounding_3.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_10.f9066
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_4.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_5.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_6.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_7.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_8.f9045
-rw-r--r--gcc/testsuite/gfortran.dg/intent_optimize_9.f9042
-rw-r--r--gcc/testsuite/gfortran.dg/intent_out_15.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/pr106985.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pr106986.f908
-rw-r--r--gcc/testsuite/lib/scanasm.exp7
-rw-r--r--gcc/testsuite/selftests/riscv/empty-func.rtl8
-rw-r--r--gcc/tree-data-ref.cc6
-rw-r--r--gcc/tree-ssa-dom.cc35
-rw-r--r--gcc/tree-ssa-dse.cc51
-rw-r--r--gcc/tree-ssa-sccvn.cc144
-rw-r--r--gcc/tree-ssa-threadbackward.cc20
-rw-r--r--gcc/tree-vect-loop.cc5
-rw-r--r--gcc/tree-vrp.cc6
-rw-r--r--gcc/tsan.cc13
-rw-r--r--gcc/value-query.cc6
-rw-r--r--gcc/value-range-pretty-print.cc19
-rw-r--r--gcc/value-range-pretty-print.h1
-rw-r--r--gcc/value-range.cc110
-rw-r--r--gcc/value-range.h95
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/unwind-dw2-fde.c8
-rw-r--r--libgfortran/ChangeLog10
-rw-r--r--libgfortran/gfortran.map6
-rw-r--r--libgfortran/ieee/ieee_arithmetic.F9012
-rw-r--r--libgo/go/cmd/cgo/gcc.go77
-rw-r--r--libgo/go/cmd/cgo/main.go1
-rw-r--r--libgo/go/cmd/cgo/out.go13
-rw-r--r--libgo/go/cmd/go/internal/load/pkg.go8
-rw-r--r--libgo/go/runtime/cgo/cgo.go18
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr106981.c19
-rw-r--r--libiberty/ChangeLog4
-rw-r--r--libiberty/README2
-rw-r--r--libstdc++-v3/ChangeLog204
-rw-r--r--libstdc++-v3/doc/xml/manual/documentation_hacking.xml4
-rw-r--r--libstdc++-v3/doc/xml/manual/policy_data_structures.xml12
-rw-r--r--libstdc++-v3/include/bits/alloc_traits.h4
-rw-r--r--libstdc++-v3/include/bits/ptr_traits.h27
-rw-r--r--libstdc++-v3/include/bits/ranges_base.h1
-rw-r--r--libstdc++-v3/include/c_compatibility/stdlib.h3
-rw-r--r--libstdc++-v3/include/debug/bitset43
-rw-r--r--libstdc++-v3/include/experimental/type_traits24
-rw-r--r--libstdc++-v3/include/std/bitset256
-rw-r--r--libstdc++-v3/include/std/type_traits72
-rw-r--r--libstdc++-v3/include/std/version1
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py5
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc5
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc5
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc5
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc5
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc5
-rw-r--r--libstdc++-v3/testsuite/17_intro/names.cc1
-rw-r--r--libstdc++-v3/testsuite/18_support/uncaught_exception/14026.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/107037.cc7
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/18604.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/18604.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/45713.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/45713.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/access/constexpr.cc57
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/access/dr396.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/to_string/dr396.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/access/to_string.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/access/to_ullong.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/to_ullong/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/access/to_ulong.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/to_ulong/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/16020.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/16020.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/2.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/2.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/3.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/3.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/38244.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/38244.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/50268.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/6282.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/constexpr.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/constexpr.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc55
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-2.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-2.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/cons/dr396.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/cons/dr396.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/count/constexpr.cc93
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/debug/invalidation/1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/debug/invalidation/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/ext/15361.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/ext/constexpr.cc32
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/hash/1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/hash/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/io/input.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/input/1.cc)2
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/observers/6124.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/count/6124.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/observers/all.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/all/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/observers/test.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/test/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/13838.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/13838.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/2.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/2.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/96303.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/96303.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/constexpr-2.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr-2.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/constexpr.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/operations/constexpr_c++23.cc31
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/requirements/constexpr_functions.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/requirements/constexpr_functions.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1_c++0x.cc (renamed from libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc)0
-rw-r--r--libstdc++-v3/testsuite/20_util/bitset/version.cc10
-rw-r--r--libstdc++-v3/testsuite/20_util/function/91456.cc3
-rw-r--r--libstdc++-v3/testsuite/20_util/headers/bitset/synopsis.cc (renamed from libstdc++-v3/testsuite/23_containers/headers/bitset/synopsis.cc)9
-rw-r--r--libstdc++-v3/testsuite/20_util/headers/memory/synopsis.cc66
-rw-r--r--libstdc++-v3/testsuite/20_util/is_assignable/requirements/access.cc22
-rw-r--r--libstdc++-v3/testsuite/20_util/is_invocable/91456.cc10
-rw-r--r--libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/is_nothrow_invocable/91456.cc (renamed from libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value_ext.cc)19
294 files changed, 8580 insertions, 3042 deletions
diff --git a/ChangeLog b/ChangeLog
index 7212978..652b069 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2022-09-23 Paul-Antoine Arras <pa@codesourcery.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
2022-09-15 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/MAINTAINERS b/MAINTAINERS
index be14685..11fa8bc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -30,7 +30,7 @@ Richard Biener <rguenther@suse.de>
Richard Earnshaw <richard.earnshaw@arm.com>
Jakub Jelinek <jakub@redhat.com>
Richard Kenner <kenner@nyu.edu>
-Jeff Law <jeffreyalaw@gmail.com>
+Jeff Law <jlaw@ventanamicro.com>
Michael Meissner <gnu@the-meissners.org>
Jason Merrill <jason@redhat.com>
David S. Miller <davem@redhat.com>
@@ -316,6 +316,7 @@ from other maintainers or reviewers.
Mark G. Adams <mark.g.adams@sympatico.ca>
Pedro Alves <palves@redhat.com>
+Paul-Antoine Arras <pa@codesourcery.com>
Raksit Ashok <raksit@google.com>
Matt Austern <austern@google.com>
David Ayers <ayers@fsfe.org>
@@ -724,6 +725,7 @@ Matthias Kretz <m.kretz@gsi.de>
Tim Lange <mail@tim-lange.me>
Jeff Law <jeffreyalaw@gmail.com>
Jeff Law <jlaw@tachyum.com>
+Jeff Law <jlaw@ventanamicro.com>
Immad Mir <mir@sourceware.org>
Gaius Mulley <gaiusmod2@gmail.com>
Siddhesh Poyarekar <siddhesh@gotplt.org>
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index d76b1b4..c375530 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,8 @@
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * filter-clang-warnings.py: Skip egrep: warning: egrep is
+ obsolescent; using grep -E.
+
2022-08-31 Martin Liska <mliska@suse.cz>
* config-list.mk: Remove deprecated ports.
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6dded16..6890dd1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,516 @@
+2022-09-25 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+
+ * doc/sourcebuild.texi: Fix chapter level.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107001
+ * omp-low.cc (lower_omp_taskgroup): Don't add GOMP_RETURN statement
+ at the end.
+ * omp-expand.cc (build_omp_regions_1): Clarify GF_OMP_TARGET_KIND_DATA
+ is not stand-alone directive. For GIMPLE_OMP_TASKGROUP, also don't
+ update parent.
+ (omp_make_gimple_edges) <case GIMPLE_OMP_TASKGROUP>: Reset
+ cur_region back after new_omp_region.
+
+2022-09-23 Vineet Gupta <vineetg@rivosinc.com>
+
+ * config/riscv/riscv.h (LOCAL_SYM_P): New.
+ (USE_LOAD_ADDRESS_MACRO): Simplify by calling LOCAL_SYM_P.
+
+2022-09-23 zhongjuzhe <juzhe.zhong@rivai.ai>
+
+ * config/riscv/riscv-modes.def (VECTOR_BOOL_MODE): Add RVV mask modes.
+ (ADJUST_NUNITS): Adjust nunits using riscv_vector_chunks.
+ (ADJUST_ALIGNMENT): Adjust alignment.
+ (ADJUST_BYTESIZE): Adjust bytesize using riscv_vector_chunks.
+ (RVV_MODES): New macro.
+ (VECTOR_MODE_WITH_PREFIX): Add RVV vector modes.
+ (VECTOR_MODES_WITH_PREFIX): Add RVV vector modes.
+
+2022-09-23 zhongjuzhe <juzhe.zhong@rivai.ai>
+
+ * common/config/riscv/riscv-common.cc: Change "static void" to "void".
+ * config.gcc: Add riscv-selftests.o
+ * config/riscv/predicates.md: Allow const_poly_int.
+ * config/riscv/riscv-protos.h (riscv_reinit): New function.
+ (riscv_parse_arch_string): change as exten function.
+ (riscv_run_selftests): New function.
+ * config/riscv/riscv.cc (riscv_cannot_force_const_mem): Don't allow poly
+ into const pool.
+ (riscv_report_v_required): New function.
+ (riscv_expand_op): New function.
+ (riscv_expand_mult_with_const_int): New function.
+ (riscv_legitimize_poly_move): Ditto.
+ (riscv_legitimize_move): New function.
+ (riscv_hard_regno_mode_ok): Add VL/VTYPE register allocation and fix
+ vector RA.
+ (riscv_convert_vector_bits): Fix riscv_vector_chunks configuration for
+ -marh no 'v'.
+ (riscv_reinit): New function.
+ (TARGET_RUN_TARGET_SELFTESTS): New target hook support.
+ * config/riscv/t-riscv: Add riscv-selftests.o.
+ * config/riscv/riscv-selftests.cc: New file.
+
+2022-09-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106922
+ * tree-ssa-sccvn.cc (vn_reference_lookup_3): Allow
+ an arbitrary number of same valued skipped stores.
+
+2022-09-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::set): Swap setters such that the one
+ accepting REAL_VALUE_TYPE does all the work.
+
+2022-09-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-cores.def (neoverse-v2): New entry.
+ (demeter): Update tunings to neoversev2.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * config/aarch64/aarch64.cc (demeter_addrcost_table): Rename to
+ neoversev2_addrcost_table.
+ (demeter_regmove_cost): Rename to neoversev2_addrcost_table.
+ (demeter_advsimd_vector_cost): Rename to neoversev2_advsimd_vector_cost.
+ (demeter_sve_vector_cost): Rename to neoversev2_sve_vector_cost.
+ (demeter_scalar_issue_info): Rename to neoversev2_scalar_issue_info.
+ (demeter_advsimd_issue_info): Rename to neoversev2_advsimd_issue_info.
+ (demeter_sve_issue_info): Rename to neoversev2_sve_issue_info.
+ (demeter_vec_issue_info): Rename to neoversev2_vec_issue_info.
+ Update references to above.
+ (demeter_vector_cost): Rename to neoversev2_vector_cost.
+ (demeter_tunings): Rename to neoversev2_tunings.
+ (aarch64_vec_op_count::rename_cycles_per_iter): Use
+ neoversev2_sve_issue_info instead of demeter_sve_issue_info.
+ * doc/invoke.texi (AArch64 Options): Document neoverse-v2.
+
+2022-09-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * range-op-float.cc (build_le): Use vrp_val_*.
+ (build_lt): Same.
+ (build_ge): Same.
+ (build_gt): Same.
+ * value-range.cc (frange::set): Chop ranges outside of the
+ representable numbers for -ffinite-math-only.
+ (frange::normalize_kind): Use vrp_val*.
+ (frange::verify_range): Same.
+ (frange::set_nonnegative): Same.
+ (range_tests_floats): Remove tests that depend on -INF and +INF.
+ * value-range.h (real_max_representable): Add prototype.
+ (real_min_representable): Same.
+ (vrp_val_max): Set max representable number for
+ -ffinite-math-only.
+ (vrp_val_min): Same but for min.
+ (frange::set_varying): Use vrp_val*.
+
+2022-09-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * real.cc (debug): New.
+
+2022-09-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range-pretty-print.cc (vrange_printer::print_real_value): New.
+ (vrange_printer::visit): Call print_real_value.
+ * value-range-pretty-print.h: New print_real_value.
+
+2022-09-23 Martin Liska <mliska@suse.cz>
+
+ * common.opt: Update -flto-compression-level documentation.
+ * opts.cc (print_filtered_help): Do not append range to an
+ option that uses \t syntax.
+
+2022-09-23 Jakub Jelinek <jakub@redhat.com>
+
+ * attribs.cc (decl_attributes): Improve diagnostics, instead of
+ saying expected between 1 and 1, found 2 just say expected 1, found 2.
+
+2022-09-23 Hu, Lin1 <lin1.hu@intel.com>
+
+ PR target/94962
+ * config/i386/constraints.md (BH): New define_constraint.
+ * config/i386/i386.cc (standard_sse_constant_p): Add return
+ 3/4 when operand matches new predicate.
+ (standard_sse_constant_opcode): Add new alternative branch to
+ return "vpcmpeqd".
+ * config/i386/predicates.md
+ (vector_all_ones_zero_extend_half_operand): New define_predicate.
+ (vector_all_ones_zero_extend_quarter_operand): Ditto.
+ * config/i386/sse.md: Add constraint to insn "mov<mode>_internal".
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_range_op): Handle no operands.
+ (range_of_call): Do not check for builtins.
+ (fold_using_range::range_of_builtin_call): Delete.
+ (fold_using_range::range_of_builtin_int_call): Delete.
+ * gimple-range-fold.h: Adjust prototypes.
+ * gimple-range-op.cc (class cfn_parity): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_GOACC_DIM_*.
+ * gimple-range-op.cc (class cfn_goacc_dim): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_BUILT_IN_STRLEN.
+ * gimple-range-op.cc (class cfn_strlen): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_ubsan_call): Delete.
+ (range_of_builtin_int_call): Remove cases for
+ CFN_BUILT_IN_UBSAN_CHECK.
+ * gimple-range-op.cc (class cfn_ubsan): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_BUILT_IN_CLRSB.
+ * gimple-range-op.cc (class cfn_clrsb): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_CTZ.
+ * gimple-range-op.cc (class cfn_ctz): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_CLZ.
+ * gimple-range-op.cc (class cfn_clz): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_FFS and CFN_POPCOUNT.
+ * gimple-range-op.cc (class cfn_pocount): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (get_letter_range): Move to new class.
+ (range_of_builtin_int_call): Remove case for CFN_BUILT_IN_TOUPPER
+ and CFN_BUILT_IN_TOLOWER.
+ * gimple-range-op.cc (class cfn_toupper_tolower): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_builtin_int_call): Remove case
+ for CFN_BUILT_IN_SIGNBIT.
+ * gimple-range-op.cc (class cfn_signbit): New.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc
+ (fold_using_range::range_of_builtin_int_call): Remove case for
+ CFN_BUILT_IN_CONSTANT_P.
+ * gimple-range-op.cc (gimple_range_op_handler::supported_p):
+ Check if a call also creates a range-op object.
+ (gimple_range_op_handler): Also check builtin calls.
+ (class cfn_constant_float_p): New. Float CFN_BUILT_IN_CONSTANT_P.
+ (class cfn_constant_p): New. Integral CFN_BUILT_IN_CONSTANT_P.
+ (gimple_range_op_handler::maybe_builtin_call): Set arguments and
+ handler for supported built-in calls.
+ * gimple-range-op.h (maybe_builtin_call): New prototype.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-fold.cc (range_of_range_op): Set result to
+ VARYING if the call to fold_range fails.
+ * tree-data-ref.cc (compute_distributive_range): Ditto.
+ * tree-vrp.cc (range_fold_binary_expr): Ditto.
+ (range_fold_unary_expr): Ditto.
+ * value-query.cc (range_query::get_tree_range): Ditto.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * range-op-float.cc (range_operator_float::fold_range): New base
+ method for "int = float op int".
+ * range-op.cc (range_op_handler::fold_range): New case.
+ * range-op.h: Update prototypes.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * gimple-range-op.cc (gimple_range_op_handler::calc_op1): Use
+ operand 1 for second range if there is no operand 2.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * Makefile.in (OBJS): Add gimple-range-op.o.
+ * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Use
+ gimple_range_op_handler.
+ * gimple-range-fold.cc (gimple_range_base_of_assignment): Move
+ to a method in gimple_range_op_handler.
+ (gimple_range_operand1): Ditto.
+ (gimple_range_operand2): Ditto.
+ (fold_using_range::fold_stmt): Use gimple_range_op_handler.
+ (fold_using_range::range_of_range_op): Ditto.
+ (fold_using_range::relation_fold_and_or): Ditto.
+ (fur_source::register_outgoing_edges): Ditto.
+ (gimple_range_ssa_names): Relocate to gimple-range-op.cc.
+ * gimple-range-fold.h: Adjust prototypes.
+ * gimple-range-gori.cc (gimple_range_calc_op1): Move
+ to a method in gimple_range_op_handler.
+ (gimple_range_calc_op2): Ditto.
+ (gori_compute::compute_operand_range): Use
+ gimple_range_op_handler.
+ (gori_compute::compute_logical_operands): Ditto.
+ (compute_operand1_range): Ditto.
+ (gori_compute::compute_operand2_range): Ditto.
+ (gori_compute::compute_operand1_and_operand2_range): Ditto.
+ * gimple-range-gori.h: Adjust protoypes.
+ * gimple-range-op.cc: New. Supply gimple_range_op_handler methods.
+ * gimple-range-op.h: New. Supply gimple_range_op_handler class.
+ * gimple-range.cc (gimple_ranger::prefill_name): Use
+ gimple_range_op_handler.
+ (gimple_ranger::prefill_stmt_dependencies): Ditto.
+ * gimple-range.h: Include gimple-range-op.h.
+ * range-op.cc (range_op_handler::range_op_handler): Adjust and
+ remove gimple * parameter option.
+ * range-op.h: Adjust prototypes.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * range-op.cc (range_op_handler::set_op_handler): Set new fields.
+ (ange_op_handler::range_op_handler): Likewise.
+ (range_op_handler::operator bool): Remove.
+ (range_op_handler::fold_range): Use appropriate handler.
+ (range_op_handler::op1_range): Likewise.
+ (range_op_handler::op2_range): Likewise.
+ (range_op_handler::lhs_op1_relation): Likewise.
+ (range_op_handler::lhs_op2_relation): Likewise.
+ (range_op_handler::op1_op2_relation): Likewise.
+ * range-op.h (class range_op_handler): Store handler pointers.
+ (range_op_handler:: operator bool): Inline.
+
+2022-09-22 Andrew MacLeod <amacleod@redhat.com>
+
+ * tree-ssa-threadbackward.cc
+ (back_threader::find_paths_to_names): Replace sequence with
+ a call to gimple_range_ssa_names.
+
+2022-09-22 Martin Liska <mliska@suse.cz>
+ Fangrui Song <i@maskray.me>
+
+ * configure: Regenerate.
+ * configure.ac: Simplify to gcc_cv_ld_compress_debug={0,1}
+ and gcc_cv_as_compress_debug={0,1}.
+ * doc/invoke.texi: Document the removal.
+ * gcc.cc (LINK_COMPRESS_DEBUG_SPEC): Simplify and ignore
+ zlib-gnu.
+ (ASM_COMPRESS_DEBUG_SPEC): Likewise.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106922
+ * tree-ssa-sccvn.cc (vn_walk_cb_data::same_val): New member.
+ (vn_walk_cb_data::finish): Perform delayed verification of
+ a skipped may-alias.
+ (vn_reference_lookup_pieces): Likewise.
+ (vn_reference_lookup): Likewise.
+ (vn_reference_lookup_3): When skipping stores of the same
+ value also handle constant stores that are more than a
+ single VDEF away by delaying the verification.
+
+2022-09-22 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/xtensa/xtensa.cc (TARGET_MAX_ANCHOR_OFFSET): New
+ definition.
+
+2022-09-22 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/xtensa/xtensa.cc (xtensa_can_output_mi_thunk)
+ (xtensa_output_mi_thunk): New functions.
+ (TARGET_ASM_CAN_OUTPUT_MI_THUNK)
+ (TARGET_ASM_OUTPUT_MI_THUNK): New macro definitions.
+ (xtensa_prepare_expand_call): Use fixed register a8 as temporary
+ when called with reload_completed set to 1.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/99407
+ * tree-ssa-dse.cc (dse_stmt_to_dr_map): New global.
+ (dse_classify_store): Use data-ref analysis to disambiguate more uses.
+ (pass_dse::use_dr_analysis_p): New pass parameter.
+ (pass_dse::set_pass_param): Implement.
+ (pass_dse::execute): Allocate and deallocate dse_stmt_to_dr_map.
+ * passes.def: Allow DR analysis for the DSE pass before loop.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.cc (can_track_predicate_on_edge): New
+ function split out from ...
+ (vn_nary_op_insert_pieces_predicated): ... here.
+
+2022-09-22 liuhongt <hongtao.liu@intel.com>
+
+ PR target/106994
+ * config/i386/mmx.md (floorv2sf2): Fix typo, use
+ register_operand instead of vector_operand for operands[1].
+
+2022-09-21 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/106967
+ * value-range.cc (frange::set): Set known NANs to undefined for
+ flag_finite_math_only.
+
+2022-09-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::combine_zeros): Call set_undefined.
+ (frange::intersect_nans): Same.
+ (frange::intersect): Same.
+ (frange::verify_range): Undefined ranges do not have a type.
+ * value-range.h (frange::set_undefined): Clear NAN flags and type.
+
+2022-09-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106984
+ * tsan.cc (instrument_builtin_call): Build the COND_EXPR condition in
+ a separate statement.
+
+2022-09-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.h (HAVE_LOCAL_CPU_DETECT,
+ EXTRA_SPEC_FUNCTIONS, MCPU_MTUNE_NATIVE_SPECS): Move definitions up before
+ OPTION_DEFAULT_SPECS.
+ (MCPU_MTUNE_NATIVE_SPECS): Pass "cpu" to
+ local_cpu_detect when rewriting -march=native and no -mcpu or -mtune
+ is given.
+ (CONFIG_TUNE_SPEC): Define.
+ (OPTION_DEFAULT_SPECS): Use CONFIG_TUNE_SPEC for "tune".
+
+2022-09-21 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/106967
+ * range-op-float.cc (foperator_equal::fold_range): Adjust for NAN.
+ (foperator_equal::op1_range): Same.
+ (foperator_not_equal::fold_range): Same.
+ (foperator_not_equal::op1_range): Same.
+ (foperator_lt::fold_range): Same.
+ (foperator_lt::op1_range): Same.
+ (foperator_lt::op2_range): Same.
+ (foperator_le::fold_range): Same.
+ (foperator_le::op1_range): Same.
+ (foperator_le::op2_range): Same.
+ (foperator_gt::fold_range): Same.
+ (foperator_gt::op1_range): Same.
+ (foperator_gt::op2_range): Same.
+ (foperator_ge::fold_range): Same.
+ (foperator_ge::op1_range): Same.
+ (foperator_ge::op2_range): Same.
+ (foperator_unordered::op1_range): Same.
+ (foperator_ordered::fold_range): Same.
+ (foperator_ordered::op1_range): Same.
+ (build_le): Assert that we don't have a NAN.
+ (build_lt): Same.
+ (build_gt): Same.
+ (build_ge): Same.
+
+2022-09-21 liuhongt <hongtao.liu@intel.com>
+
+ PR tree-optimization/106963
+ * tree-vect-loop.cc (vect_create_nonlinear_iv_init): Use
+ vec_gen_perm_mask_any instead of vec_gen_perm_mask_check.
+
+2022-09-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.h (frange::maybe_isnan): Return false for
+ undefined ranges.
+
+2022-09-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::set_nonnegative): Set +NAN.
+ (range_tests_signed_zeros): New test.
+ * value-range.h (frange::update_nan): New overload to set NAN sign.
+
+2022-09-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/106491
+ * config/aarch64/aarch64-sve-builtins.cc (scalar_types)
+ (acle_vector_types, acle_svpattern, acle_svprfop): Add GTY
+ markup to (new) extern declarations instead of to the main
+ definition.
+
+2022-09-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR tree-optimization/106794
+ PR tree-optimization/106914
+ * tree-vect-slp.cc (vect_optimize_slp_pass::internal_node_cost):
+ Only consider loads that already have a permutation.
+ (vect_optimize_slp_pass::start_choosing_layouts): Assert that
+ loads with permutations are leaf nodes. Prevent any kind of grouped
+ access from changing layout if it doesn't have a load permutation.
+
+2022-09-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-vect-data-refs.cc (vect_check_gather_scatter): Restrict
+ early-out optimisation to SSA_NAMEs.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * ctfc.cc (ctf_add_string): Replace "the the" with "the".
+ * doc/md.texi: Likewise.
+ * gimple-range-infer.cc (non_null_loadstore): Likewise.
+
+2022-09-20 liuhongt <hongtao.liu@intel.com>
+
+ PR target/106910
+ * config/i386/mmx.md (nearbyintv2sf2): New expander.
+ (rintv2sf2): Ditto.
+ (ceilv2sf2): Ditto.
+ (lceilv2sfv2si2): Ditto.
+ (floorv2sf2): Ditto.
+ (lfloorv2sfv2si2): Ditto.
+ (btruncv2sf2): Ditto.
+ (lrintv2sfv2si2): Ditto.
+ (roundv2sf2): Ditto.
+ (lroundv2sfv2si2): Ditto.
+ (*mmx_roundv2sf2): New define_insn.
+
+2022-09-20 konglin1 <lingling.kong@intel.com>
+
+ PR middle-end/105735
+ * tree-scalar-evolution.cc
+ (analyze_and_compute_bitop_with_inv_effect): New function.
+ (final_value_replacement_loop): Enhanced to handle bitop
+ with inv induction.
+
+2022-09-20 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/gnu-user.h (GNU_USER_TARGET_LINK_SPEC): For
+ -static-pie, pass -static -pie --no-dynamic-linker -z text to
+ the linker, and do not pass --dynamic-linker.
+
+2022-09-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * value-range.cc (frange::flush_denormals_to_zero): New.
+ (frange::set): Call flush_denormals_to_zero.
+ * value-range.h (class frange): Add flush_denormals_to_zero.
+
+2022-09-20 liuhongt <hongtao.liu@intel.com>
+
+ * config/i386/x86-tune-sched.cc (ix86_issue_rate): Adjust for
+ latest Intel processors.
+
+2022-09-20 konglin1 <lingling.kong@intel.com>
+
+ PR target/106887
+ * config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
+ Fixed V16BF mode case.
+
2022-09-19 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
* targhooks.cc (default_zero_call_used_regs): Improve sorry
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 54f97aa..7764f7e 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220920
+20220926
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a4689d5..59b67d9 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1416,6 +1416,7 @@ OBJS = \
gimple-range-fold.o \
gimple-range-gori.o \
gimple-range-infer.o \
+ gimple-range-op.o \
gimple-range-trace.o \
gimple-ssa-backprop.o \
gimple-ssa-isolate-paths.o \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a1c4375..c48bbdf 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * exp_ch6.adb: Replace "the the" with "the".
+ * sem_ch6.adb: Likewise.
+ * sem_disp.ads: Likewise.
+
2022-09-15 Richard Biener <rguenther@suse.de>
* gcc-interface/trans.cc (gigi): Do not initialize void_list_node.
@@ -60,7 +66,7 @@
2022-09-12 Eric Botcazou <ebotcazou@adacore.com>
- * contracts.adb (uild_Subprogram_Contract_Wrapper): Remove useless
+ * contracts.adb (Build_Subprogram_Contract_Wrapper): Remove useless
local variable. In the case of a function, replace the extended
return statement by a block statement declaring a renaming of the
call to the local subprogram after removing side effects manually.
@@ -1173,14 +1179,14 @@
2022-09-02 Eric Botcazou <ebotcazou@adacore.com>
- * exp_util.adb (Expand_Subtype_From_Expr): Be prepared for
- rewritten aggregates as expressions.
+ * exp_util.adb (Expand_Subtype_From_Expr): Be prepared for rewritten
+ aggregates as expressions.
2022-09-02 Gary Dismukes <dismukes@adacore.com>
- * exp_ch6.adb (Expand_Simple_Function_Return) Bypass creation of an actual
- subtype and unchecked conversion to that subtype when the underlying type
- of the expression has discriminants without defaults.
+ * exp_ch6.adb (Expand_Simple_Function_Return) Bypass creation of an
+ actual subtype and unchecked conversion to that subtype when the
+ underlying type of the expression has discriminants without defaults.
2022-09-02 Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 2ae4ded..199dbe0 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -200,11 +200,7 @@ UINT __gnat_current_ccs_encoding;
#endif
/* wait.h processing */
-#ifdef __MINGW32__
-# if OLD_MINGW
-# include <sys/wait.h>
-# endif
-#elif defined (__vxworks) && defined (__RTP__)
+#if defined (__vxworks) && defined (__RTP__)
# include <wait.h>
#elif defined (__Lynx__)
/* ??? We really need wait.h and it includes resource.h on Lynx. GCC
@@ -214,7 +210,7 @@ UINT __gnat_current_ccs_encoding;
preventing the inclusion of the GCC header from doing anything. */
# define GCC_RESOURCE_H
# include <sys/wait.h>
-#elif defined (__PikeOS__)
+#elif defined (__PikeOS__) || defined (__MINGW32__)
/* No wait() or waitpid() calls available. */
#else
/* Default case. */
@@ -335,11 +331,6 @@ const char *__gnat_library_template = GNAT_LIBRARY_TEMPLATE;
#if defined (__MINGW32__)
#include "mingw32.h"
-
-#if OLD_MINGW
-#include <sys/param.h>
-#endif
-
#else
#include <sys/param.h>
#endif
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index b2fa44d..f2aaa2d 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -134,9 +134,6 @@ package body Bindgen is
-- Text for aspect specifications (if any) given as part of the
-- Adainit and Adafinal spec declarations.
- function Aspect_Text return String is
- (if Enable_CUDA_Device_Expansion then " with CUDA_Global" else "");
-
----------------------------------
-- Interface_State Pragma Table --
----------------------------------
@@ -2644,10 +2641,11 @@ package body Bindgen is
end if;
WBI ("");
- WBI (" procedure " & Ada_Init_Name.all & Aspect_Text & ";");
+ WBI (" procedure " & Ada_Init_Name.all & ";");
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Init_Name.all &
", Link_Name => """ & Device_Ada_Init_Link_Name & """);");
+ WBI (" pragma CUDA_Global (" & Ada_Init_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Init_Name.all & ", """ &
Ada_Init_Name.all & """);");
@@ -2662,11 +2660,12 @@ package body Bindgen is
if not Cumulative_Restrictions.Set (No_Finalization) then
WBI ("");
- WBI (" procedure " & Ada_Final_Name.all & Aspect_Text & ";");
+ WBI (" procedure " & Ada_Final_Name.all & ";");
if Enable_CUDA_Device_Expansion then
WBI (" pragma Export (C, " & Ada_Final_Name.all &
", Link_Name => """ & Device_Ada_Final_Link_Name & """);");
+ WBI (" pragma CUDA_Global (" & Ada_Final_Name.all & ");");
else
WBI (" pragma Export (C, " & Ada_Final_Name.all & ", """ &
Ada_Final_Name.all & """);");
diff --git a/gcc/ada/cal.c b/gcc/ada/cal.c
index e1ab692..09bcc15 100644
--- a/gcc/ada/cal.c
+++ b/gcc/ada/cal.c
@@ -53,10 +53,8 @@
#ifdef __MINGW32__
#include "mingw32.h"
-#if STD_MINGW
#include <winsock.h>
#endif
-#endif
void
__gnat_timeval_to_duration (struct timeval *t, long long *sec, long *usec)
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index 34db67a..dd573d3 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -1207,7 +1207,7 @@ package body Contracts is
-- A Ghost object cannot be effectively volatile (SPARK RM 6.9(7) and
-- SPARK RM 6.9(19)).
- elsif Is_Effectively_Volatile (Obj_Id) then
+ elsif SPARK_Mode = On and then Is_Effectively_Volatile (Obj_Id) then
Error_Msg_N ("ghost object & cannot be volatile", Obj_Id);
-- A Ghost object cannot be imported or exported (SPARK RM 6.9(7)).
diff --git a/gcc/ada/cstreams.c b/gcc/ada/cstreams.c
index 10cc3a6..fc583e1 100644
--- a/gcc/ada/cstreams.c
+++ b/gcc/ada/cstreams.c
@@ -97,14 +97,6 @@ extern "C" {
#undef fileno
#endif
-/* The _IONBF value in MINGW32 stdio.h is wrong. */
-#if defined (WINNT) || defined (_WINNT)
-#if OLD_MINGW
-#undef _IONBF
-#define _IONBF 0004
-#endif
-#endif
-
int
__gnat_feof (FILE *stream)
{
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index c25e3d4..d839b1f 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -1623,13 +1623,13 @@ Multi-dimensional arrays can be modified, as shown by this example:
which changes element (1,2) to 20 and (3,4) to 30.
-Attribute Valid_Image
+Attribute Valid_Value
=======================
-.. index:: Valid_Image
+.. index:: Valid_Value
-The ``'Valid_Image`` attribute is defined for enumeration types other than
+The ``'Valid_Value`` attribute is defined for enumeration types other than
those in package Standard. This attribute is a function that takes
-a String, and returns Boolean. ``T'Valid_Image (S)`` returns True
+a String, and returns Boolean. ``T'Valid_Value (S)`` returns True
if and only if ``T'Value (S)`` would not raise Constraint_Error.
Attribute Valid_Scalars
diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
index 6a47809..d4bddff 100644
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -1719,6 +1719,7 @@ Alphabetical List of All Switches
Float_Words_BE : Nat; -- Float words stored big-endian?
Int_Size : Pos; -- Standard.Integer'Size
Long_Double_Size : Pos; -- Standard.Long_Long_Float'Size
+ Long_Long_Long_Size : Pos; -- Standard.Long_Long_Long_Integer'Size
Long_Long_Size : Pos; -- Standard.Long_Long_Integer'Size
Long_Size : Pos; -- Standard.Long_Integer'Size
Maximum_Alignment : Pos; -- Maximum permitted alignment
@@ -1816,6 +1817,7 @@ Alphabetical List of All Switches
Float_Words_BE 0
Int_Size 64
Long_Double_Size 128
+ Long_Long_Long_Size 128
Long_Long_Size 64
Long_Size 64
Maximum_Alignment 16
@@ -6229,11 +6231,33 @@ Linker switches can be specified after :switch:`-largs` builder switch.
.. index:: -fuse-ld=name
:switch:`-fuse-ld={name}`
- Linker to be used. The default is ``bfd`` for :file:`ld.bfd`,
- the alternative being ``gold`` for :file:`ld.gold`. The later is
- a more recent and faster linker, but only available on GNU/Linux
+ Linker to be used. The default is ``bfd`` for :file:`ld.bfd`; ``gold``
+ (for :file:`ld.gold`) and ``mold`` (for :file:`ld.mold`) are more
+ recent and faster alternatives, but only available on GNU/Linux
platforms.
+ .. only:: PRO
+
+ The GNAT distribution for native Linux platforms includes ``mold``,
+ compiled against OpenSSL version 1.1; however, the distribution does
+ not include OpenSSL. In order to use this linker, you may either:
+
+ * use your system's OpenSSL library, if the version matches: in this
+ situation, you need not do anything beside using the
+ :switch:`-fuse-ld=mold` switch,
+
+ * obtain a source distribution for OpenSSL 1.1, compile the
+ :file:`libcrypto.so` library and install it in the directory of
+ your choice, then include this directory in the
+ :envvar:`LD_LIBRARY_PATH` environment variable,
+
+ * install another copy of ``mold`` by other means in the directory
+ of your choice, and include this directory in the :envvar:`PATH`
+ environment variable; you may find this alternative preferable if
+ the copy of ``mold`` included in GNAT does not suit your needs
+ (e.g. being able to link against your system's OpenSSL, or using
+ another version of ``mold``).
+
.. _Binding_with_gnatbind:
Binding with ``gnatbind``
diff --git a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
index d670839..92877a2 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
@@ -15,7 +15,6 @@ This chapter describes a number of utility programs:
* :ref:`The_File_Cleanup_Utility_gnatclean`
* :ref:`The_GNAT_Library_Browser_gnatls`
* :ref:`The_Coding_Standard_Verifier_gnatcheck`
- * :ref:`The_GNAT_Metrics_Tool_gnatmetric`
* :ref:`The_GNAT_Pretty_Printer_gnatpp`
* :ref:`The_Body_Stub_Generator_gnatstub`
* :ref:`The_Backtrace_Symbolizer_gnatsymbolize`
@@ -487,1123 +486,6 @@ building specialized scripts.
For full details, plese refer to :title:`GNATcheck Reference Manual`.
-
-.. only:: PRO or GPL
-
- .. _The_GNAT_Metrics_Tool_gnatmetric:
-
- The GNAT Metrics Tool ``gnatmetric``
- ====================================
-
- .. index:: ! gnatmetric
- .. index:: Metric tool
-
- The ``gnatmetric`` tool is a utility
- for computing various program metrics.
- It takes an Ada source file as input and generates a file containing the
- metrics data as output. Various switches control which
- metrics are reported.
-
- ``gnatmetric`` is a project-aware tool
- (see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
- ``gnatmetric`` switches is named ``Metrics``.
-
- The ``gnatmetric`` command has the form
-
- ::
-
- $ gnatmetric [ switches ] { filename }
-
- where:
-
- * ``switches`` specify the metrics to compute and define the destination for
- the output
-
- * Each ``filename`` is the name of a source file to process. 'Wildcards' are
- allowed, and the file name may contain path information. If no
- ``filename`` is supplied, then the ``switches`` list must contain at least
- one :switch:`--files` switch (see :ref:`Other_gnatmetric_Switches`).
- Including both a :switch:`--files` switch and one or more ``filename``
- arguments is permitted.
-
- Note that it is no longer necessary to specify the Ada language version;
- ``gnatmetric`` can process Ada source code written in any version from
- Ada 83 onward without specifying any language version switch.
-
- The following subsections describe the various switches accepted by
- ``gnatmetric``, organized by category.
-
- .. _Output_File_Control-gnatmetric:
-
- Output File Control
- -------------------
-
- .. index:: Output file control in gnatmetric
-
- ``gnatmetric`` has two output formats. It can generate a
- textual (human-readable) form, and also XML. By default only textual
- output is generated.
-
- When generating the output in textual form, ``gnatmetric`` creates
- for each Ada source file a corresponding text file
- containing the computed metrics, except for the case when the set of metrics
- specified by gnatmetric parameters consists only of metrics that are computed
- for the whole set of analyzed sources, but not for each Ada source.
- By default, the name of the file containing metric information for a source
- is obtained by appending the :file:`.metrix` suffix to the
- name of the input source file. If not otherwise specified and no project file
- is specified as ``gnatmetric`` option this file is placed in the same
- directory as where the source file is located. If ``gnatmetric`` has a
- project file as its parameter, it places all the generated files in the
- object directory of the project (or in the project source directory if the
- project does not define an object directory). If :switch:`--subdirs` option
- is specified, the files are placed in the subrirectory of this directory
- specified by this option.
-
- All the output information generated in XML format is placed in a single
- file. By default the name of this file is :file:`metrix.xml`.
- If not otherwise specified and if no project file is specified
- as ``gnatmetric`` option this file is placed in the
- current directory.
-
- Some of the computed metrics are summed over the units passed to
- ``gnatmetric``; for example, the total number of lines of code.
- By default this information is sent to :file:`stdout`, but a file
- can be specified with the :switch:`--global-file-name` switch.
-
- The following switches control the ``gnatmetric`` output:
-
- .. index:: --generate-xml-output (gnatmetric)
-
- :switch:`--generate-xml-output`
- Generate XML output.
-
- .. index:: --generate-xml-schema (gnatmetric)
-
- :switch:`--generate-xml-schema`
- Generate XML output and an XML schema file that describes the structure
- of the XML metric report. This schema is assigned to the XML file. The schema
- file has the same name as the XML output file with :file:`.xml` suffix replaced
- with :file:`.xsd`.
-
- .. index:: --no-text-output (gnatmetric)
-
-
- :switch:`--no-text-output`
- Do not generate the output in text form (implies :switch:`-x`).
-
- .. index:: --output-dir (gnatmetric)
-
-
- :switch:`--output-dir={output_dir}`
- Put text files with detailed metrics into ``output_dir``.
-
- .. index:: --output-suffix (gnatmetric)
-
-
- :switch:`--output-suffix={file_suffix}`
- Use ``file_suffix``, instead of :file:`.metrix`
- in the name of the output file.
-
- .. index:: --global-file-name (gnatmetric)
-
- :switch:`--global-file-name={file_name}`
- Put global metrics into ``file_name``.
-
- .. index:: --xml-file-name (gnatmetric)
-
-
- :switch:`--xml-file-name={file_name}`
- Put the XML output into ``file_name``
- (also implies :switch:`--generate-xml-output`).
-
- .. index:: --short-file-names (gnatmetric)
-
- :switch:`--short-file-names`
- Use 'short' source file names in the output. (The ``gnatmetric``
- output includes the name(s) of the Ada source file(s) from which the
- metrics are computed. By default each name includes the absolute
- path. The :switch:`--short-file-names` switch causes ``gnatmetric``
- to exclude all directory information from the file names that are
- output.)
-
- .. index:: --wide-character-encoding (gnatmetric)
-
- :switch:`--wide-character-encoding={e}`
- Specify the wide character encoding method for the input and output
- files. ``e`` is one of the following:
-
- * *8* - UTF-8 encoding
-
- * *b* - Brackets encoding (default value)
-
-
- .. index:: Disable Metrics For Local Units in gnatmetric
-
- .. _Disable_Metrics_For_Local_Units:
-
- Disable Metrics For Local Units
- -------------------------------
-
- ``gnatmetric`` relies on the GNAT compilation model --
- one compilation
- unit per one source file. It computes line metrics for the whole source
- file, and it also computes syntax
- and complexity metrics for the file's outermost unit.
-
- By default, ``gnatmetric`` will also compute all metrics for certain
- kinds of locally declared program units:
-
- * subprogram (and generic subprogram) bodies;
-
- * package (and generic package) specs and bodies;
-
- * task object and type specifications and bodies;
-
- * protected object and type specifications and bodies.
-
- .. index:: Eligible local unit (for gnatmetric)
-
- These kinds of entities will be referred to as
- *eligible local program units*, or simply *eligible local units*,
- in the discussion below.
-
- Note that a subprogram declaration, generic instantiation,
- or renaming declaration only receives metrics
- computation when it appear as the outermost entity
- in a source file.
-
- Suppression of metrics computation for eligible local units can be
- obtained via the following switch:
-
-
- .. index:: --no-local-metrics (gnatmetric)
-
-
- :switch:`--no-local-metrics`
- Do not compute detailed metrics for eligible local program units.
-
-
- .. _Specifying_a_set_of_metrics_to_compute:
-
- Specifying a set of metrics to compute
- --------------------------------------
-
- By default all the metrics are reported. The switches described in this
- subsection allow you to control, on an individual basis, whether metrics are
- reported. If at least one positive metric switch is specified (that is, a
- switch that defines that a given metric or set of metrics is to be computed),
- then only explicitly specified metrics are reported.
-
- .. _Line_Metrics_Control:
-
- Line Metrics Control
- ^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Line metrics control in gnatmetric
-
- For each source file, and for each of its eligible local program
- units, ``gnatmetric`` computes the following metrics:
-
- * the total number of lines;
-
- * the total number of code lines (i.e., non-blank lines that are not
- comments)
-
- * the number of comment lines
-
- * the number of code lines containing end-of-line comments;
-
- * the comment percentage: the ratio between the number of lines that
- contain comments and the number of all non-blank lines, expressed as
- a percentage
-
- * the number of empty lines and lines containing only space characters
- and/or format effectors (blank lines)
-
- * the average number of code lines in subprogram bodies, task bodies,
- entry bodies and statement sequences in package bodies
-
- ``gnatmetric`` sums the values of the line metrics for all the files
- being processed and then generates the cumulative results. The tool
- also computes for all the files being processed the average number of
- code lines in bodies.
-
- You can use the following switches to select the specific line metrics
- to be reported.
-
-
- .. index:: --lines (gnatmetric)
- .. index:: --no-lines (gnatmetric)
-
-
- :switch:`--lines-all`
- Report all the line metrics
-
-
- :switch:`--no-lines-all`
- Do not report any of line metrics
-
-
- :switch:`--lines`
- Report the number of all lines
-
-
- :switch:`--no-lines`
- Do not report the number of all lines
-
-
- :switch:`--lines-code`
- Report the number of code lines
-
-
- :switch:`--no-lines-code`
- Do not report the number of code lines
-
-
- :switch:`--lines-comment`
- Report the number of comment lines
-
-
- :switch:`--no-lines-comment`
- Do not report the number of comment lines
-
-
- :switch:`--lines-eol-comment`
- Report the number of code lines containing
- end-of-line comments
-
-
- :switch:`--no-lines-eol-comment`
- Do not report the number of code lines containing
- end-of-line comments
-
-
- :switch:`--lines-ratio`
- Report the comment percentage in the program text
-
-
- :switch:`--no-lines-ratio`
- Do not report the comment percentage in the program text
-
-
- :switch:`--lines-blank`
- Report the number of blank lines
-
-
- :switch:`--no-lines-blank`
- Do not report the number of blank lines
-
-
- :switch:`--lines-average`
- Report the average number of code lines in subprogram bodies, task bodies,
- entry bodies and statement sequences in package bodies.
-
-
- :switch:`--no-lines-average`
- Do not report the average number of code lines in subprogram bodies,
- task bodies, entry bodies and statement sequences in package bodies.
-
-
- :switch:`--lines-spark`
- Report the number of lines written in SPARK.
-
-
- :switch:`--no-lines-spark`
- Do not report the number of lines written in SPARK.
-
-
- .. _Syntax_Metrics_Control:
-
- Syntax Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Syntax metrics control in gnatmetric
-
- ``gnatmetric`` computes various syntactic metrics for the
- outermost unit and for each eligible local unit:
-
- * *LSLOC ('Logical Source Lines Of Code')*
- The total number of declarations and the total number of
- statements. Note that the definition of declarations is the one
- given in the reference manual:
-
- "Each of the following is defined to be a declaration: any
- basic_declaration; an enumeration_literal_specification; a
- discriminant_specification; a component_declaration; a
- loop_parameter_specification; a parameter_specification; a
- subprogram_body; an entry_declaration; an
- entry_index_specification; a choice_parameter_specification; a
- generic_formal_parameter_declaration."
-
- This means for example that each enumeration literal adds one to
- the count, as well as each subprogram parameter.
-
- * *Maximal static nesting level of inner program units*
- According to :title:`Ada Reference Manual`, 10.1(1):
-
- "A program unit is either a package, a task unit, a protected
- unit, a protected entry, a generic unit, or an explicitly
- declared subprogram other than an enumeration literal."
-
- * *Maximal nesting level of composite syntactic constructs*
- This corresponds to the notion of the maximum nesting level in the
- GNAT built-in style checks (see :ref:`Style_Checking`).
-
- * *Number of formal parameters*
- Number of formal parameters of a subprogram; if a subprogram does
- have parameters, then numbers of "in", "out" and "in out"
- parameters are also reported. This metric is reported for
- subprogram specifications and for subprogram instantiations. For
- subprogram bodies, expression functions and null procedures this
- metric is reported if the construct acts as a subprogram
- declaration but is not a completion of previous declaration. This
- metric is not reported for generic and formal subprograms.
-
- For the outermost unit in the file, ``gnatmetric`` additionally
- computes the following metrics:
-
- * *Public subprograms*
- This metric is computed for package specs. It is the number of
- subprograms and generic subprograms declared in the visible part
- (including the visible part of nested packages, protected objects,
- and protected types).
-
-
- * *All subprograms*
- This metric is computed for bodies and subunits. The metric is
- equal to a total number of subprogram bodies in the compilation
- unit.
- Neither generic instantiations nor renamings-as-a-body nor body
- stubs are counted. Any subprogram body is counted, independently
- of its nesting level and enclosing constructs. Generic bodies and
- bodies of protected subprograms are counted in the same way as
- 'usual' subprogram bodies.
-
-
- * *Public types*
- This metric is computed for package specs and generic package
- declarations. It is the total number of types that can be
- referenced from outside this compilation unit, plus the number of
- types from all the visible parts of all the visible generic
- packages. Generic formal types are not counted. Only types, not
- subtypes, are included.
-
- Along with the total number of public types, the following
- types are counted and reported separately:
-
- * *Abstract types*
-
- * *Root tagged types^ (abstract, non-abstract, private,
- non-private). Type extensions are *not* counted
-
- * *Private types* (including private extensions)
-
- * *Task types*
-
- * *Protected types*
-
- * *All types*
- This metric is computed for any compilation unit. It is equal to
- the total number of the declarations of different types given in
- the compilation unit. The private and the corresponding full type
- declaration are counted as one type declaration. Incomplete type
- declarations and generic formal types are not counted.
- No distinction is made among different kinds of types (abstract,
- private etc.); the total number of types is reported.
-
- By default, all the syntax metrics are reported. You can use the following
- switches to select specific syntax metrics.
-
-
- .. index:: --syntax (gnatmetric)
- .. index:: --no-syntax (gnatmetric)
-
-
- :switch:`--syntax-all`
- Report all the syntax metrics
-
-
- :switch:`--no-syntax-all`
- Do not report any of syntax metrics
-
-
- :switch:`--declarations`
- Report the total number of declarations
-
-
- :switch:`--no-declarations`
- Do not report the total number of declarations
-
-
- :switch:`--statements`
- Report the total number of statements
-
-
- :switch:`--no-statements`
- Do not report the total number of statements
-
-
- :switch:`--public-subprograms`
- Report the number of public subprograms in a compilation unit
-
-
- :switch:`--no-public-subprograms`
- Do not report the number of public subprograms in a compilation unit
-
-
- :switch:`--all-subprograms`
- Report the number of all the subprograms in a compilation unit
-
-
- :switch:`--no-all-subprograms`
- Do not report the number of all the subprograms in a compilation unit
-
-
- :switch:`--public-types`
- Report the number of public types in a compilation unit
-
-
- :switch:`--no-public-types`
- Do not report the number of public types in a compilation unit
-
-
- :switch:`--all-types`
- Report the number of all the types in a compilation unit
-
-
- :switch:`--no-all-types`
- Do not report the number of all the types in a compilation unit
-
-
- :switch:`--unit-nesting`
- Report the maximal program unit nesting level
-
-
- :switch:`--no-unit-nesting`
- Do not report the maximal program unit nesting level
-
-
- :switch:`--construct-nesting`
- Report the maximal construct nesting level
-
-
- :switch:`--no-construct-nesting`
- Do not report the maximal construct nesting level
-
- :switch:`--param-number`
- Report the number of subprogram parameters
-
-
- :switch:`--no-param-number`
- Do not report the number of subprogram parameters
-
-
- .. _Contract_Metrics_Control:
-
- Contract Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Contract metrics control in gnatmetric
-
- :switch:`--contract-all`
- Report all the contract metrics
-
-
- :switch:`--no-contract-all`
- Do not report any of the contract metrics
-
-
- :switch:`--contract`
- Report the number of public subprograms with contracts
-
-
- :switch:`--no-contract`
- Do not report the number of public subprograms with contracts
-
-
- :switch:`--post`
- Report the number of public subprograms with postconditions
-
-
- :switch:`--no-post`
- Do not report the number of public subprograms with postconditions
-
-
- :switch:`--contract-complete`
- Report the number of public subprograms with complete contracts
-
-
- :switch:`--no-contract-complete`
- Do not report the number of public subprograms with complete contracts
-
-
- :switch:`--contract-cyclomatic`
- Report the McCabe complexity of public subprograms
-
-
- :switch:`--no-contract-cyclomatic`
- Do not report the McCabe complexity of public subprograms
-
-
- .. _Complexity_Metrics_Control:
-
- Complexity Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Complexity metrics control in gnatmetric
-
- For a program unit that is an executable body (a subprogram body
- (including generic bodies), task body, entry body or a package body
- containing its own statement sequence) ``gnatmetric`` computes the
- following complexity metrics:
-
- * McCabe cyclomatic complexity;
-
- * McCabe essential complexity;
-
- * maximal loop nesting level;
-
- * extra exit points (for subprograms);
-
- The McCabe cyclomatic complexity metric is defined
- in `http://www.mccabe.com/pdf/mccabe-nist235r.pdf <http://www.mccabe.com/pdf/mccabe-nist235r.pdf>`_
-
- According to McCabe, both control statements and short-circuit control
- forms should be taken into account when computing cyclomatic
- complexity. For Ada 2012 we have also take into account conditional
- expressions and quantified expressions. For each body, we compute
- three metric values:
-
- * the complexity introduced by control
- statements only, without taking into account short-circuit forms
- (referred as ``statement complexity`` in ``gnatmetric`` output),
-
- * the complexity introduced by short-circuit control forms only
- (referred as ``expression complexity`` in ``gnatmetric`` output),
- and
-
- * the total
- cyclomatic complexity, which is the sum of these two values
- (referred as ``cyclomatic complexity`` in ``gnatmetric`` output).
-
- The cyclomatic complexity is also computed for Ada 2012 expression functions.
- An expression function cannot have statements as its components, so only one
- metric value is computed as a cyclomatic complexity of an expression function.
-
- The origin of cyclomatic complexity metric is the need to estimate the number
- of independent paths in the control flow graph that in turn gives the number
- of tests needed to satisfy paths coverage testing completeness criterion.
- Considered from the testing point of view, a static Ada ``loop`` (that is,
- the ``loop`` statement having static subtype in loop parameter
- specification) does not add to cyclomatic complexity. By providing
- :switch:`--no-static-loop` option a user
- may specify that such loops should not be counted when computing the
- cyclomatic complexity metric
-
- The Ada essential complexity metric is a McCabe cyclomatic complexity metric
- counted for the code that is reduced by excluding all the pure structural Ada
- control statements. An compound statement is considered as a non-structural
- if it contains a ``raise`` or ``return`` statement as it subcomponent,
- or if it contains a ``goto`` statement that transfers the control outside
- the operator. A selective ``accept`` statement with a ``terminate`` alternative
- is considered a non-structural statement. When computing this metric,
- ``exit`` statements are treated in the same way as ``goto``
- statements unless the :switch:`-ne` option is specified.
-
- The Ada essential complexity metric defined here is intended to quantify
- the extent to which the software is unstructured. It is adapted from
- the McCabe essential complexity metric defined in
- http://www.mccabe.com/pdf/mccabe-nist235r.pdf
- but is modified to be more
- suitable for typical Ada usage. For example, short circuit forms
- are not penalized as unstructured in the Ada essential complexity metric.
-
- When computing cyclomatic and essential complexity, ``gnatmetric`` skips
- the code in the exception handlers and in all the nested program units. The
- code of assertions and predicates (that is, subprogram preconditions and
- postconditions, subtype predicates and type invariants) is also skipped.
-
- By default, all the complexity metrics are reported. For more fine-grained
- control you can use the following switches:
-
-
- .. index:: --complexity (gnatmetric)
- .. index:: --no-complexity (gnatmetric)
-
-
- :switch:`--complexity-all`
- Report all the complexity metrics
-
-
- :switch:`--no-complexity-all`
- Do not report any of the complexity metrics
-
-
- :switch:`--complexity-cyclomatic`
- Report the McCabe Cyclomatic Complexity
-
-
- :switch:`--no-complexity-cyclomatic`
- Do not report the McCabe Cyclomatic Complexity
-
-
- :switch:`--complexity-essential`
- Report the Essential Complexity
-
-
- :switch:`--no-complexity-essential`
- Do not report the Essential Complexity
-
-
- :switch:`--loop-nesting`
- Report maximal loop nesting level
-
-
- :switch:`--no-loop-nesting`
- Do not report maximal loop nesting level
-
-
- :switch:`--complexity-average`
- Report the average McCabe Cyclomatic Complexity for all the subprogram bodies,
- task bodies, entry bodies and statement sequences in package bodies.
- The metric is reported for whole set of processed Ada sources only.
-
-
- :switch:`--no-complexity-average`
- Do not report the average McCabe Cyclomatic Complexity for all the subprogram
- bodies, task bodies, entry bodies and statement sequences in package bodies
-
- .. index:: --no-treat-exit-as-goto (gnatmetric)
-
-
- :switch:`--no-treat-exit-as-goto`
- Do not consider ``exit`` statements as ``goto``\ s when
- computing Essential Complexity
-
- .. index:: --no-static-loop (gnatmetric)
-
-
- :switch:`--no-static-loop`
- Do not consider static loops when computing cyclomatic complexity
-
-
- :switch:`--extra-exit-points`
- Report the extra exit points for subprogram bodies. As an exit point, this
- metric counts ``return`` statements and raise statements in case when the
- raised exception is not handled in the same body. In case of a function this
- metric subtracts 1 from the number of exit points, because a function body
- must contain at least one ``return`` statement.
-
-
- :switch:`--no-extra-exit-points`
- Do not report the extra exit points for subprogram bodies
-
-
- .. _Coupling_Metrics_Control:
-
- Coupling Metrics Control
- ^^^^^^^^^^^^^^^^^^^^^^^^
-
- .. index:: Coupling metrics control in gnatmetric
-
- .. index:: Coupling metrics (in gnatmetric)
-
- Coupling metrics measure the dependencies between a given entity and other
- entities in the program. This information is useful since high coupling
- may signal potential issues with maintainability as the program evolves.
-
- ``gnatmetric`` computes the following coupling metrics:
-
-
- * *object-oriented coupling*, for classes in traditional object-oriented
- sense;
-
- * *unit coupling*, for all the program units making up a program;
-
- * *control coupling*, reflecting dependencies between a unit and
- other units that contain subprograms.
-
- .. index:: fan-out coupling
- .. index:: efferent coupling
-
- Two kinds of coupling metrics are computed:
-
- * fan-out coupling ('efferent coupling'):
- the number of entities the given entity depends upon. This metric
- reflects how the given entity depends on the changes in the
- 'external world'.
-
- .. index:: fan-in coupling
- .. index:: afferent coupling
-
- * fan-in coupling ('afferent' coupling):
- the number of entities that depend on a given entity.
- This metric reflects how the 'external world' depends on the changes in a
- given entity.
-
- Object-oriented coupling metrics measure the dependencies
- between a given class (or a group of classes) and the other classes in the
- program. In this subsection the term 'class' is used in its traditional
- object-oriented programming sense (an instantiable module that contains data
- and/or method members). A *category* (of classes) is a group of closely
- related classes that are reused and/or modified together.
-
- A class ``K``\ 's fan-out coupling is the number of classes
- that ``K`` depends upon.
- A category's fan-out coupling is the number of classes outside the
- category that the classes inside the category depend upon.
-
- A class ``K``\ 's fan-in coupling is the number of classes
- that depend upon ``K``.
- A category's fan-in coupling is the number of classes outside the
- category that depend on classes belonging to the category.
-
- Ada's object-oriented paradigm separates the instantiable entity
- (type) from the module (package), so the definition of the coupling
- metrics for Ada maps the class and class category notions
- onto Ada constructs.
-
- For the coupling metrics, several kinds of modules that define a tagged type
- or an interface type -- library packages, library generic packages, and
- library generic package instantiations -- are considered to be classes.
- A category consists of a library package (or
- a library generic package) that defines a tagged or an interface type,
- together with all its descendant (generic) packages that define tagged
- or interface types. Thus a
- category is an Ada hierarchy of library-level program units. Class
- coupling in Ada is referred to as 'tagged coupling', and category coupling
- is referred to as 'hierarchy coupling'.
-
- For any package serving as a class, its body and subunits (if any) are
- considered together with its spec when computing dependencies, and coupling
- metrics are reported for spec units only. Dependencies between classes
- mean Ada semantic dependencies. For object-oriented coupling
- metrics, only dependencies on units treated as classes are
- considered.
-
- Similarly, for unit and control coupling an entity is considered to be the
- conceptual construct consisting of the entity's specification, body, and
- any subunits (transitively).
- ``gnatmetric`` computes
- the dependencies of all these units as a whole, but
- metrics are only reported for spec
- units (or for a subprogram body unit in case if there is no
- separate spec for the given subprogram).
-
- For unit coupling, dependencies are computed between all kinds of program
- units. For control coupling, the dependencies of a given unit are limited to
- those units that define subprograms. Thus control fan-out coupling is reported
- for all units, but control fan-in coupling is only reported for units
- that define subprograms.
-
- The following simple example illustrates the difference between unit coupling
- and control coupling metrics:
-
- .. code-block:: ada
-
- package Lib_1 is
- function F_1 (I : Integer) return Integer;
- end Lib_1;
-
- package Lib_2 is
- type T_2 is new Integer;
- end Lib_2;
-
- package body Lib_1 is
- function F_1 (I : Integer) return Integer is
- begin
- return I + 1;
- end F_1;
- end Lib_1;
-
- with Lib_2; use Lib_2;
- package Pack is
- Var : T_2;
- function Fun (I : Integer) return Integer;
- end Pack;
-
- with Lib_1; use Lib_1;
- package body Pack is
- function Fun (I : Integer) return Integer is
- begin
- return F_1 (I);
- end Fun;
- end Pack;
-
- If we apply ``gnatmetric`` with the :switch:`--coupling-all` option to
- these units, the result will be:
-
- ::
-
- Coupling metrics:
- =================
- Unit Lib_1 (C:\\customers\\662\\L406-007\\lib_1.ads)
- control fan-out coupling : 0
- control fan-in coupling : 1
- unit fan-out coupling : 0
- unit fan-in coupling : 1
-
- Unit Pack (C:\\customers\\662\\L406-007\\pack.ads)
- control fan-out coupling : 1
- control fan-in coupling : 0
- unit fan-out coupling : 2
- unit fan-in coupling : 0
-
- Unit Lib_2 (C:\\customers\\662\\L406-007\\lib_2.ads)
- control fan-out coupling : 0
- unit fan-out coupling : 0
- unit fan-in coupling : 1
-
- The result does not contain values for object-oriented
- coupling because none of the argument units contains a tagged type and
- therefore none of these units can be treated as a class.
-
- The ``Pack`` package (spec and body) depends on two
- units -- ``Lib_1`` and ``Lib_2`` -- and so its unit fan-out coupling
- is 2. Since nothing depends on it, its unit fan-in coupling is 0, as
- is its control fan-in coupling. Only one of the units ``Pack`` depends
- upon defines a subprogram, so its control fan-out coupling is 1.
-
- ``Lib_2`` depends on nothing, so its fan-out metrics are 0. It does
- not define any subprograms, so it has no control fan-in metric.
- One unit (``Pack``) depends on it , so its unit fan-in coupling is 1.
-
- ``Lib_1`` is similar to ``Lib_2``, but it does define a subprogram.
- Its control fan-in coupling is 1 (because there is one unit
- depending on it).
-
- When computing coupling metrics, ``gnatmetric`` counts only
- dependencies between units that are arguments of the ``gnatmetric``
- invocation. Coupling metrics are program-wide (or project-wide) metrics, so
- you should invoke ``gnatmetric`` for
- the complete set of sources comprising your program. This can be done
- by invoking ``gnatmetric`` with the corresponding project file
- and with the :switch:`-U` option.
-
- By default, all the coupling metrics are reported. You can use the following
- switches to select specific syntax metrics.
-
- .. index:: --tagged-coupling (gnatmetric)
- .. index:: --hierarchy-coupling (gnatmetric)
- .. index:: --unit-coupling (gnatmetric)
- .. index:: --control-coupling (gnatmetric)
-
- :switch:`--coupling-all`
- Report all the coupling metrics
-
-
- :switch:`--tagged-coupling-out`
- Report tagged (class) fan-out coupling
-
-
- :switch:`--tagged-coupling-in`
- Report tagged (class) fan-in coupling
-
-
- :switch:`--hierarchy-coupling-out`
- Report hierarchy (category) fan-out coupling
-
-
- :switch:`--hierarchy-coupling-in`
- Report hierarchy (category) fan-in coupling
-
-
- :switch:`--unit-coupling-out`
- Report unit fan-out coupling
-
-
- :switch:`--unit-coupling-in`
- Report unit fan-in coupling
-
-
- :switch:`--control-coupling-out`
- Report control fan-out coupling
-
-
- :switch:`--control-coupling-in`
- Report control fan-in coupling
-
-
- .. _Other_gnatmetric_Switches:
-
- Other ``gnatmetric`` Switches
- -----------------------------
-
- Additional ``gnatmetric`` switches are as follows:
-
-
- .. index:: --version (gnatmetric)
-
- :switch:`--version`
- Display copyright and version, then exit disregarding all other options.
-
-
- .. index:: --help (gnatmetric)
-
- :switch:`--help`
- Display usage, then exit disregarding all other options.
-
-
- .. index:: -P (gnatmetric)
-
- :switch:`-P {file}`
- Indicates the name of the project file that describes the set of sources
- to be processed. The exact set of argument sources depends on other options
- specified, see below. An aggregate project is allowed as the file parameter
- only if it has exactly one non-aggregate project being aggregated.
-
-
- .. index:: -U (gnatmetric)
-
- :switch:`-U`
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), process
- all the units of the closure of the argument project. Otherwise this option
- has no effect.
-
-
- :switch:`-U {main_unit}`
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), process
- the closure of units rooted at ``main_unit``. Otherwise this option
- has no effect.
-
-
- .. index:: -X (gnatmetric)
-
- :switch:`-X{name}={value}`
- Indicates that external variable ``name`` in the argument project
- has the value ``value``. Has no effect if no project is specified.
-
-
- .. index:: --RTS (gnatmetric)
-
- :switch:`--RTS={rts-path}`
- Specifies the default location of the runtime library. Same meaning as the
- equivalent ``gnatmake`` flag (see :ref:`Switches_for_gnatmake`).
-
-
- .. index:: --subdirs=dir (gnatmetric)
-
- :switch:`--subdirs={dir}`
- Use the specified subdirectory of the project objects file (or of the
- project file directory if the project does not specify an object directory)
- for tool output files. Has no effect if no project is specified as
- tool argument r if :switch:`--no-objects-dir` is specified.
-
-
- .. index:: --files (gnatmetric)
-
- :switch:`--files={file}`
- Take as arguments the files listed in text file ``file``.
- Text file ``file`` may contain empty lines that are ignored.
- Each nonempty line should contain the name of an existing file.
- Several such switches may be specified simultaneously.
-
-
- .. index:: --ignore (gnatmetric)
-
- :switch:`--ignore={filename}`
- Do not process the sources listed in a specified file.
-
-
- .. index:: --verbose (gnatmetric)
-
- :switch:`--verbose`
- Verbose mode;
- ``gnatmetric`` generates version information and then
- a trace of sources being processed.
-
-
- .. index:: --quiet (gnatmetric)
-
- :switch:`--quiet`
- Quiet mode.
-
- If a project file is specified and no argument source is explicitly
- specified (either directly or by means of :switch:`-files` option), and no
- :switch:`-U` is specified, then the set of processed sources is
- all the immediate units of the argument project.
-
-
- Legacy Switches
- ^^^^^^^^^^^^^^^
-
- Some switches have a short form, mostly for legacy reasons,
- as shown below.
-
- .. index:: -x (gnatmetric)
-
- :switch:`-x`
- :switch:`--generate-xml-output`
-
- .. index:: -xs (gnatmetric)
-
- :switch:`-xs`
- :switch:`--generate-xml-schema`
-
- .. index:: -nt (gnatmetric)
-
- :switch:`-nt`
- :switch:`--no-text-output`
-
- .. index:: -d (gnatmetric)
-
- :switch:`-d {output-dir}`
- :switch:`--output-dir`
-
- .. index:: -o (gnatmetric)
-
- :switch:`-o {file-suffix}`
- :switch:`--output-suffix`
-
- .. index:: -og (gnatmetric)
-
- :switch:`-og {file-name}`
- :switch:`--global-file-name`
-
- .. index:: -ox (gnatmetric)
-
- :switch:`-ox {file-name}`
- :switch:`--xml-file-name`
-
- .. index:: -sfn (gnatmetric)
-
- :switch:`-sfn`
- :switch:`--short-file-names`
-
- .. index:: -W (gnatsmetric)
-
- :switch:`-W{e}`
- :switch:`--wide-character-encoding={e}`
-
- .. index:: -nolocal (gnatmetric)
-
- :switch:`-nolocal`
- :switch:`--no-local-metrics`
-
- .. index:: -ne (gnatmetric)
-
- :switch:`-ne`
- :switch:`--no-treat-exit-as-goto`
-
- .. index:: -files (gnatmetric)
-
- :switch:`-files {filename}`
- :switch:`--files`
-
- .. index:: -v (gnatmetric)
-
- :switch:`-v`
- :switch:`--verbose`
-
- .. index:: -q (gnatmetric)
-
- :switch:`-q`
- :switch:`--quiet`
-
.. only:: PRO or GPL
.. _The_GNAT_Pretty_Printer_gnatpp:
@@ -3026,7 +1908,7 @@ building specialized scripts.
naming conventions.
Note that it is no longer necessary to specify the Ada language version;
- ``gnatmetric`` can process Ada source code written in any version from
+ ``gnatstub`` can process Ada source code written in any version from
Ada 83 onward without specifying any language version switch.
* *switches*
diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
index b1889fe..48fb107 100644
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -42,17 +42,13 @@
#include "adaint.h"
#include <sys/types.h>
-#ifdef __MINGW32__
-# if OLD_MINGW
-# include <sys/wait.h>
-# endif
-#elif defined (__vxworks) && defined (__RTP__)
+#if defined (__vxworks) && defined (__RTP__)
# include <wait.h>
#elif defined (__Lynx__)
/* ??? See comment in adaint.c. */
# define GCC_RESOURCE_H
# include <sys/wait.h>
-#elif defined (__PikeOS__)
+#elif defined (__PikeOS__) || defined (__MINGW32__)
/* No wait.h available */
#else
#include <sys/wait.h>
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index cdf8605..64f2e79 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT Reference Manual , Sep 09, 2022
+GNAT Reference Manual , Sep 23, 2022
AdaCore
@@ -433,7 +433,7 @@ Implementation Defined Attributes
* Attribute Universal_Literal_String::
* Attribute Unrestricted_Access::
* Attribute Update::
-* Attribute Valid_Image::
+* Attribute Valid_Value::
* Attribute Valid_Scalars::
* Attribute VADS_Size::
* Attribute Value_Size::
@@ -10295,7 +10295,7 @@ consideration, you should minimize the use of these attributes.
* Attribute Universal_Literal_String::
* Attribute Unrestricted_Access::
* Attribute Update::
-* Attribute Valid_Image::
+* Attribute Valid_Value::
* Attribute Valid_Scalars::
* Attribute VADS_Size::
* Attribute Value_Size::
@@ -12040,7 +12040,7 @@ In general this is a risky approach. It may appear to “work” but such uses o
@code{Unrestricted_Access} are potentially non-portable, even from one version
of GNAT to another, so are best avoided if possible.
-@node Attribute Update,Attribute Valid_Image,Attribute Unrestricted_Access,Implementation Defined Attributes
+@node Attribute Update,Attribute Valid_Value,Attribute Unrestricted_Access,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1ac}
@section Attribute Update
@@ -12121,19 +12121,19 @@ A := A'Update ((1, 2) => 20, (3, 4) => 30);
which changes element (1,2) to 20 and (3,4) to 30.
-@node Attribute Valid_Image,Attribute Valid_Scalars,Attribute Update,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-valid-image}@anchor{1ad}
-@section Attribute Valid_Image
+@node Attribute Valid_Value,Attribute Valid_Scalars,Attribute Update,Implementation Defined Attributes
+@anchor{gnat_rm/implementation_defined_attributes attribute-valid-value}@anchor{1ad}
+@section Attribute Valid_Value
-@geindex Valid_Image
+@geindex Valid_Value
-The @code{'Valid_Image} attribute is defined for enumeration types other than
+The @code{'Valid_Value} attribute is defined for enumeration types other than
those in package Standard. This attribute is a function that takes
-a String, and returns Boolean. @code{T'Valid_Image (S)} returns True
+a String, and returns Boolean. @code{T'Valid_Value (S)} returns True
if and only if @code{T'Value (S)} would not raise Constraint_Error.
-@node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Valid_Image,Implementation Defined Attributes
+@node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Valid_Value,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1ae}
@section Attribute Valid_Scalars
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index f2cb1ed..7d96dbe 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Sep 09, 2022
+GNAT User's Guide for Native Platforms , Sep 26, 2022
AdaCore
@@ -9220,6 +9220,7 @@ Float_Size : Pos; -- Standard.Float'Size
Float_Words_BE : Nat; -- Float words stored big-endian?
Int_Size : Pos; -- Standard.Integer'Size
Long_Double_Size : Pos; -- Standard.Long_Long_Float'Size
+Long_Long_Long_Size : Pos; -- Standard.Long_Long_Long_Integer'Size
Long_Long_Size : Pos; -- Standard.Long_Long_Integer'Size
Long_Size : Pos; -- Standard.Long_Integer'Size
Maximum_Alignment : Pos; -- Maximum permitted alignment
@@ -9307,6 +9308,7 @@ Float_Size 32
Float_Words_BE 0
Int_Size 64
Long_Double_Size 128
+Long_Long_Long_Size 128
Long_Long_Size 64
Long_Size 64
Maximum_Alignment 16
@@ -15317,10 +15319,11 @@ Linker switches can be specified after @code{-largs} builder switch.
@item @code{-fuse-ld=`name'}
-Linker to be used. The default is @code{bfd} for @code{ld.bfd},
-the alternative being @code{gold} for @code{ld.gold}. The later is
-a more recent and faster linker, but only available on GNU/Linux
+Linker to be used. The default is @code{bfd} for @code{ld.bfd}; @code{gold}
+(for @code{ld.gold}) and @code{mold} (for @code{ld.mold}) are more
+recent and faster alternatives, but only available on GNU/Linux
platforms.
+
@end table
@node Binding with gnatbind,Linking with gnatlink,Linker Switches,Building Executable Programs with GNAT
@@ -17932,7 +17935,6 @@ instr.ads
-
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node GNAT and Program Execution,Platform-Specific Information,GNAT Utility Programs,Top
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index e7284a1..561f2ff 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -80,12 +80,6 @@
#define FD_SETSIZE 1024
#ifdef __MINGW32__
-/* winsock2.h allows WSAPoll related definitions only when
- * _WIN32_WINNT >= 0x0600 */
-#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
-#define _WIN32_WINNT 0x0600
-#endif
-
#include <winsock2.h>
#include <ws2tcpip.h>
#include <versionhelpers.h>
diff --git a/gcc/ada/mingw32.h b/gcc/ada/mingw32.h
index 1157fc6..d038211 100644
--- a/gcc/ada/mingw32.h
+++ b/gcc/ada/mingw32.h
@@ -44,11 +44,6 @@
#define UNICODE /* For Win32 API */
#endif
-/* We need functionality available only starting with Windows XP */
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
#ifndef __CYGWIN__
#include <tchar.h>
#endif
@@ -99,27 +94,4 @@ extern UINT __gnat_current_ccs_encoding;
#define WS2S(str,wstr,len) strncpy(str,wstr,len)
#endif
-#include <stdlib.h>
-
-/* STD_MINGW: standard if MINGW32 version > 1.3, we have switched to this
- version instead of the previous enhanced version to ease building GNAT on
- Windows platforms. By using STD_MINGW or OLD_MINGW it is possible to build
- GNAT using both MingW include files (Old MingW + ACT changes and standard
- MingW starting with version 1.3.
- For w64 Mingw the define STD_MINGW is always set to value 1, because
- there is no old header set present. */
-#ifdef _WIN64
-#define STD_MINGW 1
-#else
-#define STD_MINGW ((__MINGW32_MAJOR_VERSION == 1 \
- && __MINGW32_MINOR_VERSION >= 3) \
- || (__MINGW32_MAJOR_VERSION >= 2))
-#endif
-
-#define OLD_MINGW (!(STD_MINGW))
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN MAX_PATH
-#endif
-
#endif /* _MINGW32_H */
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 65c6409..24aca2c 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -189,7 +189,6 @@ package Rtsfind is
-- Children of Interfaces
Interfaces_C,
- Interfaces_Packed_Decimal,
-- Children of Interfaces.C
@@ -205,7 +204,6 @@ package Rtsfind is
System_Address_To_Access_Conversions,
System_Arith_64,
System_Arith_128,
- System_AST_Handling,
System_Assertions,
System_Atomic_Operations,
System_Atomic_Primitives,
@@ -257,9 +255,6 @@ package Rtsfind is
System_Fat_LFlt,
System_Fat_LLF,
System_Fat_SFlt,
- System_Fat_VAX_D_Float,
- System_Fat_VAX_F_Float,
- System_Fat_VAX_G_Float,
System_Finalization_Masters,
System_Finalization_Root,
System_Fore_Decimal_32,
@@ -288,14 +283,12 @@ package Rtsfind is
System_Img_LLLI,
System_Img_LLU,
System_Img_LLLU,
- System_Img_Name,
System_Img_Uns,
System_Img_WChar,
System_Interrupts,
System_Long_Long_Float_Expon,
System_Machine_Code,
System_Mantissa,
- System_Memcop,
System_Memory,
System_Multiprocessors,
System_Pack_03,
@@ -420,10 +413,7 @@ package Rtsfind is
System_Pack_127,
System_Parameters,
System_Partition_Interface,
- System_Pool_32_Global,
System_Pool_Global,
- System_Pool_Empty,
- System_Pool_Local,
System_Pool_Size,
System_Put_Images,
System_Put_Task_Images,
@@ -440,7 +430,6 @@ package Rtsfind is
System_Stream_Attributes,
System_Task_Info,
System_Tasking,
- System_Threads,
System_Unsigned_Types,
System_Val_Bool,
System_Val_Char,
@@ -461,7 +450,6 @@ package Rtsfind is
System_Val_LLLI,
System_Val_LLU,
System_Val_LLLU,
- System_Val_Name,
System_Val_Uns,
System_Val_WChar,
System_Version_Control,
@@ -475,7 +463,6 @@ package Rtsfind is
System_Wid_LLLI,
System_Wid_LLU,
System_Wid_LLLU,
- System_Wid_Name,
System_Wid_Uns,
System_Wid_WChar,
System_WWd_Char,
@@ -484,7 +471,7 @@ package Rtsfind is
-- Children of System.Atomic_Operations
- System_Atomic_Operations_Test_And_Set,
+ System_Atomic_Operations_Test_And_Set,
-- Children of System.Dim
@@ -561,17 +548,13 @@ package Rtsfind is
RE_Set_Deadline, -- Ada.Dispatching.EDF
- RE_Code_Loc, -- Ada.Exceptions
RE_Exception_Id, -- Ada.Exceptions
- RE_Exception_Identity, -- Ada.Exceptions
RE_Exception_Information, -- Ada.Exceptions
RE_Exception_Message, -- Ada.Exceptions
RE_Exception_Name_Simple, -- Ada.Exceptions
RE_Exception_Occurrence, -- Ada.Exceptions
- RE_Exception_Occurrence_Access, -- Ada.Exceptions
RE_Null_Id, -- Ada.Exceptions
RE_Null_Occurrence, -- Ada.Exceptions
- RE_Poll, -- Ada.Exceptions
RE_Raise_Exception, -- Ada.Exceptions
RE_Raise_Exception_Always, -- Ada.Exceptions
RE_Raise_From_Controlled_Operation, -- Ada.Exceptions
@@ -596,7 +579,7 @@ package Rtsfind is
RE_Names, -- Ada.Interrupts.Names
RE_Clock, -- Ada.Real_Time
- RE_Clock_Time, -- Ada.Real_Time
+ RE_Clock_Time, -- Ada.Real_Time [used by GNATprove]
RE_Time_Span, -- Ada.Real_Time
RE_Time_Span_Zero, -- Ada.Real_Time
RO_RT_Time, -- Ada.Real_Time
@@ -612,8 +595,6 @@ package Rtsfind is
RE_Stream_Element_Array, -- Ada.Streams
RE_Stream_Element_Offset, -- Ada.Streams
- RE_Stream_Access, -- Ada.Streams.Stream_IO
-
RO_SU_Super_String, -- Ada.Strings.Superbounded
RO_WI_Super_String, -- Ada.Strings.Wide_Superbounded
@@ -628,8 +609,6 @@ package Rtsfind is
RE_Buffer_Type, -- Ada.Strings.Text_Buffers.Unbounded
RE_Get, -- Ada.Strings.Text_Buffers.Unbounded
- RE_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
- RE_Wide_Wide_Get, -- Ada.Strings.Text_Buffers.Unbounded
RE_Wait_For_Release, -- Ada.Synchronous_Barriers
@@ -641,7 +620,6 @@ package Rtsfind is
RE_Address_Array, -- Ada.Tags
RE_Addr_Ptr, -- Ada.Tags
RE_Base_Address, -- Ada.Tags
- RE_Check_Interface_Conversion, -- Ada.Tags
RE_Check_TSD, -- Ada.Tags
RE_Cstring_Ptr, -- Ada.Tags
RE_CW_Membership, -- Ada.Tags
@@ -656,13 +634,11 @@ package Rtsfind is
RE_External_Tag, -- Ada.Tags
RO_TA_External_Tag, -- Ada.Tags
RE_Get_Access_Level, -- Ada.Tags
- RE_Get_Alignment, -- Ada.Tags
RE_Get_Entry_Index, -- Ada.Tags
RE_Get_Offset_Index, -- Ada.Tags
RE_Get_Prim_Op_Kind, -- Ada.Tags
RE_Get_Tagged_Kind, -- Ada.Tags
RE_HT_Link, -- Ada.Tags
- RE_Idepth, -- Ada.Tags
RE_Interfaces_Array, -- Ada.Tags
RE_Interfaces_Table, -- Ada.Tags
RE_Interface_Data, -- Ada.Tags
@@ -675,8 +651,6 @@ package Rtsfind is
RE_No_Dispatch_Table_Wrapper, -- Ada.Tags
RE_No_Tag, -- Ada.Tags
RE_NDT_Prims_Ptr, -- Ada.Tags
- RE_NDT_TSD, -- Ada.Tags
- RE_Num_Prims, -- Ada.Tags
RE_Object_Specific_Data, -- Ada.Tags
RE_Offset_To_Top, -- Ada.Tags
RE_Offset_To_Top_Ptr, -- Ada.Tags
@@ -699,11 +673,9 @@ package Rtsfind is
RE_Primary_DT, -- Ada.Tags
RE_Signature, -- Ada.Tags
RE_SSD, -- Ada.Tags
- RE_TSD, -- Ada.Tags
RE_Type_Specific_Data, -- Ada.Tags
RE_Register_Interface_Offset, -- Ada.Tags
RE_Register_Tag, -- Ada.Tags
- RE_Register_TSD, -- Ada.Tags
RE_Transportable, -- Ada.Tags
RE_Secondary_DT, -- Ada.Tags
RE_Secondary_Tag, -- Ada.Tags
@@ -749,7 +721,6 @@ package Rtsfind is
RE_Stream_T, -- CUDA.Driver_Types
- RE_Fatbin_Wrapper, -- CUDA.Internal
RE_Launch_Kernel, -- CUDA.Internal
RE_Pop_Call_Configuration, -- CUDA.Internal
RE_Push_Call_Configuration, -- CUDA.Internal
@@ -772,19 +743,14 @@ package Rtsfind is
RO_IC_Unsigned, -- Interfaces.C
- RE_Chars_Ptr, -- Interfaces.C.Strings
- RE_New_Char_Array, -- Interfaces.C.Strings
-
RE_Address, -- System
RE_Any_Priority, -- System
RE_Bit_Order, -- System
RE_Default_Priority, -- System
RE_High_Order_First, -- System
RE_Interrupt_Priority, -- System
- RE_Lib_Stop, -- System
RE_Low_Order_First, -- System
RE_Max_Base_Digits, -- System
- RE_Max_Priority, -- System
RE_Null_Address, -- System
RE_Priority, -- System
@@ -802,8 +768,6 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check128, -- System.Arith_128
RE_Scaled_Divide128, -- System.Arith_128
- RE_Create_AST_Handler, -- System.AST_Handling
-
RE_Assert_Failure, -- System.Assertions
RE_Raise_Assert_Failure, -- System.Assertions
@@ -824,9 +788,6 @@ package Rtsfind is
RE_Atomic_Test_And_Set, -- System.Atomic_Operations.Test_And_Set
RE_AST_Handler, -- System.Aux_DEC
- RE_Import_Address, -- System.Aux_DEC
- RE_Import_Value, -- System.Aux_DEC
- RE_No_AST_Handler, -- System.Aux_DEC
RE_Type_Class, -- System.Aux_DEC
RE_Type_Class_Enumeration, -- System.Aux_DEC
RE_Type_Class_Integer, -- System.Aux_DEC
@@ -954,15 +915,6 @@ package Rtsfind is
RE_Attr_Long_Long_Float, -- System.Fat_LLF
- RE_Attr_VAX_D_Float, -- System.Fat_VAX_D_Float
- RE_Fat_VAX_D, -- System.Fat_VAX_D_Float
-
- RE_Attr_VAX_F_Float, -- System.Fat_VAX_F_Float
- RE_Fat_VAX_F, -- System.Fat_VAX_F_Float
-
- RE_Attr_VAX_G_Float, -- System.Fat_VAX_G_Float
- RE_Fat_VAX_G, -- System.Fat_VAX_G_Float
-
RE_Add_Offset_To_Address, -- System.Finalization_Masters
RE_Attach, -- System.Finalization_Masters
RE_Base_Pool, -- System.Finalization_Masters
@@ -970,10 +922,8 @@ package Rtsfind is
RE_Finalization_Master_Ptr, -- System.Finalization_Masters
RE_Set_Base_Pool, -- System.Finalization_Masters
RE_Set_Finalize_Address, -- System.Finalization_Masters
- RE_Set_Is_Heterogeneous, -- System.Finalization_Masters
RE_Root_Controlled, -- System.Finalization_Root
- RE_Root_Controlled_Ptr, -- System.Finalization_Root
RE_Fore_Decimal32, -- System.Fore_Decimal_32
@@ -1649,9 +1599,7 @@ package Rtsfind is
RE_Set_127, -- System.Pack_127
RE_Adjust_Storage_Size, -- System.Parameters
- RE_Default_Secondary_Stack_Size, -- System.Parameters
RE_Default_Stack_Size, -- System.Parameters
- RE_Garbage_Collected, -- System.Parameters
RE_Size_Type, -- System.Parameters
RE_Unspecified_Size, -- System.Parameters
@@ -1677,8 +1625,6 @@ package Rtsfind is
RE_Global_Pool_Object, -- System.Pool_Global
- RE_Global_Pool_32_Object, -- System.Pool_32_Global
-
RE_Stack_Bounded_Pool, -- System.Pool_Size
RE_Put_Image_Integer, -- System.Put_Images
@@ -1744,11 +1690,8 @@ package Rtsfind is
RE_Set_Result, -- System.Partition_Interface
RE_Register_Obj_Receiving_Stub, -- System.Partition_Interface
RE_Register_Pkg_Receiving_Stub, -- System.Partition_Interface
- RE_Is_Nil, -- System.Partition_Interface
- RE_Entity_Ptr, -- System.Partition_Interface
RE_Entity_Of, -- System.Partition_Interface
RE_Inc_Usage, -- System.Partition_Interface
- RE_Set_Ref, -- System.Partition_Interface
RE_Make_Ref, -- System.Partition_Interface
RE_Get_Local_Address, -- System.Partition_Interface
RE_Get_Reference, -- System.Partition_Interface
@@ -1881,8 +1824,6 @@ package Rtsfind is
RE_Deallocate_Any_Controlled, -- System.Storage_Pools.Subpools
RE_Header_Size_With_Padding, -- System.Storage_Pools.Subpools
RE_Root_Storage_Pool_With_Subpools, -- System.Storage_Pools.Subpools
- RE_Root_Subpool, -- System.Storage_Pools.Subpools
- RE_Subpool_Handle, -- System.Storage_Pools.Subpools
RE_I_AD, -- System.Stream_Attributes
RE_I_AS, -- System.Stream_Attributes
@@ -2006,7 +1947,6 @@ package Rtsfind is
RE_Simple_Mode, -- System.Tasking
RE_Terminate_Mode, -- System.Tasking
RE_Delay_Mode, -- System.Tasking
- RE_Entry_Index, -- System.Tasking
RE_Task_Entry_Index, -- System.Tasking
RE_Self, -- System.Tasking
@@ -2244,17 +2184,13 @@ package Rtsfind is
RE_Set_Deadline => Ada_Dispatching_EDF,
- RE_Code_Loc => Ada_Exceptions,
RE_Exception_Id => Ada_Exceptions,
- RE_Exception_Identity => Ada_Exceptions,
RE_Exception_Information => Ada_Exceptions,
RE_Exception_Message => Ada_Exceptions,
RE_Exception_Name_Simple => Ada_Exceptions,
RE_Exception_Occurrence => Ada_Exceptions,
- RE_Exception_Occurrence_Access => Ada_Exceptions,
RE_Null_Id => Ada_Exceptions,
RE_Null_Occurrence => Ada_Exceptions,
- RE_Poll => Ada_Exceptions,
RE_Raise_Exception => Ada_Exceptions,
RE_Raise_Exception_Always => Ada_Exceptions,
RE_Raise_From_Controlled_Operation => Ada_Exceptions,
@@ -2295,8 +2231,6 @@ package Rtsfind is
RE_Stream_Element_Array => Ada_Streams,
RE_Stream_Element_Offset => Ada_Streams,
- RE_Stream_Access => Ada_Streams_Stream_IO,
-
RO_SU_Super_String => Ada_Strings_Superbounded,
RO_WI_Super_String => Ada_Strings_Wide_Superbounded,
@@ -2311,8 +2245,6 @@ package Rtsfind is
RE_Buffer_Type => Ada_Strings_Text_Buffers_Unbounded,
RE_Get => Ada_Strings_Text_Buffers_Unbounded,
- RE_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
- RE_Wide_Wide_Get => Ada_Strings_Text_Buffers_Unbounded,
RE_Wait_For_Release => Ada_Synchronous_Barriers,
@@ -2324,7 +2256,6 @@ package Rtsfind is
RE_Address_Array => Ada_Tags,
RE_Addr_Ptr => Ada_Tags,
RE_Base_Address => Ada_Tags,
- RE_Check_Interface_Conversion => Ada_Tags,
RE_Check_TSD => Ada_Tags,
RE_Cstring_Ptr => Ada_Tags,
RE_CW_Membership => Ada_Tags,
@@ -2339,13 +2270,11 @@ package Rtsfind is
RE_External_Tag => Ada_Tags,
RO_TA_External_Tag => Ada_Tags,
RE_Get_Access_Level => Ada_Tags,
- RE_Get_Alignment => Ada_Tags,
RE_Get_Entry_Index => Ada_Tags,
RE_Get_Offset_Index => Ada_Tags,
RE_Get_Prim_Op_Kind => Ada_Tags,
RE_Get_Tagged_Kind => Ada_Tags,
RE_HT_Link => Ada_Tags,
- RE_Idepth => Ada_Tags,
RE_Interfaces_Array => Ada_Tags,
RE_Interfaces_Table => Ada_Tags,
RE_Interface_Data => Ada_Tags,
@@ -2358,8 +2287,6 @@ package Rtsfind is
RE_No_Dispatch_Table_Wrapper => Ada_Tags,
RE_No_Tag => Ada_Tags,
RE_NDT_Prims_Ptr => Ada_Tags,
- RE_NDT_TSD => Ada_Tags,
- RE_Num_Prims => Ada_Tags,
RE_Object_Specific_Data => Ada_Tags,
RE_Offset_To_Top => Ada_Tags,
RE_Offset_To_Top_Ptr => Ada_Tags,
@@ -2382,11 +2309,9 @@ package Rtsfind is
RE_Primary_DT => Ada_Tags,
RE_Signature => Ada_Tags,
RE_SSD => Ada_Tags,
- RE_TSD => Ada_Tags,
RE_Type_Specific_Data => Ada_Tags,
RE_Register_Interface_Offset => Ada_Tags,
RE_Register_Tag => Ada_Tags,
- RE_Register_TSD => Ada_Tags,
RE_Transportable => Ada_Tags,
RE_Secondary_DT => Ada_Tags,
RE_Secondary_Tag => Ada_Tags,
@@ -2432,7 +2357,6 @@ package Rtsfind is
RE_Stream_T => CUDA_Driver_Types,
- RE_Fatbin_Wrapper => CUDA_Internal,
RE_Launch_Kernel => CUDA_Internal,
RE_Pop_Call_Configuration => CUDA_Internal,
RE_Push_Call_Configuration => CUDA_Internal,
@@ -2455,19 +2379,14 @@ package Rtsfind is
RO_IC_Unsigned => Interfaces_C,
- RE_Chars_Ptr => Interfaces_C_Strings,
- RE_New_Char_Array => Interfaces_C_Strings,
-
RE_Address => System,
RE_Any_Priority => System,
RE_Bit_Order => System,
RE_Default_Priority => System,
RE_High_Order_First => System,
RE_Interrupt_Priority => System,
- RE_Lib_Stop => System,
RE_Low_Order_First => System,
RE_Max_Base_Digits => System,
- RE_Max_Priority => System,
RE_Null_Address => System,
RE_Priority => System,
@@ -2485,8 +2404,6 @@ package Rtsfind is
RE_Subtract_With_Ovflo_Check128 => System_Arith_128,
RE_Scaled_Divide128 => System_Arith_128,
- RE_Create_AST_Handler => System_AST_Handling,
-
RE_Assert_Failure => System_Assertions,
RE_Raise_Assert_Failure => System_Assertions,
@@ -2507,9 +2424,6 @@ package Rtsfind is
RE_Atomic_Test_And_Set => System_Atomic_Operations_Test_And_Set,
RE_AST_Handler => System_Aux_DEC,
- RE_Import_Address => System_Aux_DEC,
- RE_Import_Value => System_Aux_DEC,
- RE_No_AST_Handler => System_Aux_DEC,
RE_Type_Class => System_Aux_DEC,
RE_Type_Class_Enumeration => System_Aux_DEC,
RE_Type_Class_Integer => System_Aux_DEC,
@@ -2643,15 +2557,6 @@ package Rtsfind is
RE_Attr_Long_Long_Float => System_Fat_LLF,
- RE_Attr_VAX_D_Float => System_Fat_VAX_D_Float,
- RE_Fat_VAX_D => System_Fat_VAX_D_Float,
-
- RE_Attr_VAX_F_Float => System_Fat_VAX_F_Float,
- RE_Fat_VAX_F => System_Fat_VAX_F_Float,
-
- RE_Attr_VAX_G_Float => System_Fat_VAX_G_Float,
- RE_Fat_VAX_G => System_Fat_VAX_G_Float,
-
RE_Add_Offset_To_Address => System_Finalization_Masters,
RE_Attach => System_Finalization_Masters,
RE_Base_Pool => System_Finalization_Masters,
@@ -2659,10 +2564,8 @@ package Rtsfind is
RE_Finalization_Master_Ptr => System_Finalization_Masters,
RE_Set_Base_Pool => System_Finalization_Masters,
RE_Set_Finalize_Address => System_Finalization_Masters,
- RE_Set_Is_Heterogeneous => System_Finalization_Masters,
RE_Root_Controlled => System_Finalization_Root,
- RE_Root_Controlled_Ptr => System_Finalization_Root,
RE_Fore_Decimal32 => System_Fore_Decimal_32,
@@ -3340,9 +3243,7 @@ package Rtsfind is
RE_Set_127 => System_Pack_127,
RE_Adjust_Storage_Size => System_Parameters,
- RE_Default_Secondary_Stack_Size => System_Parameters,
RE_Default_Stack_Size => System_Parameters,
- RE_Garbage_Collected => System_Parameters,
RE_Size_Type => System_Parameters,
RE_Unspecified_Size => System_Parameters,
@@ -3399,11 +3300,8 @@ package Rtsfind is
RE_Set_Result => System_Partition_Interface,
RE_Register_Obj_Receiving_Stub => System_Partition_Interface,
RE_Register_Pkg_Receiving_Stub => System_Partition_Interface,
- RE_Is_Nil => System_Partition_Interface,
- RE_Entity_Ptr => System_Partition_Interface,
RE_Entity_Of => System_Partition_Interface,
RE_Inc_Usage => System_Partition_Interface,
- RE_Set_Ref => System_Partition_Interface,
RE_Make_Ref => System_Partition_Interface,
RE_Get_Local_Address => System_Partition_Interface,
RE_Get_Reference => System_Partition_Interface,
@@ -3488,8 +3386,6 @@ package Rtsfind is
RE_Global_Pool_Object => System_Pool_Global,
- RE_Global_Pool_32_Object => System_Pool_32_Global,
-
RE_Stack_Bounded_Pool => System_Pool_Size,
RE_Put_Image_Integer => System_Put_Images,
@@ -3572,8 +3468,6 @@ package Rtsfind is
RE_Deallocate_Any_Controlled => System_Storage_Pools_Subpools,
RE_Header_Size_With_Padding => System_Storage_Pools_Subpools,
RE_Root_Storage_Pool_With_Subpools => System_Storage_Pools_Subpools,
- RE_Root_Subpool => System_Storage_Pools_Subpools,
- RE_Subpool_Handle => System_Storage_Pools_Subpools,
RE_I_AD => System_Stream_Attributes,
RE_I_AS => System_Stream_Attributes,
@@ -3697,7 +3591,6 @@ package Rtsfind is
RE_Simple_Mode => System_Tasking,
RE_Terminate_Mode => System_Tasking,
RE_Delay_Mode => System_Tasking,
- RE_Entry_Index => System_Tasking,
RE_Task_Entry_Index => System_Tasking,
RE_Self => System_Tasking,
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index af69190..5394122 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -237,9 +237,6 @@ int counter = 0;
#define CST(name,comment) C(#name,String,name,comment)
/* String constant */
-#define STR(x) STR1(x)
-#define STR1(x) #x
-
#ifdef __MINGW32__
unsigned int _CRT_fmode = _O_BINARY;
#endif
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 9525140..ab2e182 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6296,13 +6296,16 @@ package body Sem_Ch12 is
Old_Main : constant Entity_Id := Cunit_Entity (Main_Unit);
begin
- -- A new compilation unit node is built for the instance declaration
+ -- A new compilation unit node is built for the instance declaration.
+ -- It relocates the auxiliary declaration node from the compilation unit
+ -- where the instance appeared, so that declarations that originally
+ -- followed the instance will be attached to the spec compilation unit.
Decl_Cunit :=
Make_Compilation_Unit (Sloc (N),
Context_Items => Empty_List,
Unit => Act_Decl,
- Aux_Decls_Node => Make_Compilation_Unit_Aux (Sloc (N)));
+ Aux_Decls_Node => Relocate_Node (Aux_Decls_Node (Parent (N))));
Set_Parent_Spec (Act_Decl, Parent_Spec (N));
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 17bf6d9..d0f00b3 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -2429,13 +2429,9 @@ package body Sem_Ch5 is
if not Is_Entity_Name (Iter_Name)
- -- When the context is a quantified expression, the renaming
- -- declaration is delayed until the expansion phase if we are
- -- doing expansion.
+ -- Do not perform this expansion in preanalysis
- and then (Nkind (Parent (N)) /= N_Quantified_Expression
- or else (Operating_Mode = Check_Semantics
- and then not GNATprove_Mode))
+ and then Full_Analysis
-- Do not perform this expansion when expansion is disabled, where the
-- temporary may hide the transformation of a selected component into
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index b0babeb..9ae082c 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -531,7 +531,7 @@ package body Sem_Util is
-- Local variables
- E : Entity_Id := Original_Node (Expr);
+ E : Node_Id := Original_Node (Expr);
Pre : Node_Id;
-- Start of processing for Accessibility_Level
@@ -777,8 +777,18 @@ package body Sem_Util is
-- We don't handle function calls in prefix notation correctly ???
- when N_Indexed_Component | N_Selected_Component =>
- Pre := Original_Node (Prefix (E));
+ when N_Indexed_Component | N_Selected_Component | N_Slice =>
+ Pre := Prefix (E);
+
+ -- Fetch the original node when the prefix comes from the result
+ -- of expanding a function call since we want to find the level
+ -- of the original source call.
+
+ if not Comes_From_Source (Pre)
+ and then Nkind (Original_Node (Pre)) = N_Function_Call
+ then
+ Pre := Original_Node (Pre);
+ end if;
-- When E is an indexed component or selected component and
-- the current Expr is a function call, we know that we are
@@ -26549,6 +26559,14 @@ package body Sem_Util is
Item_Nam :=
Chars (Original_Node (Pragma_Identifier (Original_Node (Item))));
+ if Item_Nam = Name_Check then
+ -- Pragma "Check" preserves the original pragma name as its first
+ -- argument.
+ Item_Nam :=
+ Chars (Expression (First (Pragma_Argument_Associations
+ (Original_Node (Item)))));
+ end if;
+
else
pragma Assert (Nkind (Item) = N_Aspect_Specification);
Item_Nam := Chars (Identifier (Item));
diff --git a/gcc/ada/sem_warn.ads b/gcc/ada/sem_warn.ads
index 1894f36..6681e54 100644
--- a/gcc/ada/sem_warn.ads
+++ b/gcc/ada/sem_warn.ads
@@ -257,12 +257,9 @@ package Sem_Warn is
----------------------
function Has_Junk_Name (E : Entity_Id) return Boolean;
- -- Return True if the entity name contains any of the following substrings:
- -- discard
- -- dummy
- -- ignore
- -- junk
- -- unused
+ -- Return True if the entity name contains substrings like "junk" or
+ -- "dummy" (see the body for the complete list).
+ --
-- Used to suppress warnings on names matching these patterns. The contents
-- of Name_Buffer and Name_Len are destroyed by this call.
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index 5e9cf70..7bdfcbc 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -323,11 +323,7 @@ __gnat_ttyname (int filedes ATTRIBUTE_UNUSED)
|| defined (__QNX__)
# ifdef __MINGW32__
-# if OLD_MINGW
-# include <termios.h>
-# else
-# include <conio.h> /* for getch(), kbhit() */
-# endif
+# include <conio.h> /* for getch(), kbhit() */
# else
# include <termios.h>
# endif
diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index fb89616..b1f1032 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -737,6 +737,9 @@ decl_attributes (tree *node, tree attributes, int flags,
if (spec->max_length < 0)
inform (input_location, "expected %i or more, found %i",
spec->min_length, nargs);
+ else if (spec->min_length == spec->max_length)
+ inform (input_location, "expected %i, found %i",
+ spec->min_length, nargs);
else
inform (input_location, "expected between %i and %i, found %i",
spec->min_length, spec->max_length, nargs);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index ba3d76d..415c4cf 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,17 @@
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * c-common.cc (c_common_reswords): Add __is_convertible and
+ __is_nothrow_convertible.
+ * c-common.h (enum rid): Add RID_IS_CONVERTIBLE and
+ RID_IS_NOTHROW_CONVERTIBLE.
+
+2022-09-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/106830
+ * c-warn.cc (check_for_xor_used_as_pow): Don't try checking
+ values that don't fit in uhwi.
+
2022-09-15 Richard Biener <rguenther@suse.de>
* c-common.h (build_void_list_node): Remove.
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index c0f15f4..dce3045 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -541,6 +541,8 @@ const struct c_common_resword c_common_reswords[] =
{ "__is_constructible", RID_IS_CONSTRUCTIBLE, D_CXXONLY },
{ "__is_nothrow_assignable", RID_IS_NOTHROW_ASSIGNABLE, D_CXXONLY },
{ "__is_nothrow_constructible", RID_IS_NOTHROW_CONSTRUCTIBLE, D_CXXONLY },
+ { "__is_convertible", RID_IS_CONVERTIBLE, D_CXXONLY },
+ { "__is_nothrow_convertible", RID_IS_NOTHROW_CONVERTIBLE, D_CXXONLY },
{ "__reference_constructs_from_temporary", RID_REF_CONSTRUCTS_FROM_TEMPORARY,
D_CXXONLY },
{ "__reference_converts_from_temporary", RID_REF_CONVERTS_FROM_TEMPORARY,
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 2f592f5..31397d8 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -184,6 +184,7 @@ enum rid
RID_IS_UNION, RID_UNDERLYING_TYPE,
RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE,
RID_IS_NOTHROW_ASSIGNABLE, RID_IS_NOTHROW_CONSTRUCTIBLE,
+ RID_IS_CONVERTIBLE, RID_IS_NOTHROW_CONVERTIBLE,
RID_REF_CONSTRUCTS_FROM_TEMPORARY,
RID_REF_CONVERTS_FROM_TEMPORARY,
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index a1557eb..b709f84 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1112,7 +1112,7 @@ c_cpp_builtins (cpp_reader *pfile)
if (flag_threadsafe_statics)
cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
if (flag_char8_t)
- cpp_define (pfile, "__cpp_char8_t=201811L");
+ cpp_define (pfile, "__cpp_char8_t=202207L");
#ifndef THREAD_MODEL_SPEC
/* Targets that define THREAD_MODEL_SPEC need to define
__STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves. */
diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc
index ed79cc3..6742f44 100644
--- a/gcc/c-family/c-warn.cc
+++ b/gcc/c-family/c-warn.cc
@@ -3809,12 +3809,9 @@ check_for_xor_used_as_pow (location_t lhs_loc, tree lhs_val,
location_t operator_loc,
tree rhs_val)
{
- /* Only complain if both args are non-negative integer constants. */
- if (!(TREE_CODE (lhs_val) == INTEGER_CST
- && tree_int_cst_sgn (lhs_val) >= 0))
- return;
- if (!(TREE_CODE (rhs_val) == INTEGER_CST
- && tree_int_cst_sgn (rhs_val) >= 0))
+ /* Only complain if both args are non-negative integer constants that fit
+ in uhwi. */
+ if (!tree_fits_uhwi_p (lhs_val) || !tree_fits_uhwi_p (rhs_val))
return;
/* Only complain if the LHS is 2 or 10. */
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index b7fe1a4..4b852b8 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,29 @@
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106981
+ * c-typeck.cc (c_tree_equal): Only strip NON_LVALUE_EXPRs at the
+ start. For CONSTANT_CLASS_P or CASE_CONVERT: return false if t1 and
+ t2 have different types.
+
+2022-09-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/106830
+ * c-parser.cc (c_parser_initelt): Initialize m_decimal.
+ (c_parser_cast_expression): Likewise.
+ (c_parser_alignof_expression): Likewise.
+ (c_parser_postfix_expression_after_paren_type): Likewise.
+ (c_parser_postfix_expression_after_primary): Likewise.
+ (c_parser_expression): Likewise.
+ (c_parser_omp_variable_list): Likewise.
+ (c_parser_transaction_expression): Likewise.
+ * c-tree.h (c_expr::set_error): Likewise.
+ * c-typeck.cc (c_expr_sizeof_expr): Likewise.
+ (parser_build_unary_op): Likewise.
+ (parser_build_binary_op): Likewise.
+ (digest_init): Likewise.
+ (pop_init_level): Likewise.
+ * gimple-parser.cc (c_parser_gimple_call_internal): Likewise.
+
2022-09-19 Marek Polacek <polacek@redhat.com>
PR c/106947
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index d134448..bce79d3 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -5464,6 +5464,7 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
= objc_build_message_expr (rec, args);
mexpr.original_code = ERROR_MARK;
mexpr.original_type = NULL;
+ mexpr.m_decimal = 0;
/* Now parse and process the remainder of the
initializer, starting with this message
expression as a primary-expression. */
@@ -8146,6 +8147,7 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
+ ret.m_decimal = 0;
return ret;
}
else
@@ -8464,6 +8466,7 @@ c_parser_alignof_expression (c_parser *parser)
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
set_c_expr_source_range (&ret, start_loc, end_loc);
+ ret.m_decimal = 0;
return ret;
}
else
@@ -8483,6 +8486,7 @@ c_parser_alignof_expression (c_parser *parser)
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
set_c_expr_source_range (&ret, start_loc, end_loc);
+ ret.m_decimal = 0;
return ret;
}
}
@@ -10383,6 +10387,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
expr.value = build_compound_literal (start_loc, type, init.value, non_const,
alignas_align);
set_c_expr_source_range (&expr, init.src_range);
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
if (type != error_mark_node
@@ -10597,6 +10602,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
set_c_expr_source_range (&expr, start, finish);
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
+ expr.m_decimal = 0;
break;
case CPP_OPEN_PAREN:
/* Function call. */
@@ -10645,6 +10651,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
= c_build_function_call_vec (expr_loc, arg_loc, expr.value,
exprlist, origtypes);
set_c_expr_source_range (&expr, start, finish);
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) == INTEGER_CST
@@ -10695,6 +10702,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
expr.original_type = DECL_BIT_FIELD_TYPE (field);
}
+ expr.m_decimal = 0;
break;
case CPP_DEREF:
/* Structure element reference. */
@@ -10736,6 +10744,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
expr.original_type = DECL_BIT_FIELD_TYPE (field);
}
+ expr.m_decimal = 0;
break;
case CPP_PLUS_PLUS:
/* Postincrement. */
@@ -10806,6 +10815,7 @@ c_parser_expression (c_parser *parser)
expr.value = build_compound_expr (loc, expr.value, next.value);
expr.original_code = COMPOUND_EXPR;
expr.original_type = next.original_type;
+ expr.m_decimal = 0;
}
return expr;
}
@@ -13256,6 +13266,7 @@ c_parser_omp_variable_list (c_parser *parser,
t_expr.original_code = ERROR_MARK;
t_expr.original_type = NULL;
set_c_expr_source_range (&t_expr, op_loc, op_loc);
+ t_expr.m_decimal = 0;
t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
true, false);
t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
@@ -23566,6 +23577,7 @@ c_parser_transaction_expression (c_parser *parser, enum rid keyword)
TRANSACTION_EXPR_RELAXED (ret.value) = 1;
SET_EXPR_LOCATION (ret.value, loc);
ret.original_code = TRANSACTION_EXPR;
+ ret.m_decimal = 0;
if (!parens.require_close (parser))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index b4231a1..46a3e8e 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -164,12 +164,13 @@ struct c_expr
}
/* Set the value to error_mark_node whilst ensuring that src_range
- is initialized. */
+ and m_decimal are initialized. */
void set_error ()
{
value = error_mark_node;
src_range.m_start = UNKNOWN_LOCATION;
src_range.m_finish = UNKNOWN_LOCATION;
+ m_decimal = 0;
}
};
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 33d1e84..ac242b5 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2994,6 +2994,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
+ ret.m_decimal = 0;
pop_maybe_used (false);
}
else
@@ -3017,6 +3018,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
c_last_sizeof_loc = loc;
ret.original_code = SIZEOF_EXPR;
ret.original_type = NULL;
+ ret.m_decimal = 0;
if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr)))
{
/* sizeof is evaluated when given a vla (C99 6.5.3.4p2). */
@@ -3047,6 +3049,7 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t)
c_last_sizeof_loc = loc;
ret.original_code = SIZEOF_EXPR;
ret.original_type = NULL;
+ ret.m_decimal = 0;
if (type == error_mark_node)
{
ret.value = error_mark_node;
@@ -3782,6 +3785,7 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
result.original_code = code;
result.original_type = NULL;
+ result.m_decimal = 0;
if (reject_gcc_builtin (arg.value))
{
@@ -3844,6 +3848,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
arg1.value, arg2.value, true);
result.original_code = code;
result.original_type = NULL;
+ result.m_decimal = 0;
if (TREE_CODE (result.value) == ERROR_MARK)
{
@@ -8072,6 +8077,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
expr.value = inside_init;
expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
expr.original_type = NULL;
+ expr.m_decimal = 0;
maybe_warn_string_init (init_loc, type, expr);
if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
@@ -8936,6 +8942,7 @@ pop_init_level (location_t loc, int implicit,
ret.value = NULL_TREE;
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
+ ret.m_decimal = 0;
if (implicit == 0)
{
@@ -16044,14 +16051,10 @@ c_tree_equal (tree t1, tree t2)
if (!t1 || !t2)
return false;
- for (code1 = TREE_CODE (t1);
- CONVERT_EXPR_CODE_P (code1)
- || code1 == NON_LVALUE_EXPR;
+ for (code1 = TREE_CODE (t1); code1 == NON_LVALUE_EXPR;
code1 = TREE_CODE (t1))
t1 = TREE_OPERAND (t1, 0);
- for (code2 = TREE_CODE (t2);
- CONVERT_EXPR_CODE_P (code2)
- || code2 == NON_LVALUE_EXPR;
+ for (code2 = TREE_CODE (t2); code2 == NON_LVALUE_EXPR;
code2 = TREE_CODE (t2))
t2 = TREE_OPERAND (t2, 0);
@@ -16062,6 +16065,9 @@ c_tree_equal (tree t1, tree t2)
if (code1 != code2)
return false;
+ if (CONSTANT_CLASS_P (t1) && !comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+
switch (code1)
{
case INTEGER_CST:
@@ -16181,6 +16187,11 @@ c_tree_equal (tree t1, tree t2)
return true;
}
+ CASE_CONVERT:
+ if (!comptypes (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ break;
+
default:
break;
}
diff --git a/gcc/c/gimple-parser.cc b/gcc/c/gimple-parser.cc
index b909eac..5a2da2c 100644
--- a/gcc/c/gimple-parser.cc
+++ b/gcc/c/gimple-parser.cc
@@ -1332,6 +1332,7 @@ c_parser_gimple_call_internal (gimple_parser &parser)
exprlist.address ());
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
+ expr.m_decimal = 0;
}
}
return expr;
@@ -1751,6 +1752,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
finish = c_parser_tokens_buf (parser, 0)->location;
expr.value = build_array_ref (op_loc, expr.value, idx);
set_c_expr_source_range (&expr, start, finish);
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
@@ -1774,6 +1776,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
expr.value = build_call_array_loc
(expr_loc, TREE_TYPE (TREE_TYPE (expr.value)),
expr.value, exprlist.length (), exprlist.address ());
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -1802,6 +1805,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
expr.value = build_component_ref (op_loc, expr.value, ident,
comp_loc, UNKNOWN_LOCATION);
set_c_expr_source_range (&expr, start, finish);
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
expr.original_type = NULL;
@@ -1851,6 +1855,7 @@ c_parser_gimple_postfix_expression_after_primary (gimple_parser &parser,
ident, comp_loc,
expr.get_location ());
set_c_expr_source_range (&expr, start, finish);
+ expr.m_decimal = 0;
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
expr.original_type = NULL;
diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc
index a8b0139..a363e0b 100644
--- a/gcc/cfgcleanup.cc
+++ b/gcc/cfgcleanup.cc
@@ -2599,7 +2599,7 @@ trivially_empty_bb_p (basic_block bb)
return value. Fill in *RET and *USE with the return and use insns
if any found, otherwise NULL. All CLOBBERs are ignored. */
-static bool
+bool
bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
{
*ret = *use = NULL;
diff --git a/gcc/cfgcleanup.h b/gcc/cfgcleanup.h
index a6d882f..f1021ca 100644
--- a/gcc/cfgcleanup.h
+++ b/gcc/cfgcleanup.h
@@ -30,5 +30,6 @@ extern int flow_find_head_matching_sequence (basic_block, basic_block,
extern bool delete_unreachable_blocks (void);
extern void delete_dead_jumptables (void);
extern bool cleanup_cfg (int);
+extern bool bb_is_just_return (basic_block, rtx_insn **, rtx_insn **);
#endif /* GCC_CFGCLEANUP_H */
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index a05c338..90cd6ee 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -3901,6 +3901,7 @@ fixup_reorder_chain (void)
/* Now add jumps and labels as needed to match the blocks new
outgoing edges. */
+ bool remove_unreachable_blocks = false;
for (bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; bb ; bb = (basic_block)
bb->aux)
{
@@ -4043,10 +4044,30 @@ fixup_reorder_chain (void)
continue;
}
+ /* If E_FALL->dest is just a return block, then we can emit a
+ return rather than a jump to the return block. */
+ rtx_insn *ret, *use;
+ basic_block dest;
+ if (bb_is_just_return (e_fall->dest, &ret, &use)
+ && (PATTERN (ret) == simple_return_rtx || PATTERN (ret) == ret_rtx))
+ {
+ ret_label = PATTERN (ret);
+ dest = EXIT_BLOCK_PTR_FOR_FN (cfun);
+
+ /* E_FALL->dest might become unreachable as a result of
+ replacing the jump with a return. So arrange to remove
+ unreachable blocks. */
+ remove_unreachable_blocks = true;
+ }
+ else
+ {
+ dest = e_fall->dest;
+ }
+
/* We got here if we need to add a new jump insn.
Note force_nonfallthru can delete E_FALL and thus we have to
save E_FALL->src prior to the call to force_nonfallthru. */
- nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
+ nb = force_nonfallthru_and_redirect (e_fall, dest, ret_label);
if (nb)
{
nb->aux = bb->aux;
@@ -4134,6 +4155,12 @@ fixup_reorder_chain (void)
ei_next (&ei2);
}
}
+
+ /* Replacing a jump with a return may have exposed an unreachable
+ block. Conditionally remove them if such transformations were
+ made. */
+ if (remove_unreachable_blocks)
+ delete_unreachable_blocks ();
}
/* Perform sanity checks on the insn chain.
diff --git a/gcc/common.opt b/gcc/common.opt
index 06ef768..296d6f1 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2106,7 +2106,7 @@ Specify the algorithm to partition symbols and vars at linktime.
; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h.
flto-compression-level=
Common Joined RejectNegative UInteger Var(flag_lto_compression_level) Init(-1) IntegerRange(0, 19)
--flto-compression-level=<number> Use zlib/zstd compression level <number> for IL.
+Use zlib/zstd compression level <number> for IL.
flto-odr-type-merging
Common Ignore
diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 7721916..c39ed2e 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -1224,7 +1224,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
dependent mask bits, in case more than one -march string is passed. */
-static void
+void
riscv_parse_arch_string (const char *isa,
struct gcc_options *opts,
location_t loc)
diff --git a/gcc/config.gcc b/gcc/config.gcc
index f4e757b..c1b1215 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -515,7 +515,7 @@ pru-*-*)
;;
riscv*)
cpu_type=riscv
- extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o"
+ extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o riscv-shorten-memrefs.o riscv-selftests.o"
d_target_objs="riscv-d.o"
;;
rs6000*-*-*)
@@ -3941,6 +3941,9 @@ if test x$with_arch = x ; then
mips*-*-vxworks)
with_arch=mips2
;;
+ nvptx-*)
+ with_arch=sm_30
+ ;;
esac
# Avoid overriding --with-arch-32 and --with-arch-64 values.
@@ -5293,6 +5296,25 @@ case "${target}" in
esac
;;
+ nvptx-*)
+ supported_defaults=arch
+ TM_MULTILIB_CONFIG=$with_arch
+ #TODO 'sm_[...]' list per 'nvptx-sm.def'.
+ case $with_arch in
+ sm_30 )
+ # OK; default.
+ ;;
+ sm_35 | sm_53 | sm_70 | sm_75 | sm_80 )
+ # OK, but we'd like 'sm_30', too.
+ TM_MULTILIB_CONFIG="$TM_MULTILIB_CONFIG sm_30"
+ ;;
+ * )
+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+
powerpc*-*-* | rs6000-*-*)
supported_defaults="abi cpu cpu_32 cpu_64 float tune tune_32 tune_64 advance_toolchain"
diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def
index 3c2b165..6150448 100644
--- a/gcc/config/aarch64/aarch64-arches.def
+++ b/gcc/config/aarch64/aarch64-arches.def
@@ -41,5 +41,8 @@ AARCH64_ARCH("armv8.7-a", generic, 8_7A, 8, AARCH64_FL_FOR_ARCH8
AARCH64_ARCH("armv8.8-a", generic, 8_8A, 8, AARCH64_FL_FOR_ARCH8_8)
AARCH64_ARCH("armv8-r", generic, 8R , 8, AARCH64_FL_FOR_ARCH8_R)
AARCH64_ARCH("armv9-a", generic, 9A , 9, AARCH64_FL_FOR_ARCH9)
+AARCH64_ARCH("armv9.1-a", generic, 9_1A, 9, AARCH64_FL_FOR_ARCH9_1)
+AARCH64_ARCH("armv9.2-a", generic, 9_2A, 9, AARCH64_FL_FOR_ARCH9_2)
+AARCH64_ARCH("armv9.3-a", generic, 9_3A, 9, AARCH64_FL_FOR_ARCH9_3)
#undef AARCH64_ARCH
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index 41d9535..0402bfb 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -171,6 +171,7 @@ AARCH64_CORE("cortex-x2", cortexx2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARC
AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversen2, 0x41, 0xd49, -1)
-AARCH64_CORE("demeter", demeter, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, demeter, 0x41, 0xd4f, -1)
+AARCH64_CORE("demeter", demeter, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1)
+AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1)
#undef AARCH64_CORE
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 27da961..84e9bbf 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter"
+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,ares,neoversen1,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,zeus,neoversev1,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexx2,neoversen2,demeter,neoversev2"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 467979a..b4971bd 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -534,7 +534,7 @@ static const struct cpu_addrcost_table neoversen2_addrcost_table =
0 /* imm_offset */
};
-static const struct cpu_addrcost_table demeter_addrcost_table =
+static const struct cpu_addrcost_table neoversev2_addrcost_table =
{
{
1, /* hi */
@@ -677,7 +677,7 @@ static const struct cpu_regmove_cost neoversev1_regmove_cost =
2 /* FP2FP */
};
-static const struct cpu_regmove_cost demeter_regmove_cost =
+static const struct cpu_regmove_cost neoversev2_regmove_cost =
{
1, /* GP2GP */
/* Spilling to int<->fp instead of memory is recommended so set
@@ -2426,7 +2426,7 @@ static const struct tune_params neoversen2_tunings =
&generic_prefetch_tune
};
-static const advsimd_vec_cost demeter_advsimd_vector_cost =
+static const advsimd_vec_cost neoversev2_advsimd_vector_cost =
{
2, /* int_stmt_cost */
2, /* fp_stmt_cost */
@@ -2457,7 +2457,7 @@ static const advsimd_vec_cost demeter_advsimd_vector_cost =
1 /* store_cost */
};
-static const sve_vec_cost demeter_sve_vector_cost =
+static const sve_vec_cost neoversev2_sve_vector_cost =
{
{
2, /* int_stmt_cost */
@@ -2514,7 +2514,7 @@ static const sve_vec_cost demeter_sve_vector_cost =
3 /* scatter_store_elt_cost */
};
-static const aarch64_scalar_vec_issue_info demeter_scalar_issue_info =
+static const aarch64_scalar_vec_issue_info neoversev2_scalar_issue_info =
{
3, /* loads_stores_per_cycle */
2, /* stores_per_cycle */
@@ -2523,7 +2523,7 @@ static const aarch64_scalar_vec_issue_info demeter_scalar_issue_info =
1 /* fp_simd_store_general_ops */
};
-static const aarch64_advsimd_vec_issue_info demeter_advsimd_issue_info =
+static const aarch64_advsimd_vec_issue_info neoversev2_advsimd_issue_info =
{
{
3, /* loads_stores_per_cycle */
@@ -2537,7 +2537,7 @@ static const aarch64_advsimd_vec_issue_info demeter_advsimd_issue_info =
3 /* ld4_st4_general_ops */
};
-static const aarch64_sve_vec_issue_info demeter_sve_issue_info =
+static const aarch64_sve_vec_issue_info neoversev2_sve_issue_info =
{
{
{
@@ -2559,15 +2559,15 @@ static const aarch64_sve_vec_issue_info demeter_sve_issue_info =
1 /* gather_scatter_pair_pred_ops */
};
-static const aarch64_vec_issue_info demeter_vec_issue_info =
+static const aarch64_vec_issue_info neoversev2_vec_issue_info =
{
- &demeter_scalar_issue_info,
- &demeter_advsimd_issue_info,
- &demeter_sve_issue_info
+ &neoversev2_scalar_issue_info,
+ &neoversev2_advsimd_issue_info,
+ &neoversev2_sve_issue_info
};
/* Demeter costs for vector insn classes. */
-static const struct cpu_vector_cost demeter_vector_cost =
+static const struct cpu_vector_cost neoversev2_vector_cost =
{
1, /* scalar_int_stmt_cost */
2, /* scalar_fp_stmt_cost */
@@ -2575,17 +2575,17 @@ static const struct cpu_vector_cost demeter_vector_cost =
1, /* scalar_store_cost */
1, /* cond_taken_branch_cost */
1, /* cond_not_taken_branch_cost */
- &demeter_advsimd_vector_cost, /* advsimd */
- &demeter_sve_vector_cost, /* sve */
- &demeter_vec_issue_info /* issue_info */
+ &neoversev2_advsimd_vector_cost, /* advsimd */
+ &neoversev2_sve_vector_cost, /* sve */
+ &neoversev2_vec_issue_info /* issue_info */
};
-static const struct tune_params demeter_tunings =
+static const struct tune_params neoversev2_tunings =
{
&cortexa76_extra_costs,
- &demeter_addrcost_table,
- &demeter_regmove_cost,
- &demeter_vector_cost,
+ &neoversev2_addrcost_table,
+ &neoversev2_regmove_cost,
+ &neoversev2_vector_cost,
&generic_branch_cost,
&generic_approx_modes,
SVE_128, /* sve_width */
@@ -15566,7 +15566,7 @@ aarch64_vec_op_count::rename_cycles_per_iter () const
{
if (sve_issue_info () == &neoverse512tvb_sve_issue_info
|| sve_issue_info () == &neoversen2_sve_issue_info
- || sve_issue_info () == &demeter_sve_issue_info)
+ || sve_issue_info () == &neoversev2_sve_issue_info)
/* + 1 for an addition. We've already counted a general op for each
store, so we don't need to account for stores separately. The branch
reads no registers and so does not need to be counted either.
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2eed6e8..f790de1 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -239,6 +239,15 @@
/* Armv8.8-a architecture extensions. */
#define AARCH64_FL_V8_8 (1ULL << 45)
+/* Armv9.1-A. */
+#define AARCH64_FL_V9_1 (1ULL << 46)
+
+/* Armv9.2-A. */
+#define AARCH64_FL_V9_2 (1ULL << 47)
+
+/* Armv9.3-A. */
+#define AARCH64_FL_V9_3 (1ULL << 48)
+
/* Has FP and SIMD. */
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
@@ -273,6 +282,12 @@
#define AARCH64_FL_FOR_ARCH9 \
(AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_V9 \
| AARCH64_FL_F16)
+#define AARCH64_FL_FOR_ARCH9_1 \
+ (AARCH64_FL_FOR_ARCH9 | AARCH64_FL_FOR_ARCH8_6 | AARCH64_FL_V9_1)
+#define AARCH64_FL_FOR_ARCH9_2 \
+ (AARCH64_FL_FOR_ARCH9_1 | AARCH64_FL_FOR_ARCH8_7 | AARCH64_FL_V9_2)
+#define AARCH64_FL_FOR_ARCH9_3 \
+ (AARCH64_FL_FOR_ARCH9_2 | AARCH64_FL_FOR_ARCH8_8 | AARCH64_FL_V9_3)
/* Macros to test ISA flags. */
@@ -312,6 +327,9 @@
#define AARCH64_ISA_V8_R (aarch64_isa_flags & AARCH64_FL_V8_R)
#define AARCH64_ISA_PAUTH (aarch64_isa_flags & AARCH64_FL_PAUTH)
#define AARCH64_ISA_V9 (aarch64_isa_flags & AARCH64_FL_V9)
+#define AARCH64_ISA_V9_1 (aarch64_isa_flags & AARCH64_FL_V9_1)
+#define AARCH64_ISA_V9_2 (aarch64_isa_flags & AARCH64_FL_V9_2)
+#define AARCH64_ISA_V9_3 (aarch64_isa_flags & AARCH64_FL_V9_3)
#define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS)
#define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64)
@@ -1260,14 +1278,44 @@ extern enum aarch64_code_model aarch64_cmodel;
#define ENDIAN_LANE_N(NUNITS, N) \
(BYTES_BIG_ENDIAN ? NUNITS - 1 - N : N)
+/* Extra specs when building a native AArch64-hosted compiler.
+ Option rewriting rules based on host system. */
+#if defined(__aarch64__)
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+#define HAVE_LOCAL_CPU_DETECT
+# define EXTRA_SPEC_FUNCTIONS \
+ { "local_cpu_detect", host_detect_local_cpu }, \
+ MCPU_TO_MARCH_SPEC_FUNCTIONS
+
+/* Rewrite -m{arch,cpu,tune}=native based on the host system information.
+ When rewriting -march=native convert it into an -mcpu option if no other
+ -mcpu or -mtune was given. */
+# define MCPU_MTUNE_NATIVE_SPECS \
+ " %{march=native:%<march=native %:local_cpu_detect(%{mcpu=*|mtune=*:arch;:cpu})}" \
+ " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}" \
+ " %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
+/* This will be used in OPTION_DEFAULT_SPECS below.
+ When GCC is configured with --with-tune we don't want to materialize an
+ implicit -mtune would prevent the rewriting of -march=native into
+ -mcpu=native as per the above rules. */
+#define CONFIG_TUNE_SPEC \
+ { "tune", "%{!mcpu=*:%{!mtune=*:%{!march=native:-mtune=%(VALUE)}}}" },
+#else
+# define MCPU_MTUNE_NATIVE_SPECS ""
+# define EXTRA_SPEC_FUNCTIONS MCPU_TO_MARCH_SPEC_FUNCTIONS
+# define CONFIG_TUNE_SPEC \
+ {"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}"},
+#endif
+
/* Support for configure-time --with-arch, --with-cpu and --with-tune.
--with-arch and --with-cpu are ignored if either -mcpu or -march is used.
--with-tune is ignored if either -mtune or -mcpu is used (but is not
- affected by -march). */
+ affected by -march, except in the -march=native case as per the
+ CONFIG_TUNE_SPEC above). */
#define OPTION_DEFAULT_SPECS \
{"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
{"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
- {"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}"},
+ CONFIG_TUNE_SPEC
#define MCPU_TO_MARCH_SPEC \
" %{mcpu=*:-march=%:rewrite_mcpu(%{mcpu=*:%*})}"
@@ -1276,22 +1324,6 @@ extern const char *aarch64_rewrite_mcpu (int argc, const char **argv);
#define MCPU_TO_MARCH_SPEC_FUNCTIONS \
{ "rewrite_mcpu", aarch64_rewrite_mcpu },
-#if defined(__aarch64__)
-extern const char *host_detect_local_cpu (int argc, const char **argv);
-#define HAVE_LOCAL_CPU_DETECT
-# define EXTRA_SPEC_FUNCTIONS \
- { "local_cpu_detect", host_detect_local_cpu }, \
- MCPU_TO_MARCH_SPEC_FUNCTIONS
-
-# define MCPU_MTUNE_NATIVE_SPECS \
- " %{march=native:%<march=native %:local_cpu_detect(arch)}" \
- " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}" \
- " %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
-#else
-# define MCPU_MTUNE_NATIVE_SPECS ""
-# define EXTRA_SPEC_FUNCTIONS MCPU_TO_MARCH_SPEC_FUNCTIONS
-#endif
-
#define ASM_CPU_SPEC \
MCPU_TO_MARCH_SPEC
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 7361687..95b2b14 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -168,6 +168,9 @@
;; z Constant call address operand.
;; C Integer SSE constant with all bits set operand.
;; F Floating-point SSE constant with all bits set operand.
+;; H Integer SSE constant that is 128/256bit all ones
+;; and zero-extand to 256/512bit, or 128bit all ones
+;; and zero-extend to 512bit.
;; M x86-64 memory operand.
(define_constraint "Bf"
@@ -233,6 +236,11 @@
(and (match_test "TARGET_SSE")
(match_operand 0 "float_vector_all_ones_operand")))
+(define_constraint "BH"
+ "@internal integer constant with last half/quarter bits set operand."
+ (ior (match_operand 0 "vector_all_ones_zero_extend_half_operand")
+ (match_operand 0 "vector_all_ones_zero_extend_quarter_operand")))
+
;; NB: Similar to 'm', but don't use define_memory_constraint on x86-64
;; to prevent LRA from converting the operand to the form '(mem (reg X))'
;; where X is a base register.
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 5334363..6baff6d 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -19604,6 +19604,119 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d)
return false;
}
+/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D
+ in terms of a pair of shufps+ shufps/pshufd instructions. */
+static bool
+expand_vec_perm_shufps_shufps (struct expand_vec_perm_d *d)
+{
+ unsigned char perm1[4];
+ machine_mode vmode = d->vmode;
+ bool ok;
+ unsigned i, j, k, count = 0;
+
+ if (d->one_operand_p
+ || (vmode != V4SImode && vmode != V4SFmode))
+ return false;
+
+ if (d->testing_p)
+ return true;
+
+ for (i = 0; i < 4; ++i)
+ count += d->perm[i] > 3 ? 1 : 0;
+
+ gcc_assert (count & 3);
+
+ rtx tmp = gen_reg_rtx (vmode);
+ /* 2 from op0 and 2 from op1. */
+ if (count == 2)
+ {
+ unsigned char perm2[4];
+ for (i = 0, j = 0, k = 2; i < 4; ++i)
+ if (d->perm[i] & 4)
+ {
+ perm1[k++] = d->perm[i];
+ perm2[i] = k - 1;
+ }
+ else
+ {
+ perm1[j++] = d->perm[i];
+ perm2[i] = j - 1;
+ }
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (tmp, d->op0, d->op1,
+ perm1, d->nelt, false);
+ gcc_assert (ok);
+ if (vmode == V4SImode && TARGET_SSE2)
+ /* pshufd. */
+ ok = expand_vselect (d->target, tmp,
+ perm2, d->nelt, false);
+ else
+ {
+ /* shufps. */
+ perm2[2] += 4;
+ perm2[3] += 4;
+ ok = expand_vselect_vconcat (d->target, tmp, tmp,
+ perm2, d->nelt, false);
+ }
+ gcc_assert (ok);
+ }
+ /* 3 from one op and 1 from another. */
+ else
+ {
+ unsigned pair_idx = 8, lone_idx = 8, shift;
+
+ /* Find the lone index. */
+ for (i = 0; i < 4; ++i)
+ if ((d->perm[i] > 3 && count == 1)
+ || (d->perm[i] < 4 && count == 3))
+ lone_idx = i;
+
+ /* When lone_idx is not 0, it must from second op(count == 1). */
+ gcc_assert (count == (lone_idx ? 1 : 3));
+
+ /* Find the pair index that sits in the same half as the lone index. */
+ shift = lone_idx & 2;
+ pair_idx = 1 - lone_idx + 2 * shift;
+
+ /* First permutate lone index and pair index into the same vector as
+ [ lone, lone, pair, pair ]. */
+ perm1[1] = perm1[0]
+ = (count == 3) ? d->perm[lone_idx] : d->perm[lone_idx] - 4;
+ perm1[3] = perm1[2]
+ = (count == 3) ? d->perm[pair_idx] : d->perm[pair_idx] + 4;
+
+ /* Alway put the vector contains lone indx at the first. */
+ if (count == 1)
+ std::swap (d->op0, d->op1);
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (tmp, d->op0, d->op1,
+ perm1, d->nelt, false);
+ gcc_assert (ok);
+
+ /* Refine lone and pair index to original order. */
+ perm1[shift] = lone_idx << 1;
+ perm1[shift + 1] = pair_idx << 1;
+
+ /* Select the remaining 2 elements in another vector. */
+ for (i = 2 - shift; i < 4 - shift; ++i)
+ perm1[i] = lone_idx == 1 ? d->perm[i] + 4 : d->perm[i];
+
+ /* Adjust to original selector. */
+ if (lone_idx > 1)
+ std::swap (tmp, d->op1);
+
+ /* shufps. */
+ ok = expand_vselect_vconcat (d->target, tmp, d->op1,
+ perm1, d->nelt, false);
+
+ gcc_assert (ok);
+ }
+
+ return true;
+}
+
/* A subroutine of ix86_expand_vec_perm_const_1. Try to implement D
in terms of a pair of pshuflw + pshufhw instructions. */
@@ -22152,6 +22265,9 @@ ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
if (expand_vec_perm_2perm_pblendv (d, true))
return true;
+ if (expand_vec_perm_shufps_shufps (d))
+ return true;
+
/* Try sequences of three instructions. */
if (expand_vec_perm_even_odd_pack (d))
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index dadf453..ca799da 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -5186,7 +5186,8 @@ standard_80387_constant_rtx (int idx)
XFmode);
}
-/* Return 1 if X is all bits 0 and 2 if X is all bits 1
+/* Return 1 if X is all bits 0, 2 if X is all bits 1
+ and 3 if X is all bits 1 with zero extend
in supported SSE/AVX vector mode. */
int
@@ -5234,6 +5235,10 @@ standard_sse_constant_p (rtx x, machine_mode pred_mode)
}
}
+ if (vector_all_ones_zero_extend_half_operand (x, mode)
+ || vector_all_ones_zero_extend_quarter_operand (x, mode))
+ return 3;
+
return 0;
}
@@ -5341,6 +5346,25 @@ standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
gcc_unreachable ();
}
}
+ else if (vector_all_ones_zero_extend_half_operand (x, mode))
+ {
+ if (GET_MODE_SIZE (mode) == 64)
+ {
+ gcc_assert (TARGET_AVX512F);
+ return "vpcmpeqd \t %t0, %t0, %t0";
+ }
+ else if (GET_MODE_SIZE (mode) == 32)
+ {
+ gcc_assert (TARGET_AVX);
+ return "vpcmpeqd \t %x0, %x0, %x0";
+ }
+ gcc_unreachable ();
+ }
+ else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
+ {
+ gcc_assert (TARGET_AVX512F);
+ return "vpcmpeqd \t %x0, %x0, %x0";
+ }
gcc_unreachable ();
}
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 222a041..c359e2d 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1676,7 +1676,7 @@
(define_expand "floorv2sf2"
[(set (match_operand:V2SF 0 "register_operand")
(unspec:V2SF
- [(match_operand:V2SF 1 "vector_operand")
+ [(match_operand:V2SF 1 "register_operand")
(match_dup 2)]
UNSPEC_ROUND))]
"TARGET_SSE4_1 && !flag_trapping_math
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 4f16bb7..655eabf 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1159,6 +1159,55 @@
(match_test "INTEGRAL_MODE_P (GET_MODE (op))")
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
+/* Return true if operand is an 128/256bit all ones vector
+ that zero-extends to 256/512bit. */
+(define_predicate "vector_all_ones_zero_extend_half_operand"
+ (match_code "const_vector")
+{
+ mode = GET_MODE (op);
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT
+ || (GET_MODE_SIZE (mode) != 32
+ && GET_MODE_SIZE (mode) != 64))
+ return false;
+
+ int nelts = CONST_VECTOR_NUNITS (op);
+ for (int i = 0; i != nelts; i++)
+ {
+ rtx elt = CONST_VECTOR_ELT (op, i);
+ if (i < nelts / 2
+ && elt != CONSTM1_RTX (GET_MODE_INNER (mode)))
+ return false;
+ if (i >= nelts / 2
+ && elt != CONST0_RTX (GET_MODE_INNER (mode)))
+ return false;
+ }
+ return true;
+})
+
+/* Return true if operand is an 128bit all ones vector
+ that zero extends to 512bit. */
+(define_predicate "vector_all_ones_zero_extend_quarter_operand"
+ (match_code "const_vector")
+{
+ mode = GET_MODE (op);
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT
+ || GET_MODE_SIZE (mode) != 64)
+ return false;
+
+ int nelts = CONST_VECTOR_NUNITS (op);
+ for (int i = 0; i != nelts; i++)
+ {
+ rtx elt = CONST_VECTOR_ELT (op, i);
+ if (i < nelts / 4
+ && elt != CONSTM1_RTX (GET_MODE_INNER (mode)))
+ return false;
+ if (i >= nelts / 4
+ && elt != CONST0_RTX (GET_MODE_INNER (mode)))
+ return false;
+ }
+ return true;
+})
+
; Return true when OP is operand acceptable for vector memory operand.
; Only AVX can have misaligned memory operand.
(define_predicate "vector_memory_operand"
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index b60c0d3..5c18963 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1323,9 +1323,9 @@
(define_insn "mov<mode>_internal"
[(set (match_operand:VMOVE 0 "nonimmediate_operand"
- "=v,v ,v ,m")
+ "=v,v ,v,v ,m")
(match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand"
- " C,<sseconstm1>,vm,v"))]
+ " C,<sseconstm1>,BH,vm,v"))]
"TARGET_SSE
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))
@@ -1343,7 +1343,7 @@
gcc_unreachable ();
}
}
- [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
+ [(set_attr "type" "sselog1,sselog1,sselog1,ssemov,ssemov")
(set_attr "prefix" "maybe_vex")
(set (attr "mode")
(cond [(match_test "TARGET_AVX")
@@ -1354,7 +1354,7 @@
(and (match_test "<MODE>mode == V2DFmode")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
- (and (eq_attr "alternative" "3")
+ (and (eq_attr "alternative" "4")
(match_test "TARGET_SSE_TYPELESS_STORES"))
(const_string "V4SF")
(and (eq_attr "alternative" "0")
diff --git a/gcc/config/nvptx/gen-multilib-matches.sh b/gcc/config/nvptx/gen-multilib-matches.sh
new file mode 100755
index 0000000..9a5878e
--- /dev/null
+++ b/gcc/config/nvptx/gen-multilib-matches.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# Print nvptx 'MULTILIB_MATCHES'
+
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+set -e
+
+nvptx_sm_def="$1/nvptx-sm.def"
+multilib_options_isa_default=$2
+multilib_options_isa_list=$3
+
+sms=$(grep ^NVPTX_SM $nvptx_sm_def | sed 's/.*(//;s/,.*//')
+
+# Every variant in 'sms' has to either be remapped to the default variant
+# ('.', which is always built), or does get built as non-default variant
+# ('misa=sm_SM'; thus not remapped), or has to be remapped to the "next lower"
+# variant that does get built.
+
+# The "lowest" variant has to be built.
+sm_next_lower=INVALID
+
+for sm in $sms; do
+ if [ x"sm_$sm" = x"$multilib_options_isa_default" ]; then
+ sm_map=.
+ elif expr " $multilib_options_isa_list " : ".* sm_$sm " > /dev/null; then
+ sm_map=
+ else
+ sm_map=$sm_next_lower
+ fi
+
+ if [ x"$sm_map" = x ]; then
+ sm_next_lower=$sm
+ else
+ # Output format as required for 'MULTILIB_MATCHES'.
+ if [ x"$sm_map" = x. ]; then
+ echo ".=misa?sm_$sm"
+ else
+ echo "misa?sm_$sm_map=misa?sm_$sm"
+ fi
+
+ sm_next_lower=$sm_map
+ fi
+done
diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
index 49cc681..2fe120b 100644
--- a/gcc/config/nvptx/nvptx.cc
+++ b/gcc/config/nvptx/nvptx.cc
@@ -334,6 +334,10 @@ nvptx_option_override (void)
{
init_machine_status = nvptx_init_machine_status;
+ /* Via nvptx 'OPTION_DEFAULT_SPECS', '-misa' always appears on the command
+ line. */
+ gcc_checking_assert (OPTION_SET_P (ptx_isa_option));
+
handle_ptx_version_option ();
/* Set toplevel_reorder, unless explicitly disabled. We need
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index dc9cad1..0afc83b 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -27,6 +27,14 @@
/* Run-time Target. */
+/* Use '--with-arch' for default '-misa'. */
+#define OPTION_DEFAULT_SPECS \
+ { "arch", "%{!misa=*:-misa=%(VALUE)}" }, \
+
+/* Assembler supports '-v' option; handle similar to
+ '../../gcc.cc:asm_options', 'HAVE_GNU_AS'. */
+#define ASM_SPEC "%{v}"
+
#define STARTFILE_SPEC "%{mmainkernel:crt0.o}"
#define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
diff --git a/gcc/config/nvptx/nvptx.opt b/gcc/config/nvptx/nvptx.opt
index c5a5668..71d3b68 100644
--- a/gcc/config/nvptx/nvptx.opt
+++ b/gcc/config/nvptx/nvptx.opt
@@ -53,7 +53,7 @@ Target Mask(GOMP)
Generate code for OpenMP offloading: enables -msoft-stack and -muniform-simt.
misa=
-Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option) Init(PTX_ISA_SM30)
+Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option)
Specify the PTX ISA target architecture to use.
march=
diff --git a/gcc/config/nvptx/t-nvptx b/gcc/config/nvptx/t-nvptx
index 2b68149..9c5cbda 100644
--- a/gcc/config/nvptx/t-nvptx
+++ b/gcc/config/nvptx/t-nvptx
@@ -31,4 +31,33 @@ s-nvptx-gen-opt: $(srcdir)/config/nvptx/nvptx-sm.def \
tmp-nvptx-gen.opt $(srcdir)/config/nvptx/nvptx-gen.opt
$(STAMP) s-nvptx-gen-opt
-MULTILIB_OPTIONS = mgomp mptx=3.1
+
+# Multilib setup.
+
+MULTILIB_OPTIONS =
+MULTILIB_MATCHES =
+MULTILIB_EXCEPTIONS =
+
+MULTILIB_OPTIONS += mgomp
+
+multilib_options_isa_list := $(TM_MULTILIB_CONFIG)
+multilib_options_isa_default := $(word 1,$(multilib_options_isa_list))
+multilib_options_misa_list := $(addprefix misa=,$(multilib_options_isa_list))
+# Add the requested '-misa' variants as a multilib option ('misa=VAR1/misa=VAR2/misa=VAR3' etc.):
+empty :=
+space := $(empty) $(empty)
+MULTILIB_OPTIONS += $(subst $(space),/,$(multilib_options_misa_list))
+# ..., and remap '-misa' variants as appropriate:
+multilib_matches := $(shell $(srcdir)/config/nvptx/gen-multilib-matches.sh $(srcdir)/config/nvptx $(multilib_options_isa_default) "$(multilib_options_isa_list)")
+MULTILIB_MATCHES += $(multilib_matches)
+# ..., and don't actually build what's the default '-misa':
+MULTILIB_EXCEPTIONS += *misa=$(multilib_options_isa_default)*
+
+MULTILIB_OPTIONS += mptx=3.1
+# Filter out invalid '-misa'/'-mptx=3.1' combinations; per 'nvptx-sm.def',
+# 'nvptx.opt:ptx_version', 'nvptx.cc:first_ptx_version_supporting_sm'
+# (that is, '-mptx=3.1' only for sm_30, sm_35 variants):
+MULTILIB_EXCEPTIONS += $(foreach misa,$(filter-out %=sm_30 %=sm_35,$(multilib_options_misa_list)),*$(misa)/mptx=3.1)
+# ..., and special care has to be taken if '-mptx=3.1' is invalid for the
+# default variant:
+MULTILIB_EXCEPTIONS += $(if $(filter-out sm_30 sm_35,$(multilib_options_isa_default)),mgomp/mptx=3.1 mptx=3.1)
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 862e72b..5e149b3 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -146,6 +146,9 @@
case CONST_INT:
return !splittable_const_int_operand (op, mode);
+ case CONST_POLY_INT:
+ return known_eq (rtx_to_poly_int64 (op), BYTES_PER_RISCV_VECTOR);
+
case CONST:
case SYMBOL_REF:
case LABEL_REF:
diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index 6e30c1a..95f69e8 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -22,6 +22,147 @@ along with GCC; see the file COPYING3. If not see
FLOAT_MODE (HF, 2, ieee_half_format);
FLOAT_MODE (TF, 16, ieee_quad_format);
+/* Vector modes. */
+
+/* Encode the ratio of SEW/LMUL into the mask types. There are the following
+ * mask types. */
+
+/* | Mode | MIN_VLEN = 32 | MIN_VLEN = 64 |
+ | | SEW/LMUL | SEW/LMUL |
+ | VNx1BI | 32 | 64 |
+ | VNx2BI | 16 | 32 |
+ | VNx4BI | 8 | 16 |
+ | VNx8BI | 4 | 8 |
+ | VNx16BI | 2 | 4 |
+ | VNx32BI | 1 | 2 |
+ | VNx64BI | N/A | 1 | */
+
+VECTOR_BOOL_MODE (VNx1BI, 1, BI, 8);
+VECTOR_BOOL_MODE (VNx2BI, 2, BI, 8);
+VECTOR_BOOL_MODE (VNx4BI, 4, BI, 8);
+VECTOR_BOOL_MODE (VNx8BI, 8, BI, 8);
+VECTOR_BOOL_MODE (VNx16BI, 16, BI, 8);
+VECTOR_BOOL_MODE (VNx32BI, 32, BI, 8);
+VECTOR_BOOL_MODE (VNx64BI, 64, BI, 8);
+
+ADJUST_NUNITS (VNx1BI, riscv_vector_chunks * 1);
+ADJUST_NUNITS (VNx2BI, riscv_vector_chunks * 2);
+ADJUST_NUNITS (VNx4BI, riscv_vector_chunks * 4);
+ADJUST_NUNITS (VNx8BI, riscv_vector_chunks * 8);
+ADJUST_NUNITS (VNx16BI, riscv_vector_chunks * 16);
+ADJUST_NUNITS (VNx32BI, riscv_vector_chunks * 32);
+ADJUST_NUNITS (VNx64BI, riscv_vector_chunks * 64);
+
+ADJUST_ALIGNMENT (VNx1BI, 1);
+ADJUST_ALIGNMENT (VNx2BI, 1);
+ADJUST_ALIGNMENT (VNx4BI, 1);
+ADJUST_ALIGNMENT (VNx8BI, 1);
+ADJUST_ALIGNMENT (VNx16BI, 1);
+ADJUST_ALIGNMENT (VNx32BI, 1);
+ADJUST_ALIGNMENT (VNx64BI, 1);
+
+ADJUST_BYTESIZE (VNx1BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx2BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx4BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx8BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+ADJUST_BYTESIZE (VNx64BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
+
+/*
+ | Mode | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
+ | | LMUL | SEW/LMUL | LMUL | SEW/LMUL |
+ | VNx1QI | MF4 | 32 | MF8 | 64 |
+ | VNx2QI | MF2 | 16 | MF4 | 32 |
+ | VNx4QI | M1 | 8 | MF2 | 16 |
+ | VNx8QI | M2 | 4 | M1 | 8 |
+ | VNx16QI | M4 | 2 | M2 | 4 |
+ | VNx32QI | M8 | 1 | M4 | 2 |
+ | VNx64QI | N/A | N/A | M8 | 1 |
+ | VNx1(HI|HF) | MF2 | 32 | MF4 | 64 |
+ | VNx2(HI|HF) | M1 | 16 | MF2 | 32 |
+ | VNx4(HI|HF) | M2 | 8 | M1 | 16 |
+ | VNx8(HI|HF) | M4 | 4 | M2 | 8 |
+ | VNx16(HI|HF)| M8 | 2 | M4 | 4 |
+ | VNx32(HI|HF)| N/A | N/A | M8 | 2 |
+ | VNx1(SI|SF) | M1 | 32 | MF2 | 64 |
+ | VNx2(SI|SF) | M2 | 16 | M1 | 32 |
+ | VNx4(SI|SF) | M4 | 8 | M2 | 16 |
+ | VNx8(SI|SF) | M8 | 4 | M4 | 8 |
+ | VNx16(SI|SF)| N/A | N/A | M8 | 4 |
+ | VNx1(DI|DF) | N/A | N/A | M1 | 64 |
+ | VNx2(DI|DF) | N/A | N/A | M2 | 32 |
+ | VNx4(DI|DF) | N/A | N/A | M4 | 16 |
+ | VNx8(DI|DF) | N/A | N/A | M8 | 8 |
+*/
+
+/* Define RVV modes whose sizes are multiples of 64-bit chunks. */
+#define RVV_MODES(NVECS, VB, VH, VS, VD) \
+ VECTOR_MODES_WITH_PREFIX (VNx, INT, 8 * NVECS, 0); \
+ VECTOR_MODES_WITH_PREFIX (VNx, FLOAT, 8 * NVECS, 0); \
+ \
+ ADJUST_NUNITS (VB##QI, riscv_vector_chunks * NVECS * 8); \
+ ADJUST_NUNITS (VH##HI, riscv_vector_chunks * NVECS * 4); \
+ ADJUST_NUNITS (VS##SI, riscv_vector_chunks * NVECS * 2); \
+ ADJUST_NUNITS (VD##DI, riscv_vector_chunks * NVECS); \
+ ADJUST_NUNITS (VH##HF, riscv_vector_chunks * NVECS * 4); \
+ ADJUST_NUNITS (VS##SF, riscv_vector_chunks * NVECS * 2); \
+ ADJUST_NUNITS (VD##DF, riscv_vector_chunks * NVECS); \
+ \
+ ADJUST_ALIGNMENT (VB##QI, 1); \
+ ADJUST_ALIGNMENT (VH##HI, 2); \
+ ADJUST_ALIGNMENT (VS##SI, 4); \
+ ADJUST_ALIGNMENT (VD##DI, 8); \
+ ADJUST_ALIGNMENT (VH##HF, 2); \
+ ADJUST_ALIGNMENT (VS##SF, 4); \
+ ADJUST_ALIGNMENT (VD##DF, 8);
+
+/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
+ So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1DImode and VNx1DFmode. */
+VECTOR_MODE_WITH_PREFIX (VNx, INT, DI, 1, 0);
+VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, DF, 1, 0);
+RVV_MODES (1, VNx8, VNx4, VNx2, VNx1)
+RVV_MODES (2, VNx16, VNx8, VNx4, VNx2)
+RVV_MODES (4, VNx32, VNx16, VNx8, VNx4)
+RVV_MODES (8, VNx64, VNx32, VNx16, VNx8)
+
+VECTOR_MODES_WITH_PREFIX (VNx, INT, 4, 0);
+VECTOR_MODES_WITH_PREFIX (VNx, FLOAT, 4, 0);
+ADJUST_NUNITS (VNx4QI, riscv_vector_chunks * 4);
+ADJUST_NUNITS (VNx2HI, riscv_vector_chunks * 2);
+ADJUST_NUNITS (VNx2HF, riscv_vector_chunks * 2);
+ADJUST_ALIGNMENT (VNx4QI, 1);
+ADJUST_ALIGNMENT (VNx2HI, 2);
+ADJUST_ALIGNMENT (VNx2HF, 2);
+
+/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
+ So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1SImode and VNx1SFmode. */
+VECTOR_MODE_WITH_PREFIX (VNx, INT, SI, 1, 0);
+VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, SF, 1, 0);
+ADJUST_NUNITS (VNx1SI, riscv_vector_chunks);
+ADJUST_NUNITS (VNx1SF, riscv_vector_chunks);
+ADJUST_ALIGNMENT (VNx1SI, 4);
+ADJUST_ALIGNMENT (VNx1SF, 4);
+
+VECTOR_MODES_WITH_PREFIX (VNx, INT, 2, 0);
+ADJUST_NUNITS (VNx2QI, riscv_vector_chunks * 2);
+ADJUST_ALIGNMENT (VNx2QI, 1);
+
+/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
+ So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1HImode and VNx1HFmode. */
+VECTOR_MODE_WITH_PREFIX (VNx, INT, HI, 1, 0);
+VECTOR_MODE_WITH_PREFIX (VNx, FLOAT, HF, 1, 0);
+ADJUST_NUNITS (VNx1HI, riscv_vector_chunks);
+ADJUST_NUNITS (VNx1HF, riscv_vector_chunks);
+ADJUST_ALIGNMENT (VNx1HI, 2);
+ADJUST_ALIGNMENT (VNx1HF, 2);
+
+/* 'VECTOR_MODES_WITH_PREFIX' does not allow ncomponents < 2.
+ So we use 'VECTOR_MODE_WITH_PREFIX' to define VNx1QImode. */
+VECTOR_MODE_WITH_PREFIX (VNx, INT, QI, 1, 0);
+ADJUST_NUNITS (VNx1QI, riscv_vector_chunks);
+ADJUST_ALIGNMENT (VNx1QI, 1);
+
/* TODO: According to RISC-V 'V' ISA spec, the maximun vector length can
be 65536 for a single vector register which means the vector mode in
GCC can be maximum = 65536 * 8 bits (LMUL=8).
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 649c5c9..f9a2baa 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -74,6 +74,7 @@ extern bool riscv_expand_block_move (rtx, rtx, rtx);
extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *);
extern rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *);
extern bool riscv_gpr_save_operation_p (rtx);
+extern void riscv_reinit (void);
/* Routines implemented in riscv-c.cc. */
void riscv_cpu_cpp_builtins (cpp_reader *);
@@ -86,6 +87,7 @@ extern void riscv_init_builtins (void);
/* Routines implemented in riscv-common.cc. */
extern std::string riscv_arch_str (bool version_p = true);
+extern void riscv_parse_arch_string (const char *, struct gcc_options *, location_t);
extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
@@ -105,4 +107,11 @@ struct riscv_cpu_info {
extern const riscv_cpu_info *riscv_find_cpu (const char *);
+/* Routines implemented in riscv-selftests.cc. */
+#if CHECKING_P
+namespace selftest {
+extern void riscv_run_selftests (void);
+} // namespace selftest
+#endif
+
#endif /* ! GCC_RISCV_PROTOS_H */
diff --git a/gcc/config/riscv/riscv-selftests.cc b/gcc/config/riscv/riscv-selftests.cc
new file mode 100644
index 0000000..636874e
--- /dev/null
+++ b/gcc/config/riscv/riscv-selftests.cc
@@ -0,0 +1,241 @@
+/* This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#define IN_TARGET_CODE 1
+
+#define INCLUDE_STRING
+#define INCLUDE_MAP
+#define INCLUDE_VECTOR
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "function.h"
+#include "memmodel.h"
+#include "emit-rtl.h"
+#include "tm_p.h"
+#include "expr.h"
+#include "selftest.h"
+#include "selftest-rtl.h"
+
+#if CHECKING_P
+using namespace selftest;
+class riscv_selftest_arch_abi_setter
+{
+private:
+ std::string m_arch_backup;
+ enum riscv_abi_type m_abi_backup;
+
+public:
+ riscv_selftest_arch_abi_setter (const char *arch, enum riscv_abi_type abi)
+ : m_arch_backup (riscv_arch_str ()), m_abi_backup (riscv_abi)
+ {
+ riscv_parse_arch_string (arch, &global_options, UNKNOWN_LOCATION);
+ riscv_abi = abi;
+ riscv_reinit ();
+ }
+ ~riscv_selftest_arch_abi_setter ()
+ {
+ riscv_parse_arch_string (m_arch_backup.c_str (), &global_options,
+ UNKNOWN_LOCATION);
+ riscv_abi = m_abi_backup;
+ riscv_reinit ();
+ }
+};
+
+static poly_int64
+eval_value (rtx x, std::map<unsigned, rtx> &regno_to_rtx)
+{
+ if (!REG_P (x))
+ {
+ debug (x);
+ gcc_unreachable ();
+ }
+
+ rtx expr = NULL_RTX;
+ unsigned regno = REGNO (x);
+ expr = regno_to_rtx[regno];
+
+ poly_int64 op1_val = 0;
+ poly_int64 op2_val = 0;
+ if (UNARY_P (expr))
+ {
+ op1_val = eval_value (XEXP (expr, 0), regno_to_rtx);
+ }
+ if (BINARY_P (expr))
+ {
+ op1_val = eval_value (XEXP (expr, 0), regno_to_rtx);
+ op2_val = eval_value (XEXP (expr, 1), regno_to_rtx);
+ }
+
+ switch (GET_CODE (expr))
+ {
+ case CONST_POLY_INT:
+ return rtx_to_poly_int64 (expr);
+ case CONST_INT:
+ return INTVAL (expr);
+
+ case MULT:
+ if (op1_val.is_constant ())
+ return op1_val.to_constant () * op2_val;
+ else if (op2_val.is_constant ())
+ return op1_val * op2_val.to_constant ();
+ else
+ gcc_unreachable ();
+ case PLUS:
+ return op1_val + op2_val;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Calculate the value of x register in the sequence. */
+static poly_int64
+calculate_x_in_sequence (rtx reg)
+{
+ std::map<unsigned, rtx> regno_to_rtx;
+ rtx_insn *insn;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx pat = PATTERN (insn);
+ rtx dest = SET_DEST (pat);
+
+ if (GET_CODE (pat) == CLOBBER)
+ continue;
+
+ if (SUBREG_P (dest))
+ continue;
+
+ gcc_assert (REG_P (dest));
+ rtx note = find_reg_equal_equiv_note (insn);
+ unsigned regno = REGNO (dest);
+ if (note)
+ regno_to_rtx[regno] = XEXP (note, 0);
+ else
+ regno_to_rtx[regno] = SET_SRC (pat);
+ }
+
+ return eval_value (reg, regno_to_rtx);
+}
+
+typedef enum
+{
+ POLY_TEST_DIMODE,
+ POLY_TEST_PMODE
+} poly_test_mode_t;
+
+static void
+simple_poly_selftest (const char *arch, enum riscv_abi_type abi,
+ const std::vector<machine_mode> &modes)
+{
+ riscv_selftest_arch_abi_setter rv (arch, abi);
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("riscv/empty-func.rtl"));
+ set_new_first_and_last_insn (NULL, NULL);
+
+ for (machine_mode mode : modes)
+ emit_move_insn (gen_reg_rtx (mode),
+ gen_int_mode (BYTES_PER_RISCV_VECTOR, mode));
+}
+
+static void
+run_poly_int_selftest (const char *arch, enum riscv_abi_type abi,
+ poly_test_mode_t test_mode,
+ const std::vector<poly_int64> &worklist)
+{
+ riscv_selftest_arch_abi_setter rv (arch, abi);
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("riscv/empty-func.rtl"));
+ set_new_first_and_last_insn (NULL, NULL);
+ machine_mode mode = VOIDmode;
+
+ switch (test_mode)
+ {
+ case POLY_TEST_DIMODE:
+ mode = DImode;
+ break;
+ case POLY_TEST_PMODE:
+ mode = Pmode;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ for (const poly_int64 &poly_val : worklist)
+ {
+ start_sequence ();
+ rtx dest = gen_reg_rtx (mode);
+ emit_move_insn (dest, gen_int_mode (poly_val, mode));
+ ASSERT_TRUE (known_eq (calculate_x_in_sequence (dest), poly_val));
+ end_sequence ();
+ }
+}
+
+static void
+run_poly_int_selftests (void)
+{
+ std::vector<poly_int64> worklist
+ = {BYTES_PER_RISCV_VECTOR, BYTES_PER_RISCV_VECTOR * 8,
+ BYTES_PER_RISCV_VECTOR * 32, -BYTES_PER_RISCV_VECTOR * 8,
+ -BYTES_PER_RISCV_VECTOR * 32, BYTES_PER_RISCV_VECTOR * 7,
+ BYTES_PER_RISCV_VECTOR * 31, -BYTES_PER_RISCV_VECTOR * 7,
+ -BYTES_PER_RISCV_VECTOR * 31, BYTES_PER_RISCV_VECTOR * 9,
+ BYTES_PER_RISCV_VECTOR * 33, -BYTES_PER_RISCV_VECTOR * 9,
+ -BYTES_PER_RISCV_VECTOR * 33, poly_int64 (207, 0),
+ poly_int64 (-207, 0), poly_int64 (0, 207),
+ poly_int64 (0, -207), poly_int64 (5555, 0),
+ poly_int64 (0, 5555), poly_int64 (4096, 4096),
+ poly_int64 (17, 4088), poly_int64 (3889, 4104),
+ poly_int64 (-4096, -4096), poly_int64 (219, -4088),
+ poly_int64 (-4309, -4104), poly_int64 (-7337, 88),
+ poly_int64 (9317, -88), poly_int64 (4, 4),
+ poly_int64 (17, 4), poly_int64 (-7337, 4),
+ poly_int64 (-4, -4), poly_int64 (-389, -4),
+ poly_int64 (4789, -4), poly_int64 (-5977, 1508),
+ poly_int64 (219, -1508), poly_int64 (2, 2),
+ poly_int64 (33, 2), poly_int64 (-7337, 2),
+ poly_int64 (-2, -2), poly_int64 (-389, -2),
+ poly_int64 (4789, -2), poly_int64 (-3567, 954),
+ poly_int64 (945, -954), poly_int64 (1, 1),
+ poly_int64 (977, 1), poly_int64 (-339, 1),
+ poly_int64 (-1, -1), poly_int64 (-12, -1),
+ poly_int64 (44, -1), poly_int64 (9567, 77),
+ poly_int64 (3467, -77)};
+
+ simple_poly_selftest ("rv64imafdv", ABI_LP64D,
+ {QImode, HImode, SImode, DImode});
+ simple_poly_selftest ("rv32imafdv", ABI_ILP32D, {QImode, HImode, SImode});
+
+ run_poly_int_selftest ("rv64imafdv", ABI_LP64D, POLY_TEST_PMODE, worklist);
+ run_poly_int_selftest ("rv64imafd_zve32x1p0", ABI_LP64D, POLY_TEST_PMODE,
+ worklist);
+ run_poly_int_selftest ("rv32imafdv", ABI_ILP32, POLY_TEST_PMODE, worklist);
+ run_poly_int_selftest ("rv32imafdv", ABI_ILP32, POLY_TEST_DIMODE, worklist);
+ run_poly_int_selftest ("rv32imafd_zve32x1p0", ABI_ILP32D, POLY_TEST_PMODE,
+ worklist);
+ run_poly_int_selftest ("rv32imafd_zve32x1p0", ABI_ILP32D, POLY_TEST_DIMODE,
+ worklist);
+}
+namespace selftest {
+/* Run all target-specific selftests. */
+void
+riscv_run_selftests (void)
+{
+ run_poly_int_selftests ();
+}
+} // namespace selftest
+#endif /* #if CHECKING_P */
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 675d92c..4d5d887 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -57,6 +57,8 @@ along with GCC; see the file COPYING3. If not see
#include "predict.h"
#include "tree-pass.h"
#include "opts.h"
+#include "tm-constrs.h"
+#include "rtl-iter.h"
/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
#define UNSPEC_ADDRESS_P(X) \
@@ -778,6 +780,12 @@ riscv_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
enum riscv_symbol_type type;
rtx base, offset;
+ /* There's no way to calculate VL-based values using relocations. */
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, x, ALL)
+ if (GET_CODE (*iter) == CONST_POLY_INT)
+ return true;
+
/* There is no assembler syntax for expressing an address-sized
high part. */
if (GET_CODE (x) == HIGH)
@@ -1684,12 +1692,268 @@ riscv_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
riscv_emit_move (dest, src);
}
+/* Report when we try to do something that requires vector when vector is
+ disabled. This is an error of last resort and isn't very high-quality. It
+ usually involves attempts to measure the vector length in some way. */
+
+static void
+riscv_report_v_required (void)
+{
+ static bool reported_p = false;
+
+ /* Avoid reporting a slew of messages for a single oversight. */
+ if (reported_p)
+ return;
+
+ error ("this operation requires the RVV ISA extension");
+ inform (input_location, "you can enable RVV using the command-line"
+ " option %<-march%>, or by using the %<target%>"
+ " attribute or pragma");
+ reported_p = true;
+}
+
+/* Helper function to operation for rtx_code CODE. */
+static void
+riscv_expand_op (enum rtx_code code, machine_mode mode, rtx op0, rtx op1,
+ rtx op2)
+{
+ if (can_create_pseudo_p ())
+ {
+ rtx result;
+ if (GET_RTX_CLASS (code) == RTX_UNARY)
+ result = expand_simple_unop (mode, code, op1, NULL_RTX, false);
+ else
+ result = expand_simple_binop (mode, code, op1, op2, NULL_RTX, false,
+ OPTAB_DIRECT);
+ riscv_emit_move (op0, result);
+ }
+ else
+ {
+ rtx pat;
+ /* The following implementation is for prologue and epilogue.
+ Because prologue and epilogue can not use pseudo register.
+ We can't using expand_simple_binop or expand_simple_unop. */
+ if (GET_RTX_CLASS (code) == RTX_UNARY)
+ pat = gen_rtx_fmt_e (code, mode, op1);
+ else
+ pat = gen_rtx_fmt_ee (code, mode, op1, op2);
+ emit_insn (gen_rtx_SET (op0, pat));
+ }
+}
+
+/* Expand mult operation with constant integer, multiplicand also used as a
+ * temporary register. */
+
+static void
+riscv_expand_mult_with_const_int (machine_mode mode, rtx dest, rtx multiplicand,
+ int multiplier)
+{
+ if (multiplier == 0)
+ {
+ riscv_emit_move (dest, GEN_INT (0));
+ return;
+ }
+
+ bool neg_p = multiplier < 0;
+ int multiplier_abs = abs (multiplier);
+
+ if (multiplier_abs == 1)
+ {
+ if (neg_p)
+ riscv_expand_op (NEG, mode, dest, multiplicand, NULL_RTX);
+ else
+ riscv_emit_move (dest, multiplicand);
+ }
+ else
+ {
+ if (pow2p_hwi (multiplier_abs))
+ {
+ /*
+ multiplicand = [BYTES_PER_RISCV_VECTOR].
+ 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 8].
+ Sequence:
+ csrr a5, vlenb
+ slli a5, a5, 3
+ 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 8].
+ Sequence:
+ csrr a5, vlenb
+ slli a5, a5, 3
+ neg a5, a5
+ */
+ riscv_expand_op (ASHIFT, mode, dest, multiplicand,
+ gen_int_mode (exact_log2 (multiplier_abs), QImode));
+ if (neg_p)
+ riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
+ }
+ else if (pow2p_hwi (multiplier_abs + 1))
+ {
+ /*
+ multiplicand = [BYTES_PER_RISCV_VECTOR].
+ 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 7].
+ Sequence:
+ csrr a5, vlenb
+ slli a4, a5, 3
+ sub a5, a4, a5
+ 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 7].
+ Sequence:
+ csrr a5, vlenb
+ slli a4, a5, 3
+ sub a5, a4, a5 + neg a5, a5 => sub a5, a5, a4
+ */
+ riscv_expand_op (ASHIFT, mode, dest, multiplicand,
+ gen_int_mode (exact_log2 (multiplier_abs + 1),
+ QImode));
+ if (neg_p)
+ riscv_expand_op (MINUS, mode, dest, multiplicand, dest);
+ else
+ riscv_expand_op (MINUS, mode, dest, dest, multiplicand);
+ }
+ else if (pow2p_hwi (multiplier - 1))
+ {
+ /*
+ multiplicand = [BYTES_PER_RISCV_VECTOR].
+ 1. const_poly_int:P [BYTES_PER_RISCV_VECTOR * 9].
+ Sequence:
+ csrr a5, vlenb
+ slli a4, a5, 3
+ add a5, a4, a5
+ 2. const_poly_int:P [-BYTES_PER_RISCV_VECTOR * 9].
+ Sequence:
+ csrr a5, vlenb
+ slli a4, a5, 3
+ add a5, a4, a5
+ neg a5, a5
+ */
+ riscv_expand_op (ASHIFT, mode, dest, multiplicand,
+ gen_int_mode (exact_log2 (multiplier_abs - 1),
+ QImode));
+ riscv_expand_op (PLUS, mode, dest, dest, multiplicand);
+ if (neg_p)
+ riscv_expand_op (NEG, mode, dest, dest, NULL_RTX);
+ }
+ else
+ {
+ /* We use multiplication for remaining cases. */
+ gcc_assert (
+ TARGET_MUL
+ && "M-extension must be enabled to calculate the poly_int "
+ "size/offset.");
+ riscv_emit_move (dest, gen_int_mode (multiplier, mode));
+ riscv_expand_op (MULT, mode, dest, dest, multiplicand);
+ }
+ }
+}
+
+/* Analyze src and emit const_poly_int mov sequence. */
+
+static void
+riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src)
+{
+ poly_int64 value = rtx_to_poly_int64 (src);
+ int offset = value.coeffs[0];
+ int factor = value.coeffs[1];
+ int vlenb = BYTES_PER_RISCV_VECTOR.coeffs[1];
+ int div_factor = 0;
+ /* Calculate (const_poly_int:MODE [m, n]) using scalar instructions.
+ For any (const_poly_int:MODE [m, n]), the calculation formula is as
+ follows.
+ constant = m - n.
+ When minimum VLEN = 32, poly of VLENB = (4, 4).
+ base = vlenb(4, 4) or vlenb/2(2, 2) or vlenb/4(1, 1).
+ When minimum VLEN > 32, poly of VLENB = (8, 8).
+ base = vlenb(8, 8) or vlenb/2(4, 4) or vlenb/4(2, 2) or vlenb/8(1, 1).
+ magn = (n, n) / base.
+ (m, n) = base * magn + constant.
+ This calculation doesn't need div operation. */
+
+ emit_move_insn (tmp, gen_int_mode (BYTES_PER_RISCV_VECTOR, mode));
+
+ if (BYTES_PER_RISCV_VECTOR.is_constant ())
+ {
+ gcc_assert (value.is_constant ());
+ riscv_emit_move (dest, GEN_INT (value.to_constant ()));
+ return;
+ }
+ else if ((factor % vlenb) == 0)
+ div_factor = 1;
+ else if ((factor % (vlenb / 2)) == 0)
+ div_factor = 2;
+ else if ((factor % (vlenb / 4)) == 0)
+ div_factor = 4;
+ else if ((factor % (vlenb / 8)) == 0)
+ div_factor = 8;
+ else
+ gcc_unreachable ();
+
+ if (div_factor != 1)
+ riscv_expand_op (LSHIFTRT, mode, tmp, tmp,
+ gen_int_mode (exact_log2 (div_factor), QImode));
+
+ riscv_expand_mult_with_const_int (mode, dest, tmp,
+ factor / (vlenb / div_factor));
+ HOST_WIDE_INT constant = offset - factor;
+
+ if (constant == 0)
+ return;
+ else if (SMALL_OPERAND (constant))
+ riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
+ else
+ {
+ /* Handle the constant value is not a 12-bit value. */
+ rtx high;
+
+ /* Leave OFFSET as a 16-bit offset and put the excess in HIGH.
+ The addition inside the macro CONST_HIGH_PART may cause an
+ overflow, so we need to force a sign-extension check. */
+ high = gen_int_mode (CONST_HIGH_PART (constant), mode);
+ constant = CONST_LOW_PART (constant);
+ riscv_emit_move (tmp, high);
+ riscv_expand_op (PLUS, mode, dest, tmp, dest);
+ riscv_expand_op (PLUS, mode, dest, dest, gen_int_mode (constant, mode));
+ }
+}
+
/* If (set DEST SRC) is not a valid move instruction, emit an equivalent
sequence that is valid. */
bool
riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
{
+ if (CONST_POLY_INT_P (src))
+ {
+ poly_int64 value = rtx_to_poly_int64 (src);
+ if (!value.is_constant () && !TARGET_VECTOR)
+ {
+ riscv_report_v_required ();
+ return false;
+ }
+
+ if (satisfies_constraint_vp (src))
+ return false;
+
+ if (GET_MODE_SIZE (mode).to_constant () < GET_MODE_SIZE (Pmode))
+ {
+ /* In RV32 system, handle (const_poly_int:QI [m, n])
+ (const_poly_int:HI [m, n]).
+ In RV64 system, handle (const_poly_int:QI [m, n])
+ (const_poly_int:HI [m, n])
+ (const_poly_int:SI [m, n]). */
+ rtx tmp = gen_reg_rtx (Pmode);
+ riscv_legitimize_poly_move (Pmode, gen_lowpart (Pmode, dest), tmp,
+ src);
+ }
+ else
+ {
+ /* In RV32 system, handle (const_poly_int:SI [m, n])
+ (const_poly_int:DI [m, n]).
+ In RV64 system, handle (const_poly_int:DI [m, n]).
+ FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
+ the offset should not exceed 4GiB in general. */
+ rtx tmp = gen_reg_rtx (mode);
+ riscv_legitimize_poly_move (mode, dest, tmp, src);
+ }
+ return true;
+ }
/* Expand
(set (reg:QI target) (mem:QI (address)))
to
@@ -5033,6 +5297,9 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (!riscv_v_ext_vector_mode_p (mode))
return false;
+ if (!V_REG_P (regno + nregs - 1))
+ return false;
+
/* 3.3.2. LMUL = 2,4,8, register numbers should be multiple of 2,4,8.
but for mask vector register, register numbers can be any number. */
int lmul = 1;
@@ -5041,6 +5308,8 @@ riscv_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (lmul != 1)
return ((regno % lmul) == 0);
}
+ else if (regno == VL_REGNUM || regno == VTYPE_REGNUM)
+ return true;
else
return false;
@@ -5231,10 +5500,6 @@ riscv_init_machine_status (void)
static poly_uint16
riscv_convert_vector_bits (void)
{
- /* The runtime invariant is only meaningful when TARGET_VECTOR is enabled. */
- if (!TARGET_VECTOR)
- return 0;
-
if (TARGET_MIN_VLEN > 32)
{
/* When targetting minimum VLEN > 32, we should use 64-bit chunk size.
@@ -5255,7 +5520,13 @@ riscv_convert_vector_bits (void)
riscv_bytes_per_vector_chunk = 4;
}
- return poly_uint16 (1, 1);
+ /* Set riscv_vector_chunks as poly (1, 1) run-time constant if TARGET_VECTOR
+ is enabled. Set riscv_vector_chunks as 1 compile-time constant if
+ TARGET_VECTOR is disabled. riscv_vector_chunks is used in "riscv-modes.def"
+ to set RVV mode size. The RVV machine modes size are run-time constant if
+ TARGET_VECTOR is enabled. The RVV machine modes size remains default
+ compile-time constant if TARGET_VECTOR is disabled. */
+ return TARGET_VECTOR ? poly_uint16 (1, 1) : 1;
}
/* Implement TARGET_OPTION_OVERRIDE. */
@@ -6002,6 +6273,23 @@ riscv_init_libfuncs (void)
set_optab_libfunc (unord_optab, HFmode, NULL);
}
+#if CHECKING_P
+void
+riscv_reinit (void)
+{
+ riscv_option_override ();
+ init_adjust_machine_modes ();
+ init_derived_machine_modes ();
+ reinit_regs ();
+ init_optabs ();
+}
+#endif
+
+#if CHECKING_P
+#undef TARGET_RUN_TARGET_SELFTESTS
+#define TARGET_RUN_TARGET_SELFTESTS selftest::riscv_run_selftests
+#endif /* #if CHECKING_P */
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index eb1284e..363113c 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -749,18 +749,19 @@ typedef struct {
#define CASE_VECTOR_MODE SImode
#define CASE_VECTOR_PC_RELATIVE (riscv_cmodel != CM_MEDLOW)
+#define LOCAL_SYM_P(sym) \
+ ((SYMBOL_REF_P (sym) && SYMBOL_REF_LOCAL_P (sym)) \
+ || ((GET_CODE (sym) == CONST) \
+ && SYMBOL_REF_P (XEXP (XEXP (sym, 0),0)) \
+ && SYMBOL_REF_LOCAL_P (XEXP (XEXP (sym, 0),0))))
+
/* The load-address macro is used for PC-relative addressing of symbols
that bind locally. Don't use it for symbols that should be addressed
via the GOT. Also, avoid it for CM_MEDLOW, where LUI addressing
currently results in more opportunities for linker relaxation. */
#define USE_LOAD_ADDRESS_MACRO(sym) \
(!TARGET_EXPLICIT_RELOCS && \
- ((flag_pic \
- && ((SYMBOL_REF_P (sym) && SYMBOL_REF_LOCAL_P (sym)) \
- || ((GET_CODE (sym) == CONST) \
- && SYMBOL_REF_P (XEXP (XEXP (sym, 0),0)) \
- && SYMBOL_REF_LOCAL_P (XEXP (XEXP (sym, 0),0))))) \
- || riscv_cmodel == CM_MEDANY))
+ ((flag_pic && LOCAL_SYM_P (sym)) || riscv_cmodel == CM_MEDANY))
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 0
diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
index 19736b3..2b82e5f 100644
--- a/gcc/config/riscv/t-riscv
+++ b/gcc/config/riscv/t-riscv
@@ -23,6 +23,10 @@ riscv-shorten-memrefs.o: $(srcdir)/config/riscv/riscv-shorten-memrefs.cc
$(COMPILE) $<
$(POSTCOMPILE)
+riscv-selftests.o: $(srcdir)/config/riscv/riscv-selftests.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
PASSES_EXTRA += $(srcdir)/config/riscv/riscv-passes.def
$(common_out_file): $(srcdir)/config/riscv/riscv-cores.def \
diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc
index ddd849e..a11d020 100644
--- a/gcc/config/rs6000/rs6000-logue.cc
+++ b/gcc/config/rs6000/rs6000-logue.cc
@@ -4920,7 +4920,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
a REG_CFA_DEF_CFA note, but that's OK; A duplicate is
discarded by dwarf2cfi.cc/dwarf2out.cc, and in any case would
be harmless if emitted. */
- if (frame_pointer_needed)
+ if (frame_pointer_needed_indeed)
{
insn = get_last_insn ();
add_reg_note (insn, REG_CFA_DEF_CFA,
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index a0d33d2..0171705 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1475,7 +1475,7 @@
[(match_operand:VEC_L 0 "vlogical_operand")
(match_operand:VEC_L 1 "vlogical_operand")
(match_operand:QI 2 "reg_or_short_operand")]
- "TARGET_ALTIVEC"
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
{
rtx bitshift = operands[2];
rtx shift;
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 3ae586c..9861913 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -3648,7 +3648,7 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total = 0;
return true;
case SET: {
- rtx dest = SET_DEST (x);
+ rtx dst = SET_DEST (x);
rtx src = SET_SRC (x);
switch (GET_CODE (src))
@@ -3669,7 +3669,6 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
slightly more expensive than a normal load. */
*total = COSTS_N_INSNS (1) + 2;
- rtx dst = SET_DEST (src);
rtx then = XEXP (src, 1);
rtx els = XEXP (src, 2);
@@ -3696,25 +3695,25 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
break;
}
- switch (GET_CODE (dest))
+ switch (GET_CODE (dst))
{
case SUBREG:
- if (!REG_P (SUBREG_REG (dest)))
+ if (!REG_P (SUBREG_REG (dst)))
*total += rtx_cost (SUBREG_REG (src), VOIDmode, SET, 0, speed);
/* fallthrough */
case REG:
/* If this is a VR -> VR copy, count the number of
registers. */
- if (VECTOR_MODE_P (GET_MODE (dest)) && REG_P (src))
+ if (VECTOR_MODE_P (GET_MODE (dst)) && REG_P (src))
{
- int nregs = s390_hard_regno_nregs (VR0_REGNUM, GET_MODE (dest));
+ int nregs = s390_hard_regno_nregs (VR0_REGNUM, GET_MODE (dst));
*total = COSTS_N_INSNS (nregs);
}
/* Same for GPRs. */
else if (REG_P (src))
{
int nregs
- = s390_hard_regno_nregs (GPR0_REGNUM, GET_MODE (dest));
+ = s390_hard_regno_nregs (GPR0_REGNUM, GET_MODE (dst));
*total = COSTS_N_INSNS (nregs);
}
else
@@ -3722,7 +3721,7 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total += rtx_cost (src, mode, SET, 1, speed);
return true;
case MEM: {
- rtx address = XEXP (dest, 0);
+ rtx address = XEXP (dst, 0);
rtx tmp;
HOST_WIDE_INT tmp2;
if (s390_loadrelative_operand_p (address, &tmp, &tmp2))
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index f1b3331..828c764 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -191,6 +191,15 @@ static bool xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED,
static HOST_WIDE_INT xtensa_starting_frame_offset (void);
static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void);
static bool xtensa_function_ok_for_sibcall (tree, tree);
+static bool xtensa_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ const_tree function ATTRIBUTE_UNUSED);
+static void xtensa_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset,
+ tree function);
+
static rtx xtensa_delegitimize_address (rtx);
@@ -351,6 +360,15 @@ static rtx xtensa_delegitimize_address (rtx);
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL xtensa_function_ok_for_sibcall
+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK xtensa_can_output_mi_thunk
+
+#undef TARGET_ASM_OUTPUT_MI_THUNK
+#define TARGET_ASM_OUTPUT_MI_THUNK xtensa_output_mi_thunk
+
+#undef TARGET_MAX_ANCHOR_OFFSET
+#define TARGET_MAX_ANCHOR_OFFSET 1020
+
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2173,7 +2191,16 @@ xtensa_prepare_expand_call (int callop, rtx *operands)
addr = gen_sym_PLT (addr);
if (!call_insn_operand (addr, VOIDmode))
- XEXP (operands[callop], 0) = copy_to_mode_reg (Pmode, addr);
+ {
+ /* This may be called while generating MI thunk when we pretend
+ that reload is over. Use a8 as a temporary register in that case. */
+ rtx reg = can_create_pseudo_p ()
+ ? copy_to_mode_reg (Pmode, addr)
+ : copy_to_suggested_reg (addr,
+ gen_rtx_REG (Pmode, A8_REG),
+ Pmode);
+ XEXP (operands[callop], 0) = reg;
+ }
}
@@ -4983,6 +5010,96 @@ xtensa_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_U
return true;
}
+static bool
+xtensa_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ const_tree function ATTRIBUTE_UNUSED)
+{
+ if (TARGET_WINDOWED_ABI)
+ return false;
+
+ return true;
+}
+
+/* Output code to add DELTA to the first argument, and then jump
+ to FUNCTION. Used for C++ multiple inheritance. */
+static void
+xtensa_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset,
+ tree function)
+{
+ rtx this_rtx;
+ rtx funexp;
+ rtx_insn *insn;
+ int this_reg_no;
+ rtx temp0 = gen_rtx_REG (Pmode, A9_REG);
+ const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
+
+ reload_completed = 1;
+
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
+ this_reg_no = 3;
+ else
+ this_reg_no = 2;
+
+ this_rtx = gen_rtx_REG (Pmode, A0_REG + this_reg_no);
+
+ if (delta)
+ {
+ if (xtensa_simm8 (delta))
+ emit_insn (gen_addsi3 (this_rtx, this_rtx, GEN_INT (delta)));
+ else
+ {
+ emit_move_insn (temp0, GEN_INT (delta));
+ emit_insn (gen_addsi3 (this_rtx, this_rtx, temp0));
+ }
+ }
+
+ if (vcall_offset)
+ {
+ rtx temp1 = gen_rtx_REG (Pmode, A0_REG + 10);
+ rtx addr = temp1;
+
+ emit_move_insn (temp0, gen_rtx_MEM (Pmode, this_rtx));
+ if (xtensa_uimm8x4 (vcall_offset))
+ addr = plus_constant (Pmode, temp0, vcall_offset);
+ else if (xtensa_simm8 (vcall_offset))
+ emit_insn (gen_addsi3 (temp1, temp0, GEN_INT (vcall_offset)));
+ else
+ {
+ emit_move_insn (temp1, GEN_INT (vcall_offset));
+ emit_insn (gen_addsi3 (temp1, temp0, temp1));
+ }
+ emit_move_insn (temp1, gen_rtx_MEM (Pmode, addr));
+ emit_insn (gen_add2_insn (this_rtx, temp1));
+ }
+
+ /* Generate a tail call to the target function. */
+ if (!TREE_USED (function))
+ {
+ assemble_external (function);
+ TREE_USED (function) = 1;
+ }
+
+ funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
+ insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
+ SIBLING_CALL_P (insn) = 1;
+
+ insn = get_insns ();
+ shorten_branches (insn);
+ assemble_start_function (thunk, fnname);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1);
+ final_end_function ();
+ assemble_end_function (thunk, fnname);
+
+ /* Stop pretending to be a post-reload pass. */
+ reload_completed = 0;
+}
+
static rtx
xtensa_delegitimize_address (rtx op)
{
diff --git a/gcc/configure b/gcc/configure
index 817d765..70a013e 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -29727,16 +29727,9 @@ else
if $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null
then
gcc_cv_as_compress_debug=0
- # Since binutils 2.26, gas supports --compress-debug-sections=type,
+ # Since binutils 2.26, gas supports --compress-debug-sections=zlib,
# defaulting to the ELF gABI format.
- elif $gcc_cv_as --compress-debug-sections=zlib-gnu -o conftest.o conftest.s > /dev/null 2>&1
- then
- gcc_cv_as_compress_debug=2
- gcc_cv_as_compress_debug_option="--compress-debug-sections"
- gcc_cv_as_no_compress_debug_option="--nocompress-debug-sections"
- # Before binutils 2.26, gas only supported --compress-debug-options and
- # emitted the traditional GNU format.
- elif $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s > /dev/null 2>&1
+ elif $gcc_cv_as --compress-debug-sections=zlib -o conftest.o conftest.s > /dev/null 2>&1
then
gcc_cv_as_compress_debug=1
gcc_cv_as_compress_debug_option="--compress-debug-sections"
@@ -30254,48 +30247,16 @@ $as_echo "$gcc_cv_ld_eh_gc_sections_bug" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for compressed debug sections" >&5
$as_echo_n "checking linker for compressed debug sections... " >&6; }
-# gold/gld support compressed debug sections since binutils 2.19/2.21
-# In binutils 2.26, gld gained support for the ELF gABI format.
-if test $in_tree_ld = yes ; then
- gcc_cv_ld_compress_debug=0
- if test $ld_is_mold = yes; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes && test $ld_is_gold = yes; then
- gcc_cv_ld_compress_debug=2
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 26 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes && test $ld_is_gold = no; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
+# GNU ld/gold support --compressed-debug-sections=zlib since binutils 2.26.
+if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zlib-gabi\>' > /dev/null; then
gcc_cv_ld_compress_debug=1
- fi
-elif echo "$ld_ver" | grep GNU > /dev/null; then
- if test $ld_is_mold = yes; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$ld_vers_major" -lt 2 \
- || test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 21; then
- gcc_cv_ld_compress_debug=0
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
- gcc_cv_ld_compress_debug=1
- else
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- fi
- if test $ld_is_gold = yes; then
- gcc_cv_ld_compress_debug=2
gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- fi
else
case "${target}" in
*-*-solaris2*)
# Introduced in Solaris 11.2.
if $gcc_cv_ld --help 2>&1 | grep -- '-z compress-sections' > /dev/null; then
- gcc_cv_ld_compress_debug=3
+ gcc_cv_ld_compress_debug=1
gcc_cv_ld_compress_debug_option="-z compress-sections"
else
gcc_cv_ld_compress_debug=0
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 59f205a1..96e10d7 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5732,16 +5732,9 @@ gcc_GAS_CHECK_FEATURE([compressed debug sections],
if $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null
then
gcc_cv_as_compress_debug=0
- # Since binutils 2.26, gas supports --compress-debug-sections=type,
+ # Since binutils 2.26, gas supports --compress-debug-sections=zlib,
# defaulting to the ELF gABI format.
- elif $gcc_cv_as --compress-debug-sections=zlib-gnu -o conftest.o conftest.s > /dev/null 2>&1
- then
- gcc_cv_as_compress_debug=2
- gcc_cv_as_compress_debug_option="--compress-debug-sections"
- gcc_cv_as_no_compress_debug_option="--nocompress-debug-sections"
- # Before binutils 2.26, gas only supported --compress-debug-options and
- # emitted the traditional GNU format.
- elif $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s > /dev/null 2>&1
+ elif $gcc_cv_as --compress-debug-sections=zlib -o conftest.o conftest.s > /dev/null 2>&1
then
gcc_cv_as_compress_debug=1
gcc_cv_as_compress_debug_option="--compress-debug-sections"
@@ -6130,49 +6123,17 @@ fi
AC_MSG_RESULT($gcc_cv_ld_eh_gc_sections_bug)
AC_MSG_CHECKING(linker for compressed debug sections)
-# gold/gld support compressed debug sections since binutils 2.19/2.21
-# In binutils 2.26, gld gained support for the ELF gABI format.
-if test $in_tree_ld = yes ; then
- gcc_cv_ld_compress_debug=0
- if test $ld_is_mold = yes; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes && test $ld_is_gold = yes; then
- gcc_cv_ld_compress_debug=2
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 26 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes && test $ld_is_gold = no; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2 \
- && test $in_tree_ld_is_elf = yes; then
+# GNU ld/gold support --compressed-debug-sections=zlib since binutils 2.26.
+if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zlib-gabi\>' > /dev/null; then
gcc_cv_ld_compress_debug=1
- fi
-elif echo "$ld_ver" | grep GNU > /dev/null; then
- if test $ld_is_mold = yes; then
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- elif test "$ld_vers_major" -lt 2 \
- || test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 21; then
- gcc_cv_ld_compress_debug=0
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
- gcc_cv_ld_compress_debug=1
- else
- gcc_cv_ld_compress_debug=3
- gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- fi
- if test $ld_is_gold = yes; then
- gcc_cv_ld_compress_debug=2
gcc_cv_ld_compress_debug_option="--compress-debug-sections"
- fi
else
changequote(,)dnl
case "${target}" in
*-*-solaris2*)
# Introduced in Solaris 11.2.
if $gcc_cv_ld --help 2>&1 | grep -- '-z compress-sections' > /dev/null; then
- gcc_cv_ld_compress_debug=3
+ gcc_cv_ld_compress_debug=1
gcc_cv_ld_compress_debug_option="-z compress-sections"
else
gcc_cv_ld_compress_debug=0
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dc4ce202..b9b2729 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,55 @@
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_CONVERTIBLE
+ and CPTK_IS_NOTHROW_CONVERTIBLE.
+ * cp-objcp-common.cc (names_builtin_p): Handle RID_IS_CONVERTIBLE
+ RID_IS_NOTHROW_CONVERTIBLE.
+ * cp-tree.h (enum cp_trait_kind): Add CPTK_IS_CONVERTIBLE and
+ CPTK_IS_NOTHROW_CONVERTIBLE.
+ (is_convertible): Declare.
+ (is_nothrow_convertible): Likewise.
+ * cxx-pretty-print.cc (pp_cxx_trait_expression): Handle
+ CPTK_IS_CONVERTIBLE and CPTK_IS_NOTHROW_CONVERTIBLE.
+ * method.cc (is_convertible): New.
+ (is_nothrow_convertible): Likewise.
+ * parser.cc (cp_parser_primary_expression): Handle RID_IS_CONVERTIBLE
+ and RID_IS_NOTHROW_CONVERTIBLE.
+ (cp_parser_trait_expr): Likewise.
+ * semantics.cc (trait_expr_value): Handle CPTK_IS_CONVERTIBLE and
+ CPTK_IS_NOTHROW_CONVERTIBLE.
+ (finish_trait_expr): Likewise.
+
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106983
+ * typeck2.cc (split_nonconstant_init_1): Check TYPE_P.
+
+2022-09-22 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/106826
+ * module.cc (trees_out::decl_value): Use get_template_info in
+ the MK_partial case to handle both VAR_DECL and TYPE_DECL.
+ (trees_out::key_mergeable): Likewise.
+ (trees_in::key_mergeable): Likewise.
+ (has_definition): Consider DECL_INITIAL of a partial variable
+ template specialization.
+ (depset::hash::make_dependency): Handle partial variable template
+ specializations too.
+
+2022-09-20 Patrick Palka <ppalka@redhat.com>
+
+ * decl.cc (cp_finish_decl): After updating the deduced type of a
+ VAR_DECL, also update the corresponding TEMPLATE_DECL if there
+ is one.
+
+2022-09-20 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/106761
+ * module.cc (trees_out::type_node) <case TYPE_PACK_EXPANSION>:
+ Stream PACK_EXPANSION_EXTRA_ARGS.
+ (trees_in::tree_node) <case TYPE_PACK_EXPANSION>: Likewise.
+
2022-09-17 Patrick Palka <ppalka@redhat.com>
* module.cc (friend_from_decl_list): Don't consider
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 568318f..5839bfb 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3697,6 +3697,12 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
inform (loc, " %qT does not have unique object representations", t1);
break;
+ case CPTK_IS_CONVERTIBLE:
+ inform (loc, " %qT is not convertible from %qE", t2, t1);
+ break;
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, " %qT is not %<nothrow%> convertible from %qE", t2, t1);
+ break;
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
inform (loc, " %qT is not a reference that binds to a temporary "
"object of type %qT (direct-initialization)", t1, t2);
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 1ffac08..6497569 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -463,6 +463,8 @@ names_builtin_p (const char *name)
case RID_IS_NOTHROW_ASSIGNABLE:
case RID_IS_NOTHROW_CONSTRUCTIBLE:
case RID_UNDERLYING_TYPE:
+ case RID_IS_CONVERTIBLE:
+ case RID_IS_NOTHROW_CONVERTIBLE:
case RID_REF_CONSTRUCTS_FROM_TEMPORARY:
case RID_REF_CONVERTS_FROM_TEMPORARY:
return true;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f19ecaf..e4d8920 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1407,6 +1407,8 @@ enum cp_trait_kind
CPTK_IS_CONSTRUCTIBLE,
CPTK_IS_NOTHROW_ASSIGNABLE,
CPTK_IS_NOTHROW_CONSTRUCTIBLE,
+ CPTK_IS_CONVERTIBLE,
+ CPTK_IS_NOTHROW_CONVERTIBLE,
CPTK_REF_CONSTRUCTS_FROM_TEMPORARY,
CPTK_REF_CONVERTS_FROM_TEMPORARY
};
@@ -7116,6 +7118,8 @@ extern tree forward_parm (tree);
extern bool is_trivially_xible (enum tree_code, tree, tree);
extern bool is_nothrow_xible (enum tree_code, tree, tree);
extern bool is_xible (enum tree_code, tree, tree);
+extern bool is_convertible (tree, tree);
+extern bool is_nothrow_convertible (tree, tree);
extern bool ref_xes_from_temporary (tree, tree, bool);
extern tree get_defaulted_eh_spec (tree, tsubst_flags_t = tf_warning_or_error);
extern bool maybe_explain_implicit_delete (tree);
diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index 4459083..e18143e3 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -2696,6 +2696,12 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
pp_cxx_ws_string (pp, "__is_nothrow_constructible");
break;
+ case CPTK_IS_CONVERTIBLE:
+ pp_cxx_ws_string (pp, "__is_convertible");
+ break;
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
+ pp_cxx_ws_string (pp, "__is_nothrow_convertible");
+ break;
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
pp_cxx_ws_string (pp, "__reference_constructs_from_temporary");
break;
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 070f673..80467c1 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -8180,6 +8180,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
return;
}
cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
+
+ /* Update the type of the corresponding TEMPLATE_DECL to match. */
+ if (DECL_LANG_SPECIFIC (decl)
+ && DECL_TEMPLATE_INFO (decl)
+ && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl)) == decl)
+ TREE_TYPE (DECL_TI_TEMPLATE (decl)) = type;
}
if (ensure_literal_type_for_constexpr_object (decl) == error_mark_node)
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 573ef01..9f917f1 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -2236,6 +2236,44 @@ ref_xes_from_temporary (tree to, tree from, bool direct_init_p)
return ref_conv_binds_directly (to, val, direct_init_p).is_false ();
}
+/* Worker for is_{,nothrow_}convertible. Attempt to perform an implicit
+ conversion from FROM to TO and return the result. */
+
+static tree
+is_convertible_helper (tree from, tree to)
+{
+ if (VOID_TYPE_P (from) && VOID_TYPE_P (to))
+ return integer_one_node;
+ cp_unevaluated u;
+ tree expr = build_stub_object (from);
+ return perform_implicit_conversion (to, expr, tf_none);
+}
+
+/* Return true if FROM can be converted to TO using implicit conversions,
+ or both FROM and TO are possibly cv-qualified void. NB: This doesn't
+ implement the "Access checks are performed as if from a context unrelated
+ to either type" restriction. */
+
+bool
+is_convertible (tree from, tree to)
+{
+ tree expr = is_convertible_helper (from, to);
+ if (expr == error_mark_node)
+ return false;
+ return !!expr;
+}
+
+/* Like is_convertible, but the conversion is also noexcept. */
+
+bool
+is_nothrow_convertible (tree from, tree to)
+{
+ tree expr = is_convertible_helper (from, to);
+ if (expr == NULL_TREE || expr == error_mark_node)
+ return false;
+ return expr_noexcept_p (expr, tf_none);
+}
+
/* Categorize various special_function_kinds. */
#define SFK_CTOR_P(sfk) \
((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 9a9ef4e..7496df5 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -7789,8 +7789,9 @@ trees_out::decl_value (tree decl, depset *dep)
}
else
{
- tree_node (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner)));
- tree_node (CLASSTYPE_TI_ARGS (TREE_TYPE (inner)));
+ tree ti = get_template_info (inner);
+ tree_node (TI_TEMPLATE (ti));
+ tree_node (TI_ARGS (ti));
}
}
tree_node (get_constraints (decl));
@@ -8184,13 +8185,18 @@ trees_in::decl_value ()
/* Set the TEMPLATE_DECL's type. */
TREE_TYPE (decl) = TREE_TYPE (inner);
- if (mk & MK_template_mask
- || mk == MK_partial)
+ /* Add to specialization tables now that constraints etc are
+ added. */
+ if (mk == MK_partial)
{
- /* Add to specialization tables now that constraints etc are
- added. */
- bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask);
-
+ bool is_type = TREE_CODE (inner) == TYPE_DECL;
+ spec.spec = is_type ? type : inner;
+ add_mergeable_specialization (!is_type, false,
+ &spec, decl, spec_flags);
+ }
+ else if (mk & MK_template_mask)
+ {
+ bool is_type = !(mk & MK_tmpl_decl_mask);
spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl;
add_mergeable_specialization (!is_type,
!is_type && mk & MK_tmpl_alias_mask,
@@ -10625,9 +10631,10 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
case MK_partial:
{
+ tree ti = get_template_info (inner);
key.constraints = get_constraints (inner);
- key.ret = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner));
- key.args = CLASSTYPE_TI_ARGS (TREE_TYPE (inner));
+ key.ret = TI_TEMPLATE (ti);
+ key.args = TI_ARGS (ti);
}
break;
}
@@ -10866,8 +10873,8 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
spec; spec = TREE_CHAIN (spec))
{
tree tmpl = TREE_VALUE (spec);
- if (template_args_equal (key.args,
- CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)))
+ tree ti = get_template_info (tmpl);
+ if (template_args_equal (key.args, TI_ARGS (ti))
&& cp_tree_equal (key.constraints,
get_constraints
(DECL_TEMPLATE_RESULT (tmpl))))
@@ -11381,8 +11388,7 @@ has_definition (tree decl)
case VAR_DECL:
if (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INFO (decl)
- && DECL_USE_TEMPLATE (decl) < 2)
+ && DECL_TEMPLATE_INFO (decl))
return DECL_INITIAL (decl);
else
{
@@ -12498,11 +12504,14 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
if (!dep)
{
- if (DECL_IMPLICIT_TYPEDEF_P (decl)
- /* ... not an enum, for instance. */
- && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
- && TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
- && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2)
+ if ((DECL_IMPLICIT_TYPEDEF_P (decl)
+ /* ... not an enum, for instance. */
+ && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
+ && TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
+ && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2)
+ || (VAR_P (decl)
+ && DECL_LANG_SPECIFIC (decl)
+ && DECL_USE_TEMPLATE (decl) == 2))
{
/* A partial or explicit specialization. Partial
specializations might not be in the hash table, because
@@ -12515,7 +12524,7 @@ depset::hash::make_dependency (tree decl, entity_kind ek)
dep_hash, and then convert the dep we just found into a
redirect. */
- tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (decl));
+ tree ti = get_template_info (decl);
tree tmpl = TI_TEMPLATE (ti);
tree partial = NULL_TREE;
for (tree spec = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 3cbe0d6..bb83d1c 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -5922,6 +5922,8 @@ cp_parser_primary_expression (cp_parser *parser,
case RID_IS_CONSTRUCTIBLE:
case RID_IS_NOTHROW_ASSIGNABLE:
case RID_IS_NOTHROW_CONSTRUCTIBLE:
+ case RID_IS_CONVERTIBLE:
+ case RID_IS_NOTHROW_CONVERTIBLE:
case RID_REF_CONSTRUCTS_FROM_TEMPORARY:
case RID_REF_CONVERTS_FROM_TEMPORARY:
return cp_parser_trait_expr (parser, token->keyword);
@@ -11008,6 +11010,14 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
kind = CPTK_IS_NOTHROW_CONSTRUCTIBLE;
variadic = true;
break;
+ case RID_IS_CONVERTIBLE:
+ kind = CPTK_IS_CONVERTIBLE;
+ binary = true;
+ break;
+ case RID_IS_NOTHROW_CONVERTIBLE:
+ kind = CPTK_IS_NOTHROW_CONVERTIBLE;
+ binary = true;
+ break;
case RID_REF_CONSTRUCTS_FROM_TEMPORARY:
kind = CPTK_REF_CONSTRUCTS_FROM_TEMPORARY;
binary = true;
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index db4e808..1f088fe 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31010,7 +31010,7 @@ add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt,
/* A partial specialization. */
tree cons = tree_cons (elt->args, decl,
DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl));
- TREE_TYPE (cons) = elt->spec;
+ TREE_TYPE (cons) = decl_p ? TREE_TYPE (elt->spec) : elt->spec;
DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl) = cons;
}
}
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 8656207..92fc795 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12044,6 +12044,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
return is_nothrow_xible (INIT_EXPR, type1, type2);
+ case CPTK_IS_CONVERTIBLE:
+ return is_convertible (type1, type2);
+
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
+ return is_nothrow_convertible (type1, type2);
+
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
@@ -12165,6 +12171,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
case CPTK_IS_NOTHROW_ASSIGNABLE:
case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+ case CPTK_IS_CONVERTIBLE:
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
case CPTK_REF_CONVERTS_FROM_TEMPORARY:
if (!check_trait_type (type1)
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index 688e9c1..739097a 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -597,7 +597,7 @@ split_nonconstant_init_1 (tree dest, tree init, bool last,
if (prev == field_index)
break;
tree ptype = TREE_TYPE (prev);
- if (type_build_dtor_call (ptype))
+ if (TYPE_P (ptype) && type_build_dtor_call (ptype))
{
tree pcref = build3 (COMPONENT_REF, ptype, dest, prev,
NULL_TREE);
@@ -1118,6 +1118,15 @@ array_string_literal_compatible_p (tree type, tree init)
if (ordinary_char_type_p (to_char_type)
&& ordinary_char_type_p (from_char_type))
return true;
+
+ /* P2513 (C++20/C++23): "an array of char or unsigned char may
+ be initialized by a UTF-8 string literal, or by such a string
+ literal enclosed in braces." */
+ if (from_char_type == char8_type_node
+ && (to_char_type == char_type_node
+ || to_char_type == unsigned_char_type_node))
+ return true;
+
return false;
}
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 0449dc1..a0792fe 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -4560,6 +4560,15 @@ the GCC sources.
Use the @option{--disable-sjlj-exceptions} and
@option{--enable-newlib-io-long-long} options when configuring.
+The @option{--with-arch} option may be specified to override the
+default value for the @option{-march} option, and to also build
+corresponding target libraries.
+The default is @option{--with-arch=sm_30}.
+
+For example, if @option{--with-arch=sm_70} is specified,
+@option{-march=sm_30} and @option{-march=sm_70} target libraries are
+built, and code generation defaults to @option{-march=sm_70}.
+
@html
<hr />
@end html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a134df7..4a01cfb 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -9863,7 +9863,7 @@ security-sensitive value is written to an output file
See @uref{https://cwe.mitre.org/data/definitions/532.html, CWE-532: Information Exposure Through Log Files}.
-@item Wanalyzer-exposure-through-uninit-copy
+@item -Wanalyzer-exposure-through-uninit-copy
@opindex Wanalyzer-exposure-through-uninit-copy
@opindex Wno-analyzer-exposure-through-uninit-copy
This warning requires both @option{-fanalyzer} and the use of a plugin
@@ -11039,12 +11039,11 @@ location views are enabled.
Produce compressed debug sections in DWARF format, if that is supported.
If @var{type} is not given, the default type depends on the capabilities
of the assembler and linker used. @var{type} may be one of
-@samp{none} (don't compress debug sections), @samp{zlib} (use zlib
-compression in ELF gABI format), or @samp{zlib-gnu} (use zlib
-compression in traditional GNU format). If the linker doesn't support
-writing compressed debug sections, the option is rejected. Otherwise,
-if the assembler does not support them, @option{-gz} is silently ignored
-when producing object files.
+@samp{none} (don't compress debug sections), or @samp{zlib} (use zlib
+compression in ELF gABI format). If the linker doesn't support writing
+compressed debug sections, the option is rejected. Otherwise, if the
+assembler does not support them, @option{-gz} is silently ignored when
+producing object files.
@item -femit-struct-debug-baseonly
@opindex femit-struct-debug-baseonly
@@ -19644,6 +19643,9 @@ and the features that they enable by default:
@item @samp{armv8.7-a} @tab Armv8.7-A @tab @samp{armv8.6-a}, @samp{+ls64}
@item @samp{armv8.8-a} @tab Armv8.8-a @tab @samp{armv8.7-a}, @samp{+mops}
@item @samp{armv9-a} @tab Armv9-A @tab @samp{armv8.5-a}, @samp{+sve}, @samp{+sve2}
+@item @samp{armv9.1-a} @tab Armv9.1-A @tab @samp{armv9-a}, @samp{+bf16}, @samp{+i8mm}
+@item @samp{armv9.2-a} @tab Armv9.2-A @tab @samp{armv9.1-a}, @samp{+ls64}
+@item @samp{armv9.3-a} @tab Armv9.3-A @tab @samp{armv9.2-a}, @samp{+mops}
@item @samp{armv8-r} @tab Armv8-R @tab @samp{armv8-r}
@end multitable
@@ -19674,7 +19676,7 @@ performance of the code. Permissible values for this option are:
@samp{cortex-a78}, @samp{cortex-a78ae}, @samp{cortex-a78c},
@samp{ares}, @samp{exynos-m1}, @samp{emag}, @samp{falkor},
@samp{neoverse-512tvb}, @samp{neoverse-e1}, @samp{neoverse-n1},
-@samp{neoverse-n2}, @samp{neoverse-v1}, @samp{qdf24xx},
+@samp{neoverse-n2}, @samp{neoverse-v1}, @samp{neoverse-v2}, @samp{qdf24xx},
@samp{saphira}, @samp{phecda}, @samp{xgene1}, @samp{vulcan},
@samp{octeontx}, @samp{octeontx81}, @samp{octeontx83},
@samp{octeontx2}, @samp{octeontx2t98}, @samp{octeontx2t96}
@@ -28014,7 +28016,9 @@ supported.
Generate code for the specified PTX ISA target architecture
(e.g.@: @samp{sm_35}). Valid architecture strings are @samp{sm_30},
@samp{sm_35}, @samp{sm_53}, @samp{sm_70}, @samp{sm_75} and
-@samp{sm_80}. The default target architecture is sm_30.
+@samp{sm_80}.
+The default depends on how the compiler has been configured, see
+@option{--with-arch}.
This option sets the value of the preprocessor macro
@code{__PTX_SM__}; for instance, for @samp{sm_35}, it has the value
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 760ff95..52357cc 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2447,7 +2447,7 @@ PowerPC target pre-defines macro _ARCH_PWR9 which means the @code{-mcpu}
setting is Power9 or later.
@end table
-@subsection RISC-V specific attributes
+@subsubsection RISC-V specific attributes
@table @code
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f5f8ac0..6985e62 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,119 @@
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ * trans-expr.cc (gfc_conv_procedure_call): Allow strictly
+ matching derived types.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/99169
+ * trans-expr.cc (gfc_conv_procedure_call): Remove conditions
+ on ALLOCATABLE and POINTER attributes guarding clobber
+ generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87401
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for ASSOCIATE variables.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ on SAVE attribute guarding clobber generation.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * trans-expr.cc (gfc_conv_procedure_call): Remove condition
+ disabling clobber generation for dummy variables. Remove
+ obsolete comment.
+
+2022-09-25 Harald Anlauf <anlauf@gmx.de>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Use dummy
+ information from associated_dummy if there is no information
+ from the procedure interface.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/106817
+ * trans-expr.cc (gfc_conv_procedure_call): Collect all clobbers
+ to their own separate block. Append the block of clobbers to
+ the procedure preliminary block after the argument evaluation
+ codes for all the arguments.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * trans-expr.cc (gfc_conv_procedure_call): Retrieve variable
+ from the just calculated variable reference.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ * trans.h (gfc_conv_expr_reference): Remove add_clobber
+ argument.
+ * trans-expr.cc (gfc_conv_expr_reference): Ditto. Inline code
+ depending on add_clobber and conditions controlling it ...
+ (gfc_conv_procedure_call): ... to here.
+
+2022-09-22 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100103
+ * trans-array.cc (gfc_is_reallocatable_lhs): Add select rank
+ temporary associate names as possible targets of automatic
+ reallocation.
+
+2022-09-22 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82868
+ * trans-decl.cc (generate_coarray_sym_init): Skip symbol
+ if attr.associate_var.
+
+2022-09-20 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/104143
+ * interface.cc (compare_parameter): Permit scalar args to
+ 'type(*), dimension(*)'.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106986
+ * simplify.cc (gfc_simplify_findloc): Do not try to simplify
+ intrinsic FINDLOC when the ARRAY argument has a NULL shape.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106985
+ * expr.cc (gfc_simplify_expr): Avoid NULL pointer dereference.
+
+2022-09-20 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100132
+ * trans-types.cc (create_fn_spec): Fix function attributes when
+ passing polymorphic pointers.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ PR fortran/106636
+ * gfortran.texi: Add back link to ISO_VARYING_STRING.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * gfortran.texi: Replace "the the" with "the".
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ PR fortran/106636
+ * gfortran.texi: Remove 2 dead links.
+
2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* libgfortran.h: Declare GFC_FPE_AWAY.
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc
index be94c18..290ddf3 100644
--- a/gcc/fortran/expr.cc
+++ b/gcc/fortran/expr.cc
@@ -2287,7 +2287,8 @@ gfc_simplify_expr (gfc_expr *p, int type)
initialization expression, or we want a subsection. */
if (p->symtree->n.sym->attr.flavor == FL_PARAMETER
&& (gfc_init_expr_flag || p->ref
- || p->symtree->n.sym->value->expr_type != EXPR_ARRAY))
+ || (p->symtree->n.sym->value
+ && p->symtree->n.sym->value->expr_type != EXPR_ARRAY)))
{
if (!simplify_parameter_variable (p, type))
return false;
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 71eec78..d3e1995 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2692,7 +2692,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
- if the actual argument is (a substring of) an element of a
non-assumed-shape/non-pointer/non-polymorphic array; or
- (F2003) if the actual argument is of type character of default/c_char
- kind. */
+ kind.
+ - (F2018) if the dummy argument is type(*). */
is_pointer = actual->expr_type == EXPR_VARIABLE
? actual->symtree->n.sym->attr.pointer : false;
@@ -2759,6 +2760,14 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
if (ref == NULL && actual->expr_type != EXPR_NULL)
{
+ if (actual->rank == 0
+ && formal->ts.type == BT_ASSUMED
+ && formal->as
+ && formal->as->type == AS_ASSUMED_SIZE)
+ /* This is new in F2018, type(*) is new in TS29113, but gfortran does
+ not differentiate. Thus, if type(*) exists, it is valid;
+ otherwise, type(*) is already rejected. */
+ return true;
if (where
&& (!formal->attr.artificial || (!formal->maybe_array
&& !maybe_dummy_array_arg (actual))))
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 140c177..c0fbd0e 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -5895,6 +5895,7 @@ gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim,
bool back_val = false;
if (!is_constant_array_expr (array)
+ || array->shape == NULL
|| !gfc_is_constant_expr (dim))
return NULL;
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 0513495..795ce14 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -10378,7 +10378,7 @@ gfc_is_reallocatable_lhs (gfc_expr *expr)
/* An allocatable class variable with no reference. */
if (sym->ts.type == BT_CLASS
- && !sym->attr.associate_var
+ && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
&& CLASS_DATA (sym)->attr.allocatable
&& expr->ref
&& ((expr->ref->type == REF_ARRAY && expr->ref->u.ar.type == AR_FULL
@@ -10393,7 +10393,7 @@ gfc_is_reallocatable_lhs (gfc_expr *expr)
/* An allocatable variable. */
if (sym->attr.allocatable
- && !sym->attr.associate_var
+ && (!sym->attr.associate_var || sym->attr.select_rank_temporary)
&& expr->ref
&& expr->ref->type == REF_ARRAY
&& expr->ref->u.ar.type == AR_FULL)
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 908a4c6..5d16d64 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -5529,6 +5529,7 @@ generate_coarray_sym_init (gfc_symbol *sym)
if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
|| sym->attr.use_assoc || !sym->attr.referenced
+ || sym->attr.associate_var
|| sym->attr.select_type_temporary)
return;
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 7895d03..4f3ae82 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6018,7 +6018,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_charlen cl;
gfc_expr *e;
gfc_symbol *fsym;
- stmtblock_t post;
enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
gfc_component *comp = NULL;
int arglen;
@@ -6062,7 +6061,9 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
info = NULL;
+ stmtblock_t post, clobbers;
gfc_init_block (&post);
+ gfc_init_block (&clobbers);
gfc_init_interface_mapping (&mapping);
if (!comp)
{
@@ -6395,7 +6396,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
&& e->symtree->n.sym->attr.pointer))
&& fsym && fsym->attr.target)
/* Make sure the function only gets called once. */
- gfc_conv_expr_reference (&parmse, e, false);
+ gfc_conv_expr_reference (&parmse, e);
else if (e->expr_type == EXPR_FUNCTION
&& e->symtree->n.sym->result
&& e->symtree->n.sym->result != e->symtree->n.sym
@@ -6502,22 +6503,55 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
}
else
{
- bool add_clobber;
- add_clobber = fsym && fsym->attr.intent == INTENT_OUT
- && !fsym->attr.allocatable && !fsym->attr.pointer
- && e->symtree && e->symtree->n.sym
- && !e->symtree->n.sym->attr.dimension
- && !e->symtree->n.sym->attr.pointer
- && !e->symtree->n.sym->attr.allocatable
- /* See PR 41453. */
- && !e->symtree->n.sym->attr.dummy
- /* FIXME - PR 87395 and PR 41453 */
- && e->symtree->n.sym->attr.save == SAVE_NONE
- && !e->symtree->n.sym->attr.associate_var
- && e->ts.type != BT_CHARACTER && e->ts.type != BT_DERIVED
- && e->ts.type != BT_CLASS && !sym->attr.elemental;
-
- gfc_conv_expr_reference (&parmse, e, add_clobber);
+ gfc_conv_expr_reference (&parmse, e);
+
+ gfc_symbol *dsym = fsym;
+ gfc_dummy_arg *dummy;
+
+ /* Use associated dummy as fallback for formal
+ argument if there is no explicit interface. */
+ if (dsym == NULL
+ && (dummy = arg->associated_dummy)
+ && dummy->intrinsicness == GFC_NON_INTRINSIC_DUMMY_ARG
+ && dummy->u.non_intrinsic->sym)
+ dsym = dummy->u.non_intrinsic->sym;
+
+ if (dsym
+ && dsym->attr.intent == INTENT_OUT
+ && !dsym->attr.allocatable
+ && !dsym->attr.pointer
+ && e->expr_type == EXPR_VARIABLE
+ && e->ref == NULL
+ && e->symtree
+ && e->symtree->n.sym
+ && !e->symtree->n.sym->attr.dimension
+ && e->ts.type != BT_CHARACTER
+ && e->ts.type != BT_CLASS
+ && (e->ts.type != BT_DERIVED
+ || (dsym->ts.type == BT_DERIVED
+ && e->ts.u.derived == dsym->ts.u.derived
+ /* Types with allocatable components are
+ excluded from clobbering because we need
+ the unclobbered pointers to free the
+ allocatable components in the callee.
+ Same goes for finalizable types or types
+ with finalizable components, we need to
+ pass the unclobbered values to the
+ finalization routines.
+ For parameterized types, it's less clear
+ but they may not have a constant size
+ so better exclude them in any case. */
+ && !e->ts.u.derived->attr.alloc_comp
+ && !e->ts.u.derived->attr.pdt_type
+ && !gfc_is_finalizable (e->ts.u.derived, NULL)))
+ && !sym->attr.elemental)
+ {
+ tree var;
+ var = build_fold_indirect_ref_loc (input_location,
+ parmse.expr);
+ tree clobber = build_clobber (TREE_TYPE (var));
+ gfc_add_modify (&clobbers, var, clobber);
+ }
}
/* Catch base objects that are not variables. */
if (e->ts.type == BT_CLASS
@@ -7384,6 +7418,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
vec_safe_push (arglist, parmse.expr);
}
+ gfc_add_block_to_block (&se->pre, &clobbers);
gfc_finish_interface_mapping (&mapping, &se->pre, &se->post);
if (comp)
@@ -9484,7 +9519,7 @@ gfc_conv_expr_type (gfc_se * se, gfc_expr * expr, tree type)
values only. */
void
-gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
+gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
{
gfc_ss *ss;
tree var;
@@ -9524,16 +9559,6 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr, bool add_clobber)
gfc_add_block_to_block (&se->pre, &se->post);
se->expr = var;
}
- else if (add_clobber && expr->ref == NULL)
- {
- tree clobber;
- tree var;
- /* FIXME: This fails if var is passed by reference, see PR
- 41453. */
- var = expr->symtree->n.sym->backend_decl;
- clobber = build_clobber (TREE_TYPE (var));
- gfc_add_modify (&se->pre, var, clobber);
- }
return;
}
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 0ea7c74..c062a5b 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -3054,12 +3054,23 @@ create_fn_spec (gfc_symbol *sym, tree fntype)
for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
if (spec_len < sizeof (spec))
{
- if (!f->sym || f->sym->attr.pointer || f->sym->attr.target
+ bool is_class = false;
+ bool is_pointer = false;
+
+ if (f->sym)
+ {
+ is_class = f->sym->ts.type == BT_CLASS && CLASS_DATA (f->sym)
+ && f->sym->attr.class_ok;
+ is_pointer = is_class ? CLASS_DATA (f->sym)->attr.class_pointer
+ : f->sym->attr.pointer;
+ }
+
+ if (f->sym == NULL || is_pointer || f->sym->attr.target
|| f->sym->attr.external || f->sym->attr.cray_pointer
|| (f->sym->ts.type == BT_DERIVED
&& (f->sym->ts.u.derived->attr.proc_pointer_comp
|| f->sym->ts.u.derived->attr.pointer_comp))
- || (f->sym->ts.type == BT_CLASS
+ || (is_class
&& (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp
|| CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp))
|| (f->sym->ts.type == BT_INTEGER && f->sym->ts.is_c_interop))
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 03d5288..bc9035c 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -499,8 +499,7 @@ tree gfc_build_compare_string (tree, tree, tree, tree, int, enum tree_code);
void gfc_conv_expr (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_val (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_lhs (gfc_se * se, gfc_expr * expr);
-void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr,
- bool add_clobber = false);
+void gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr);
void gfc_conv_expr_type (gfc_se * se, gfc_expr *, tree);
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 1584611..7578988 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -831,21 +831,11 @@ proper position among the other output files. */
#define LINK_COMPRESS_DEBUG_SPEC \
" %{gz*:%e-gz is not supported in this configuration} "
#elif HAVE_LD_COMPRESS_DEBUG == 1
-/* GNU style on input, GNU ld options. Reject, not useful. */
-#define LINK_COMPRESS_DEBUG_SPEC \
- " %{gz*:%e-gz is not supported in this configuration} "
-#elif HAVE_LD_COMPRESS_DEBUG == 2
-/* GNU style, GNU gold options. */
-#define LINK_COMPRESS_DEBUG_SPEC \
- " %{gz|gz=zlib-gnu:" LD_COMPRESS_DEBUG_OPTION "=zlib}" \
- " %{gz=none:" LD_COMPRESS_DEBUG_OPTION "=none}" \
- " %{gz=zlib:%e-gz=zlib is not supported in this configuration} "
-#elif HAVE_LD_COMPRESS_DEBUG == 3
/* ELF gABI style. */
#define LINK_COMPRESS_DEBUG_SPEC \
" %{gz|gz=zlib:" LD_COMPRESS_DEBUG_OPTION "=zlib}" \
" %{gz=none:" LD_COMPRESS_DEBUG_OPTION "=none}" \
- " %{gz=zlib-gnu:" LD_COMPRESS_DEBUG_OPTION "=zlib-gnu} "
+ " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */
#else
#error Unknown value for HAVE_LD_COMPRESS_DEBUG.
#endif
@@ -885,31 +875,25 @@ proper position among the other output files. */
#endif
/* Assembler options for compressed debug sections. */
-#if HAVE_LD_COMPRESS_DEBUG < 2
+#if HAVE_LD_COMPRESS_DEBUG == 0
/* Reject if the linker cannot write compressed debug sections. */
#define ASM_COMPRESS_DEBUG_SPEC \
" %{gz*:%e-gz is not supported in this configuration} "
-#else /* HAVE_LD_COMPRESS_DEBUG >= 2 */
+#else /* HAVE_LD_COMPRESS_DEBUG >= 1 */
#if HAVE_AS_COMPRESS_DEBUG == 0
/* No assembler support. Ignore silently. */
#define ASM_COMPRESS_DEBUG_SPEC \
" %{gz*:} "
#elif HAVE_AS_COMPRESS_DEBUG == 1
-/* GNU style, GNU as options. */
-#define ASM_COMPRESS_DEBUG_SPEC \
- " %{gz|gz=zlib-gnu:" AS_COMPRESS_DEBUG_OPTION "}" \
- " %{gz=none:" AS_NO_COMPRESS_DEBUG_OPTION "}" \
- " %{gz=zlib:%e-gz=zlib is not supported in this configuration} "
-#elif HAVE_AS_COMPRESS_DEBUG == 2
/* ELF gABI style. */
#define ASM_COMPRESS_DEBUG_SPEC \
" %{gz|gz=zlib:" AS_COMPRESS_DEBUG_OPTION "=zlib}" \
" %{gz=none:" AS_COMPRESS_DEBUG_OPTION "=none}" \
- " %{gz=zlib-gnu:" AS_COMPRESS_DEBUG_OPTION "=zlib-gnu} "
+ " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */
#else
#error Unknown value for HAVE_AS_COMPRESS_DEBUG.
#endif
-#endif /* HAVE_LD_COMPRESS_DEBUG >= 2 */
+#endif /* HAVE_LD_COMPRESS_DEBUG >= 1 */
/* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
to the assembler, when compiling assembly sources only. */
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index 194e8f8..95deadf 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -43,7 +43,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
if (!gsi_end_p (gsi))
{
gimple *s = gsi_stmt (gsi);
- if (is_a<gcond *> (s) && range_op_handler (s))
+ if (is_a<gcond *> (s) && gimple_range_op_handler::supported_p (s))
return gsi_stmt (gsi);
if (is_a <gswitch *> (s))
return gsi_stmt (gsi);
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index a45fc7a..c381ef9 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "vr-values.h"
#include "range.h"
#include "value-query.h"
-#include "range-op.h"
+#include "gimple-range-op.h"
#include "gimple-range.h"
// Construct a fur_source, and set the m_query field.
@@ -463,73 +463,6 @@ gimple_range_adjustment (vrange &res, const gimple *stmt)
}
}
-// Return the base of the RHS of an assignment.
-
-static tree
-gimple_range_base_of_assignment (const gimple *stmt)
-{
- gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
- tree op1 = gimple_assign_rhs1 (stmt);
- if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
- return get_base_address (TREE_OPERAND (op1, 0));
- return op1;
-}
-
-// Return the first operand of this statement if it is a valid operand
-// supported by ranges, otherwise return NULL_TREE. Special case is
-// &(SSA_NAME expr), return the SSA_NAME instead of the ADDR expr.
-
-tree
-gimple_range_operand1 (const gimple *stmt)
-{
- gcc_checking_assert (range_op_handler (stmt));
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_COND:
- return gimple_cond_lhs (stmt);
- case GIMPLE_ASSIGN:
- {
- tree base = gimple_range_base_of_assignment (stmt);
- if (base && TREE_CODE (base) == MEM_REF)
- {
- // If the base address is an SSA_NAME, we return it
- // here. This allows processing of the range of that
- // name, while the rest of the expression is simply
- // ignored. The code in range_ops will see the
- // ADDR_EXPR and do the right thing.
- tree ssa = TREE_OPERAND (base, 0);
- if (TREE_CODE (ssa) == SSA_NAME)
- return ssa;
- }
- return base;
- }
- default:
- break;
- }
- return NULL;
-}
-
-// Return the second operand of statement STMT, otherwise return NULL_TREE.
-
-tree
-gimple_range_operand2 (const gimple *stmt)
-{
- gcc_checking_assert (range_op_handler (stmt));
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_COND:
- return gimple_cond_rhs (stmt);
- case GIMPLE_ASSIGN:
- if (gimple_num_ops (stmt) >= 3)
- return gimple_assign_rhs2 (stmt);
- default:
- break;
- }
- return NULL_TREE;
-}
-
// Calculate a range for statement S and return it in R. If NAME is provided it
// represents the SSA_NAME on the LHS of the statement. It is only required
// if there is more than one lhs/output. If a range cannot
@@ -551,8 +484,9 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
&& gimple_assign_rhs_code (s) == ADDR_EXPR)
return range_of_address (as_a <irange> (r), s, src);
- if (range_op_handler (s))
- res = range_of_range_op (r, s, src);
+ gimple_range_op_handler handler (s);
+ if (handler)
+ res = range_of_range_op (r, handler, src);
else if (is_a<gphi *>(s))
res = range_of_phi (r, as_a<gphi *> (s), src);
else if (is_a<gcall *>(s))
@@ -587,17 +521,29 @@ fold_using_range::fold_stmt (vrange &r, gimple *s, fur_source &src, tree name)
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
+fold_using_range::range_of_range_op (vrange &r,
+ gimple_range_op_handler &handler,
+ fur_source &src)
{
+ gcc_checking_assert (handler);
+ gimple *s = handler.stmt ();
tree type = gimple_range_type (s);
if (!type)
return false;
- range_op_handler handler (s);
- gcc_checking_assert (handler);
- tree lhs = gimple_get_lhs (s);
- tree op1 = gimple_range_operand1 (s);
- tree op2 = gimple_range_operand2 (s);
+ tree lhs = handler.lhs ();
+ tree op1 = handler.operand1 ();
+ tree op2 = handler.operand2 ();
+
+ // Certain types of builtin functions may have no arguments.
+ if (!op1)
+ {
+ Value_Range r1 (type);
+ if (!handler.fold_range (r, type, r1, r1))
+ r.set_varying (type);
+ return true;
+ }
+
Value_Range range1 (TREE_TYPE (op1));
Value_Range range2 (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
@@ -608,7 +554,8 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
// Fold range, and register any dependency if available.
Value_Range r2 (type);
r2.set_varying (type);
- handler.fold_range (r, type, range1, r2);
+ if (!handler.fold_range (r, type, range1, r2))
+ r.set_varying (type);
if (lhs && gimple_range_ssa_p (op1))
{
if (src.gori ())
@@ -631,7 +578,8 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
fputc ('\n', dump_file);
}
// Fold range, and register any dependency if available.
- handler.fold_range (r, type, range1, range2, rel);
+ if (!handler.fold_range (r, type, range1, range2, rel))
+ r.set_varying (type);
if (irange::supports_p (type))
relation_fold_and_or (as_a <irange> (r), s, src);
if (lhs)
@@ -885,7 +833,7 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src)
// If a range cannot be calculated, return false.
bool
-fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &src)
+fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &)
{
tree type = gimple_range_type (call);
if (!type)
@@ -894,9 +842,7 @@ fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &src)
tree lhs = gimple_call_lhs (call);
bool strict_overflow_p;
- if (range_of_builtin_call (r, call, src))
- ;
- else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
+ if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
r.set_nonnegative (type);
else if (gimple_call_nonnull_result_p (call)
|| gimple_call_nonnull_arg (call))
@@ -914,387 +860,6 @@ fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &src)
return true;
}
-// Return the range of a __builtin_ubsan* in CALL and set it in R.
-// CODE is the type of ubsan call (PLUS_EXPR, MINUS_EXPR or
-// MULT_EXPR).
-
-void
-fold_using_range::range_of_builtin_ubsan_call (irange &r, gcall *call,
- tree_code code, fur_source &src)
-{
- gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR
- || code == MULT_EXPR);
- tree type = gimple_range_type (call);
- range_op_handler op (code, type);
- gcc_checking_assert (op);
- int_range_max ir0, ir1;
- tree arg0 = gimple_call_arg (call, 0);
- tree arg1 = gimple_call_arg (call, 1);
- src.get_operand (ir0, arg0);
- src.get_operand (ir1, arg1);
- // Check for any relation between arg0 and arg1.
- relation_kind relation = src.query_relation (arg0, arg1);
-
- bool saved_flag_wrapv = flag_wrapv;
- // Pretend the arithmetic is wrapping. If there is any overflow,
- // we'll complain, but will actually do wrapping operation.
- flag_wrapv = 1;
- op.fold_range (r, type, ir0, ir1, relation);
- flag_wrapv = saved_flag_wrapv;
-
- // If for both arguments vrp_valueize returned non-NULL, this should
- // have been already folded and if not, it wasn't folded because of
- // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
- if (r.singleton_p ())
- r.set_varying (type);
-}
-
-// Return TRUE if we recognize the target character set and return the
-// range for lower case and upper case letters.
-
-static bool
-get_letter_range (tree type, irange &lowers, irange &uppers)
-{
- // ASCII
- int a = lang_hooks.to_target_charset ('a');
- int z = lang_hooks.to_target_charset ('z');
- int A = lang_hooks.to_target_charset ('A');
- int Z = lang_hooks.to_target_charset ('Z');
-
- if ((z - a == 25) && (Z - A == 25))
- {
- lowers = int_range<2> (build_int_cst (type, a), build_int_cst (type, z));
- uppers = int_range<2> (build_int_cst (type, A), build_int_cst (type, Z));
- return true;
- }
- // Unknown character set.
- return false;
-}
-
-// For a builtin in CALL, return a range in R if known and return
-// TRUE. Otherwise return FALSE.
-
-bool
-fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
- fur_source &src)
-{
- combined_fn func = gimple_call_combined_fn (call);
- if (func == CFN_LAST)
- return false;
-
- tree type = gimple_range_type (call);
- gcc_checking_assert (type);
-
- if (irange::supports_p (type))
- return range_of_builtin_int_call (as_a <irange> (r), call, src);
-
- return false;
-}
-
-bool
-fold_using_range::range_of_builtin_int_call (irange &r, gcall *call,
- fur_source &src)
-{
- combined_fn func = gimple_call_combined_fn (call);
- if (func == CFN_LAST)
- return false;
-
- tree type = gimple_range_type (call);
- tree arg;
- int mini, maxi, zerov = 0, prec;
- scalar_int_mode mode;
-
- switch (func)
- {
- case CFN_BUILT_IN_CONSTANT_P:
- {
- arg = gimple_call_arg (call, 0);
- Value_Range tmp (TREE_TYPE (arg));
- if (src.get_operand (tmp, arg) && tmp.singleton_p ())
- {
- r.set (build_one_cst (type), build_one_cst (type));
- return true;
- }
- if (cfun->after_inlining)
- {
- r.set_zero (type);
- return true;
- }
- break;
- }
-
- case CFN_BUILT_IN_SIGNBIT:
- {
- arg = gimple_call_arg (call, 0);
- frange tmp;
- if (src.get_operand (tmp, arg))
- {
- bool signbit;
- if (tmp.signbit_p (signbit))
- {
- if (signbit)
- r.set_nonzero (type);
- else
- r.set_zero (type);
- return true;
- }
- return false;
- }
- break;
- }
-
- case CFN_BUILT_IN_TOUPPER:
- {
- arg = gimple_call_arg (call, 0);
- // If the argument isn't compatible with the LHS, do nothing.
- if (!range_compatible_p (type, TREE_TYPE (arg)))
- return false;
- if (!src.get_operand (r, arg))
- return false;
-
- int_range<3> lowers;
- int_range<3> uppers;
- if (!get_letter_range (type, lowers, uppers))
- return false;
-
- // Return the range passed in without any lower case characters,
- // but including all the upper case ones.
- lowers.invert ();
- r.intersect (lowers);
- r.union_ (uppers);
- return true;
- }
-
- case CFN_BUILT_IN_TOLOWER:
- {
- arg = gimple_call_arg (call, 0);
- // If the argument isn't compatible with the LHS, do nothing.
- if (!range_compatible_p (type, TREE_TYPE (arg)))
- return false;
- if (!src.get_operand (r, arg))
- return false;
-
- int_range<3> lowers;
- int_range<3> uppers;
- if (!get_letter_range (type, lowers, uppers))
- return false;
-
- // Return the range passed in without any upper case characters,
- // but including all the lower case ones.
- uppers.invert ();
- r.intersect (uppers);
- r.union_ (lowers);
- return true;
- }
-
- CASE_CFN_FFS:
- CASE_CFN_POPCOUNT:
- // __builtin_ffs* and __builtin_popcount* return [0, prec].
- arg = gimple_call_arg (call, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec;
- src.get_operand (r, arg);
- // If arg is non-zero, then ffs or popcount are non-zero.
- if (!range_includes_zero_p (&r))
- mini = 1;
- // If some high bits are known to be zero, decrease the maximum.
- if (!r.undefined_p ())
- {
- if (TYPE_SIGN (r.type ()) == SIGNED)
- range_cast (r, unsigned_type_for (r.type ()));
- wide_int max = r.upper_bound ();
- maxi = wi::floor_log2 (max) + 1;
- }
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
- return true;
-
- CASE_CFN_PARITY:
- r.set (build_zero_cst (type), build_one_cst (type));
- return true;
-
- CASE_CFN_CLZ:
- // __builtin_c[lt]z* return [0, prec-1], except when the
- // argument is 0, but that is undefined behavior.
- //
- // For __builtin_c[lt]z* consider argument of 0 always undefined
- // behavior, for internal fns depending on C?Z_DEFINED_VALUE_AT_ZERO.
- arg = gimple_call_arg (call, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec - 1;
- mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
- if (gimple_call_internal_p (call))
- {
- if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
- && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
- {
- // Only handle the single common value.
- if (zerov == prec)
- maxi = prec;
- else
- // Magic value to give up, unless we can prove arg is non-zero.
- mini = -2;
- }
- }
-
- src.get_operand (r, arg);
- // From clz of minimum we can compute result maximum.
- if (!r.undefined_p ())
- {
- // From clz of minimum we can compute result maximum.
- if (wi::gt_p (r.lower_bound (), 0, TYPE_SIGN (r.type ())))
- {
- maxi = prec - 1 - wi::floor_log2 (r.lower_bound ());
- if (mini == -2)
- mini = 0;
- }
- else if (!range_includes_zero_p (&r))
- {
- mini = 0;
- maxi = prec - 1;
- }
- if (mini == -2)
- break;
- // From clz of maximum we can compute result minimum.
- wide_int max = r.upper_bound ();
- int newmini = prec - 1 - wi::floor_log2 (max);
- if (max == 0)
- {
- // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
- // return [prec, prec], otherwise ignore the range.
- if (maxi == prec)
- mini = prec;
- }
- else
- mini = newmini;
- }
- if (mini == -2)
- break;
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
- return true;
-
- CASE_CFN_CTZ:
- // __builtin_ctz* return [0, prec-1], except for when the
- // argument is 0, but that is undefined behavior.
- //
- // For __builtin_ctz* consider argument of 0 always undefined
- // behavior, for internal fns depending on CTZ_DEFINED_VALUE_AT_ZERO.
- arg = gimple_call_arg (call, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- mini = 0;
- maxi = prec - 1;
- mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
- if (gimple_call_internal_p (call))
- {
- if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
- && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
- {
- // Handle only the two common values.
- if (zerov == -1)
- mini = -1;
- else if (zerov == prec)
- maxi = prec;
- else
- // Magic value to give up, unless we can prove arg is non-zero.
- mini = -2;
- }
- }
- src.get_operand (r, arg);
- if (!r.undefined_p ())
- {
- // If arg is non-zero, then use [0, prec - 1].
- if (!range_includes_zero_p (&r))
- {
- mini = 0;
- maxi = prec - 1;
- }
- // If some high bits are known to be zero, we can decrease
- // the maximum.
- wide_int max = r.upper_bound ();
- if (max == 0)
- {
- // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
- // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
- // Otherwise ignore the range.
- if (mini == -1)
- maxi = -1;
- else if (maxi == prec)
- mini = prec;
- }
- // If value at zero is prec and 0 is in the range, we can't lower
- // the upper bound. We could create two separate ranges though,
- // [0,floor_log2(max)][prec,prec] though.
- else if (maxi != prec)
- maxi = wi::floor_log2 (max);
- }
- if (mini == -2)
- break;
- r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
- return true;
-
- CASE_CFN_CLRSB:
- arg = gimple_call_arg (call, 0);
- prec = TYPE_PRECISION (TREE_TYPE (arg));
- r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
- return true;
- case CFN_UBSAN_CHECK_ADD:
- range_of_builtin_ubsan_call (r, call, PLUS_EXPR, src);
- return true;
- case CFN_UBSAN_CHECK_SUB:
- range_of_builtin_ubsan_call (r, call, MINUS_EXPR, src);
- return true;
- case CFN_UBSAN_CHECK_MUL:
- range_of_builtin_ubsan_call (r, call, MULT_EXPR, src);
- return true;
-
- case CFN_GOACC_DIM_SIZE:
- case CFN_GOACC_DIM_POS:
- // Optimizing these two internal functions helps the loop
- // optimizer eliminate outer comparisons. Size is [1,N]
- // and pos is [0,N-1].
- {
- bool is_pos = func == CFN_GOACC_DIM_POS;
- int axis = oacc_get_ifn_dim_arg (call);
- int size = oacc_get_fn_dim_size (current_function_decl, axis);
- if (!size)
- // If it's dynamic, the backend might know a hardware limitation.
- size = targetm.goacc.dim_limit (axis);
-
- r.set (build_int_cst (type, is_pos ? 0 : 1),
- size
- ? build_int_cst (type, size - is_pos) : vrp_val_max (type));
- return true;
- }
-
- case CFN_BUILT_IN_STRLEN:
- if (tree lhs = gimple_call_lhs (call))
- if (ptrdiff_type_node
- && (TYPE_PRECISION (ptrdiff_type_node)
- == TYPE_PRECISION (TREE_TYPE (lhs))))
- {
- tree type = TREE_TYPE (lhs);
- tree max = vrp_val_max (ptrdiff_type_node);
- wide_int wmax
- = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
- tree range_min = build_zero_cst (type);
- // To account for the terminating NULL, the maximum length
- // is one less than the maximum array size, which in turn
- // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
- // smaller than the former type).
- // FIXME: Use max_object_size() - 1 here.
- tree range_max = wide_int_to_tree (type, wmax - 2);
- r.set (range_min, range_max);
- return true;
- }
- break;
- default:
- break;
- }
- return false;
-}
-
-
// Calculate a range for COND_EXPR statement S and return it in R.
// If a range cannot be calculated, return false.
@@ -1430,9 +995,10 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
else if (code != BIT_IOR_EXPR && code != TRUTH_OR_EXPR)
return;
- tree lhs = gimple_get_lhs (s);
- tree ssa1 = gimple_range_ssa_p (gimple_range_operand1 (s));
- tree ssa2 = gimple_range_ssa_p (gimple_range_operand2 (s));
+ gimple_range_op_handler handler (s);
+ tree lhs = handler.lhs ();
+ tree ssa1 = gimple_range_ssa_p (handler.operand1 ());
+ tree ssa2 = gimple_range_ssa_p (handler.operand2 ());
// Deal with || and && only when there is a full set of symbolics.
if (!lhs || !ssa1 || !ssa2
@@ -1448,18 +1014,18 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
gimple *ssa1_stmt = SSA_NAME_DEF_STMT (ssa1);
gimple *ssa2_stmt = SSA_NAME_DEF_STMT (ssa2);
- range_op_handler handler1 (SSA_NAME_DEF_STMT (ssa1));
- range_op_handler handler2 (SSA_NAME_DEF_STMT (ssa2));
+ gimple_range_op_handler handler1 (ssa1_stmt);
+ gimple_range_op_handler handler2 (ssa2_stmt);
// If either handler is not present, no relation can be found.
if (!handler1 || !handler2)
return;
// Both stmts will need to have 2 ssa names in the stmt.
- tree ssa1_dep1 = gimple_range_ssa_p (gimple_range_operand1 (ssa1_stmt));
- tree ssa1_dep2 = gimple_range_ssa_p (gimple_range_operand2 (ssa1_stmt));
- tree ssa2_dep1 = gimple_range_ssa_p (gimple_range_operand1 (ssa2_stmt));
- tree ssa2_dep2 = gimple_range_ssa_p (gimple_range_operand2 (ssa2_stmt));
+ tree ssa1_dep1 = gimple_range_ssa_p (handler1.operand1 ());
+ tree ssa1_dep2 = gimple_range_ssa_p (handler1.operand2 ());
+ tree ssa2_dep1 = gimple_range_ssa_p (handler2.operand1 ());
+ tree ssa2_dep2 = gimple_range_ssa_p (handler2.operand2 ());
if (!ssa1_dep1 || !ssa1_dep2 || !ssa2_dep1 || !ssa2_dep2)
return;
@@ -1516,7 +1082,7 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
tree name;
basic_block bb = gimple_bb (s);
- range_op_handler handler (s);
+ gimple_range_op_handler handler (s);
if (!handler)
return;
@@ -1529,7 +1095,6 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
e0 = NULL;
}
-
if (e1)
{
// If this edge is never taken, ignore it.
@@ -1544,8 +1109,8 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
// First, register the gcond itself. This will catch statements like
// if (a_2 < b_5)
- tree ssa1 = gimple_range_ssa_p (gimple_range_operand1 (s));
- tree ssa2 = gimple_range_ssa_p (gimple_range_operand2 (s));
+ tree ssa1 = gimple_range_ssa_p (handler.operand1 ());
+ tree ssa2 = gimple_range_ssa_p (handler.operand2 ());
if (ssa1 && ssa2)
{
if (e0)
@@ -1575,11 +1140,11 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
if (TREE_CODE (TREE_TYPE (name)) != BOOLEAN_TYPE)
continue;
gimple *stmt = SSA_NAME_DEF_STMT (name);
- range_op_handler handler (stmt);
+ gimple_range_op_handler handler (stmt);
if (!handler)
continue;
- tree ssa1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
- tree ssa2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
+ tree ssa1 = gimple_range_ssa_p (handler.operand1 ());
+ tree ssa2 = gimple_range_ssa_p (handler.operand2 ());
Value_Range r (TREE_TYPE (name));
if (ssa1 && ssa2)
{
@@ -1600,36 +1165,3 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
}
}
}
-
-// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
-// on the statement. For efficiency, it is an error to not pass in enough
-// elements for the vector. Return the number of ssa-names.
-
-unsigned
-gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
-{
- tree ssa;
- int count = 0;
-
- if (range_op_handler (stmt))
- {
- gcc_checking_assert (vec_size >= 2);
- if ((ssa = gimple_range_ssa_p (gimple_range_operand1 (stmt))))
- vec[count++] = ssa;
- if ((ssa = gimple_range_ssa_p (gimple_range_operand2 (stmt))))
- vec[count++] = ssa;
- }
- else if (is_a<gassign *> (stmt)
- && gimple_assign_rhs_code (stmt) == COND_EXPR)
- {
- gcc_checking_assert (vec_size >= 3);
- gassign *st = as_a<gassign *> (stmt);
- if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
- vec[count++] = ssa;
- if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
- vec[count++] = ssa;
- if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
- vec[count++] = ssa;
- }
- return count;
-}
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index f2eab72..d1ed2bc 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -96,15 +96,6 @@ range_compatible_p (tree type1, tree type2)
&& TYPE_SIGN (type1) == TYPE_SIGN (type2));
}
-extern tree gimple_range_operand1 (const gimple *s);
-extern tree gimple_range_operand2 (const gimple *s);
-
-// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
-// on the statement. For efficiency, it is an error to not pass in enough
-// elements for the vector. Return the number of ssa-names.
-
-unsigned gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt);
-
// Source of all operands for fold_using_range and gori_compute.
// It abstracts out the source of an operand so it can come from a stmt or
// and edge or anywhere a derived class of fur_source wants.
@@ -169,14 +160,11 @@ public:
bool fold_stmt (vrange &r, gimple *s, class fur_source &src,
tree name = NULL_TREE);
protected:
- bool range_of_range_op (vrange &r, gimple *s, fur_source &src);
+ bool range_of_range_op (vrange &r, gimple_range_op_handler &handler,
+ fur_source &src);
bool range_of_call (vrange &r, gcall *call, fur_source &src);
bool range_of_cond_expr (vrange &r, gassign* cond, fur_source &src);
bool range_of_address (irange &r, gimple *s, fur_source &src);
- bool range_of_builtin_call (vrange &r, gcall *call, fur_source &src);
- bool range_of_builtin_int_call (irange &r, gcall *call, fur_source &src);
- void range_of_builtin_ubsan_call (irange &r, gcall *call, tree_code code,
- fur_source &src);
bool range_of_phi (vrange &r, gphi *phi, fur_source &src);
void range_of_ssa_name_with_loop_info (vrange &, tree, class loop *, gphi *,
fur_source &src);
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 957b8d5..40b2f2f 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -29,83 +29,6 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-pretty-print.h"
#include "gimple-range.h"
-// Calculate what we can determine of the range of this unary
-// statement's operand if the lhs of the expression has the range
-// LHS_RANGE. Return false if nothing can be determined.
-
-bool
-gimple_range_calc_op1 (vrange &r, const gimple *stmt, const vrange &lhs_range)
-{
- gcc_checking_assert (gimple_num_ops (stmt) < 3);
- // Give up on empty ranges.
- if (lhs_range.undefined_p ())
- return false;
-
- // Unary operations require the type of the first operand in the
- // second range position.
- tree type = TREE_TYPE (gimple_range_operand1 (stmt));
- Value_Range type_range (type);
- type_range.set_varying (type);
- return range_op_handler (stmt).op1_range (r, type, lhs_range, type_range);
-}
-
-// Calculate what we can determine of the range of this statement's
-// first operand if the lhs of the expression has the range LHS_RANGE
-// and the second operand has the range OP2_RANGE. Return false if
-// nothing can be determined.
-
-bool
-gimple_range_calc_op1 (vrange &r, const gimple *stmt,
- const vrange &lhs_range, const vrange &op2_range)
-{
- // Give up on empty ranges.
- if (lhs_range.undefined_p ())
- return false;
-
- // Unary operation are allowed to pass a range in for second operand
- // as there are often additional restrictions beyond the type which
- // can be imposed. See operator_cast::op1_range().
- tree type = TREE_TYPE (gimple_range_operand1 (stmt));
- // If op2 is undefined, solve as if it is varying.
- if (op2_range.undefined_p ())
- {
- // This is sometimes invoked on single operand stmts.
- if (gimple_num_ops (stmt) < 3)
- return false;
- tree op2_type = TREE_TYPE (gimple_range_operand2 (stmt));
- Value_Range trange (op2_type);
- trange.set_varying (op2_type);
- return range_op_handler (stmt).op1_range (r, type, lhs_range, trange);
- }
- return range_op_handler (stmt).op1_range (r, type, lhs_range, op2_range);
-}
-
-// Calculate what we can determine of the range of this statement's
-// second operand if the lhs of the expression has the range LHS_RANGE
-// and the first operand has the range OP1_RANGE. Return false if
-// nothing can be determined.
-
-bool
-gimple_range_calc_op2 (vrange &r, const gimple *stmt,
- const vrange &lhs_range, const vrange &op1_range)
-{
- // Give up on empty ranges.
- if (lhs_range.undefined_p ())
- return false;
-
- tree type = TREE_TYPE (gimple_range_operand2 (stmt));
- // If op1 is undefined, solve as if it is varying.
- if (op1_range.undefined_p ())
- {
- tree op1_type = TREE_TYPE (gimple_range_operand1 (stmt));
- Value_Range trange (op1_type);
- trange.set_varying (op1_type);
- return range_op_handler (stmt).op2_range (r, type, lhs_range, trange);
- }
- return range_op_handler (stmt).op2_range (r, type, lhs_range,
- op1_range);
-}
-
// Return TRUE if GS is a logical && or || expression.
static inline bool
@@ -695,17 +618,18 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
if (is_a<gswitch *> (stmt))
return compute_operand_range_switch (r, as_a<gswitch *> (stmt), lhs, name,
src);
- if (!range_op_handler (stmt))
+ gimple_range_op_handler handler (stmt);
+ if (!handler)
return false;
- tree op1 = gimple_range_ssa_p (gimple_range_operand1 (stmt));
- tree op2 = gimple_range_ssa_p (gimple_range_operand2 (stmt));
+ tree op1 = gimple_range_ssa_p (handler.operand1 ());
+ tree op2 = gimple_range_ssa_p (handler.operand2 ());
// Handle end of lookup first.
if (op1 == name)
- return compute_operand1_range (r, stmt, lhs, name, src);
+ return compute_operand1_range (r, handler, lhs, name, src);
if (op2 == name)
- return compute_operand2_range (r, stmt, lhs, name, src);
+ return compute_operand2_range (r, handler, lhs, name, src);
// NAME is not in this stmt, but one of the names in it ought to be
// derived from it.
@@ -733,10 +657,10 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
tree type = TREE_TYPE (name);
Value_Range op1_trange (type), op1_frange (type);
Value_Range op2_trange (type), op2_frange (type);
- compute_logical_operands (op1_trange, op1_frange, stmt,
+ compute_logical_operands (op1_trange, op1_frange, handler,
as_a <irange> (lhs),
name, src, op1, op1_in_chain);
- compute_logical_operands (op2_trange, op2_frange, stmt,
+ compute_logical_operands (op2_trange, op2_frange, handler,
as_a <irange> (lhs),
name, src, op2, op2_in_chain);
res = logical_combine (r,
@@ -748,11 +672,11 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt,
}
// Follow the appropriate operands now.
else if (op1_in_chain && op2_in_chain)
- res = compute_operand1_and_operand2_range (r, stmt, lhs, name, src);
+ res = compute_operand1_and_operand2_range (r, handler, lhs, name, src);
else if (op1_in_chain)
- res = compute_operand1_range (r, stmt, lhs, name, src);
+ res = compute_operand1_range (r, handler, lhs, name, src);
else if (op2_in_chain)
- res = compute_operand2_range (r, stmt, lhs, name, src);
+ res = compute_operand2_range (r, handler, lhs, name, src);
else
gcc_unreachable ();
@@ -944,13 +868,14 @@ gori_compute::logical_combine (vrange &r, enum tree_code code,
void
gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
- gimple *stmt,
+ gimple_range_op_handler &handler,
const irange &lhs,
tree name, fur_source &src,
tree op, bool op_in_chain)
{
+ gimple *stmt = handler.stmt ();
gimple *src_stmt = gimple_range_ssa_p (op) ? SSA_NAME_DEF_STMT (op) : NULL;
- if (!op_in_chain || !src_stmt || chain_import_p (gimple_get_lhs (stmt), op))
+ if (!op_in_chain || !src_stmt || chain_import_p (handler.lhs (), op))
{
// If op is not in the def chain, or defined in this block,
// use its known value on entry to the block.
@@ -999,12 +924,15 @@ gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
// R, or false if no range could be calculated.
bool
-gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
+gori_compute::compute_operand1_range (vrange &r,
+ gimple_range_op_handler &handler,
const vrange &lhs, tree name,
fur_source &src)
{
- tree op1 = gimple_range_operand1 (stmt);
- tree op2 = gimple_range_operand2 (stmt);
+ gimple *stmt = handler.stmt ();
+ tree op1 = handler.operand1 ();
+ tree op2 = handler.operand2 ();
+
Value_Range op1_range (TREE_TYPE (op1));
Value_Range tmp (TREE_TYPE (op1));
Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
@@ -1016,7 +944,7 @@ gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
if (op2)
{
src.get_operand (op2_range, op2);
- if (!gimple_range_calc_op1 (tmp, stmt, lhs, op2_range))
+ if (!handler.calc_op1 (tmp, lhs, op2_range))
return false;
}
else
@@ -1024,7 +952,7 @@ gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
// We pass op1_range to the unary operation. Nomally it's a
// hidden range_for_type parameter, but sometimes having the
// actual range can result in better information.
- if (!gimple_range_calc_op1 (tmp, stmt, lhs, op1_range))
+ if (!handler.calc_op1 (tmp, lhs, op1_range))
return false;
}
@@ -1079,12 +1007,15 @@ gori_compute::compute_operand1_range (vrange &r, gimple *stmt,
// R, or false if no range could be calculated.
bool
-gori_compute::compute_operand2_range (vrange &r, gimple *stmt,
+gori_compute::compute_operand2_range (vrange &r,
+ gimple_range_op_handler &handler,
const vrange &lhs, tree name,
fur_source &src)
{
- tree op1 = gimple_range_operand1 (stmt);
- tree op2 = gimple_range_operand2 (stmt);
+ gimple *stmt = handler.stmt ();
+ tree op1 = handler.operand1 ();
+ tree op2 = handler.operand2 ();
+
Value_Range op1_range (TREE_TYPE (op1));
Value_Range op2_range (TREE_TYPE (op2));
Value_Range tmp (TREE_TYPE (op2));
@@ -1093,7 +1024,7 @@ gori_compute::compute_operand2_range (vrange &r, gimple *stmt,
src.get_operand (op2_range, op2);
// Intersect with range for op2 based on lhs and op1.
- if (!gimple_range_calc_op2 (tmp, stmt, lhs, op1_range))
+ if (!handler.calc_op2 (tmp, lhs, op1_range))
return false;
unsigned idx;
@@ -1148,7 +1079,8 @@ gori_compute::compute_operand2_range (vrange &r, gimple *stmt,
bool
gori_compute::compute_operand1_and_operand2_range (vrange &r,
- gimple *stmt,
+ gimple_range_op_handler
+ &handler,
const vrange &lhs,
tree name,
fur_source &src)
@@ -1157,11 +1089,11 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r,
// Calculate a good a range for op2. Since op1 == op2, this will
// have already included whatever the actual range of name is.
- if (!compute_operand2_range (op_range, stmt, lhs, name, src))
+ if (!compute_operand2_range (op_range, handler, lhs, name, src))
return false;
// Now get the range thru op1.
- if (!compute_operand1_range (r, stmt, lhs, name, src))
+ if (!compute_operand1_range (r, handler, lhs, name, src))
return false;
// Both operands have to be simultaneously true, so perform an intersection.
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index 3d57ab9..0c776ef 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -170,17 +170,18 @@ private:
tree name, class fur_source &src);
bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs,
tree name, fur_source &src);
- bool compute_operand1_range (vrange &r, gimple *stmt, const vrange &lhs,
- tree name, fur_source &src);
- bool compute_operand2_range (vrange &r, gimple *stmt, const vrange &lhs,
- tree name, fur_source &src);
- bool compute_operand1_and_operand2_range (vrange &r, gimple *stmt,
+ bool compute_operand1_range (vrange &r, gimple_range_op_handler &handler,
+ const vrange &lhs, tree name, fur_source &src);
+ bool compute_operand2_range (vrange &r, gimple_range_op_handler &handler,
+ const vrange &lhs, tree name, fur_source &src);
+ bool compute_operand1_and_operand2_range (vrange &r,
+ gimple_range_op_handler &handler,
const vrange &lhs, tree name,
fur_source &src);
void compute_logical_operands (vrange &true_range, vrange &false_range,
- gimple *stmt, const irange &lhs,
- tree name, fur_source &src, tree op,
- bool op_in_chain);
+ gimple_range_op_handler &handler,
+ const irange &lhs, tree name, fur_source &src,
+ tree op, bool op_in_chain);
bool logical_combine (vrange &r, enum tree_code code, const irange &lhs,
const vrange &op1_true, const vrange &op1_false,
const vrange &op2_true, const vrange &op2_false);
@@ -192,16 +193,6 @@ private:
int m_not_executable_flag;
};
-// These routines provide a GIMPLE interface to the range-ops code.
-extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
- const vrange &lhs_range);
-extern bool gimple_range_calc_op1 (vrange &r, const gimple *s,
- const vrange &lhs_range,
- const vrange &op2_range);
-extern bool gimple_range_calc_op2 (vrange &r, const gimple *s,
- const vrange &lhs_range,
- const vrange &op1_range);
-
// For each name that is an import into BB's exports..
#define FOR_EACH_GORI_IMPORT_NAME(gori, bb, name) \
for (gori_export_iterator iter ((gori).imports ((bb))); \
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
new file mode 100644
index 0000000..d7c6dfa
--- /dev/null
+++ b/gcc/gimple-range-op.cc
@@ -0,0 +1,820 @@
+/* Code for GIMPLE range op related routines.
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+ and Aldy Hernandez <aldyh@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "insn-codes.h"
+#include "tree.h"
+#include "gimple.h"
+#include "ssa.h"
+#include "gimple-pretty-print.h"
+#include "optabs-tree.h"
+#include "gimple-iterator.h"
+#include "gimple-fold.h"
+#include "wide-int.h"
+#include "fold-const.h"
+#include "case-cfn-macros.h"
+#include "omp-general.h"
+#include "cfgloop.h"
+#include "tree-ssa-loop.h"
+#include "tree-scalar-evolution.h"
+#include "langhooks.h"
+#include "vr-values.h"
+#include "range.h"
+#include "value-query.h"
+#include "gimple-range.h"
+
+// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
+// on the statement. For efficiency, it is an error to not pass in enough
+// elements for the vector. Return the number of ssa-names.
+
+unsigned
+gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt)
+{
+ tree ssa;
+ int count = 0;
+
+ gimple_range_op_handler handler (stmt);
+ if (handler)
+ {
+ gcc_checking_assert (vec_size >= 2);
+ if ((ssa = gimple_range_ssa_p (handler.operand1 ())))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (handler.operand2 ())))
+ vec[count++] = ssa;
+ }
+ else if (is_a<gassign *> (stmt)
+ && gimple_assign_rhs_code (stmt) == COND_EXPR)
+ {
+ gcc_checking_assert (vec_size >= 3);
+ gassign *st = as_a<gassign *> (stmt);
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs1 (st))))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs2 (st))))
+ vec[count++] = ssa;
+ if ((ssa = gimple_range_ssa_p (gimple_assign_rhs3 (st))))
+ vec[count++] = ssa;
+ }
+ return count;
+}
+
+// Return the base of the RHS of an assignment.
+
+static tree
+gimple_range_base_of_assignment (const gimple *stmt)
+{
+ gcc_checking_assert (gimple_code (stmt) == GIMPLE_ASSIGN);
+ tree op1 = gimple_assign_rhs1 (stmt);
+ if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+ return get_base_address (TREE_OPERAND (op1, 0));
+ return op1;
+}
+
+// If statement is supported by range-ops, set the CODE and return the TYPE.
+
+static tree
+get_code_and_type (gimple *s, enum tree_code &code)
+{
+ tree type = NULL_TREE;
+ code = NOP_EXPR;
+
+ if (const gassign *ass = dyn_cast<const gassign *> (s))
+ {
+ code = gimple_assign_rhs_code (ass);
+ // The LHS of a comparison is always an int, so we must look at
+ // the operands.
+ if (TREE_CODE_CLASS (code) == tcc_comparison)
+ type = TREE_TYPE (gimple_assign_rhs1 (ass));
+ else
+ type = TREE_TYPE (gimple_assign_lhs (ass));
+ }
+ else if (const gcond *cond = dyn_cast<const gcond *> (s))
+ {
+ code = gimple_cond_code (cond);
+ type = TREE_TYPE (gimple_cond_lhs (cond));
+ }
+ return type;
+}
+
+// If statement S has a supported range_op handler return TRUE.
+
+bool
+gimple_range_op_handler::supported_p (gimple *s)
+{
+ enum tree_code code;
+ tree type = get_code_and_type (s, code);
+ if (type && range_op_handler (code, type))
+ return true;
+ if (is_a <gcall *> (s) && gimple_range_op_handler (s))
+ return true;
+ return false;
+}
+
+// Construct a handler object for statement S.
+
+gimple_range_op_handler::gimple_range_op_handler (gimple *s)
+{
+ enum tree_code code;
+ tree type = get_code_and_type (s, code);
+ m_stmt = s;
+ m_op1 = NULL_TREE;
+ m_op2 = NULL_TREE;
+ if (type)
+ set_op_handler (code, type);
+
+ if (m_valid)
+ switch (gimple_code (m_stmt))
+ {
+ case GIMPLE_COND:
+ m_op1 = gimple_cond_lhs (m_stmt);
+ m_op2 = gimple_cond_rhs (m_stmt);
+ return;
+ case GIMPLE_ASSIGN:
+ m_op1 = gimple_range_base_of_assignment (m_stmt);
+ if (m_op1 && TREE_CODE (m_op1) == MEM_REF)
+ {
+ // If the base address is an SSA_NAME, we return it
+ // here. This allows processing of the range of that
+ // name, while the rest of the expression is simply
+ // ignored. The code in range_ops will see the
+ // ADDR_EXPR and do the right thing.
+ tree ssa = TREE_OPERAND (m_op1, 0);
+ if (TREE_CODE (ssa) == SSA_NAME)
+ m_op1 = ssa;
+ }
+ if (gimple_num_ops (m_stmt) >= 3)
+ m_op2 = gimple_assign_rhs2 (m_stmt);
+ return;
+ default:
+ gcc_unreachable ();
+ return;
+ }
+ // If no range-op table entry handled this stmt, check for other supported
+ // statements.
+ if (is_a <gcall *> (m_stmt))
+ maybe_builtin_call ();
+}
+
+// Calculate what we can determine of the range of this unary
+// statement's operand if the lhs of the expression has the range
+// LHS_RANGE. Return false if nothing can be determined.
+
+bool
+gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range)
+{
+ gcc_checking_assert (gimple_num_ops (m_stmt) < 3);
+ // Give up on empty ranges.
+ if (lhs_range.undefined_p ())
+ return false;
+
+ // Unary operations require the type of the first operand in the
+ // second range position.
+ tree type = TREE_TYPE (operand1 ());
+ Value_Range type_range (type);
+ type_range.set_varying (type);
+ return op1_range (r, type, lhs_range, type_range);
+}
+
+// Calculate what we can determine of the range of this statement's
+// first operand if the lhs of the expression has the range LHS_RANGE
+// and the second operand has the range OP2_RANGE. Return false if
+// nothing can be determined.
+
+bool
+gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range,
+ const vrange &op2_range)
+{
+ // Give up on empty ranges.
+ if (lhs_range.undefined_p ())
+ return false;
+
+ // Unary operation are allowed to pass a range in for second operand
+ // as there are often additional restrictions beyond the type which
+ // can be imposed. See operator_cast::op1_range().
+ tree type = TREE_TYPE (operand1 ());
+ // If op2 is undefined, solve as if it is varying.
+ if (op2_range.undefined_p ())
+ {
+ if (gimple_num_ops (m_stmt) < 3)
+ return false;
+ tree op2_type;
+ // This is sometimes invoked on single operand stmts.
+ if (operand2 ())
+ op2_type = TREE_TYPE (operand2 ());
+ else
+ op2_type = TREE_TYPE (operand1 ());
+ Value_Range trange (op2_type);
+ trange.set_varying (op2_type);
+ return op1_range (r, type, lhs_range, trange);
+ }
+ return op1_range (r, type, lhs_range, op2_range);
+}
+
+// Calculate what we can determine of the range of this statement's
+// second operand if the lhs of the expression has the range LHS_RANGE
+// and the first operand has the range OP1_RANGE. Return false if
+// nothing can be determined.
+
+bool
+gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range,
+ const vrange &op1_range)
+{
+ // Give up on empty ranges.
+ if (lhs_range.undefined_p ())
+ return false;
+
+ tree type = TREE_TYPE (operand2 ());
+ // If op1 is undefined, solve as if it is varying.
+ if (op1_range.undefined_p ())
+ {
+ tree op1_type = TREE_TYPE (operand1 ());
+ Value_Range trange (op1_type);
+ trange.set_varying (op1_type);
+ return op2_range (r, type, lhs_range, trange);
+ }
+ return op2_range (r, type, lhs_range, op1_range);
+}
+
+// --------------------------------------------------------------------
+
+// Implement range operator for float CFN_BUILT_IN_CONSTANT_P.
+class cfn_constant_float_p : public range_operator_float
+{
+public:
+ using range_operator_float::fold_range;
+ virtual bool fold_range (irange &r, tree type, const frange &lh,
+ const irange &, relation_kind) const
+ {
+ if (lh.singleton_p ())
+ {
+ r.set (build_one_cst (type), build_one_cst (type));
+ return true;
+ }
+ if (cfun->after_inlining)
+ {
+ r.set_zero (type);
+ return true;
+ }
+ return false;
+ }
+} op_cfn_constant_float_p;
+
+// Implement range operator for integral CFN_BUILT_IN_CONSTANT_P.
+class cfn_constant_p : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+ {
+ if (lh.singleton_p ())
+ {
+ r.set (build_one_cst (type), build_one_cst (type));
+ return true;
+ }
+ if (cfun->after_inlining)
+ {
+ r.set_zero (type);
+ return true;
+ }
+ return false;
+ }
+} op_cfn_constant_p;
+
+// Implement range operator for CFN_BUILT_IN_SIGNBIT.
+class cfn_signbit : public range_operator_float
+{
+public:
+ using range_operator_float::fold_range;
+ virtual bool fold_range (irange &r, tree type, const frange &lh,
+ const irange &, relation_kind) const
+ {
+ bool signbit;
+ if (lh.signbit_p (signbit))
+ {
+ if (signbit)
+ r.set_nonzero (type);
+ else
+ r.set_zero (type);
+ return true;
+ }
+ return false;
+ }
+} op_cfn_signbit;
+
+// Implement range operator for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER.
+class cfn_toupper_tolower : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ cfn_toupper_tolower (bool toupper) { m_toupper = toupper; }
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const;
+private:
+ bool get_letter_range (tree type, irange &lowers, irange &uppers) const;
+ bool m_toupper;
+} op_cfn_toupper (true), op_cfn_tolower (false);
+
+// Return TRUE if we recognize the target character set and return the
+// range for lower case and upper case letters.
+
+bool
+cfn_toupper_tolower::get_letter_range (tree type, irange &lowers,
+ irange &uppers) const
+{
+ // ASCII
+ int a = lang_hooks.to_target_charset ('a');
+ int z = lang_hooks.to_target_charset ('z');
+ int A = lang_hooks.to_target_charset ('A');
+ int Z = lang_hooks.to_target_charset ('Z');
+
+ if ((z - a == 25) && (Z - A == 25))
+ {
+ lowers = int_range<2> (build_int_cst (type, a), build_int_cst (type, z));
+ uppers = int_range<2> (build_int_cst (type, A), build_int_cst (type, Z));
+ return true;
+ }
+ // Unknown character set.
+ return false;
+}
+
+bool
+cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+{
+ int_range<3> lowers;
+ int_range<3> uppers;
+ if (!get_letter_range (type, lowers, uppers))
+ return false;
+
+ r = lh;
+ if (m_toupper)
+ {
+ // Return the range passed in without any lower case characters,
+ // but including all the upper case ones.
+ lowers.invert ();
+ r.intersect (lowers);
+ r.union_ (uppers);
+ }
+ else
+ {
+ // Return the range passed in without any lower case characters,
+ // but including all the upper case ones.
+ uppers.invert ();
+ r.intersect (uppers);
+ r.union_ (lowers);
+ }
+ return true;
+}
+
+// Implement range operator for CFN_BUILT_IN_FFS and CFN_BUILT_IN_POPCOUNT.
+class cfn_popcount : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+ {
+ if (lh.undefined_p ())
+ return false;
+ // __builtin_ffs* and __builtin_popcount* return [0, prec].
+ int prec = TYPE_PRECISION (lh.type ());
+ // If arg is non-zero, then ffs or popcount are non-zero.
+ int mini = range_includes_zero_p (&lh) ? 0 : 1;
+ int maxi = prec;
+
+ // If some high bits are known to be zero, decrease the maximum.
+ int_range_max tmp = lh;
+ if (TYPE_SIGN (tmp.type ()) == SIGNED)
+ range_cast (tmp, unsigned_type_for (tmp.type ()));
+ wide_int max = tmp.upper_bound ();
+ maxi = wi::floor_log2 (max) + 1;
+ r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ return true;
+ }
+} op_cfn_popcount;
+
+// Implement range operator for CFN_BUILT_IN_CLZ
+class cfn_clz : public range_operator
+{
+public:
+ cfn_clz (bool internal) { m_gimple_call_internal_p = internal; }
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const;
+private:
+ bool m_gimple_call_internal_p;
+} op_cfn_clz (false), op_cfn_clz_internal (true);
+
+bool
+cfn_clz::fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+{
+ // __builtin_c[lt]z* return [0, prec-1], except when the
+ // argument is 0, but that is undefined behavior.
+ //
+ // For __builtin_c[lt]z* consider argument of 0 always undefined
+ // behavior, for internal fns depending on C?Z_DEFINED_ALUE_AT_ZERO.
+ if (lh.undefined_p ())
+ return false;
+ int prec = TYPE_PRECISION (lh.type ());
+ int mini = 0;
+ int maxi = prec - 1;
+ int zerov = 0;
+ scalar_int_mode mode = SCALAR_INT_TYPE_MODE (lh.type ());
+ if (m_gimple_call_internal_p)
+ {
+ if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
+ && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
+ {
+ // Only handle the single common value.
+ if (zerov == prec)
+ maxi = prec;
+ else
+ // Magic value to give up, unless we can prove arg is non-zero.
+ mini = -2;
+ }
+ }
+
+ // From clz of minimum we can compute result maximum.
+ if (wi::gt_p (lh.lower_bound (), 0, TYPE_SIGN (lh.type ())))
+ {
+ maxi = prec - 1 - wi::floor_log2 (lh.lower_bound ());
+ if (mini == -2)
+ mini = 0;
+ }
+ else if (!range_includes_zero_p (&lh))
+ {
+ mini = 0;
+ maxi = prec - 1;
+ }
+ if (mini == -2)
+ return false;
+ // From clz of maximum we can compute result minimum.
+ wide_int max = lh.upper_bound ();
+ int newmini = prec - 1 - wi::floor_log2 (max);
+ if (max == 0)
+ {
+ // If CLZ_DEFINED_VALUE_AT_ZERO is 2 with VALUE of prec,
+ // return [prec, prec], otherwise ignore the range.
+ if (maxi == prec)
+ mini = prec;
+ }
+ else
+ mini = newmini;
+
+ if (mini == -2)
+ return false;
+ r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ return true;
+}
+
+// Implement range operator for CFN_BUILT_IN_CTZ
+class cfn_ctz : public range_operator
+{
+public:
+ cfn_ctz (bool internal) { m_gimple_call_internal_p = internal; }
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const;
+private:
+ bool m_gimple_call_internal_p;
+} op_cfn_ctz (false), op_cfn_ctz_internal (true);
+
+bool
+cfn_ctz::fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+{
+ if (lh.undefined_p ())
+ return false;
+ int prec = TYPE_PRECISION (lh.type ());
+ int mini = 0;
+ int maxi = prec - 1;
+ int zerov = 0;
+ scalar_int_mode mode = SCALAR_INT_TYPE_MODE (lh.type ());
+
+ if (m_gimple_call_internal_p)
+ {
+ if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
+ && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
+ {
+ // Handle only the two common values.
+ if (zerov == -1)
+ mini = -1;
+ else if (zerov == prec)
+ maxi = prec;
+ else
+ // Magic value to give up, unless we can prove arg is non-zero.
+ mini = -2;
+ }
+ }
+ // If arg is non-zero, then use [0, prec - 1].
+ if (!range_includes_zero_p (&lh))
+ {
+ mini = 0;
+ maxi = prec - 1;
+ }
+ // If some high bits are known to be zero, we can decrease
+ // the maximum.
+ wide_int max = lh.upper_bound ();
+ if (max == 0)
+ {
+ // Argument is [0, 0]. If CTZ_DEFINED_VALUE_AT_ZERO
+ // is 2 with value -1 or prec, return [-1, -1] or [prec, prec].
+ // Otherwise ignore the range.
+ if (mini == -1)
+ maxi = -1;
+ else if (maxi == prec)
+ mini = prec;
+ }
+ // If value at zero is prec and 0 is in the range, we can't lower
+ // the upper bound. We could create two separate ranges though,
+ // [0,floor_log2(max)][prec,prec] though.
+ else if (maxi != prec)
+ maxi = wi::floor_log2 (max);
+
+ if (mini == -2)
+ return false;
+ r.set (build_int_cst (type, mini), build_int_cst (type, maxi));
+ return true;
+}
+
+
+// Implement range operator for CFN_BUILT_IN_
+class cfn_clrsb : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+ {
+ if (lh.undefined_p ())
+ return false;
+ int prec = TYPE_PRECISION (lh.type ());
+ r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1));
+ return true;
+ }
+} op_cfn_clrsb;
+
+
+// Implement range operator for CFN_BUILT_IN_
+class cfn_ubsan : public range_operator
+{
+public:
+ cfn_ubsan (enum tree_code code) { m_code = code; }
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &rh, relation_kind rel) const
+ {
+ range_op_handler handler (m_code, type);
+ gcc_checking_assert (handler);
+
+ bool saved_flag_wrapv = flag_wrapv;
+ // Pretend the arithmetic is wrapping. If there is any overflow,
+ // we'll complain, but will actually do wrapping operation.
+ flag_wrapv = 1;
+ bool result = handler.fold_range (r, type, lh, rh, rel);
+ flag_wrapv = saved_flag_wrapv;
+
+ // If for both arguments vrp_valueize returned non-NULL, this should
+ // have been already folded and if not, it wasn't folded because of
+ // overflow. Avoid removing the UBSAN_CHECK_* calls in that case.
+ if (result && r.singleton_p ())
+ r.set_varying (type);
+ return result;
+ }
+private:
+ enum tree_code m_code;
+};
+
+cfn_ubsan op_cfn_ubsan_add (PLUS_EXPR);
+cfn_ubsan op_cfn_ubsan_sub (MINUS_EXPR);
+cfn_ubsan op_cfn_ubsan_mul (MULT_EXPR);
+
+
+// Implement range operator for CFN_BUILT_IN_STRLEN
+class cfn_strlen : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &,
+ const irange &, relation_kind) const
+ {
+ tree max = vrp_val_max (ptrdiff_type_node);
+ wide_int wmax
+ = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
+ tree range_min = build_zero_cst (type);
+ // To account for the terminating NULL, the maximum length
+ // is one less than the maximum array size, which in turn
+ // is one less than PTRDIFF_MAX (or SIZE_MAX where it's
+ // smaller than the former type).
+ // FIXME: Use max_object_size() - 1 here.
+ tree range_max = wide_int_to_tree (type, wmax - 2);
+ r.set (range_min, range_max);
+ return true;
+ }
+} op_cfn_strlen;
+
+
+// Implement range operator for CFN_BUILT_IN_GOACC_DIM
+class cfn_goacc_dim : public range_operator
+{
+public:
+ cfn_goacc_dim (bool is_pos) { m_is_pos = is_pos; }
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &lh,
+ const irange &, relation_kind) const
+ {
+ tree axis_tree;
+ if (!lh.singleton_p (&axis_tree))
+ return false;
+ HOST_WIDE_INT axis = TREE_INT_CST_LOW (axis_tree);
+ int size = oacc_get_fn_dim_size (current_function_decl, axis);
+ if (!size)
+ // If it's dynamic, the backend might know a hardware limitation.
+ size = targetm.goacc.dim_limit (axis);
+
+ r.set (build_int_cst (type, m_is_pos ? 0 : 1),
+ size
+ ? build_int_cst (type, size - m_is_pos) : vrp_val_max (type));
+ return true;
+ }
+private:
+ bool m_is_pos;
+} op_cfn_goacc_dim_size (false), op_cfn_goacc_dim_pos (true);
+
+
+// Implement range operator for CFN_BUILT_IN_
+class cfn_parity : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ virtual bool fold_range (irange &r, tree type, const irange &,
+ const irange &, relation_kind) const
+ {
+ r.set (build_zero_cst (type), build_one_cst (type));
+ return true;
+ }
+} op_cfn_parity;
+
+// Set up a gimple_range_op_handler for any built in function which can be
+// supported via range-ops.
+
+void
+gimple_range_op_handler::maybe_builtin_call ()
+{
+ gcc_checking_assert (is_a <gcall *> (m_stmt));
+
+ gcall *call = as_a <gcall *> (m_stmt);
+ combined_fn func = gimple_call_combined_fn (call);
+ if (func == CFN_LAST)
+ return;
+ tree type = gimple_range_type (call);
+ gcc_checking_assert (type);
+ if (!Value_Range::supports_type_p (type))
+ return;
+
+ switch (func)
+ {
+ case CFN_BUILT_IN_CONSTANT_P:
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ if (irange::supports_p (TREE_TYPE (m_op1)))
+ m_int = &op_cfn_constant_p;
+ else if (frange::supports_p (TREE_TYPE (m_op1)))
+ m_float = &op_cfn_constant_float_p;
+ else
+ m_valid = false;
+ break;
+
+ case CFN_BUILT_IN_SIGNBIT:
+ m_op1 = gimple_call_arg (call, 0);
+ m_float = &op_cfn_signbit;
+ m_valid = true;
+ break;
+
+ case CFN_BUILT_IN_TOUPPER:
+ case CFN_BUILT_IN_TOLOWER:
+ // Only proceed If the argument is compatible with the LHS.
+ m_op1 = gimple_call_arg (call, 0);
+ if (range_compatible_p (type, TREE_TYPE (m_op1)))
+ {
+ m_valid = true;
+ m_int = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower
+ : &op_cfn_toupper;
+ }
+ break;
+
+ CASE_CFN_FFS:
+ CASE_CFN_POPCOUNT:
+ m_op1 = gimple_call_arg (call, 0);
+ m_int = &op_cfn_popcount;
+ m_valid = true;
+ break;
+
+ CASE_CFN_CLZ:
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ if (gimple_call_internal_p (call))
+ m_int = &op_cfn_clz_internal;
+ else
+ m_int = &op_cfn_clz;
+ break;
+
+ CASE_CFN_CTZ:
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ if (gimple_call_internal_p (call))
+ m_int = &op_cfn_ctz_internal;
+ else
+ m_int = &op_cfn_ctz;
+ break;
+
+ CASE_CFN_CLRSB:
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ m_int = &op_cfn_clrsb;
+ break;
+
+ case CFN_UBSAN_CHECK_ADD:
+ m_op1 = gimple_call_arg (call, 0);
+ m_op2 = gimple_call_arg (call, 1);
+ m_valid = true;
+ m_int = &op_cfn_ubsan_add;
+ break;
+
+ case CFN_UBSAN_CHECK_SUB:
+ m_op1 = gimple_call_arg (call, 0);
+ m_op2 = gimple_call_arg (call, 1);
+ m_valid = true;
+ m_int = &op_cfn_ubsan_sub;
+ break;
+
+ case CFN_UBSAN_CHECK_MUL:
+ m_op1 = gimple_call_arg (call, 0);
+ m_op2 = gimple_call_arg (call, 1);
+ m_valid = true;
+ m_int = &op_cfn_ubsan_mul;
+ break;
+
+ case CFN_BUILT_IN_STRLEN:
+ {
+ tree lhs = gimple_call_lhs (call);
+ if (lhs && ptrdiff_type_node && (TYPE_PRECISION (ptrdiff_type_node)
+ == TYPE_PRECISION (TREE_TYPE (lhs))))
+ {
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ m_int = &op_cfn_strlen;
+ }
+ break;
+ }
+
+ // Optimizing these two internal functions helps the loop
+ // optimizer eliminate outer comparisons. Size is [1,N]
+ // and pos is [0,N-1].
+ case CFN_GOACC_DIM_SIZE:
+ // This call will ensure all the asserts are triggered.
+ oacc_get_ifn_dim_arg (call);
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ m_int = &op_cfn_goacc_dim_size;
+ break;
+
+ case CFN_GOACC_DIM_POS:
+ // This call will ensure all the asserts are triggered.
+ oacc_get_ifn_dim_arg (call);
+ m_op1 = gimple_call_arg (call, 0);
+ m_valid = true;
+ m_int = &op_cfn_goacc_dim_pos;
+ break;
+
+ CASE_CFN_PARITY:
+ m_valid = true;
+ m_int = &op_cfn_parity;
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/gcc/gimple-range-op.h b/gcc/gimple-range-op.h
new file mode 100644
index 0000000..6876419
--- /dev/null
+++ b/gcc/gimple-range-op.h
@@ -0,0 +1,52 @@
+/* Header file for the GIMPLE range-op interface.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+ and Aldy Hernandez <aldyh@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_GIMPLE_RANGE_OP_H
+#define GCC_GIMPLE_RANGE_OP_H
+
+#include "range-op.h"
+
+
+class gimple_range_op_handler : public range_op_handler
+{
+public:
+ static bool supported_p (gimple *s);
+ gimple_range_op_handler (gimple *s);
+ inline gimple *stmt () const { return m_stmt; }
+ inline tree lhs () const { return gimple_get_lhs (m_stmt); }
+ tree operand1 () const { gcc_checking_assert (m_valid); return m_op1; }
+ tree operand2 () const { gcc_checking_assert (m_valid); return m_op2; }
+ bool calc_op1 (vrange &r, const vrange &lhs_range);
+ bool calc_op1 (vrange &r, const vrange &lhs_range, const vrange &op2_range);
+ bool calc_op2 (vrange &r, const vrange &lhs_range, const vrange &op1_range);
+private:
+ void maybe_builtin_call ();
+ gimple *m_stmt;
+ tree m_op1, m_op2;
+};
+
+// Given stmt S, fill VEC, up to VEC_SIZE elements, with relevant ssa-names
+// on the statement. For efficiency, it is an error to not pass in enough
+// elements for the vector. Return the number of ssa-names.
+
+unsigned gimple_range_ssa_names (tree *vec, unsigned vec_size, gimple *stmt);
+
+#endif // GCC_GIMPLE_RANGE_OP_H
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index eb347ee..d67d649 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -341,7 +341,7 @@ gimple_ranger::prefill_name (vrange &r, tree name)
if (!gimple_range_ssa_p (name))
return;
gimple *stmt = SSA_NAME_DEF_STMT (name);
- if (!range_op_handler (stmt) && !is_a<gphi *> (stmt))
+ if (!gimple_range_op_handler::supported_p (stmt) && !is_a<gphi *> (stmt))
return;
bool current;
@@ -364,7 +364,7 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
gcc_checking_assert (stmt && gimple_bb (stmt));
// Only pre-process range-ops and phis.
- if (!range_op_handler (stmt) && !is_a<gphi *> (stmt))
+ if (!gimple_range_op_handler::supported_p (stmt) && !is_a<gphi *> (stmt))
return;
// Mark where on the stack we are starting.
@@ -422,14 +422,15 @@ gimple_ranger::prefill_stmt_dependencies (tree ssa)
}
else
{
- gcc_checking_assert (range_op_handler (stmt));
- tree op = gimple_range_operand2 (stmt);
+ gimple_range_op_handler handler (stmt);
+ gcc_checking_assert (handler);
+ tree op = handler.operand2 ();
if (op)
{
Value_Range r (TREE_TYPE (op));
prefill_name (r, op);
}
- op = gimple_range_operand1 (stmt);
+ op = handler.operand1 ();
if (op)
{
Value_Range r (TREE_TYPE (op));
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 34f6102..8b2ff56 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "range.h"
#include "value-query.h"
-#include "range-op.h"
+#include "gimple-range-op.h"
#include "gimple-range-trace.h"
#include "gimple-range-edge.h"
#include "gimple-range-fold.h"
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index dce38e7..f7a7985 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-6543b7fc6da533eb976b37649a925e7fd5a521fa
+42efec8c126cf3787bc7c89d9c7f224eff7c5a21
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 5cac8df..5dc0bf1 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -10712,7 +10712,10 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
case GF_OMP_TARGET_KIND_OACC_ENTER_DATA:
case GF_OMP_TARGET_KIND_OACC_EXIT_DATA:
case GF_OMP_TARGET_KIND_OACC_DECLARE:
- /* ..., other than for those stand-alone directives... */
+ /* ..., other than for those stand-alone directives...
+ To be precise, target data isn't stand-alone, but
+ gimplifier put the end API call into try finally block
+ for it, so omp expansion can treat it as such. */
region = NULL;
break;
default:
@@ -10728,6 +10731,11 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
&& gimple_omp_task_taskwait_p (stmt))
/* #pragma omp taskwait depend(...) is a stand-alone directive. */
region = NULL;
+ else if (code == GIMPLE_OMP_TASKGROUP)
+ /* #pragma omp taskgroup isn't a stand-alone directive, but
+ gimplifier put the end API call into try finall block
+ for it, so omp expansion can treat it as such. */
+ region = NULL;
/* ..., this directive becomes the parent for a new region. */
if (region)
parent = region;
@@ -10927,13 +10935,18 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_MASKED:
case GIMPLE_OMP_SCOPE:
- case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_SECTION:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
break;
+ case GIMPLE_OMP_TASKGROUP:
+ cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ cur_region = cur_region->outer;
+ break;
+
case GIMPLE_OMP_TASK:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index f0469d2..dc42c75 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -7631,6 +7631,7 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
incoming = build_simple_mem_ref (incoming);
}
else
+ /* Note that 'var' might be a mem ref. */
v1 = v2 = v3 = var;
/* Determine position in reduction buffer, which may be used
@@ -7659,26 +7660,28 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, setup_code,
unshare_expr (ref_to_res),
- incoming, level, op, off);
+ unshare_expr (incoming),
+ level, op, off);
tree init_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, init_code,
unshare_expr (ref_to_res),
- v1, level, op, off);
+ unshare_expr (v1), level, op, off);
tree fini_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, fini_code,
unshare_expr (ref_to_res),
- v2, level, op, off);
+ unshare_expr (v2), level, op, off);
tree teardown_call
= build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION,
TREE_TYPE (var), 6, teardown_code,
- ref_to_res, v3, level, op, off);
+ ref_to_res, unshare_expr (v3),
+ level, op, off);
- gimplify_assign (v1, setup_call, &before_fork);
- gimplify_assign (v2, init_call, &after_fork);
- gimplify_assign (v3, fini_call, &before_join);
- gimplify_assign (outgoing, teardown_call, &after_join);
+ gimplify_assign (unshare_expr (v1), setup_call, &before_fork);
+ gimplify_assign (unshare_expr (v2), init_call, &after_fork);
+ gimplify_assign (unshare_expr (v3), fini_call, &before_join);
+ gimplify_assign (unshare_expr (outgoing), teardown_call, &after_join);
}
/* Now stitch things together. */
@@ -9724,7 +9727,6 @@ lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
- gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
gimple_bind_add_seq (bind, dseq);
pop_gimplify_context (bind);
diff --git a/gcc/opts.cc b/gcc/opts.cc
index e058aaf..eb5db01 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -1801,7 +1801,7 @@ print_filtered_help (unsigned int include_flags,
help = new_help;
}
- if (option->range_max != -1)
+ if (option->range_max != -1 && tab == NULL)
{
char b[128];
snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
diff --git a/gcc/passes.def b/gcc/passes.def
index 6bb92ef..939ec3e 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -263,7 +263,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_sancov);
NEXT_PASS (pass_asan);
NEXT_PASS (pass_tsan);
- NEXT_PASS (pass_dse);
+ NEXT_PASS (pass_dse, true /* use DR analysis */);
NEXT_PASS (pass_dce);
/* Pass group that runs when 1) enabled, 2) there are loops
in the function. Make sure to run pass_fix_loops before
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index eeb2b8e..55d13c7 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,7 @@
+2022-09-22 Joseph Myers <joseph@codesourcery.com>
+
+ * fr.po: Update.
+
2022-08-30 Joseph Myers <joseph@codesourcery.com>
* sv.po: Update.
diff --git a/gcc/po/fr.po b/gcc/po/fr.po
index 4190306..39cbfb7 100644
--- a/gcc/po/fr.po
+++ b/gcc/po/fr.po
@@ -97,10 +97,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: gcc 12.1.0\n"
+"Project-Id-Version: gcc 12.2.0\n"
"Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n"
"POT-Creation-Date: 2022-08-17 22:17+0000\n"
-"PO-Revision-Date: 2022-05-09 10:26+0200\n"
+"PO-Revision-Date: 2022-09-16 06:43+0200\n"
"Last-Translator: Frédéric Marchal <fmarchal@perso.be>\n"
"Language-Team: French <traduc@traduc.org>\n"
"Language: fr\n"
@@ -58941,10 +58941,9 @@ msgid "redeclared here as %q#D"
msgstr "redéclaré ici comme %q#D"
#: cp/pt.cc:6321
-#, fuzzy, gcc-internal-format
-#| msgid "declared here"
+#, gcc-internal-format
msgid "redeclared here"
-msgstr "déclaré ici"
+msgstr "redéclaré ici"
#: cp/pt.cc:6332
#, gcc-internal-format
@@ -62308,10 +62307,9 @@ msgid "toHash() must be declared as extern (D) size_t toHash() const nothrow @sa
msgstr "toHash() doit être déclaré comme extern (D) size_t toHash() const nothrow @safe et non comme %s"
#: d/typeinfo.cc:1415
-#, fuzzy, gcc-internal-format
-#| msgid "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>"
+#, gcc-internal-format
msgid "expression %qs requires %<object.TypeInfo%> and cannot be used with %<-fno-rtti%>"
-msgstr "%<object.TypeInfo%> ne peut pas être utilisé avec %<-fno-rtti%>"
+msgstr "l'expression %qs requiert %<object.TypeInfo%> et ne peut pas être utilisée avec %<-fno-rtti%>"
#: d/typeinfo.cc:1419
#, gcc-internal-format
@@ -64958,10 +64956,9 @@ msgid "BIND(C) statement at %C"
msgstr "Instruction BIND(C) à %C"
#: fortran/decl.cc:6268
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "CLASS variable %qs at %L cannot have the PARAMETER attribute"
+#, gcc-internal-format, gfc-internal-format
msgid "CLASS entity at %C cannot have the PARAMETER attribute"
-msgstr "La variable CLASS %qs à %L ne peut pas avoir l'attribut PARAMETER"
+msgstr "L'entité CLASS à %C ne peut pas avoir l'attribut PARAMETER"
#: fortran/decl.cc:6300
#, gcc-internal-format, gfc-internal-format
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 1e39a07..6e9d51d 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -62,6 +62,16 @@ bool
range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED,
const frange &lh ATTRIBUTE_UNUSED,
+ const irange &rh ATTRIBUTE_UNUSED,
+ relation_kind rel ATTRIBUTE_UNUSED) const
+{
+ return false;
+}
+
+bool
+range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ const frange &lh ATTRIBUTE_UNUSED,
const frange &rh ATTRIBUTE_UNUSED,
relation_kind rel ATTRIBUTE_UNUSED) const
{
@@ -190,8 +200,7 @@ frelop_early_resolve (irange &r, tree type,
static inline void
frange_drop_inf (frange &r, tree type)
{
- REAL_VALUE_TYPE max;
- real_max_representable (&max, type);
+ REAL_VALUE_TYPE max = real_max_representable (type);
frange tmp (type, r.lower_bound (), max);
r.intersect (tmp);
}
@@ -202,8 +211,7 @@ frange_drop_inf (frange &r, tree type)
static inline void
frange_drop_ninf (frange &r, tree type)
{
- REAL_VALUE_TYPE min;
- real_min_representable (&min, type);
+ REAL_VALUE_TYPE min = real_min_representable (type);
frange tmp (type, min, r.upper_bound ());
r.intersect (tmp);
}
@@ -230,12 +238,10 @@ frange_add_zeros (frange &r, tree type)
static bool
build_le (frange &r, tree type, const frange &val)
{
- if (val.known_isnan ())
- {
- r.set_undefined ();
- return false;
- }
- r.set (type, dconstninf, val.upper_bound ());
+ gcc_checking_assert (!val.known_isnan ());
+
+ REAL_VALUE_TYPE ninf = frange_val_min (type);
+ r.set (type, ninf, val.upper_bound ());
// Add both zeros if there's the possibility of zero equality.
frange_add_zeros (r, type);
@@ -248,11 +254,8 @@ build_le (frange &r, tree type, const frange &val)
static bool
build_lt (frange &r, tree type, const frange &val)
{
- if (val.known_isnan ())
- {
- r.set_undefined ();
- return false;
- }
+ gcc_checking_assert (!val.known_isnan ());
+
// < -INF is outside the range.
if (real_isinf (&val.upper_bound (), 1))
{
@@ -263,7 +266,8 @@ build_lt (frange &r, tree type, const frange &val)
return false;
}
// We only support closed intervals.
- r.set (type, dconstninf, val.upper_bound ());
+ REAL_VALUE_TYPE ninf = frange_val_min (type);
+ r.set (type, ninf, val.upper_bound ());
return true;
}
@@ -272,12 +276,10 @@ build_lt (frange &r, tree type, const frange &val)
static bool
build_ge (frange &r, tree type, const frange &val)
{
- if (val.known_isnan ())
- {
- r.set_undefined ();
- return false;
- }
- r.set (type, val.lower_bound (), dconstinf);
+ gcc_checking_assert (!val.known_isnan ());
+
+ REAL_VALUE_TYPE inf = frange_val_max (type);
+ r.set (type, val.lower_bound (), inf);
// Add both zeros if there's the possibility of zero equality.
frange_add_zeros (r, type);
@@ -290,11 +292,8 @@ build_ge (frange &r, tree type, const frange &val)
static bool
build_gt (frange &r, tree type, const frange &val)
{
- if (val.known_isnan ())
- {
- r.set_undefined ();
- return false;
- }
+ gcc_checking_assert (!val.known_isnan ());
+
// > +INF is outside the range.
if (real_isinf (&val.lower_bound (), 0))
{
@@ -306,7 +305,8 @@ build_gt (frange &r, tree type, const frange &val)
}
// We only support closed intervals.
- r.set (type, val.lower_bound (), dconstinf);
+ REAL_VALUE_TYPE inf = frange_val_max (type);
+ r.set (type, val.lower_bound (), inf);
return true;
}
@@ -365,9 +365,11 @@ foperator_equal::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_EQ))
return true;
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_false (type);
// We can be sure the values are always equal or not if both ranges
// consist of a single value, and then compare them.
- if (op1.singleton_p () && op2.singleton_p ())
+ else if (op1.singleton_p () && op2.singleton_p ())
{
if (op1 == op2)
r = range_true (type);
@@ -393,25 +395,33 @@ foperator_equal::fold_range (irange &r, tree type,
bool
foperator_equal::op1_range (frange &r, tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind rel) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- // If it's true, the result is the same as OP2.
- r = op2;
- // Add both zeros if there's the possibility of zero equality.
- frange_add_zeros (r, type);
- // The TRUE side of op1 == op2 implies op1 is !NAN.
- r.clear_nan ();
+ // The TRUE side of x == NAN is unreachable.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else
+ {
+ // If it's true, the result is the same as OP2.
+ r = op2;
+ // Add both zeros if there's the possibility of zero equality.
+ frange_add_zeros (r, type);
+ // The TRUE side of op1 == op2 implies op1 is !NAN.
+ r.clear_nan ();
+ }
break;
case BRS_FALSE:
- r.set_varying (type);
// The FALSE side of op1 == op1 implies op1 is a NAN.
if (rel == VREL_EQ)
r.set_nan (type);
+ // On the FALSE side of x == NAN, we know nothing about x.
+ else if (op2.known_isnan ())
+ r.set_varying (type);
// If the result is false, the only time we know anything is
// if OP2 is a constant.
else if (op2.singleton_p ()
@@ -420,6 +430,8 @@ foperator_equal::op1_range (frange &r, tree type,
REAL_VALUE_TYPE tmp = op2.lower_bound ();
r.set (type, tmp, tmp, VR_ANTI_RANGE);
}
+ else
+ r.set_varying (type);
break;
default:
@@ -453,9 +465,12 @@ foperator_not_equal::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_NE))
return true;
+ // x != NAN is always TRUE.
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_true (type);
// We can be sure the values are always equal or not if both ranges
// consist of a single value, and then compare them.
- if (op1.singleton_p () && op2.singleton_p ())
+ else if (op1.singleton_p () && op2.singleton_p ())
{
if (op1 != op2)
r = range_true (type);
@@ -481,7 +496,7 @@ foperator_not_equal::fold_range (irange &r, tree type,
bool
foperator_not_equal::op1_range (frange &r, tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
@@ -502,12 +517,18 @@ foperator_not_equal::op1_range (frange &r, tree type,
break;
case BRS_FALSE:
- // If it's false, the result is the same as OP2.
- r = op2;
- // Add both zeros if there's the possibility of zero equality.
- frange_add_zeros (r, type);
- // The FALSE side of op1 != op2 implies op1 is !NAN.
- r.clear_nan ();
+ // The FALSE side of x != NAN is impossible.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else
+ {
+ // If it's false, the result is the same as OP2.
+ r = op2;
+ // Add both zeros if there's the possibility of zero equality.
+ frange_add_zeros (r, type);
+ // The FALSE side of op1 != op2 implies op1 is !NAN.
+ r.clear_nan ();
+ }
break;
default:
@@ -545,7 +566,9 @@ foperator_lt::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LT))
return true;
- if (finite_operands_p (op1, op2))
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_false (type);
+ else if (finite_operands_p (op1, op2))
{
if (real_less (&op1.upper_bound (), &op2.lower_bound ()))
r = range_true (type);
@@ -555,8 +578,6 @@ foperator_lt::fold_range (irange &r, tree type,
else
r = range_true_and_false (type);
}
- else if (op1.known_isnan () || op2.known_isnan ())
- r = range_false (type);
else
r = range_true_and_false (type);
return true;
@@ -566,13 +587,16 @@ bool
foperator_lt::op1_range (frange &r,
tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_lt (r, type, op2))
+ // The TRUE side of x < NAN is unreachable.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else if (build_lt (r, type, op2))
{
r.clear_nan ();
// x < y implies x is not +INF.
@@ -581,7 +605,11 @@ foperator_lt::op1_range (frange &r,
break;
case BRS_FALSE:
- build_ge (r, type, op2);
+ // On the FALSE side of x < NAN, we know nothing about x.
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_ge (r, type, op2);
break;
default:
@@ -594,13 +622,16 @@ bool
foperator_lt::op2_range (frange &r,
tree type,
const irange &lhs,
- const frange &op1 ATTRIBUTE_UNUSED,
+ const frange &op1,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_gt (r, type, op1))
+ // The TRUE side of NAN < x is unreachable.
+ if (op1.known_isnan ())
+ r.set_undefined ();
+ else if (build_gt (r, type, op1))
{
r.clear_nan ();
// x < y implies y is not -INF.
@@ -609,7 +640,11 @@ foperator_lt::op2_range (frange &r,
break;
case BRS_FALSE:
- build_le (r, type, op1);
+ // On the FALSE side of NAN < x, we know nothing about x.
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_le (r, type, op1);
break;
default:
@@ -647,7 +682,9 @@ foperator_le::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_LE))
return true;
- if (finite_operands_p (op1, op2))
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_false (type);
+ else if (finite_operands_p (op1, op2))
{
if (real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ()))
r = range_true (type);
@@ -657,8 +694,6 @@ foperator_le::fold_range (irange &r, tree type,
else
r = range_true_and_false (type);
}
- else if (op1.known_isnan () || op2.known_isnan ())
- r = range_false (type);
else
r = range_true_and_false (type);
return true;
@@ -674,12 +709,19 @@ foperator_le::op1_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_le (r, type, op2))
+ // The TRUE side of x <= NAN is unreachable.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else if (build_le (r, type, op2))
r.clear_nan ();
break;
case BRS_FALSE:
- build_gt (r, type, op2);
+ // On the FALSE side of x <= NAN, we know nothing about x.
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_gt (r, type, op2);
break;
default:
@@ -698,12 +740,19 @@ foperator_le::op2_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_ge (r, type, op1))
+ // The TRUE side of NAN <= x is unreachable.
+ if (op1.known_isnan ())
+ r.set_undefined ();
+ else if (build_ge (r, type, op1))
r.clear_nan ();
break;
case BRS_FALSE:
- build_lt (r, type, op1);
+ // On the FALSE side of NAN <= x, we know nothing about x.
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_lt (r, type, op1);
break;
default:
@@ -741,7 +790,9 @@ foperator_gt::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GT))
return true;
- if (finite_operands_p (op1, op2))
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_false (type);
+ else if (finite_operands_p (op1, op2))
{
if (real_compare (GT_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
r = range_true (type);
@@ -751,8 +802,6 @@ foperator_gt::fold_range (irange &r, tree type,
else
r = range_true_and_false (type);
}
- else if (op1.known_isnan () || op2.known_isnan ())
- r = range_false (type);
else
r = range_true_and_false (type);
return true;
@@ -762,13 +811,16 @@ bool
foperator_gt::op1_range (frange &r,
tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_gt (r, type, op2))
+ // The TRUE side of x > NAN is unreachable.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else if (build_gt (r, type, op2))
{
r.clear_nan ();
// x > y implies x is not -INF.
@@ -777,7 +829,11 @@ foperator_gt::op1_range (frange &r,
break;
case BRS_FALSE:
- build_le (r, type, op2);
+ // On the FALSE side of x > NAN, we know nothing about x.
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_le (r, type, op2);
break;
default:
@@ -790,13 +846,16 @@ bool
foperator_gt::op2_range (frange &r,
tree type,
const irange &lhs,
- const frange &op1 ATTRIBUTE_UNUSED,
+ const frange &op1,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- if (build_lt (r, type, op1))
+ // The TRUE side of NAN > x is unreachable.
+ if (op1.known_isnan ())
+ r.set_undefined ();
+ else if (build_lt (r, type, op1))
{
r.clear_nan ();
// x > y implies y is not +INF.
@@ -805,7 +864,11 @@ foperator_gt::op2_range (frange &r,
break;
case BRS_FALSE:
- build_ge (r, type, op1);
+ // On The FALSE side of NAN > x, we know nothing about x.
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_ge (r, type, op1);
break;
default:
@@ -843,7 +906,9 @@ foperator_ge::fold_range (irange &r, tree type,
if (frelop_early_resolve (r, type, op1, op2, rel, VREL_GE))
return true;
- if (finite_operands_p (op1, op2))
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_false (type);
+ else if (finite_operands_p (op1, op2))
{
if (real_compare (GE_EXPR, &op1.lower_bound (), &op2.upper_bound ()))
r = range_true (type);
@@ -853,8 +918,6 @@ foperator_ge::fold_range (irange &r, tree type,
else
r = range_true_and_false (type);
}
- else if (op1.known_isnan () || op2.known_isnan ())
- r = range_false (type);
else
r = range_true_and_false (type);
return true;
@@ -870,12 +933,19 @@ foperator_ge::op1_range (frange &r,
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- build_ge (r, type, op2);
- r.clear_nan ();
+ // The TRUE side of x >= NAN is unreachable.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else if (build_ge (r, type, op2))
+ r.clear_nan ();
break;
case BRS_FALSE:
- build_lt (r, type, op2);
+ // On the FALSE side of x >= NAN, we know nothing about x.
+ if (op2.known_isnan ())
+ r.set_varying (type);
+ else
+ build_lt (r, type, op2);
break;
default:
@@ -892,13 +962,23 @@ foperator_ge::op2_range (frange &r, tree type,
{
switch (get_bool_state (r, lhs, type))
{
- case BRS_FALSE:
- build_gt (r, type, op1);
+ case BRS_TRUE:
+ // The TRUE side of NAN >= x is unreachable.
+ if (op1.known_isnan ())
+ r.set_undefined ();
+ else
+ {
+ build_le (r, type, op1);
+ r.clear_nan ();
+ }
break;
- case BRS_TRUE:
- build_le (r, type, op1);
- r.clear_nan ();
+ case BRS_FALSE:
+ // On the FALSE side of NAN >= x, we know nothing about x.
+ if (op1.known_isnan ())
+ r.set_varying (type);
+ else
+ build_gt (r, type, op1);
break;
default:
@@ -949,23 +1029,30 @@ foperator_unordered::fold_range (irange &r, tree type,
bool
foperator_unordered::op1_range (frange &r, tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- r.set_varying (type);
// Since at least one operand must be NAN, if one of them is
// not, the other must be.
if (!op2.maybe_isnan ())
r.set_nan (type);
+ else
+ r.set_varying (type);
break;
case BRS_FALSE:
- r.set_varying (type);
- // A false UNORDERED means both operands are !NAN.
- r.clear_nan ();
+ // A false UNORDERED means both operands are !NAN, so it's
+ // impossible for op2 to be a NAN.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else
+ {
+ r.set_varying (type);
+ r.clear_nan ();
+ }
break;
default:
@@ -1002,10 +1089,10 @@ foperator_ordered::fold_range (irange &r, tree type,
const frange &op1, const frange &op2,
relation_kind) const
{
- if (!op1.maybe_isnan () && !op2.maybe_isnan ())
- r = range_true (type);
- else if (op1.known_isnan () || op2.known_isnan ())
+ if (op1.known_isnan () || op2.known_isnan ())
r = range_false (type);
+ else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
+ r = range_true (type);
else
r = range_true_and_false (type);
return true;
@@ -1014,15 +1101,21 @@ foperator_ordered::fold_range (irange &r, tree type,
bool
foperator_ordered::op1_range (frange &r, tree type,
const irange &lhs,
- const frange &op2 ATTRIBUTE_UNUSED,
+ const frange &op2,
relation_kind rel) const
{
switch (get_bool_state (r, lhs, type))
{
case BRS_TRUE:
- r.set_varying (type);
- // The TRUE side of op1 ORDERED op2 implies op1 is !NAN.
- r.clear_nan ();
+ // The TRUE side of ORDERED means both operands are !NAN, so
+ // it's impossible for op2 to be a NAN.
+ if (op2.known_isnan ())
+ r.set_undefined ();
+ else
+ {
+ r.set_varying (type);
+ r.clear_nan ();
+ }
break;
case BRS_FALSE:
@@ -1046,13 +1139,16 @@ class foperator_relop_unknown : public range_operator_float
public:
bool fold_range (irange &r, tree type,
- const frange &, const frange &,
+ const frange &op1, const frange &op2,
relation_kind) const final override
{
- r.set_varying (type);
+ if (op1.known_isnan () || op2.known_isnan ())
+ r = range_true (type);
+ else
+ r.set_varying (type);
return true;
}
-} fop_relop_unknown;
+} fop_unordered_relop_unknown;
// Instantiate a range_op_table for floating point operations.
@@ -1077,11 +1173,11 @@ floating_op_table::floating_op_table ()
set (LE_EXPR, fop_le);
set (GT_EXPR, fop_gt);
set (GE_EXPR, fop_ge);
- set (UNLE_EXPR, fop_relop_unknown);
- set (UNLT_EXPR, fop_relop_unknown);
- set (UNGE_EXPR, fop_relop_unknown);
- set (UNGT_EXPR, fop_relop_unknown);
- set (UNEQ_EXPR, fop_relop_unknown);
+ set (UNLE_EXPR, fop_unordered_relop_unknown);
+ set (UNLT_EXPR, fop_unordered_relop_unknown);
+ set (UNGE_EXPR, fop_unordered_relop_unknown);
+ set (UNGT_EXPR, fop_unordered_relop_unknown);
+ set (UNEQ_EXPR, fop_unordered_relop_unknown);
set (ORDERED_EXPR, fop_ordered);
set (UNORDERED_EXPR, fop_unordered);
}
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 806edf1..fc930f4 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2951,6 +2951,15 @@ operator_bitwise_and::op1_range (irange &r, tree type,
}
if (r.undefined_p ())
set_nonzero_range_from_mask (r, type, lhs);
+
+ // For 0 = op1 & MASK, op1 is ~MASK.
+ if (lhs.zero_p () && op2.singleton_p ())
+ {
+ wide_int nz = wi::bit_not (op2.get_nonzero_bits ());
+ int_range<2> tmp (type);
+ tmp.set_nonzero_bits (nz);
+ r.intersect (tmp);
+ }
return true;
}
@@ -4159,76 +4168,68 @@ get_float_handler (enum tree_code code, tree)
return (*floating_tree_table)[code];
}
-range_op_handler::range_op_handler (tree_code code, tree type)
- : m_code (code), m_type (type)
-{
-}
-
-range_op_handler::range_op_handler (const gimple *s)
+void
+range_op_handler::set_op_handler (tree_code code, tree type)
{
- if (const gassign *ass = dyn_cast<const gassign *> (s))
+ if (irange::supports_p (type))
{
- m_code = gimple_assign_rhs_code (ass);
- // The LHS of a comparison is always an int, so we must look at
- // the operands.
- if (TREE_CODE_CLASS (m_code) == tcc_comparison)
- m_type = TREE_TYPE (gimple_assign_rhs1 (ass));
- else
- m_type = TREE_TYPE (gimple_assign_lhs (ass));
+ m_float = NULL;
+ m_int = get_handler (code, type);
+ m_valid = m_int != NULL;
}
- else if (const gcond *cond = dyn_cast<const gcond *> (s))
+ else if (frange::supports_p (type))
{
- m_code = gimple_cond_code (cond);
- m_type = TREE_TYPE (gimple_cond_lhs (cond));
+ m_int = NULL;
+ m_float = get_float_handler (code, type);
+ m_valid = m_float != NULL;
}
else
{
- // A null type means there is no handler for this combination,
- // but the decision whether there is one or not, is delayed
- // until operator bool below is queried.
- m_code = NOP_EXPR;
- m_type = nullptr;
+ m_int = NULL;
+ m_float = NULL;
+ m_valid = false;
}
}
-// Return TRUE if there is a handler available for the current
-// combination of tree_code and type.
+range_op_handler::range_op_handler ()
+{
+ m_int = NULL;
+ m_float = NULL;
+ m_valid = false;
+}
-range_op_handler::operator bool () const
+range_op_handler::range_op_handler (tree_code code, tree type)
{
- if (!m_type)
- return false;
- if (frange::supports_p (m_type))
- return get_float_handler (m_code, m_type);
- return get_handler (m_code, m_type);
+ set_op_handler (code, type);
}
+
bool
range_op_handler::fold_range (vrange &r, tree type,
const vrange &lh,
const vrange &rh,
relation_kind rel) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->fold_range (as_a <irange> (r), type,
- as_a <irange> (lh),
- as_a <irange> (rh), rel);
- }
- if (frange::supports_p (m_type))
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->fold_range (as_a <irange> (r), type,
+ as_a <irange> (lh),
+ as_a <irange> (rh), rel);
+
+ if (is_a <irange> (r))
{
- range_operator_float *op = get_float_handler (m_code, m_type);
- if (is_a <irange> (r))
- return op->fold_range (as_a <irange> (r), type,
- as_a <frange> (lh),
- as_a <frange> (rh), rel);
- return op->fold_range (as_a <frange> (r), type,
- as_a <frange> (lh),
- as_a <frange> (rh), rel);
+ if (is_a <irange> (rh))
+ return m_float->fold_range (as_a <irange> (r), type,
+ as_a <frange> (lh),
+ as_a <irange> (rh), rel);
+ else
+ return m_float->fold_range (as_a <irange> (r), type,
+ as_a <frange> (lh),
+ as_a <frange> (rh), rel);
}
- gcc_unreachable ();
- return false;
+ return m_float->fold_range (as_a <frange> (r), type,
+ as_a <frange> (lh),
+ as_a <frange> (rh), rel);
}
bool
@@ -4237,26 +4238,19 @@ range_op_handler::op1_range (vrange &r, tree type,
const vrange &op2,
relation_kind rel) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->op1_range (as_a <irange> (r), type,
- as_a <irange> (lhs),
- as_a <irange> (op2), rel);
- }
- if (frange::supports_p (m_type))
- {
- range_operator_float *op = get_float_handler (m_code, m_type);
- if (is_a <irange> (lhs))
- return op->op1_range (as_a <frange> (r), type,
- as_a <irange> (lhs),
- as_a <frange> (op2), rel);
- return op->op1_range (as_a <frange> (r), type,
- as_a <frange> (lhs),
- as_a <frange> (op2), rel);
- }
- gcc_unreachable ();
- return false;
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->op1_range (as_a <irange> (r), type,
+ as_a <irange> (lhs),
+ as_a <irange> (op2), rel);
+
+ if (is_a <irange> (lhs))
+ return m_float->op1_range (as_a <frange> (r), type,
+ as_a <irange> (lhs),
+ as_a <frange> (op2), rel);
+ return m_float->op1_range (as_a <frange> (r), type,
+ as_a <frange> (lhs),
+ as_a <frange> (op2), rel);
}
bool
@@ -4265,26 +4259,19 @@ range_op_handler::op2_range (vrange &r, tree type,
const vrange &op1,
relation_kind rel) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->op2_range (as_a <irange> (r), type,
- as_a <irange> (lhs),
- as_a <irange> (op1), rel);
- }
- if (frange::supports_p (m_type))
- {
- range_operator_float *op = get_float_handler (m_code, m_type);
- if (is_a <irange> (lhs))
- return op->op2_range (as_a <frange> (r), type,
- as_a <irange> (lhs),
- as_a <frange> (op1), rel);
- return op->op2_range (as_a <frange> (r), type,
- as_a <frange> (lhs),
- as_a <frange> (op1), rel);
- }
- gcc_unreachable ();
- return false;
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->op2_range (as_a <irange> (r), type,
+ as_a <irange> (lhs),
+ as_a <irange> (op1), rel);
+
+ if (is_a <irange> (lhs))
+ return m_float->op2_range (as_a <frange> (r), type,
+ as_a <irange> (lhs),
+ as_a <frange> (op1), rel);
+ return m_float->op2_range (as_a <frange> (r), type,
+ as_a <frange> (lhs),
+ as_a <frange> (op1), rel);
}
relation_kind
@@ -4293,26 +4280,19 @@ range_op_handler::lhs_op1_relation (const vrange &lhs,
const vrange &op2,
relation_kind rel) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->lhs_op1_relation (as_a <irange> (lhs),
- as_a <irange> (op1),
- as_a <irange> (op2), rel);
- }
- if (frange::supports_p (m_type))
- {
- range_operator_float *op = get_float_handler (m_code, m_type);
- if (is_a <irange> (lhs))
- return op->lhs_op1_relation (as_a <irange> (lhs),
- as_a <frange> (op1),
- as_a <frange> (op2), rel);
- return op->lhs_op1_relation (as_a <frange> (lhs),
- as_a <frange> (op1),
- as_a <frange> (op2), rel);
- }
- gcc_unreachable ();
- return VREL_VARYING;
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->lhs_op1_relation (as_a <irange> (lhs),
+ as_a <irange> (op1),
+ as_a <irange> (op2), rel);
+
+ if (is_a <irange> (lhs))
+ return m_float->lhs_op1_relation (as_a <irange> (lhs),
+ as_a <frange> (op1),
+ as_a <frange> (op2), rel);
+ return m_float->lhs_op1_relation (as_a <frange> (lhs),
+ as_a <frange> (op1),
+ as_a <frange> (op2), rel);
}
relation_kind
@@ -4321,43 +4301,28 @@ range_op_handler::lhs_op2_relation (const vrange &lhs,
const vrange &op2,
relation_kind rel) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->lhs_op2_relation (as_a <irange> (lhs),
- as_a <irange> (op1),
- as_a <irange> (op2), rel);
- }
- if (frange::supports_p (m_type))
- {
- range_operator_float *op = get_float_handler (m_code, m_type);
- if (is_a <irange> (lhs))
- return op->lhs_op2_relation (as_a <irange> (lhs),
- as_a <frange> (op1),
- as_a <frange> (op2), rel);
- return op->lhs_op2_relation (as_a <frange> (lhs),
- as_a <frange> (op1),
- as_a <frange> (op2), rel);
- }
- gcc_unreachable ();
- return VREL_VARYING;
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->lhs_op2_relation (as_a <irange> (lhs),
+ as_a <irange> (op1),
+ as_a <irange> (op2), rel);
+
+ if (is_a <irange> (lhs))
+ return m_float->lhs_op2_relation (as_a <irange> (lhs),
+ as_a <frange> (op1),
+ as_a <frange> (op2), rel);
+ return m_float->lhs_op2_relation (as_a <frange> (lhs),
+ as_a <frange> (op1),
+ as_a <frange> (op2), rel);
}
relation_kind
range_op_handler::op1_op2_relation (const vrange &lhs) const
{
- if (irange::supports_p (m_type))
- {
- range_operator *op = get_handler (m_code, m_type);
- return op->op1_op2_relation (as_a <irange> (lhs));
- }
- if (frange::supports_p (m_type))
- {
- range_operator_float *op = get_float_handler (m_code, m_type);
- return op->op1_op2_relation (as_a <irange> (lhs));
- }
- gcc_unreachable ();
- return VREL_VARYING;
+ gcc_checking_assert (m_valid);
+ if (m_int)
+ return m_int->op1_op2_relation (as_a <irange> (lhs));
+ return m_float->op1_op2_relation (as_a <irange> (lhs));
}
// Cast the range in R to TYPE.
@@ -4656,6 +4621,15 @@ range_op_bitwise_and_tests ()
op_bitwise_and.op1_range (res, integer_type_node, i1, i2);
ASSERT_TRUE (res == int_range<1> (integer_type_node));
+ // For 0 = x & MASK, x is ~MASK.
+ {
+ int_range<2> zero (integer_zero_node, integer_zero_node);
+ int_range<2> mask = int_range<2> (INT (7), INT (7));
+ op_bitwise_and.op1_range (res, integer_type_node, zero, mask);
+ wide_int inv = wi::shwi (~7U, TYPE_PRECISION (integer_type_node));
+ ASSERT_TRUE (res.get_nonzero_bits () == inv);
+ }
+
// (NONZERO | X) is nonzero.
i1.set_nonzero (integer_type_node);
i2.set_varying (integer_type_node);
diff --git a/gcc/range-op.h b/gcc/range-op.h
index 37d9aa9..b2f063a 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -117,6 +117,11 @@ public:
const frange &lh,
const frange &rh,
relation_kind rel = VREL_VARYING) const;
+ // Unary operations have the range of the LHS as op2.
+ virtual bool fold_range (irange &r, tree type,
+ const frange &lh,
+ const irange &rh,
+ relation_kind rel = VREL_VARYING) const;
virtual bool fold_range (irange &r, tree type,
const frange &lh,
const frange &rh,
@@ -160,9 +165,9 @@ public:
class range_op_handler
{
public:
+ range_op_handler ();
range_op_handler (enum tree_code code, tree type);
- range_op_handler (const gimple *s);
- operator bool () const;
+ inline operator bool () const { return m_valid; }
bool fold_range (vrange &r, tree type,
const vrange &lh,
@@ -185,9 +190,11 @@ public:
const vrange &op2,
relation_kind = VREL_VARYING) const;
relation_kind op1_op2_relation (const vrange &lhs) const;
-private:
- enum tree_code m_code;
- tree m_type;
+protected:
+ void set_op_handler (enum tree_code code, tree type);
+ bool m_valid;
+ range_operator *m_int;
+ range_operator_float *m_float;
};
extern bool range_cast (vrange &, tree type);
diff --git a/gcc/real.cc b/gcc/real.cc
index 73bbac6..aae7c33 100644
--- a/gcc/real.cc
+++ b/gcc/real.cc
@@ -1900,6 +1900,14 @@ real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
digits, crop_trailing_zeros, VOIDmode);
}
+DEBUG_FUNCTION void
+debug (const REAL_VALUE_TYPE &r)
+{
+ char s[60];
+ real_to_hexadecimal (s, &r, sizeof (s), 0, 1);
+ fprintf (stderr, "%s\n", s);
+}
+
/* Render R as a hexadecimal floating point constant. Emit DIGITS
significant digits in the result, bounded by BUF_SIZE. If DIGITS is 0,
choose the maximum for the representation. If CROP_TRAILING_ZEROS,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a6048da..0e7cd64e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,261 @@
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ * gfortran.dg/intent_optimize_10.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/99169
+ * gfortran.dg/intent_optimize_9.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87401
+ * gfortran.dg/intent_optimize_8.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * gfortran.dg/intent_optimize_7.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/41453
+ PR fortran/87395
+ * gfortran.dg/intent_optimize_6.f90: New test.
+
+2022-09-25 Harald Anlauf <anlauf@gmx.de>
+ Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * gfortran.dg/intent_optimize_5.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/106817
+ * gfortran.dg/intent_optimize_4.f90: New test.
+
+2022-09-25 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/105012
+ * gfortran.dg/intent_out_15.f90: New test.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/107001
+ * c-c++-common/gomp/pr107001.c: New test.
+
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106981
+ * c-c++-common/gomp/pr106981.c: New test.
+
+2022-09-23 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c2x-complit-1.c, gcc.dg/c2x-concat-1.c,
+ gcc.dg/cpp/c2x-ucn-1.c: New tests.
+
+2022-09-23 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
+ Yvan ROUX <yvan.roux@foss.st.com>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vld1x2.c: Replace
+ dg-xfail-if with dg-skip-if.
+ * gcc.target/aarch64/advsimd-intrinsics/vld1x3.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/vld1x4.c: Likewise.
+
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * g++.dg/ext/has-builtin-1.C: Enhance to test __is_convertible and
+ __is_nothrow_convertible.
+ * g++.dg/ext/is_convertible1.C: New test.
+ * g++.dg/ext/is_convertible2.C: New test.
+ * g++.dg/ext/is_nothrow_convertible1.C: New test.
+ * g++.dg/ext/is_nothrow_convertible2.C: New test.
+
+2022-09-23 zhongjuzhe <juzhe.zhong@rivai.ai>
+
+ * selftests/riscv/empty-func.rtl: New test.
+
+2022-09-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106922
+ * g++.dg/torture/pr106922.C: New testcase.
+
+2022-09-23 Tamar Christina <tamar.christina@arm.com>
+
+ * lib/scanasm.exp (check_function_body): Add debug output to verbose log
+ on failure.
+
+2022-09-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/106922
+ * g++.dg/tree-ssa/pr106922.C: Scan in cddce3 dump rather than
+ dce3. Remove -fdump-tree-pre-details from dg-options.
+
+2022-09-23 Hu, Lin1 <lin1.hu@intel.com>
+
+ PR target/94962
+ * gcc.target/i386/avx256-unaligned-load-1.c: Modify test.
+ * gcc.target/i386/avx256-unaligned-store-1.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-2.c: Ditto.
+ * gcc.target/i386/avx256-unaligned-store-3.c: Ditto.
+ * gcc.target/i386/pr94962-1.c: New test.
+ * gcc.target/i386/pr94962-2.c: Ditto.
+ * gcc.target/i386/pr94962-3.c: Ditto.
+ * gcc.target/i386/pr94962-4.c: Ditto.
+
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106983
+ * g++.dg/other/error36.C: New test.
+
+2022-09-22 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100103
+ * gfortran.dg/PR100103.f90: New test.
+
+2022-09-22 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/82868
+ * gfortran.dg/associate_26a.f90: New test.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/102801
+ * g++.dg/warn/Wuninitialized-33.C: New testcase.
+
+2022-09-22 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/106826
+ * g++.dg/modules/partial-2_a.C: New test.
+ * g++.dg/modules/partial-2_b.C: New test.
+
+2022-09-22 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/106830
+ * gcc.dg/Wxor-used-as-pow-pr106830.c: New test.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106922
+ * gcc.dg/tree-ssa/ssa-fre-100.c: New testcase.
+ * g++.dg/tree-ssa/pr106922.C: Adjust.
+
+2022-09-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/99407
+ * gcc.dg/vect/tsvc/vect-tsvc-s243.c: Remove XFAIL.
+
+2022-09-22 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr106994.c: New test.
+
+2022-09-21 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106984
+ * gcc.dg/tsan/pr106984.c: New testcase.
+
+2022-09-21 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/ieee/rounding_3.f90: New test.
+
+2022-09-21 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/106967
+ * gcc.dg/tree-ssa/pr106967.c: New test.
+
+2022-09-21 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr106963.c: New test.
+
+2022-09-20 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/104143
+ * gfortran.dg/c-interop/c407b-2.f90: Remove dg-error.
+ * gfortran.dg/assumed_type_16.f90: New test.
+ * gfortran.dg/assumed_type_17.f90: New test.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106986
+ * gfortran.dg/pr106986.f90: New test.
+
+2022-09-20 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/106985
+ * gfortran.dg/pr106985.f90: New test.
+
+2022-09-20 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/modules/xtreme-header-2.h: Include <execution>.
+ * g++.dg/modules/xtreme-header-6.h: Include implemented
+ C++20 library headers.
+ * g++.dg/modules/xtreme-header.h: Likewise. Remove
+ NO_ASSOCIATED_LAMBDA workaround. Include implemented C++23
+ library headers.
+
+2022-09-20 Patrick Palka <ppalka@redhat.com>
+
+ * g++.dg/modules/auto-3.h: New test.
+ * g++.dg/modules/auto-3_a.H: New test.
+ * g++.dg/modules/auto-3_b.C: New test.
+
+2022-09-20 José Rui Faustino de Sousa <jrfsousa@gmail.com>
+
+ PR fortran/100132
+ * gfortran.dg/PR100132.f90: New test.
+
+2022-09-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/pr106914.c: New test.
+ * g++.dg/vect/pr106794.cc: Likewise.
+
+2022-09-20 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/vect-gather-5.c: New test.
+
+2022-09-20 Aldy Hernandez <aldyh@redhat.com>
+
+ PR tree-optimization/106970
+ * gcc.dg/tree-ssa/pr106970.c: New test.
+
+2022-09-20 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/106761
+ * g++.dg/modules/pr106761.h: New test.
+ * g++.dg/modules/pr106761_a.H: New test.
+ * g++.dg/modules/pr106761_b.C: New test.
+
+2022-09-20 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/warn/Wclass-memaccess.C: Replace "the the" with "the".
+ * g++.dg/warn/Wconversion-real-integer2.C: Likewise.
+ * gcc.target/powerpc/p9-extract-1.c: Likewise.
+ * gcc.target/s390/s390.exp: Likewise.
+ * gcc.target/s390/zvector/vec-cmp-2.c: Likewise.
+ * gdc.dg/torture/simd_store.d: Likewise.
+ * gfortran.dg/actual_array_offset_1.f90: Likewise.
+ * gfortran.dg/pdt_15.f03: Likewise.
+ * gfortran.dg/pointer_array_8.f90: Likewise.
+
+2022-09-20 liuhongt <hongtao.liu@intel.com>
+
+ * gcc.target/i386/pr106910-1.c: New test.
+
+2022-09-20 konglin1 <lingling.kong@intel.com>
+
+ * gcc.target/i386/pr105735-1.c: New test.
+ * gcc.target/i386/pr105735-2.c: New test.
+
+2022-09-20 konglin1 <lingling.kong@intel.com>
+
+ PR target/106887
+ * gcc.target/i386/vect-bfloat16-2c.c: New test.
+
2022-09-19 Marek Polacek <polacek@redhat.com>
PR c/106947
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-7.c b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
new file mode 100644
index 0000000..482b0ab
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-7.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+/* PR middle-end/106982 */
+
+long long n = 100;
+int multiplicitive_n = 128;
+
+void test1(double *rand, double *a, double *b, double *c)
+{
+#pragma acc data copyin(a[0:10*multiplicitive_n], b[0:10*multiplicitive_n]) copyout(c[0:10])
+ {
+#pragma acc parallel loop
+ for (int i = 0; i < 10; ++i)
+ {
+ double temp = 1.0;
+#pragma acc loop vector reduction(*:temp)
+ for (int j = 0; j < multiplicitive_n; ++j)
+ temp *= a[(i * multiplicitive_n) + j] + b[(i * multiplicitive_n) + j];
+ c[i] = temp;
+ }
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-8.c b/gcc/testsuite/c-c++-common/goacc/reduction-8.c
new file mode 100644
index 0000000..2c3ed49
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-8.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+/* PR middle-end/106982 */
+
+void test1(double *c)
+{
+ double reduced[5];
+#pragma acc parallel loop gang private(reduced)
+ for (int x = 0; x < 5; ++x)
+#pragma acc loop worker reduction(*:reduced)
+ for (int y = 0; y < 5; ++y) { }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr106981.c b/gcc/testsuite/c-c++-common/gomp/pr106981.c
new file mode 100644
index 0000000..a21d3c2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr106981.c
@@ -0,0 +1,9 @@
+/* PR c/106981 */
+/* { dg-do compile } */
+
+void
+foo (int a, double *b, double *c, double *d, long long e)
+{
+#pragma omp atomic capture
+ c[a] = d[((int) (e / 10 + 1))] = b[a] + d[((int) e / 10 + 1)]; /* { dg-error "invalid form" } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr107001.c b/gcc/testsuite/c-c++-common/gomp/pr107001.c
new file mode 100644
index 0000000..9c19d9b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr107001.c
@@ -0,0 +1,14 @@
+/* PR c/107001 */
+/* { dg-do compile } */
+/* { dg-options "-O0 -fopenmp -fexceptions" } */
+/* { dg-require-effective-target exceptions } */
+
+void bar (void);
+void foo (void)
+{
+ #pragma omp taskgroup
+ {
+ #pragma omp taskgroup
+ bar ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
index d3e4072..0537e1d 100644
--- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
+++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
@@ -504,8 +504,8 @@
#ifndef __cpp_char8_t
# error "__cpp_char8_t"
-#elif __cpp_char8_t != 201811
-# error "__cpp_char8_t != 201811"
+#elif __cpp_char8_t != 202207
+# error "__cpp_char8_t != 202207"
#endif
#ifndef __cpp_designated_initializers
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t3.C b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
new file mode 100644
index 0000000..071a718
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
@@ -0,0 +1,37 @@
+// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
+// { dg-do compile { target c++20 } }
+
+const char *p1 = u8""; // { dg-error "invalid conversion" }
+const unsigned char *p2 = u8""; // { dg-error "invalid conversion" }
+const signed char *p3 = u8""; // { dg-error "invalid conversion" }
+const char *p4 = { u8"" }; // { dg-error "invalid conversion" }
+const unsigned char *p5 = { u8"" }; // { dg-error "invalid conversion" }
+const signed char *p6 = { u8"" }; // { dg-error "invalid conversion" }
+const char *p7 = static_cast<const char *>(u8""); // { dg-error "invalid" }
+const char a1[] = u8"text";
+const unsigned char a2[] = u8"";
+const signed char a3[] = u8""; // { dg-error "cannot initialize array" }
+const char a4[] = { u8"text" };
+const unsigned char a5[] = { u8"" };
+const signed char a6[] = { u8"" }; // { dg-error "cannot initialize array" }
+
+const char *
+resource_id ()
+{
+ static const char res_id[] = u8"";
+ return res_id;
+}
+
+const char8_t x[] = "fail"; // { dg-error "cannot initialize array" }
+
+void fn (const char a[]);
+void
+g ()
+{
+ fn (u8"z"); // { dg-error "invalid conversion" }
+}
+
+char c = u8'c';
+unsigned char uc = u8'c';
+signed char sc = u8'c';
+char8_t c8 = 'c';
diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t4.C b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
new file mode 100644
index 0000000..c18081b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
@@ -0,0 +1,17 @@
+// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
+// { dg-do compile { target c++20 } }
+// [diff.cpp20.dcl]
+
+struct A {
+ char8_t s[10];
+};
+struct B {
+ char s[10];
+};
+
+void f(A);
+void f(B);
+
+int main() {
+ f({u8""}); // { dg-error "ambiguous" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
index c65ea6b..02f3a37 100644
--- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
+++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
@@ -504,8 +504,8 @@
#ifndef __cpp_char8_t
# error "__cpp_char8_t"
-#elif __cpp_char8_t != 201811
-# error "__cpp_char8_t != 201811"
+#elif __cpp_char8_t != 202207
+# error "__cpp_char8_t != 202207"
#endif
#ifndef __cpp_designated_initializers
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
index df1063f..2d0f904 100644
--- a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
+++ b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
@@ -5,6 +5,6 @@
#if !defined(__cpp_char8_t)
# error __cpp_char8_t is not defined!
-#elif __cpp_char8_t != 201811
-# error __cpp_char8_t != 201811
+#elif __cpp_char8_t != 202207
+# error __cpp_char8_t != 202207
#endif
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
index c713bc1..02a96ff 100644
--- a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
+++ b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
@@ -21,7 +21,7 @@ const char8_t (&rca4)[2] = u8"x";
const char8_t (&rca5)[2] = u"x"; // { dg-error "invalid initialization of reference of type .const char8_t ....... from expression of type .const char16_t ...." "char8_t" }
char ca1[] = "x";
-char ca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
+char ca2[] = u8"x";
char8_t ca3[] = "x"; // { dg-error "from a string literal with type array of .char." "char8_t" }
char8_t ca4[] = u8"x";
char8_t ca5[] = u"x"; // { dg-error "from a string literal with type array of .char16_t." "char8_t" }
@@ -30,4 +30,4 @@ signed char sca1[] = "x";
signed char sca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
unsigned char uca1[] = "x";
-unsigned char uca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
+unsigned char uca2[] = u8"x";
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index fe25cb2..17dabf6 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -131,3 +131,9 @@
#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
#endif
+#if !__has_builtin (__is_convertible)
+# error "__has_builtin (__is_convertible) failed"
+#endif
+#if !__has_builtin (__is_nothrow_convertible)
+# error "__has_builtin (__is_nothrow_convertible) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_convertible1.C b/gcc/testsuite/g++.dg/ext/is_convertible1.C
new file mode 100644
index 0000000..2e72945
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_convertible1.C
@@ -0,0 +1,269 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+template<typename From, typename To>
+struct is_convertible {
+ static const bool value = __is_convertible(From, To);
+};
+
+struct from_int {
+ from_int(int);
+};
+
+struct from_charp {
+ from_charp(const char *);
+};
+
+struct to_int {
+ operator int();
+};
+
+typedef int Fn(int);
+typedef char Arr[10];
+enum E { XYZZY };
+
+SA(!__is_convertible(int, void));
+SA(__is_convertible(int, int));
+SA(__is_convertible(int, from_int));
+SA(__is_convertible(long, from_int));
+SA(__is_convertible(double, from_int));
+SA(__is_convertible(const int, from_int));
+SA(__is_convertible(const int&, from_int));
+SA(__is_convertible(to_int, int));
+SA(__is_convertible(to_int, const int&));
+SA(__is_convertible(to_int, long));
+SA(!__is_convertible(to_int, int&));
+SA(!__is_convertible(to_int, from_int));
+SA(!__is_convertible(int, Fn));
+SA(!__is_convertible(int, Fn*));
+SA(!__is_convertible(int, Fn&));
+SA(!__is_convertible(int, Arr));
+SA(!__is_convertible(int, Arr&));
+SA(!__is_convertible(int, int&));
+SA(__is_convertible(int, const int&));
+SA(!__is_convertible(const int, int&));
+SA(__is_convertible(const int, const int&));
+SA(!__is_convertible(int, int*));
+
+SA(!__is_convertible(int, E));
+SA(__is_convertible(E, int));
+
+SA(__is_convertible(int&, int));
+SA(__is_convertible(int&, int&));
+SA(__is_convertible(int&, const int&));
+SA(!__is_convertible(const int&, int&));
+SA(__is_convertible(const int&, const int&));
+SA(!__is_convertible(int&, int*));
+SA(!__is_convertible(int&, void));
+SA(!__is_convertible(int&, Fn));
+SA(!__is_convertible(int&, Fn*));
+SA(!__is_convertible(int&, Fn&));
+SA(!__is_convertible(int&, Arr));
+SA(!__is_convertible(int&, Arr&));
+
+SA(!__is_convertible(int*, int));
+SA(!__is_convertible(int*, int&));
+SA(!__is_convertible(int*, void));
+SA(__is_convertible(int*, int*));
+SA(__is_convertible(int*, const int*));
+SA(!__is_convertible(const int*, int*));
+SA(__is_convertible(const int*, const int*));
+SA(!__is_convertible(int*, Fn));
+SA(!__is_convertible(int*, Fn*));
+SA(!__is_convertible(int*, Fn&));
+SA(!__is_convertible(int*, Arr));
+SA(!__is_convertible(int*, Arr&));
+SA(!__is_convertible(int*, float*));
+
+SA(__is_convertible(void, void));
+SA(!__is_convertible(void, char));
+SA(!__is_convertible(void, char&));
+SA(!__is_convertible(void, char*));
+SA(!__is_convertible(char, void));
+SA(__is_convertible(const void, void));
+SA(__is_convertible(void, const void));
+SA(__is_convertible(const void, const void));
+SA(!__is_convertible(void, Fn));
+SA(!__is_convertible(void, Fn&));
+SA(!__is_convertible(void, Fn*));
+SA(!__is_convertible(void, Arr));
+SA(!__is_convertible(void, Arr&));
+
+SA(!__is_convertible(Fn, void));
+SA(!__is_convertible(Fn, Fn));
+SA(__is_convertible(Fn, Fn*));
+SA(__is_convertible(Fn, Fn&));
+SA(!__is_convertible(int(int), int(int)));
+SA(__is_convertible(int(int), int(&)(int)));
+SA(__is_convertible(int(int), int(&&)(int)));
+SA(__is_convertible(int(int), int(*)(int)));
+SA(__is_convertible(int(int), int(*const)(int)));
+SA(!__is_convertible(int(int), char));
+SA(!__is_convertible(int(int), char*));
+SA(!__is_convertible(int(int), char&));
+
+SA(!__is_convertible(Fn&, void));
+SA(!__is_convertible(Fn&, Fn));
+SA(__is_convertible(Fn&, Fn&));
+SA(__is_convertible(Fn&, Fn*));
+SA(!__is_convertible(Fn&, Arr));
+SA(!__is_convertible(Fn&, Arr&));
+SA(!__is_convertible(Fn&, char));
+SA(!__is_convertible(Fn&, char&));
+SA(!__is_convertible(Fn&, char*));
+
+SA(!__is_convertible(Fn*, void));
+SA(!__is_convertible(Fn*, Fn));
+SA(!__is_convertible(Fn*, Fn&));
+SA(__is_convertible(Fn*, Fn*));
+SA(!__is_convertible(Fn*, Arr));
+SA(!__is_convertible(Fn*, Arr&));
+SA(!__is_convertible(Fn*, char));
+SA(!__is_convertible(Fn*, char&));
+SA(!__is_convertible(Fn*, char*));
+
+SA(!__is_convertible(Arr, void));
+SA(!__is_convertible(Arr, Fn));
+SA(!__is_convertible(Arr, Fn*));
+SA(!__is_convertible(Arr, Fn&));
+SA(!__is_convertible(Arr, Arr));
+SA(!__is_convertible(Arr, Arr&));
+SA(__is_convertible(Arr, const Arr&));
+SA(!__is_convertible(Arr, volatile Arr&));
+SA(!__is_convertible(Arr, const volatile Arr&));
+SA(!__is_convertible(const Arr, Arr&));
+SA(__is_convertible(const Arr, const Arr&));
+SA(__is_convertible(Arr, Arr&&));
+SA(__is_convertible(Arr, const Arr&&));
+SA(__is_convertible(Arr, volatile Arr&&));
+SA(__is_convertible(Arr, const volatile Arr&&));
+SA(__is_convertible(const Arr, const Arr&&));
+SA(!__is_convertible(Arr&, Arr&&));
+SA(!__is_convertible(Arr&&, Arr&));
+SA(!__is_convertible(Arr, char));
+SA(__is_convertible(Arr, char*));
+SA(__is_convertible(Arr, const char*));
+SA(!__is_convertible(Arr, char&));
+SA(!__is_convertible(const Arr, char*));
+SA(__is_convertible(const Arr, const char*));
+SA(!__is_convertible(int, int[1]));
+SA(!__is_convertible(int[1], int[1]));
+SA(!__is_convertible(int[1], int(&)[1]));
+SA(__is_convertible(int(&)[1], int(&)[1]));
+SA(__is_convertible(int(&)[1], const int(&)[1]));
+SA(!__is_convertible(const int(&)[1], int(&)[1]));
+SA(!__is_convertible(int[1][1], int*));
+SA(!__is_convertible(int[][1], int*));
+
+SA(!__is_convertible(Arr&, void));
+SA(!__is_convertible(Arr&, Fn));
+SA(!__is_convertible(Arr&, Fn*));
+SA(!__is_convertible(Arr&, Fn&));
+SA(!__is_convertible(Arr&, Arr));
+SA(__is_convertible(Arr&, Arr&));
+SA(__is_convertible(Arr&, const Arr&));
+SA(!__is_convertible(const Arr&, Arr&));
+SA(__is_convertible(const Arr&, const Arr&));
+SA(!__is_convertible(Arr&, char));
+SA(__is_convertible(Arr&, char*));
+SA(__is_convertible(Arr&, const char*));
+SA(!__is_convertible(Arr&, char&));
+SA(!__is_convertible(const Arr&, char*));
+SA(__is_convertible(const Arr&, const char*));
+SA(__is_convertible(Arr, from_charp));
+SA(__is_convertible(Arr&, from_charp));
+
+struct B { };
+struct D : B { };
+
+SA(__is_convertible(D, B));
+SA(__is_convertible(D*, B*));
+SA(__is_convertible(D&, B&));
+SA(!__is_convertible(B, D));
+SA(!__is_convertible(B*, D*));
+SA(!__is_convertible(B&, D&));
+
+/* These are taken from LLVM's test/SemaCXX/type-traits.cpp. */
+
+struct I {
+ int i;
+ I(int _i) : i(_i) { }
+ operator int() const {
+ return i;
+ }
+};
+
+struct F
+{
+ float f;
+ F(float _f) : f(_f) {}
+ F(const I& obj)
+ : f(static_cast<float>(obj.i)) {}
+ operator float() const {
+ return f;
+ }
+ operator I() const {
+ return I(static_cast<int>(f));
+ }
+};
+
+SA(__is_convertible(I, I));
+SA(__is_convertible(I, const I));
+SA(__is_convertible(I, int));
+SA(__is_convertible(int, I));
+SA(__is_convertible(I, F));
+SA(__is_convertible(F, I));
+SA(__is_convertible(F, float));
+SA(__is_convertible(float, F));
+
+template<typename>
+struct X {
+ template<typename U> X(const X<U>&);
+};
+
+SA(__is_convertible(X<int>, X<float>));
+SA(__is_convertible(X<float>, X<int>));
+
+struct Abstract {
+ virtual void f() = 0;
+};
+
+SA(!__is_convertible(Abstract, Abstract));
+
+class hidden {
+ hidden(const hidden&);
+ friend void test ();
+};
+
+SA(__is_convertible(hidden&, hidden&));
+SA(__is_convertible(hidden&, const hidden&));
+SA(__is_convertible(hidden&, volatile hidden&));
+SA(__is_convertible(hidden&, const volatile hidden&));
+SA(__is_convertible(const hidden&, const hidden&));
+SA(__is_convertible(const hidden&, const volatile hidden&));
+SA(__is_convertible(volatile hidden&, const volatile hidden&));
+SA(__is_convertible(const volatile hidden&, const volatile hidden&));
+SA(!__is_convertible(const hidden&, hidden&));
+
+void
+test ()
+{
+ /* __is_convertible(hidden, hidden) should be false despite the
+ friend declaration above, because "Access checks are performed
+ as if from a context unrelated to either type", but we don't
+ implement that for the built-in (std::is_convertible works as
+ expected). This is the case for __is_assignable as well. */
+ //SA(!__is_convertible(hidden, hidden));
+}
+
+void
+test2 ()
+{
+ struct X { };
+ struct Y {
+ explicit Y(X); // not viable for implicit conversions
+ };
+ SA(!__is_convertible(X, Y));
+}
diff --git a/gcc/testsuite/g++.dg/ext/is_convertible2.C b/gcc/testsuite/g++.dg/ext/is_convertible2.C
new file mode 100644
index 0000000..9b46e26
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_convertible2.C
@@ -0,0 +1,46 @@
+// PR c++/106784
+// { dg-do compile { target c++20 } }
+// Adapted from <https://en.cppreference.com/w/cpp/types/is_convertible>.
+
+#include <string>
+#include <string_view>
+
+#define SA(X) static_assert((X),#X)
+
+class E { public: template<class T> E(T&&) { } };
+
+int main()
+{
+ class A {};
+ class B : public A {};
+ class C {};
+ class D { public: operator C() { return c; } C c; };
+
+ SA(__is_convertible(B*, A*));
+ SA(!__is_convertible(A*, B*));
+ SA(__is_convertible(D, C));
+ SA(!__is_convertible(B*, C*));
+ SA(__is_convertible(A, E));
+
+ using std::operator "" s, std::operator "" sv;
+
+ auto stringify = []<typename T>(T x) {
+ if constexpr (std::is_convertible_v<T, std::string> or
+ std::is_convertible_v<T, std::string_view>) {
+ return x;
+ } else {
+ return std::to_string(x);
+ }
+ };
+
+ const char* three = "three";
+
+ SA(!__is_convertible(std::string_view, std::string));
+ SA(__is_convertible(std::string, std::string_view));
+
+ auto s1 = stringify("one"s);
+ auto s2 = stringify("two"sv);
+ auto s3 = stringify(three);
+ auto s4 = stringify(42);
+ auto s5 = stringify(42.);
+}
diff --git a/gcc/testsuite/g++.dg/ext/is_convertible3.C b/gcc/testsuite/g++.dg/ext/is_convertible3.C
new file mode 100644
index 0000000..7a986d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_convertible3.C
@@ -0,0 +1,9 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+// Make sure we don't reject this at runtime by trying to instantiate
+// something that would be ill-formed.
+
+struct A;
+struct B { template<class T> B(const T&) noexcept { T::nonexistent; } };
+
+static_assert(__is_convertible(const A&, B), "");
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_convertible1.C b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible1.C
new file mode 100644
index 0000000..bb7243e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible1.C
@@ -0,0 +1,270 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+// Like is_convertible1.C, but conversion functions are made noexcept.
+
+#define SA(X) static_assert((X),#X)
+
+template<typename From, typename To>
+struct is_nothrow_convertible {
+ static const bool value = __is_nothrow_convertible(From, To);
+};
+
+struct from_int {
+ from_int(int) noexcept;
+};
+
+struct from_charp {
+ from_charp(const char *) noexcept;
+};
+
+struct to_int {
+ operator int() noexcept;
+};
+
+typedef int Fn(int);
+typedef char Arr[10];
+enum E { XYZZY };
+
+SA(!__is_nothrow_convertible(int, void));
+SA(__is_nothrow_convertible(int, int));
+SA(__is_nothrow_convertible(int, from_int));
+SA(__is_nothrow_convertible(long, from_int));
+SA(__is_nothrow_convertible(double, from_int));
+SA(__is_nothrow_convertible(const int, from_int));
+SA(__is_nothrow_convertible(const int&, from_int));
+SA(__is_nothrow_convertible(to_int, int));
+SA(__is_nothrow_convertible(to_int, const int&));
+SA(__is_nothrow_convertible(to_int, long));
+SA(!__is_nothrow_convertible(to_int, int&));
+SA(!__is_nothrow_convertible(to_int, from_int));
+SA(!__is_nothrow_convertible(int, Fn));
+SA(!__is_nothrow_convertible(int, Fn*));
+SA(!__is_nothrow_convertible(int, Fn&));
+SA(!__is_nothrow_convertible(int, Arr));
+SA(!__is_nothrow_convertible(int, Arr&));
+SA(!__is_nothrow_convertible(int, int&));
+SA(__is_nothrow_convertible(int, const int&));
+SA(!__is_nothrow_convertible(const int, int&));
+SA(__is_nothrow_convertible(const int, const int&));
+SA(!__is_nothrow_convertible(int, int*));
+
+SA(!__is_nothrow_convertible(int, E));
+SA(__is_nothrow_convertible(E, int));
+
+SA(__is_nothrow_convertible(int&, int));
+SA(__is_nothrow_convertible(int&, int&));
+SA(__is_nothrow_convertible(int&, const int&));
+SA(!__is_nothrow_convertible(const int&, int&));
+SA(__is_nothrow_convertible(const int&, const int&));
+SA(!__is_nothrow_convertible(int&, int*));
+SA(!__is_nothrow_convertible(int&, void));
+SA(!__is_nothrow_convertible(int&, Fn));
+SA(!__is_nothrow_convertible(int&, Fn*));
+SA(!__is_nothrow_convertible(int&, Fn&));
+SA(!__is_nothrow_convertible(int&, Arr));
+SA(!__is_nothrow_convertible(int&, Arr&));
+
+SA(!__is_nothrow_convertible(int*, int));
+SA(!__is_nothrow_convertible(int*, int&));
+SA(!__is_nothrow_convertible(int*, void));
+SA(__is_nothrow_convertible(int*, int*));
+SA(__is_nothrow_convertible(int*, const int*));
+SA(!__is_nothrow_convertible(const int*, int*));
+SA(__is_nothrow_convertible(const int*, const int*));
+SA(!__is_nothrow_convertible(int*, Fn));
+SA(!__is_nothrow_convertible(int*, Fn*));
+SA(!__is_nothrow_convertible(int*, Fn&));
+SA(!__is_nothrow_convertible(int*, Arr));
+SA(!__is_nothrow_convertible(int*, Arr&));
+SA(!__is_nothrow_convertible(int*, float*));
+
+SA(__is_nothrow_convertible(void, void));
+SA(!__is_nothrow_convertible(void, char));
+SA(!__is_nothrow_convertible(void, char&));
+SA(!__is_nothrow_convertible(void, char*));
+SA(!__is_nothrow_convertible(char, void));
+SA(__is_nothrow_convertible(const void, void));
+SA(__is_nothrow_convertible(void, const void));
+SA(__is_nothrow_convertible(const void, const void));
+SA(!__is_nothrow_convertible(void, Fn));
+SA(!__is_nothrow_convertible(void, Fn&));
+SA(!__is_nothrow_convertible(void, Fn*));
+SA(!__is_nothrow_convertible(void, Arr));
+SA(!__is_nothrow_convertible(void, Arr&));
+
+SA(!__is_nothrow_convertible(Fn, void));
+SA(!__is_nothrow_convertible(Fn, Fn));
+SA(__is_nothrow_convertible(Fn, Fn*));
+SA(__is_nothrow_convertible(Fn, Fn&));
+SA(!__is_nothrow_convertible(int(int), int(int)));
+SA(__is_nothrow_convertible(int(int), int(&)(int)));
+SA(__is_nothrow_convertible(int(int), int(&&)(int)));
+SA(__is_nothrow_convertible(int(int), int(*)(int)));
+SA(__is_nothrow_convertible(int(int), int(*const)(int)));
+SA(!__is_nothrow_convertible(int(int), char));
+SA(!__is_nothrow_convertible(int(int), char*));
+SA(!__is_nothrow_convertible(int(int), char&));
+
+SA(!__is_nothrow_convertible(Fn&, void));
+SA(!__is_nothrow_convertible(Fn&, Fn));
+SA(__is_nothrow_convertible(Fn&, Fn&));
+SA(__is_nothrow_convertible(Fn&, Fn*));
+SA(!__is_nothrow_convertible(Fn&, Arr));
+SA(!__is_nothrow_convertible(Fn&, Arr&));
+SA(!__is_nothrow_convertible(Fn&, char));
+SA(!__is_nothrow_convertible(Fn&, char&));
+SA(!__is_nothrow_convertible(Fn&, char*));
+
+SA(!__is_nothrow_convertible(Fn*, void));
+SA(!__is_nothrow_convertible(Fn*, Fn));
+SA(!__is_nothrow_convertible(Fn*, Fn&));
+SA(__is_nothrow_convertible(Fn*, Fn*));
+SA(!__is_nothrow_convertible(Fn*, Arr));
+SA(!__is_nothrow_convertible(Fn*, Arr&));
+SA(!__is_nothrow_convertible(Fn*, char));
+SA(!__is_nothrow_convertible(Fn*, char&));
+SA(!__is_nothrow_convertible(Fn*, char*));
+
+SA(!__is_nothrow_convertible(Arr, void));
+SA(!__is_nothrow_convertible(Arr, Fn));
+SA(!__is_nothrow_convertible(Arr, Fn*));
+SA(!__is_nothrow_convertible(Arr, Fn&));
+SA(!__is_nothrow_convertible(Arr, Arr));
+SA(!__is_nothrow_convertible(Arr, Arr&));
+SA(__is_nothrow_convertible(Arr, const Arr&));
+SA(!__is_nothrow_convertible(Arr, volatile Arr&));
+SA(!__is_nothrow_convertible(Arr, const volatile Arr&));
+SA(!__is_nothrow_convertible(const Arr, Arr&));
+SA(__is_nothrow_convertible(const Arr, const Arr&));
+SA(__is_nothrow_convertible(Arr, Arr&&));
+SA(__is_nothrow_convertible(Arr, const Arr&&));
+SA(__is_nothrow_convertible(Arr, volatile Arr&&));
+SA(__is_nothrow_convertible(Arr, const volatile Arr&&));
+SA(__is_nothrow_convertible(const Arr, const Arr&&));
+SA(!__is_nothrow_convertible(Arr&, Arr&&));
+SA(!__is_nothrow_convertible(Arr&&, Arr&));
+SA(!__is_nothrow_convertible(Arr, char));
+SA(__is_nothrow_convertible(Arr, char*));
+SA(__is_nothrow_convertible(Arr, const char*));
+SA(!__is_nothrow_convertible(Arr, char&));
+SA(!__is_nothrow_convertible(const Arr, char*));
+SA(__is_nothrow_convertible(const Arr, const char*));
+SA(!__is_nothrow_convertible(int, int[1]));
+SA(!__is_nothrow_convertible(int[1], int[1]));
+SA(!__is_nothrow_convertible(int[1], int(&)[1]));
+SA(__is_nothrow_convertible(int(&)[1], int(&)[1]));
+SA(__is_nothrow_convertible(int(&)[1], const int(&)[1]));
+SA(!__is_nothrow_convertible(const int(&)[1], int(&)[1]));
+SA(!__is_nothrow_convertible(int[1][1], int*));
+SA(!__is_nothrow_convertible(int[][1], int*));
+
+SA(!__is_nothrow_convertible(Arr&, void));
+SA(!__is_nothrow_convertible(Arr&, Fn));
+SA(!__is_nothrow_convertible(Arr&, Fn*));
+SA(!__is_nothrow_convertible(Arr&, Fn&));
+SA(!__is_nothrow_convertible(Arr&, Arr));
+SA(__is_nothrow_convertible(Arr&, Arr&));
+SA(__is_nothrow_convertible(Arr&, const Arr&));
+SA(!__is_nothrow_convertible(const Arr&, Arr&));
+SA(__is_nothrow_convertible(const Arr&, const Arr&));
+SA(!__is_nothrow_convertible(Arr&, char));
+SA(__is_nothrow_convertible(Arr&, char*));
+SA(__is_nothrow_convertible(Arr&, const char*));
+SA(!__is_nothrow_convertible(Arr&, char&));
+SA(!__is_nothrow_convertible(const Arr&, char*));
+SA(__is_nothrow_convertible(const Arr&, const char*));
+SA(__is_nothrow_convertible(Arr, from_charp));
+SA(__is_nothrow_convertible(Arr&, from_charp));
+
+struct B { };
+struct D : B { };
+
+SA(__is_nothrow_convertible(D, B));
+SA(__is_nothrow_convertible(D*, B*));
+SA(__is_nothrow_convertible(D&, B&));
+SA(!__is_nothrow_convertible(B, D));
+SA(!__is_nothrow_convertible(B*, D*));
+SA(!__is_nothrow_convertible(B&, D&));
+
+/* These are taken from LLVM's test/SemaCXX/type-traits.cpp. */
+
+struct I {
+ int i;
+ I(int _i) noexcept : i(_i) { }
+ operator int() const noexcept {
+ return i;
+ }
+};
+
+struct F
+{
+ float f;
+ F(float _f) noexcept : f(_f) {}
+ F(const I& obj) noexcept
+ : f(static_cast<float>(obj.i)) {}
+ operator float() const noexcept {
+ return f;
+ }
+ operator I() const noexcept {
+ return I(static_cast<int>(f));
+ }
+};
+
+SA(__is_nothrow_convertible(I, I));
+SA(__is_nothrow_convertible(I, const I));
+SA(__is_nothrow_convertible(I, int));
+SA(__is_nothrow_convertible(int, I));
+SA(__is_nothrow_convertible(I, F));
+SA(__is_nothrow_convertible(F, I));
+SA(__is_nothrow_convertible(F, float));
+SA(__is_nothrow_convertible(float, F));
+
+template<typename>
+struct X {
+ template<typename U> X(const X<U>&) noexcept;
+};
+
+SA(__is_nothrow_convertible(X<int>, X<float>));
+SA(__is_nothrow_convertible(X<float>, X<int>));
+
+struct Abstract {
+ virtual void f() = 0;
+};
+
+SA(!__is_nothrow_convertible(Abstract, Abstract));
+
+class hidden {
+ hidden(const hidden&);
+ friend void test ();
+};
+
+SA(__is_nothrow_convertible(hidden&, hidden&));
+SA(__is_nothrow_convertible(hidden&, const hidden&));
+SA(__is_nothrow_convertible(hidden&, volatile hidden&));
+SA(__is_nothrow_convertible(hidden&, const volatile hidden&));
+SA(__is_nothrow_convertible(const hidden&, const hidden&));
+SA(__is_nothrow_convertible(const hidden&, const volatile hidden&));
+SA(__is_nothrow_convertible(volatile hidden&, const volatile hidden&));
+SA(__is_nothrow_convertible(const volatile hidden&, const volatile hidden&));
+SA(!__is_nothrow_convertible(const hidden&, hidden&));
+
+void
+test ()
+{
+ /* __is_nothrow_convertible(hidden, hidden) should be false despite the
+ friend declaration above, because "Access checks are performed
+ as if from a context unrelated to either type", but we don't
+ implement that for the built-in (std::is_convertible works as
+ expected). This is the case for __is_assignable as well. */
+ //SA(!__is_nothrow_convertible(hidden, hidden));
+}
+
+void
+test2 ()
+{
+ struct X { };
+ struct Y {
+ explicit Y(X); // not viable for implicit conversions
+ };
+ SA(!__is_nothrow_convertible(X, Y));
+}
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_convertible2.C b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible2.C
new file mode 100644
index 0000000..aa08917
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible2.C
@@ -0,0 +1,19 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+
+#define SA(X) static_assert((X),#X)
+
+struct A { };
+struct B { };
+
+struct M {
+ operator A();
+ operator B() noexcept;
+ M(const A&);
+ M(const B&) noexcept;
+};
+
+SA(!__is_nothrow_convertible(A, M));
+SA(!__is_nothrow_convertible(M, A));
+SA(__is_nothrow_convertible(B, M));
+SA(__is_nothrow_convertible(M, B));
diff --git a/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C
new file mode 100644
index 0000000..05b1e1d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_nothrow_convertible3.C
@@ -0,0 +1,9 @@
+// PR c++/106784
+// { dg-do compile { target c++11 } }
+// Make sure we don't reject this at runtime by trying to instantiate
+// something that would be ill-formed.
+
+struct A;
+struct B { template<class T> B(const T&) noexcept { T::nonexistent; } };
+
+static_assert(__is_nothrow_convertible(const A&, B), "");
diff --git a/gcc/testsuite/g++.dg/modules/auto-3.h b/gcc/testsuite/g++.dg/modules/auto-3.h
new file mode 100644
index 0000000..f129433
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/auto-3.h
@@ -0,0 +1,10 @@
+template<class>
+struct __tree_barrier {
+ static const auto __phase_alignment_1 = 0;
+
+ template<class>
+ static const auto __phase_alignment_2 = 0;
+};
+
+template<class>
+inline auto __phase_alignment_3 = 0;
diff --git a/gcc/testsuite/g++.dg/modules/auto-3_a.H b/gcc/testsuite/g++.dg/modules/auto-3_a.H
new file mode 100644
index 0000000..25a7a73
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/auto-3_a.H
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+#include "auto-3.h"
diff --git a/gcc/testsuite/g++.dg/modules/auto-3_b.C b/gcc/testsuite/g++.dg/modules/auto-3_b.C
new file mode 100644
index 0000000..03b6d46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/auto-3_b.C
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodules-ts -fno-module-lazy" }
+
+#include "auto-3.h"
+import "auto-3_a.H";
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.cc b/gcc/testsuite/g++.dg/modules/partial-2.cc
new file mode 100644
index 0000000..1316bf5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.cc
@@ -0,0 +1,17 @@
+static_assert(is_reference_v<int&>);
+static_assert(is_reference_v<int&&>);
+static_assert(!is_reference_v<int>);
+
+static_assert(A::is_reference_v<long&>);
+static_assert(A::is_reference_v<long&&>);
+static_assert(!A::is_reference_v<long>);
+
+#if __cpp_concepts
+static_assert(concepts::is_reference_v<char&>);
+static_assert(concepts::is_reference_v<char&&>);
+static_assert(!concepts::is_reference_v<char>);
+
+static_assert(concepts::A::is_reference_v<bool&>);
+static_assert(concepts::A::is_reference_v<bool&&>);
+static_assert(!concepts::A::is_reference_v<bool>);
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2.h b/gcc/testsuite/g++.dg/modules/partial-2.h
new file mode 100644
index 0000000..afcfce7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2.h
@@ -0,0 +1,38 @@
+template<class T> constexpr bool is_reference_v = false;
+template<class T> constexpr bool is_reference_v<T&> = true;
+template<class T> constexpr bool is_reference_v<T&&> = true;
+
+struct A {
+ template<class T> static constexpr bool is_reference_v = false;
+};
+
+template<class T> constexpr bool A::is_reference_v<T&> = true;
+template<class T> constexpr bool A::is_reference_v<T&&> = true;
+
+#if __cpp_concepts
+namespace concepts {
+ template<class T> bool is_reference_v;
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool is_reference_v<T> = false;
+
+ struct A {
+ template<class T> static bool is_reference_v;
+ };
+
+ template<class T> requires __is_same(T, T&)
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires __is_same(T, T&&) && (!__is_same(T, T&))
+ constexpr bool A::is_reference_v<T> = true;
+
+ template<class T> requires (!__is_same(T, T&)) && (!__is_same(T, T&&))
+ constexpr bool A::is_reference_v<T> = false;
+}
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C
new file mode 100644
index 0000000..1582f56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C
@@ -0,0 +1,6 @@
+// PR c++/106826
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr106826 }
+export module pr106826;
+
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C
new file mode 100644
index 0000000..1b0c7a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C
@@ -0,0 +1,5 @@
+// PR c++/106826
+// { dg-additional-options -fmodules-ts }
+module pr106826;
+
+#include "partial-2.cc"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_c.H b/gcc/testsuite/g++.dg/modules/partial-2_c.H
new file mode 100644
index 0000000..bd83852
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_c.H
@@ -0,0 +1,5 @@
+// PR c++/107033
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+
+#include "partial-2.h"
diff --git a/gcc/testsuite/g++.dg/modules/partial-2_d.C b/gcc/testsuite/g++.dg/modules/partial-2_d.C
new file mode 100644
index 0000000..ed54d3c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/partial-2_d.C
@@ -0,0 +1,8 @@
+// PR c++/107033
+// { dg-additional-options -fmodules-ts }
+// { dg-module-cmi pr107033 }
+export module pr107033;
+
+import "partial-2_c.H";
+
+#include "partial-2.cc"
diff --git a/gcc/testsuite/g++.dg/modules/xtreme-header-2.h b/gcc/testsuite/g++.dg/modules/xtreme-header-2.h
index ded093e..dfe94aa 100644
--- a/gcc/testsuite/g++.dg/modules/xtreme-header-2.h
+++ b/gcc/testsuite/g++.dg/modules/xtreme-header-2.h
@@ -1,8 +1,7 @@
// Everything that transitively includes <ranges>
#include <algorithm>
-// FIXME: PR 97549
-// #include <execution>
+#include <execution>
#include <functional>
#include <future>
#include <memory>
diff --git a/gcc/testsuite/g++.dg/modules/xtreme-header-6.h b/gcc/testsuite/g++.dg/modules/xtreme-header-6.h
index 85894b2..8d024b6 100644
--- a/gcc/testsuite/g++.dg/modules/xtreme-header-6.h
+++ b/gcc/testsuite/g++.dg/modules/xtreme-header-6.h
@@ -1,22 +1,22 @@
// C++20 headers
#if __cplusplus > 201703
#include <version>
+#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#if __cpp_coroutines
#include <coroutine>
#endif
+#include <latch>
#include <numbers>
+#include <semaphore>
+#include <source_location>
#include <span>
#include <stop_token>
+#include <syncstream>
#if 0
// Unimplemented
-#include <barrier>
#include <format>
-#include <latch>
-#include <semaphore>
-#include <source_location>
-#include <syncstream>
#endif
#endif
diff --git a/gcc/testsuite/g++.dg/modules/xtreme-header.h b/gcc/testsuite/g++.dg/modules/xtreme-header.h
index 41302c7..3147aaf 100644
--- a/gcc/testsuite/g++.dg/modules/xtreme-header.h
+++ b/gcc/testsuite/g++.dg/modules/xtreme-header.h
@@ -1,17 +1,8 @@
// All the headers!
-#if __cplusplus > 201703L
-// FIXME: if we include everything, something goes wrong with location
-// information. We used to not handle lambdas attached to global
-// vars, and this is a convienient flag to stop including everything.
-#define NO_ASSOCIATED_LAMBDA 1
-#endif
-
// C++ 17 and below
#if 1
-#if !NO_ASSOCIATED_LAMBDA
#include <algorithm>
-#endif
#include <any>
#include <array>
#include <atomic>
@@ -26,19 +17,12 @@
#include <cwctype>
#include <deque>
#include <exception>
-#if !NO_ASSOCIATED_LAMBDA
-// FIXME: PR 97549
-//#include <execution>
-#endif
+#include <execution>
#include <filesystem>
#include <forward_list>
#include <fstream>
-#if !NO_ASSOCIATED_LAMBDA
#include <functional>
-#endif
-#if !NO_ASSOCIATED_LAMBDA
#include <future>
-#endif
#include <initializer_list>
#include <iomanip>
#include <ios>
@@ -49,12 +33,8 @@
#include <list>
#include <locale>
#include <map>
-#if !NO_ASSOCIATED_LAMBDA
#include <memory>
-#endif
-#if !NO_ASSOCIATED_LAMBDA
#include <memory_resource>
-#endif
#include <mutex>
#include <new>
#include <numeric>
@@ -63,12 +43,8 @@
#include <queue>
#include <random>
#include <ratio>
-#if !NO_ASSOCIATED_LAMBDA
#include <regex>
-#endif
-#if !NO_ASSOCIATED_LAMBDA
#include <scoped_allocator>
-#endif
#include <set>
#include <shared_mutex>
#include <sstream>
@@ -78,9 +54,7 @@
#include <string>
#include <string_view>
#include <system_error>
-#if !NO_ASSOCIATED_LAMBDA
#include <thread>
-#endif
#include <tuple>
#include <type_traits>
#include <typeindex>
@@ -88,9 +62,7 @@
#include <unordered_map>
#include <unordered_set>
#include <utility>
-#if !NO_ASSOCIATED_LAMBDA
#include <valarray>
-#endif
#include <variant>
#include <vector>
#endif
@@ -119,26 +91,39 @@
#if __cplusplus > 201703
#if 1
#include <version>
+#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#if __cpp_coroutines
#include <coroutine>
#endif
-#if !NO_ASSOCIATED_LAMBDA
-#include <ranges>
-#endif
+#include <latch>
#include <numbers>
+#include <ranges>
+#include <semaphore>
+#include <source_location>
#include <span>
#include <stop_token>
+#include <syncstream>
#if 0
// Unimplemented
-#include <barrier>
#include <format>
-#include <latch>
-#include <semaphore>
-#include <source_location>
-#include <syncstream>
#endif
#endif
#endif
+
+// C++23
+#if __cplusplus > 202002L
+#include <expected>
+#include <spanstream>
+#include <stacktrace>
+#if 0
+// Unimplemented
+#include <flat_map>
+#include <flat_set>
+#include <generator>
+#include <mdspan>
+#include <print>
+#endif
+#endif
diff --git a/gcc/testsuite/g++.dg/other/error36.C b/gcc/testsuite/g++.dg/other/error36.C
new file mode 100644
index 0000000..5562878
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/error36.C
@@ -0,0 +1,13 @@
+// PR c++/106983
+// { dg-do compile { target c++20 } }
+
+typedef unsigned long long A;
+typedef union
+{
+ struct B s; // { dg-error "incomplete" }
+ A a;
+} U;
+void f (A x, unsigned int b)
+{
+ const U y = {.a = x};
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr106922.C b/gcc/testsuite/g++.dg/torture/pr106922.C
new file mode 100644
index 0000000..046fc6c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr106922.C
@@ -0,0 +1,48 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-additional-options "-Wall" }
+// -O1 doesn't iterate VN and thus has bogus uninit diagnostics
+// { dg-skip-if "" { *-*-* } { "-O1" } { "" } }
+
+#include <vector>
+
+#include <optional>
+template <class T>
+using Optional = std::optional<T>;
+
+#include <sstream>
+
+struct MyOptionalStructWithInt {
+ int myint; /* works without this */
+ Optional<std::vector<std::string>> myoptional;
+};
+
+struct MyOptionalsStruct {
+ MyOptionalStructWithInt external1;
+ MyOptionalStructWithInt external2;
+};
+
+struct MyStruct { };
+std::ostream &operator << (std::ostream &os, const MyStruct &myStruct);
+
+std::vector<MyStruct> getMyStructs();
+
+void test()
+{
+ MyOptionalsStruct externals;
+ MyOptionalStructWithInt internal1;
+ MyOptionalStructWithInt internal2;
+
+ std::vector<MyStruct> myStructs;
+ myStructs = getMyStructs();
+
+ for (const auto& myStruct : myStructs)
+ {
+ std::stringstream address_stream;
+ address_stream << myStruct;
+ internal1.myint = internal2.myint = 0;
+ externals.external1 = internal1;
+ externals.external2 = internal2;
+ externals.external2 = internal2;
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
index faf379b..2aec497 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr106922.C
@@ -1,5 +1,5 @@
// { dg-require-effective-target c++20 }
-// { dg-options "-O2 -fdump-tree-pre-details -fdump-tree-cddce3" }
+// { dg-options "-O2 -fdump-tree-cddce3" }
template <typename> struct __new_allocator {
void deallocate(int *, int) { operator delete(0); }
@@ -87,5 +87,4 @@ void testfunctionfoo() {
}
}
-// { dg-final { scan-tree-dump-times "Found fully redundant value" 4 "pre" { xfail { ! lp64 } } } }
-// { dg-final { scan-tree-dump-not "m_initialized" "cddce3" { xfail { ! lp64 } } } }
+// { dg-final { scan-tree-dump-not "m_initialized" "cddce3" } }
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-33.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-33.C
new file mode 100644
index 0000000..1bb0639
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-33.C
@@ -0,0 +1,55 @@
+// PR102801
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O2 -Wall" }
+
+#include <algorithm>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+class C {
+ bool b{}; // { dg-bogus "uninitialized" }
+
+ struct Shared {};
+ using SharedPtr = std::shared_ptr<const Shared>;
+
+ SharedPtr shared;
+
+public:
+ C() = delete;
+ C(bool bIn) : b(bIn) {}
+ ~C();
+ int someMethod() const;
+};
+
+using OptC = std::optional<C>;
+
+class C2 {
+ OptC c;
+public:
+ C2() = default;
+ C2(const C &cIn) : c(cIn) {}
+ ~C2();
+ void operator()() const;
+ void swap(C2 &o) { std::swap(c, o.c); }
+};
+
+
+template <typename T>
+class Q {
+ std::vector<T> queue;
+public:
+ void Add(std::vector<T> &items) {
+ for (T & item : items) {
+ queue.push_back(T());
+ item.swap(queue.back());
+ }
+ }
+ void Exec();
+};
+
+extern void foo(Q<C2> & q, std::vector<C2> &items);
+void foo(Q<C2> & q, std::vector<C2> &items) { q.Add(items); q.Exec(); }
diff --git a/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c b/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c
new file mode 100644
index 0000000..104897a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wxor-used-as-pow-pr106830.c
@@ -0,0 +1,6 @@
+/* { dg-require-effective-target int128 }
+ { dg-options "-Wno-pedantic" } */
+
+void foo0_u16_0() {
+ (__int128)(18302628885633695743 << 4) ^ 0; /* { dg-warning "integer constant is so large that it is unsigned" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-complit-1.c b/gcc/testsuite/gcc.dg/c2x-complit-1.c
new file mode 100644
index 0000000..af92d4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-complit-1.c
@@ -0,0 +1,35 @@
+/* Test storage duration of compound literals in parameter lists for C2x. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int x;
+
+void f (int a[(int) { x }]);
+
+int *q;
+
+int
+fp (int *p)
+{
+ q = p;
+ return 1;
+}
+
+void
+g (int a, int b[fp ((int [2]) { a, a + 2 })])
+{
+ if (q[0] != a || q[1] != a + 2)
+ abort ();
+}
+
+int
+main (void)
+{
+ int t[1] = { 0 };
+ g (1, t);
+ g (2, t);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-concat-1.c b/gcc/testsuite/gcc.dg/c2x-concat-1.c
new file mode 100644
index 0000000..e92eaaf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-concat-1.c
@@ -0,0 +1,31 @@
+/* Test errors for bad string literal concatenation. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+void *pLU = L"" U""; /* { dg-error "non-standard concatenation" } */
+void *pL_U = L"" "" U""; /* { dg-error "non-standard concatenation" } */
+void *pLu = L"" u""; /* { dg-error "non-standard concatenation" } */
+void *pL_u = L"" "" u""; /* { dg-error "non-standard concatenation" } */
+void *pLu8 = L"" u8""; /* { dg-error "non-standard concatenation" } */
+void *pL_u8 = L"" "" u8""; /* { dg-error "non-standard concatenation" } */
+
+void *pUL = U"" L""; /* { dg-error "non-standard concatenation" } */
+void *pU_L = U"" "" L""; /* { dg-error "non-standard concatenation" } */
+void *pUu = U"" u""; /* { dg-error "non-standard concatenation" } */
+void *pU_u = U"" "" u""; /* { dg-error "non-standard concatenation" } */
+void *pUu8 = U"" u8""; /* { dg-error "non-standard concatenation" } */
+void *pU_u8 = U"" "" u8""; /* { dg-error "non-standard concatenation" } */
+
+void *puL = u"" L""; /* { dg-error "non-standard concatenation" } */
+void *pu_L = u"" "" L""; /* { dg-error "non-standard concatenation" } */
+void *puU = u"" U""; /* { dg-error "non-standard concatenation" } */
+void *pu_U = u"" "" U""; /* { dg-error "non-standard concatenation" } */
+void *puu8 = u"" u8""; /* { dg-error "non-standard concatenation" } */
+void *pu_u8 = u"" "" u8""; /* { dg-error "non-standard concatenation" } */
+
+void *pu8L = u8"" L""; /* { dg-error "non-standard concatenation" } */
+void *pu8_L = u8"" "" L""; /* { dg-error "non-standard concatenation" } */
+void *pu8U = u8"" U""; /* { dg-error "non-standard concatenation" } */
+void *pu8_U = u8"" "" U""; /* { dg-error "non-standard concatenation" } */
+void *pu8u = u8"" u""; /* { dg-error "non-standard concatenation" } */
+void *pu8_u = u8"" "" u""; /* { dg-error "non-standard concatenation" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-ucn-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-ucn-1.c
new file mode 100644
index 0000000..a4998ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/c2x-ucn-1.c
@@ -0,0 +1,996 @@
+/* Test characters not permitted in UCNs in C2x. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if U'\u0000' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu0 = U"\u0000"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000000' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU0 = U"\U00000000"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0001' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu1 = U"\u0001"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000001' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU1 = U"\U00000001"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0002' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu2 = U"\u0002"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000002' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU2 = U"\U00000002"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0003' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu3 = U"\u0003"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000003' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU3 = U"\U00000003"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0004' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu4 = U"\u0004"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000004' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU4 = U"\U00000004"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0005' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu5 = U"\u0005"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000005' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU5 = U"\U00000005"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0006' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu6 = U"\u0006"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000006' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU6 = U"\U00000006"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0007' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu7 = U"\u0007"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000007' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU7 = U"\U00000007"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0008' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu8 = U"\u0008"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000008' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU8 = U"\U00000008"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0009' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu9 = U"\u0009"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000009' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU9 = U"\U00000009"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu10 = U"\u000a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU10 = U"\U0000000a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu11 = U"\u000b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU11 = U"\U0000000b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu12 = U"\u000c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU12 = U"\U0000000c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu13 = U"\u000d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU13 = U"\U0000000d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu14 = U"\u000e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU14 = U"\U0000000e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u000f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu15 = U"\u000f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000000f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU15 = U"\U0000000f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0010' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu16 = U"\u0010"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000010' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU16 = U"\U00000010"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0011' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu17 = U"\u0011"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000011' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU17 = U"\U00000011"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0012' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu18 = U"\u0012"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000012' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU18 = U"\U00000012"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0013' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu19 = U"\u0013"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000013' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU19 = U"\U00000013"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0014' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu20 = U"\u0014"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000014' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU20 = U"\U00000014"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0015' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu21 = U"\u0015"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000015' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU21 = U"\U00000015"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0016' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu22 = U"\u0016"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000016' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU22 = U"\U00000016"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0017' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu23 = U"\u0017"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000017' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU23 = U"\U00000017"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0018' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu24 = U"\u0018"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000018' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU24 = U"\U00000018"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0019' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu25 = U"\u0019"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000019' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU25 = U"\U00000019"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu26 = U"\u001a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU26 = U"\U0000001a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu27 = U"\u001b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU27 = U"\U0000001b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu28 = U"\u001c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU28 = U"\U0000001c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu29 = U"\u001d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU29 = U"\U0000001d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu30 = U"\u001e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU30 = U"\U0000001e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u001f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu31 = U"\u001f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000001f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU31 = U"\U0000001f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0020' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu32 = U"\u0020"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000020' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU32 = U"\U00000020"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0021' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu33 = U"\u0021"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000021' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU33 = U"\U00000021"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0022' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu34 = U"\u0022"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000022' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU34 = U"\U00000022"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0023' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu35 = U"\u0023"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000023' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU35 = U"\U00000023"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0024'
+#endif
+void *tu36 = U"\u0024";
+#if U'\U00000024'
+#endif
+void *tU36 = U"\U00000024";
+#if U'\u0025' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu37 = U"\u0025"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000025' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU37 = U"\U00000025"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0026' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu38 = U"\u0026"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000026' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU38 = U"\U00000026"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0027' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu39 = U"\u0027"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000027' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU39 = U"\U00000027"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0028' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu40 = U"\u0028"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000028' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU40 = U"\U00000028"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0029' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu41 = U"\u0029"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000029' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU41 = U"\U00000029"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu42 = U"\u002a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU42 = U"\U0000002a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu43 = U"\u002b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU43 = U"\U0000002b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu44 = U"\u002c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU44 = U"\U0000002c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu45 = U"\u002d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU45 = U"\U0000002d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu46 = U"\u002e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU46 = U"\U0000002e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u002f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu47 = U"\u002f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000002f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU47 = U"\U0000002f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0030' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu48 = U"\u0030"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000030' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU48 = U"\U00000030"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0031' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu49 = U"\u0031"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000031' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU49 = U"\U00000031"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0032' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu50 = U"\u0032"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000032' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU50 = U"\U00000032"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0033' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu51 = U"\u0033"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000033' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU51 = U"\U00000033"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0034' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu52 = U"\u0034"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000034' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU52 = U"\U00000034"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0035' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu53 = U"\u0035"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000035' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU53 = U"\U00000035"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0036' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu54 = U"\u0036"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000036' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU54 = U"\U00000036"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0037' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu55 = U"\u0037"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000037' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU55 = U"\U00000037"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0038' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu56 = U"\u0038"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000038' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU56 = U"\U00000038"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0039' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu57 = U"\u0039"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000039' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU57 = U"\U00000039"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu58 = U"\u003a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU58 = U"\U0000003a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu59 = U"\u003b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU59 = U"\U0000003b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu60 = U"\u003c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU60 = U"\U0000003c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu61 = U"\u003d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU61 = U"\U0000003d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu62 = U"\u003e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU62 = U"\U0000003e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u003f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu63 = U"\u003f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000003f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU63 = U"\U0000003f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0040'
+#endif
+void *tu64 = U"\u0040";
+#if U'\U00000040'
+#endif
+void *tU64 = U"\U00000040";
+#if U'\u0041' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu65 = U"\u0041"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000041' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU65 = U"\U00000041"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0042' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu66 = U"\u0042"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000042' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU66 = U"\U00000042"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0043' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu67 = U"\u0043"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000043' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU67 = U"\U00000043"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0044' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu68 = U"\u0044"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000044' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU68 = U"\U00000044"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0045' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu69 = U"\u0045"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000045' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU69 = U"\U00000045"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0046' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu70 = U"\u0046"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000046' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU70 = U"\U00000046"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0047' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu71 = U"\u0047"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000047' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU71 = U"\U00000047"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0048' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu72 = U"\u0048"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000048' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU72 = U"\U00000048"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0049' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu73 = U"\u0049"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000049' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU73 = U"\U00000049"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu74 = U"\u004a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU74 = U"\U0000004a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu75 = U"\u004b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU75 = U"\U0000004b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu76 = U"\u004c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU76 = U"\U0000004c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu77 = U"\u004d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU77 = U"\U0000004d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu78 = U"\u004e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU78 = U"\U0000004e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u004f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu79 = U"\u004f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000004f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU79 = U"\U0000004f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0050' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu80 = U"\u0050"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000050' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU80 = U"\U00000050"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0051' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu81 = U"\u0051"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000051' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU81 = U"\U00000051"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0052' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu82 = U"\u0052"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000052' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU82 = U"\U00000052"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0053' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu83 = U"\u0053"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000053' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU83 = U"\U00000053"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0054' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu84 = U"\u0054"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000054' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU84 = U"\U00000054"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0055' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu85 = U"\u0055"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000055' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU85 = U"\U00000055"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0056' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu86 = U"\u0056"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000056' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU86 = U"\U00000056"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0057' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu87 = U"\u0057"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000057' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU87 = U"\U00000057"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0058' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu88 = U"\u0058"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000058' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU88 = U"\U00000058"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0059' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu89 = U"\u0059"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000059' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU89 = U"\U00000059"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu90 = U"\u005a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU90 = U"\U0000005a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu91 = U"\u005b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU91 = U"\U0000005b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu92 = U"\u005c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU92 = U"\U0000005c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu93 = U"\u005d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU93 = U"\U0000005d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu94 = U"\u005e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU94 = U"\U0000005e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u005f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu95 = U"\u005f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000005f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU95 = U"\U0000005f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0060'
+#endif
+void *tu96 = U"\u0060";
+#if U'\U00000060'
+#endif
+void *tU96 = U"\U00000060";
+#if U'\u0061' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu97 = U"\u0061"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000061' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU97 = U"\U00000061"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0062' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu98 = U"\u0062"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000062' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU98 = U"\U00000062"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0063' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu99 = U"\u0063"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000063' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU99 = U"\U00000063"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0064' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu100 = U"\u0064"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000064' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU100 = U"\U00000064"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0065' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu101 = U"\u0065"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000065' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU101 = U"\U00000065"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0066' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu102 = U"\u0066"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000066' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU102 = U"\U00000066"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0067' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu103 = U"\u0067"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000067' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU103 = U"\U00000067"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0068' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu104 = U"\u0068"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000068' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU104 = U"\U00000068"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0069' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu105 = U"\u0069"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000069' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU105 = U"\U00000069"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu106 = U"\u006a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU106 = U"\U0000006a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu107 = U"\u006b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU107 = U"\U0000006b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu108 = U"\u006c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU108 = U"\U0000006c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu109 = U"\u006d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU109 = U"\U0000006d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu110 = U"\u006e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU110 = U"\U0000006e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u006f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu111 = U"\u006f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000006f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU111 = U"\U0000006f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0070' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu112 = U"\u0070"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000070' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU112 = U"\U00000070"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0071' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu113 = U"\u0071"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000071' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU113 = U"\U00000071"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0072' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu114 = U"\u0072"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000072' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU114 = U"\U00000072"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0073' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu115 = U"\u0073"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000073' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU115 = U"\U00000073"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0074' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu116 = U"\u0074"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000074' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU116 = U"\U00000074"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0075' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu117 = U"\u0075"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000075' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU117 = U"\U00000075"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0076' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu118 = U"\u0076"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000076' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU118 = U"\U00000076"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0077' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu119 = U"\u0077"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000077' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU119 = U"\U00000077"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0078' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu120 = U"\u0078"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000078' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU120 = U"\U00000078"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0079' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu121 = U"\u0079"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000079' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU121 = U"\U00000079"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu122 = U"\u007a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU122 = U"\U0000007a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu123 = U"\u007b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU123 = U"\U0000007b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu124 = U"\u007c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU124 = U"\U0000007c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu125 = U"\u007d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU125 = U"\U0000007d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu126 = U"\u007e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU126 = U"\U0000007e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u007f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu127 = U"\u007f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000007f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU127 = U"\U0000007f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0080' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu128 = U"\u0080"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000080' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU128 = U"\U00000080"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0081' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu129 = U"\u0081"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000081' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU129 = U"\U00000081"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0082' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu130 = U"\u0082"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000082' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU130 = U"\U00000082"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0083' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu131 = U"\u0083"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000083' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU131 = U"\U00000083"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0084' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu132 = U"\u0084"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000084' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU132 = U"\U00000084"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0085' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu133 = U"\u0085"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000085' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU133 = U"\U00000085"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0086' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu134 = U"\u0086"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000086' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU134 = U"\U00000086"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0087' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu135 = U"\u0087"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000087' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU135 = U"\U00000087"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0088' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu136 = U"\u0088"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000088' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU136 = U"\U00000088"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0089' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu137 = U"\u0089"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000089' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU137 = U"\U00000089"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu138 = U"\u008a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU138 = U"\U0000008a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu139 = U"\u008b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU139 = U"\U0000008b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu140 = U"\u008c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU140 = U"\U0000008c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu141 = U"\u008d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU141 = U"\U0000008d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu142 = U"\u008e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU142 = U"\U0000008e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u008f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu143 = U"\u008f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000008f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU143 = U"\U0000008f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0090' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu144 = U"\u0090"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000090' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU144 = U"\U00000090"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0091' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu145 = U"\u0091"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000091' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU145 = U"\U00000091"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0092' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu146 = U"\u0092"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000092' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU146 = U"\U00000092"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0093' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu147 = U"\u0093"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000093' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU147 = U"\U00000093"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0094' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu148 = U"\u0094"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000094' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU148 = U"\U00000094"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0095' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu149 = U"\u0095"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000095' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU149 = U"\U00000095"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0096' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu150 = U"\u0096"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000096' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU150 = U"\U00000096"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0097' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu151 = U"\u0097"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000097' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU151 = U"\U00000097"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0098' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu152 = U"\u0098"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000098' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU152 = U"\U00000098"; /* { dg-error "is not a valid universal character" } */
+#if U'\u0099' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu153 = U"\u0099"; /* { dg-error "is not a valid universal character" } */
+#if U'\U00000099' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU153 = U"\U00000099"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu154 = U"\u009a"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009a' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU154 = U"\U0000009a"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu155 = U"\u009b"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009b' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU155 = U"\U0000009b"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu156 = U"\u009c"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009c' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU156 = U"\U0000009c"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu157 = U"\u009d"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009d' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU157 = U"\U0000009d"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu158 = U"\u009e"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009e' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU158 = U"\U0000009e"; /* { dg-error "is not a valid universal character" } */
+#if U'\u009f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tu159 = U"\u009f"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000009f' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tU159 = U"\U0000009f"; /* { dg-error "is not a valid universal character" } */
+#if U'\u00a0'
+#endif
+void *tu160 = U"\u00a0";
+#if U'\U000000a0'
+#endif
+void *tU160 = U"\U000000a0";
+
+#if U'\ud800' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tud800 = U"\ud800"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000d800' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tUd800 = U"\U0000d800"; /* { dg-error "is not a valid universal character" } */
+
+#if U'\udfff' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tudfff = U"\udfff"; /* { dg-error "is not a valid universal character" } */
+#if U'\U0000dfff' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tUdfff = U"\U0000dfff"; /* { dg-error "is not a valid universal character" } */
+
+#if U'\U0010ffff'
+#endif
+void *tU10ffff = U"\U0010ffff";
+
+#if U'\U00110000' /* { dg-error "is outside the UCS codespace" } */
+#endif
+void *tU110000 = U"\U00110000"; /* { dg-error "is outside the UCS codespace" } */
+
+#if U'\Uffffffff' /* { dg-error "is not a valid universal character" } */
+#endif
+void *tUffffffff = U"\Uffffffff"; /* { dg-error "is not a valid universal character" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr106967.c b/gcc/testsuite/gcc.dg/tree-ssa/pr106967.c
new file mode 100644
index 0000000..bff2795
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr106967.c
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-options "-O2 -ffinite-math-only -fno-trapping-math -fno-tree-dominator-opts" }
+
+void
+foo (float x, int *y)
+{
+ int i;
+ float sum2 = 0.0;
+
+ for (i = 0; i < *y; ++i)
+ sum2 += x;
+
+ sum2 = 1.0 / sum2;
+ if (sum2 * 0.0 < 5.E-5)
+ *y = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c
new file mode 100644
index 0000000..5010aed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107009.c
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-dom2-alias" }
+
+typedef __SIZE_TYPE__ size_t;
+
+void saxpy(size_t n)
+{
+ if (n == 0 || n % 8 != 0)
+ __builtin_unreachable();
+
+ extern void foobar (size_t n);
+ foobar (n);
+}
+
+// { dg-final { scan-tree-dump "NONZERO.*fff8" "dom2" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c
new file mode 100644
index 0000000..ead7654
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-100.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+float bar, baz;
+void foo (int *p, int n)
+{
+ *p = 0;
+ do
+ {
+ bar = 1.;
+ /* When iterating we should have optimistically value-numbered
+ *p to zero, on the second iteration we have to prove the
+ store below does not affect the value of this load though.
+ We can compare the stored value against the value from the
+ previous iteration instead relying on a non-walking lookup. */
+ if (*p)
+ {
+ baz = 2.;
+ *p = 0;
+ }
+ }
+ while (--n);
+}
+
+/* { dg-final { scan-tree-dump-not "baz" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tsan/pr106984.c b/gcc/testsuite/gcc.dg/tsan/pr106984.c
new file mode 100644
index 0000000..69cf83d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tsan/pr106984.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=thread" } */
+
+int svcsw (int *ptr, int oldval, int newval)
+{
+ return __sync_val_compare_and_swap (ptr, oldval, newval);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c
index 9361821..6eb0240 100644
--- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c
+++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c
@@ -38,4 +38,4 @@ int main (int argc, char **argv)
return 0;
}
-/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x2.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x2.c
index 92a139b..f933102 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x2.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x2.c
@@ -1,6 +1,6 @@
/* We haven't implemented these intrinsics for arm yet. */
-/* { dg-xfail-if "" { arm*-*-* } } */
/* { dg-do run } */
+/* { dg-skip-if "unsupported" { arm*-*-* } } */
/* { dg-options "-O3" } */
#include <arm_neon.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x3.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x3.c
index 6ddd507..b20dec0 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x3.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x3.c
@@ -1,6 +1,6 @@
/* We haven't implemented these intrinsics for arm yet. */
-/* { dg-xfail-if "" { arm*-*-* } } */
/* { dg-do run } */
+/* { dg-skip-if "unsupported" { arm*-*-* } } */
/* { dg-options "-O3" } */
#include <arm_neon.h>
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c
index 451a0af..e59f845 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vld1x4.c
@@ -1,6 +1,6 @@
/* We haven't implemented these intrinsics for arm yet. */
-/* { dg-xfail-if "" { arm*-*-* } } */
/* { dg-do run } */
+/* { dg-skip-if "unsupported" { arm*-*-* } } */
/* { dg-options "-O3" } */
#include <arm_neon.h>
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
index 68378a5..7115b0a 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-load-1.c
@@ -14,6 +14,6 @@ avx_test (void)
c[i] = a[i] * b[i+3];
}
-/* { dg-final { scan-assembler-not "vmovups\[^\n\r]*movv8sf_internal/2" } } */
-/* { dg-final { scan-assembler "movv4sf_internal/2" } } */
+/* { dg-final { scan-assembler-not "vmovups\[^\n\r]*movv8sf_internal/3" } } */
+/* { dg-final { scan-assembler "movv4sf_internal/3" } } */
/* { dg-final { scan-assembler "vinsertf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
index d82aecf..4c71395 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c
@@ -17,6 +17,6 @@ avx_test (void)
d[i] = c[i] * 20.0;
}
-/* { dg-final { scan-assembler-not "vmovups.*movv8sf_internal/3" } } */
-/* { dg-final { scan-assembler "vmovups.*movv4sf_internal/3" } } */
+/* { dg-final { scan-assembler-not "vmovups.*movv8sf_internal/4" } } */
+/* { dg-final { scan-assembler "vmovups.*movv4sf_internal/4" } } */
/* { dg-final { scan-assembler "vextractf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
index be12529..4978c37 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-2.c
@@ -23,6 +23,6 @@ avx_test (void)
}
}
-/* { dg-final { scan-assembler-not "vmovdqu.*movv32qi_internal/3" } } */
-/* { dg-final { scan-assembler "vmovdqu.*movv16qi_internal/3" } } */
+/* { dg-final { scan-assembler-not "vmovdqu.*movv32qi_internal/4" } } */
+/* { dg-final { scan-assembler "vmovdqu.*movv16qi_internal/4" } } */
/* { dg-final { scan-assembler "vextract.128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
index 918028d..67635fb 100644
--- a/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
+++ b/gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic -fno-common" } */
+/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic -fno-common -mno-avx512f" } */
#define N 1024
@@ -17,6 +17,6 @@ avx_test (void)
d[i] = c[i] * 20.0;
}
-/* { dg-final { scan-assembler-not "vmovupd.*movv4df_internal/3" } } */
-/* { dg-final { scan-assembler "vmovupd.*movv2df_internal/3" } } */
+/* { dg-final { scan-assembler-not "vmovupd.*movv4df_internal/4" } } */
+/* { dg-final { scan-assembler "vmovupd.*movv2df_internal/4" } } */
/* { dg-final { scan-assembler "vextractf128" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr106963.c b/gcc/testsuite/gcc.target/i386/pr106963.c
new file mode 100644
index 0000000..9f2d20e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106963.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mno-avx2" } */
+
+void
+foo_neg_const (int *a)
+{
+ int i, b = 1;
+
+ for (i = 0; i < 1000; i++)
+ {
+ a[i] = b;
+ b = -b;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr106994.c b/gcc/testsuite/gcc.target/i386/pr106994.c
new file mode 100644
index 0000000..0803311
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106994.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=skylake -Ofast" } */
+
+typedef struct {
+ float ymin, ymax;
+} rctf;
+
+rctf view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked;
+float view2d_map_cur_using_maskUI_view2d_view_ortho_yofs;
+
+void BLI_rctf_translate();
+void glLoadIdentity();
+
+void
+view2d_map_cur_using_maskUI_view2d_view_ortho() {
+ BLI_rctf_translate(&view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked);
+ view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked.ymin =
+ __builtin_floor(view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked.ymin) -
+ view2d_map_cur_using_maskUI_view2d_view_ortho_yofs;
+ view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked.ymax =
+ __builtin_floor(view2d_map_cur_using_maskUI_view2d_view_ortho_curmasked.ymax) -
+ view2d_map_cur_using_maskUI_view2d_view_ortho_yofs;
+ glLoadIdentity();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-1.c b/gcc/testsuite/gcc.target/i386/pr53346-1.c
new file mode 100644
index 0000000..6d230da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-1.c
@@ -0,0 +1,70 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -O2 -mno-sse3" } */
+/* { dg-final { scan-assembler-times "shufps" 15 } } */
+/* { dg-final { scan-assembler-times "pshufd" 2 } } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+v4si
+__attribute__((noipa))
+foo (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 5, 3);
+}
+
+v4si
+__attribute__((noipa))
+foo1 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 5, 2, 3);
+}
+
+v4si
+__attribute__((noipa))
+foo2 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 3, 5);
+}
+
+v4si
+__attribute__((noipa))
+foo3 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 1, 4, 5, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo4 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 3, 6, 7, 5);
+}
+
+v4si
+__attribute__((noipa))
+foo5 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 7, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo6 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 3, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo7 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 3, 4, 6);
+}
+
+v4si
+__attribute__((noipa))
+foo8 (v4si a, v4si b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 6, 3);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-2.c b/gcc/testsuite/gcc.target/i386/pr53346-2.c
new file mode 100644
index 0000000..0c6c7b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-2.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+#include "pr53346-1.c"
+
+static void
+sse2_test ()
+{
+ v4si a = __extension__(v4si) { 0, 1, 2, 3 };
+ v4si b = __extension__(v4si) { 4, 5, 6, 7 };
+ v4si exp = __extension__(v4si) { 1, 2, 5, 3 };
+ v4si dest;
+ dest = foo (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 5, 2, 3 };
+ dest = foo1 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 2, 3, 5 };
+ dest = foo2 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 1, 4, 5, 6 };
+ dest = foo3 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 3, 6, 7, 5 };
+ dest = foo4 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 7, 6 };
+ dest = foo5 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 3, 6 };
+ dest = foo6 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 3, 4, 6 };
+ dest = foo7 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4si) { 2, 4, 6, 3 };
+ dest = foo8 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-3.c b/gcc/testsuite/gcc.target/i386/pr53346-3.c
new file mode 100644
index 0000000..0b204f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-3.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -O2 -mno-sse3" } */
+/* { dg-final { scan-assembler-times "shufps" 17 } } */
+
+typedef float v4sf __attribute__((vector_size(16)));
+
+v4sf
+__attribute__((noipa))
+foo (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 5, 3);
+}
+
+v4sf
+__attribute__((noipa))
+foo1 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 5, 2, 3);
+}
+
+v4sf
+__attribute__((noipa))
+foo2 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 2, 3, 5);
+}
+
+v4sf
+__attribute__((noipa))
+foo3 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 1, 4, 5, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo4 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 3, 6, 7, 5);
+}
+
+v4sf
+__attribute__((noipa))
+foo5 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 7, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo6 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 3, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo7 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 3, 4, 6);
+}
+
+v4sf
+__attribute__((noipa))
+foo8 (v4sf a, v4sf b)
+{
+ return __builtin_shufflevector (a, b, 2, 4, 6, 3);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr53346-4.c b/gcc/testsuite/gcc.target/i386/pr53346-4.c
new file mode 100644
index 0000000..9e4e45b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr53346-4.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+#include "pr53346-3.c"
+
+static void
+sse2_test ()
+{
+ v4sf a = __extension__(v4sf) { 0, 1, 2, 3 };
+ v4sf b = __extension__(v4sf) { 4, 5, 6, 7 };
+ v4sf exp = __extension__(v4sf) { 1, 2, 5, 3 };
+ v4sf dest;
+ dest = foo (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 5, 2, 3 };
+ dest = foo1 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 2, 3, 5 };
+ dest = foo2 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 1, 4, 5, 6 };
+ dest = foo3 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 3, 6, 7, 5 };
+ dest = foo4 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 7, 6 };
+ dest = foo5 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 3, 6 };
+ dest = foo6 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 3, 4, 6 };
+ dest = foo7 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+ exp = __extension__ (v4sf) { 2, 4, 6, 3 };
+ dest = foo8 (a, b);
+ if (__builtin_memcmp (&dest, &exp, 16))
+ __builtin_abort ();
+
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr94962-1.c b/gcc/testsuite/gcc.target/i386/pr94962-1.c
new file mode 100644
index 0000000..e3b0124
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr94962-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
+/* { dg-final { scan-assembler-times "vpcmpeqd\[ \\t\]+%xmm\[0-9\]" 1 } } */
+
+#include <immintrin.h>
+
+__m256i mask()
+{
+ return _mm256_zextsi128_si256(_mm_set1_epi8(-1));
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr94962-2.c b/gcc/testsuite/gcc.target/i386/pr94962-2.c
new file mode 100644
index 0000000..4e10e92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr94962-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
+/* { dg-final { scan-assembler-times "vpcmpeqd\[ \\t\]+%xmm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "vpcmpeqd\[ \\t\]+%ymm\[0-9\]" 1 } } */
+
+#include <immintrin.h>
+
+__m512i mask1()
+{
+ return _mm512_zextsi128_si512(_mm_set1_epi8(-1));
+}
+
+__m512i mask2()
+{
+ return _mm512_zextsi256_si512(_mm256_set1_epi8(-1));
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr94962-3.c b/gcc/testsuite/gcc.target/i386/pr94962-3.c
new file mode 100644
index 0000000..8d0b997
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr94962-3.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
+/* { dg-final { scan-assembler-times "vpcmpeqd\[ \\t\]+%ymm\[0-9\]" 4 } } */
+
+typedef long long __v8di __attribute__ ((__vector_size__ (64)));
+typedef int __v16si __attribute__ ((__vector_size__ (64)));
+typedef short __v32hi __attribute__ ((__vector_size__ (64)));
+typedef char __v64qi __attribute__ ((__vector_size__ (64)));
+typedef long long __m512i __attribute__ ((__vector_size__ (64), __may_alias__));
+
+__m512i
+__attribute__ ((noinline, noclone))
+foo1 ()
+{
+ return __extension__ (__m512i)(__v8di) { -1, -1, -1, -1,
+ 0, 0, 0, 0 };
+}
+
+__m512i
+__attribute__ ((noinline, noclone))
+foo2 ()
+{
+ return __extension__ (__m512i)(__v16si) { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+}
+
+__m512i
+__attribute__ ((noinline, noclone))
+foo3 ()
+{
+ return __extension__ (__m512i)(__v32hi) { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+}
+
+__m512i
+__attribute__ ((noinline, noclone))
+foo4 ()
+{
+ return __extension__ (__m512i)(__v64qi) { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr94962-4.c b/gcc/testsuite/gcc.target/i386/pr94962-4.c
new file mode 100644
index 0000000..5502c39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr94962-4.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler-not "vmovdqa" } } */
+/* { dg-final { scan-assembler-times "vpcmpeqd\[ \\t\]+%xmm\[0-9\]" 4 } } */
+
+typedef long long __v4di __attribute__ ((__vector_size__ (32)));
+typedef int __v8si __attribute__ ((__vector_size__ (32)));
+typedef short __v16hi __attribute__ ((__vector_size__ (32)));
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+typedef long long __m256i __attribute__ ((__vector_size__ (32), __may_alias__));
+
+__m256i
+__attribute__ ((noinline, noclone))
+foo1 ()
+{
+ return __extension__ (__m256i)(__v4di) { -1, -1, 0, 0 };
+}
+
+__m256i
+__attribute__ ((noinline, noclone))
+foo2 ()
+{
+ return __extension__ (__m256i)(__v8si) { -1, -1, -1, -1,
+ 0, 0, 0, 0 };
+}
+
+__m256i
+__attribute__ ((noinline, noclone))
+foo3 ()
+{
+ return __extension__ (__m256i)(__v16hi) { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+}
+
+__m256i
+__attribute__ ((noinline, noclone))
+foo4 ()
+{
+ return __extension__ (__m256i)(__v32qi) { -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 };
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr100645.c b/gcc/testsuite/gcc.target/powerpc/pr100645.c
new file mode 100644
index 0000000..c4e92cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr100645.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-mdejagnu-cpu=power6 -maltivec" } */
+
+/* This used to ICE. */
+
+typedef long long v2di __attribute__ ((vector_size (16)));
+
+v2di
+foo_v2di_l (v2di x)
+{
+ return __builtin_shuffle ((v2di){0, 0}, x, (v2di){3, 0});
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/pr96072.c b/gcc/testsuite/gcc.target/powerpc/pr96072.c
new file mode 100644
index 0000000..10341c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr96072.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O2" } */
+
+/* This used to ICE with the SYSV ABI (PR96072). */
+
+void
+he (int jn)
+{
+ {
+ int bh[jn];
+ if (jn != 0)
+ goto wa;
+ }
+wa:;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/ret-1.c b/gcc/testsuite/gcc.target/riscv/ret-1.c
new file mode 100644
index 0000000..28133aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/ret-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* This was extracted from coremark. */
+
+
+typedef signed short ee_s16;
+typedef struct list_data_s
+{
+ ee_s16 data16;
+ ee_s16 idx;
+} list_data;
+
+typedef struct list_head_s
+{
+ struct list_head_s *next;
+ struct list_data_s *info;
+} list_head;
+
+
+list_head *
+core_list_find(list_head *list, list_data *info)
+{
+ if (info->idx >= 0)
+ {
+ while (list && (list->info->idx != info->idx))
+ list = list->next;
+ return list;
+ }
+ else
+ {
+ while (list && ((list->info->data16 & 0xff) != info->data16))
+ list = list->next;
+ return list;
+ }
+}
+
+/* There is only one legitimate unconditional jump, so test for that,
+ which will catch the case where bb-reorder leaves a jump to a ret
+ in the IL. */
+/* { dg-final { scan-assembler-times "jump" 1 } } */
+
diff --git a/gcc/testsuite/gfortran.dg/PR100103.f90 b/gcc/testsuite/gfortran.dg/PR100103.f90
new file mode 100644
index 0000000..2140561
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100103.f90
@@ -0,0 +1,76 @@
+! { dg-do run }
+!
+! Test the fix for PR100103
+!
+
+program main_p
+ implicit none
+
+ integer :: i
+ integer, parameter :: n = 11
+
+ type :: foo_t
+ integer :: i
+ end type foo_t
+
+ type(foo_t), parameter :: a(*) = [(foo_t(i), i=1,n)]
+
+ type(foo_t), allocatable :: bar_d(:)
+ class(foo_t), allocatable :: bar_p(:)
+ class(*), allocatable :: bar_u(:)
+
+
+ call foo_d(bar_d)
+ if(.not.allocated(bar_d)) stop 1
+ if(any(bar_d%i/=a%i)) stop 2
+ deallocate(bar_d)
+ call foo_p(bar_p)
+ if(.not.allocated(bar_p)) stop 3
+ if(any(bar_p%i/=a%i)) stop 4
+ deallocate(bar_p)
+ call foo_u(bar_u)
+ if(.not.allocated(bar_u)) stop 5
+ select type(bar_u)
+ type is(foo_t)
+ if(any(bar_u%i/=a%i)) stop 6
+ class default
+ stop 7
+ end select
+ deallocate(bar_u)
+
+contains
+
+ subroutine foo_d(that)
+ type(foo_t), allocatable, intent(out) :: that(..)
+
+ select rank(that)
+ rank(1)
+ that = a
+ rank default
+ stop 8
+ end select
+ end subroutine foo_d
+
+ subroutine foo_p(that)
+ class(foo_t), allocatable, intent(out) :: that(..)
+
+ select rank(that)
+ rank(1)
+ that = a
+ rank default
+ stop 9
+ end select
+ end subroutine foo_p
+
+ subroutine foo_u(that)
+ class(*), allocatable, intent(out) :: that(..)
+
+ select rank(that)
+ rank(1)
+ that = a
+ rank default
+ stop 10
+ end select
+ end subroutine foo_u
+
+end program main_p
diff --git a/gcc/testsuite/gfortran.dg/PR100132.f90 b/gcc/testsuite/gfortran.dg/PR100132.f90
new file mode 100644
index 0000000..78ae670
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100132.f90
@@ -0,0 +1,75 @@
+! { dg-do run }
+!
+! Test the fix for PR100132
+!
+
+module main_m
+ implicit none
+
+ private
+
+ public :: &
+ foo_t
+
+ public :: &
+ set, &
+ get
+
+ type :: foo_t
+ integer :: i
+ end type foo_t
+
+ type(foo_t), save, pointer :: data => null()
+
+contains
+
+ subroutine set(this)
+ class(foo_t), pointer, intent(in) :: this
+
+ if(associated(data)) stop 1
+ data => this
+ end subroutine set
+
+ subroutine get(this)
+ type(foo_t), pointer, intent(out) :: this
+
+ if(.not.associated(data)) stop 4
+ this => data
+ nullify(data)
+ end subroutine get
+
+end module main_m
+
+program main_p
+
+ use :: main_m, only: &
+ foo_t, set, get
+
+ implicit none
+
+ integer, parameter :: n = 1000
+
+ type(foo_t), pointer :: ps
+ type(foo_t), target :: s
+ integer :: i, j, yay, nay
+
+ yay = 0
+ nay = 0
+ do i = 1, n
+ s%i = i
+ call set(s)
+ call get(ps)
+ if(.not.associated(ps)) stop 13
+ j = ps%i
+ if(i/=j) stop 14
+ if(i/=s%i) stop 15
+ if(ps%i/=s%i) stop 16
+ if(associated(ps, s))then
+ yay = yay + 1
+ else
+ nay = nay + 1
+ end if
+ end do
+ if((yay/=n).or.(nay/=0)) stop 17
+
+end program main_p
diff --git a/gcc/testsuite/gfortran.dg/associate_26a.f90 b/gcc/testsuite/gfortran.dg/associate_26a.f90
new file mode 100644
index 0000000..85aebeb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_26a.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib" }
+!
+! Test the fix for PR78152 and the followup in PR82868
+!
+! Contributed by <physiker@toast2.net>
+!
+program co_assoc
+ implicit none
+ integer, parameter :: p = 5
+ real, allocatable :: a(:,:)[:,:]
+ allocate (a(p,p)[2,*])
+ associate (i => a(1:p, 1:p))
+ end associate
+end program co_assoc
diff --git a/gcc/testsuite/gfortran.dg/assumed_type_16.f90 b/gcc/testsuite/gfortran.dg/assumed_type_16.f90
new file mode 100644
index 0000000..52d8ef5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_type_16.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-additional-options "-std=f2008" }
+!
+! PR fortran/104143
+!
+ interface
+ subroutine foo(x)
+ type(*) :: x(*) ! { dg-error "Fortran 2018: Assumed type" }
+ end
+ end interface
+ integer :: a
+ call foo(a) ! { dg-error "Type mismatch in argument" }
+ call foo((a)) ! { dg-error "Type mismatch in argument" }
+end
diff --git a/gcc/testsuite/gfortran.dg/assumed_type_17.f90 b/gcc/testsuite/gfortran.dg/assumed_type_17.f90
new file mode 100644
index 0000000..d6ccd30
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/assumed_type_17.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-additional-options "-std=f2018 -fdump-tree-original" }
+!
+! PR fortran/104143
+!
+ interface
+ subroutine foo(x)
+ type(*) :: x(*)
+ end
+ end interface
+ integer :: a
+ call foo(a)
+ call foo((a))
+end
+
+! { dg-final { scan-tree-dump-times "foo \\(&a\\);" 1 "original" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = a;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "foo \\(&D.\[0-9\]+\\);" 1 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/c-interop/c407b-2.f90 b/gcc/testsuite/gfortran.dg/c-interop/c407b-2.f90
index 4f9f6c7..49352fc 100644
--- a/gcc/testsuite/gfortran.dg/c-interop/c407b-2.f90
+++ b/gcc/testsuite/gfortran.dg/c-interop/c407b-2.f90
@@ -40,7 +40,7 @@ subroutine s0 (x)
call g (x, 1)
call f (x, 1) ! { dg-error "Type mismatch" }
- call h (x, 1) ! { dg-error "Rank mismatch" }
+ call h (x, 1) ! Scalar to type(*),dimension(*): Invalid in TS29113 but valid since F2018
end subroutine
! Check that you can't use an assumed-type array variable in an array
diff --git a/gcc/testsuite/gfortran.dg/ieee/rounding_3.f90 b/gcc/testsuite/gfortran.dg/ieee/rounding_3.f90
new file mode 100644
index 0000000..ff4e834
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/rounding_3.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+
+ ! Test IEEE_GET_ROUNDING_MODE and IEEE_SET_ROUNDING_MODE
+ ! with a RADIX argument
+ use, intrinsic :: ieee_arithmetic
+ implicit none
+
+ real :: sx1
+ type(ieee_round_type) :: r
+
+ if (ieee_support_rounding(ieee_up, sx1) .and. &
+ ieee_support_rounding(ieee_down, sx1)) then
+
+ call ieee_set_rounding_mode(ieee_up)
+ call ieee_get_rounding_mode(r)
+ if (r /= ieee_up) stop 1
+
+ call ieee_set_rounding_mode(ieee_down, radix=2)
+ call ieee_get_rounding_mode(r, radix=2)
+ if (r /= ieee_down) stop 2
+
+ call ieee_set_rounding_mode(ieee_up, radix=10)
+ call ieee_get_rounding_mode(r, radix=2)
+ if (r /= ieee_down) stop 3
+ end if
+
+end
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_10.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_10.f90
new file mode 100644
index 0000000..d8bc1bb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_10.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes in the case of non-polymorphic derived type arguments:
+! - one clobber to be emitted in the caller before calls to FOO in the *.original dump,
+! - no clobber to be emitted in the caller before calls to BAR in the *.original dump,
+! - the initialization constants to be optimized away in the *.optimized dump.
+
+module x
+ implicit none
+ type :: t
+ integer :: c
+ end type t
+ type, extends(t) :: u
+ integer :: d
+ end type u
+contains
+ subroutine foo(a)
+ type(t), intent(out) :: a
+ a = t(42)
+ end subroutine foo
+ subroutine bar(b)
+ class(t), intent(out) :: b
+ b%c = 24
+ end subroutine bar
+end module x
+
+program main
+ use x
+ implicit none
+ type(t) :: tc
+ type(u) :: uc, ud
+ class(t), allocatable :: te, tf
+
+ tc = t(123456789)
+ call foo(tc)
+ if (tc%c /= 42) stop 1
+
+ uc = u(987654321, 0)
+ call foo(uc%t)
+ if (uc%c /= 42) stop 2
+ if (uc%d /= 0) stop 3
+
+ ud = u(11223344, 0)
+ call bar(ud)
+ if (ud%c /= 24) stop 4
+
+ te = t(55667788)
+ call foo(te)
+ if (te%c /= 42) stop 5
+
+ tf = t(99887766)
+ call bar(tf)
+ if (tf%c /= 24) stop 6
+
+end program main
+
+! We don't support class descriptors, neither derived type components, so there is a clobber for tc only;
+! no clobber for uc, ud, te, tf.
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "tc = {CLOBBER};" "original" } }
+
+! There is a clobber for tc, so we should manage to optimize away the associated initialization constant (but not other
+! initialization constants).
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_4.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_4.f90
new file mode 100644
index 0000000..effbaa1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_4.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+!
+! PR fortran/106817
+! Check that for an actual argument whose dummy is INTENT(OUT),
+! the clobber that is emitted in the caller before a procedure call
+! happens after any expression depending on the argument value has been
+! evaluated.
+!
+
+module m
+ implicit none
+contains
+ subroutine copy1(out, in)
+ integer, intent(in) :: in
+ integer, intent(out) :: out
+ out = in
+ end subroutine copy1
+ subroutine copy2(in, out)
+ integer, intent(in) :: in
+ integer, intent(out) :: out
+ out = in
+ end subroutine copy2
+end module m
+
+program p
+ use m
+ implicit none
+ integer :: a, b
+
+ ! Clobbering of a should happen after a+1 has been evaluated.
+ a = 3
+ call copy1(a, a+1)
+ if (a /= 4) stop 1
+
+ ! Clobbering order does not depend on the order of arguments.
+ ! It should also come last with reversed arguments.
+ b = 12
+ call copy2(b+1, b)
+ if (b /= 13) stop 2
+
+end program p
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_5.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_5.f90
new file mode 100644
index 0000000..2f184bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_5.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/105012
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before the call to Y in the *.original dump, and the
+! initialization constant to be optimized away in the *.optimized dump,
+! despite the non-explicit interface if the subroutine with the INTENT(OUT)
+! is declared in the same file.
+
+SUBROUTINE Y (Z)
+ integer, intent(out) :: Z
+ Z = 42
+END SUBROUTINE Y
+PROGRAM TEST
+ integer :: X
+ X = 123456789
+ CALL Y (X)
+ if (X.ne.42) STOP 1
+END PROGRAM
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "x = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_6.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_6.f90
new file mode 100644
index 0000000..72fec3d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_6.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constant to be optimized away in the *.optimized dump,
+! in the case of an argument passed by reference to the caller.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer(kind=4), intent(out) :: a
+ a = 42
+ end subroutine foo
+ subroutine bar(b)
+ integer(kind=4) :: b
+ b = 123456789
+ call foo(b)
+ end subroutine bar
+end module x
+
+program main
+ use x
+ implicit none
+ integer(kind=4) :: c
+ call bar(c)
+ if (c /= 42) stop 1
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "\\*\\\(integer\\\(kind=4\\\) \\*\\\) b = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_7.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_7.f90
new file mode 100644
index 0000000..c2f2192
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_7.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of SAVE variables.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer :: c = 0
+
+ ! implicit SAVE attribute
+ c = 123456789
+ call foo(c)
+ if (c /= 42) stop 1
+
+ ! explicit SAVE attribute
+ call check_save_explicit
+
+contains
+ subroutine check_save_explicit
+ integer, save :: d
+ d = 987654321
+ call foo(d)
+ if (d /= 42) stop 2
+ end subroutine check_save_explicit
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "c = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "d = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_8.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_8.f90
new file mode 100644
index 0000000..4336fce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_8.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of associate variables.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer :: c1, c2
+
+ c1 = 123456789
+ associate (d1 => c1)
+ call foo(d1)
+ if (d1 /= 42) stop 1
+ end associate
+ if (c1 /= 42) stop 2
+
+ c2 = 0
+ associate (d2 => c2)
+ d2 = 987654321
+ call foo(d2)
+ if (d2 /= 42) stop 3
+ end associate
+ if (c2 /= 42) stop 4
+
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "d1 = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "\\*d2 = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_optimize_9.f90 b/gcc/testsuite/gfortran.dg/intent_optimize_9.f90
new file mode 100644
index 0000000..0146dff
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_optimize_9.f90
@@ -0,0 +1,42 @@
+! { dg-do run }
+! { dg-additional-options "-fno-inline -fno-ipa-modref -fdump-tree-optimized -fdump-tree-original" }
+!
+! PR fortran/41453
+! Check that the INTENT(OUT) attribute causes one clobber to be emitted in
+! the caller before each call to FOO in the *.original dump, and the
+! initialization constants to be optimized away in the *.optimized dump,
+! in the case of scalar allocatables and pointers.
+
+module x
+implicit none
+contains
+ subroutine foo(a)
+ integer, intent(out) :: a
+ a = 42
+ end subroutine foo
+end module x
+
+program main
+ use x
+ implicit none
+ integer, allocatable :: ca
+ integer, target :: ct
+ integer, pointer :: cp
+
+ allocate(ca)
+ ca = 123456789
+ call foo(ca)
+ if (ca /= 42) stop 1
+ deallocate(ca)
+
+ ct = 987654321
+ cp => ct
+ call foo(cp)
+ if (ct /= 42) stop 2
+end program main
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 2 "original" } }
+! { dg-final { scan-tree-dump "\\*ca = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump "\\*cp = {CLOBBER};" "original" } }
+! { dg-final { scan-tree-dump-not "123456789" "optimized" { target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "987654321" "optimized" { target __OPTIMIZE__ } } }
diff --git a/gcc/testsuite/gfortran.dg/intent_out_15.f90 b/gcc/testsuite/gfortran.dg/intent_out_15.f90
new file mode 100644
index 0000000..64334e6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_out_15.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/105012
+! The following case was triggering an ICE because of a clobber
+! on the DERFC function decl instead of its result.
+
+module error_function
+integer, parameter :: r8 = selected_real_kind(12) ! 8 byte real
+contains
+SUBROUTINE CALERF_r8(ARG, RESULT, JINT)
+ integer, parameter :: rk = r8
+ real(rk), intent(in) :: arg
+ real(rk), intent(out) :: result
+ IF (Y .LE. THRESH) THEN
+ END IF
+end SUBROUTINE CALERF_r8
+FUNCTION DERFC(X)
+ integer, parameter :: rk = r8 ! 8 byte real
+ real(rk), intent(in) :: X
+ real(rk) :: DERFC
+ CALL CALERF_r8(X, DERFC, JINT)
+END FUNCTION DERFC
+end module error_function
+
+! { dg-final { scan-tree-dump-times "CLOBBER" 1 "original" } }
+! { dg-final { scan-tree-dump "__result_derfc = {CLOBBER};" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/pr106985.f90 b/gcc/testsuite/gfortran.dg/pr106985.f90
new file mode 100644
index 0000000..f4ed925
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr106985.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR fortran/106985 - ICE in gfc_simplify_expr
+! Contributed by G.Steinmetz
+
+program p
+ integer, parameter :: a(2) = 1
+ integer, parameter :: b = a(2) + b ! { dg-error "before its definition is complete" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr106986.f90 b/gcc/testsuite/gfortran.dg/pr106986.f90
new file mode 100644
index 0000000..a309b25
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr106986.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR fortran/106986 - ICE in simplify_findloc_nodim
+! Contributed by G.Steinmetz
+
+program p
+ integer, parameter :: a(:) = [1] ! { dg-error "deferred shape" }
+ print *, findloc (a, 1)
+end
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index a80630b..7c9dcfc 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -803,7 +803,12 @@ proc check_function_body { functions name body_regexp } {
if { ![info exists up_functions($name)] } {
return 0
}
- return [regexp "^$body_regexp\$" $up_functions($name)]
+ set fn_res [regexp "^$body_regexp\$" $up_functions($name)]
+ if { !$fn_res } {
+ verbose -log "body: $body_regexp"
+ verbose -log "against: $up_functions($name)"
+ }
+ return $fn_res
}
# Check the implementations of functions against expected output. Used as:
diff --git a/gcc/testsuite/selftests/riscv/empty-func.rtl b/gcc/testsuite/selftests/riscv/empty-func.rtl
new file mode 100644
index 0000000..32bcf72
--- /dev/null
+++ b/gcc/testsuite/selftests/riscv/empty-func.rtl
@@ -0,0 +1,8 @@
+(function "func"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index ff9327f..91bfb619d 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -594,7 +594,8 @@ compute_distributive_range (tree type, value_range &op0_range,
if (result_range)
{
range_op_handler op (code, type);
- op.fold_range (*result_range, type, op0_range, op1_range);
+ if (!op.fold_range (*result_range, type, op0_range, op1_range))
+ result_range->set_varying (type);
}
/* The distributive property guarantees that if TYPE is no narrower
@@ -642,7 +643,8 @@ compute_distributive_range (tree type, value_range &op0_range,
range_op_handler op (code, ssizetype);
bool saved_flag_wrapv = flag_wrapv;
flag_wrapv = 1;
- op.fold_range (wide_range, ssizetype, op0_range, op1_range);
+ if (!op.fold_range (wide_range, ssizetype, op0_range, op1_range))
+ wide_range.set_varying (ssizetype);;
flag_wrapv = saved_flag_wrapv;
if (wide_range.num_pairs () != 1 || !range_int_cst_p (&wide_range))
return false;
diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc
index 513e0c8..84bef79 100644
--- a/gcc/tree-ssa-dom.cc
+++ b/gcc/tree-ssa-dom.cc
@@ -1227,29 +1227,30 @@ void
dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb)
{
edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
-
if (!pred_e)
return;
gimple *stmt = last_stmt (pred_e->src);
+ if (!stmt
+ || gimple_code (stmt) != GIMPLE_COND
+ || !assert_unreachable_fallthru_edge_p (pred_e))
+ return;
+
tree name;
- if (stmt
- && gimple_code (stmt) == GIMPLE_COND
- && (name = gimple_cond_lhs (stmt))
- && TREE_CODE (name) == SSA_NAME
- && assert_unreachable_fallthru_edge_p (pred_e)
- && all_uses_feed_or_dominated_by_stmt (name, stmt))
- {
- Value_Range r (TREE_TYPE (name));
+ gori_compute &gori = m_ranger->gori ();
+ FOR_EACH_GORI_EXPORT_NAME (gori, pred_e->src, name)
+ if (all_uses_feed_or_dominated_by_stmt (name, stmt))
+ {
+ Value_Range r (TREE_TYPE (name));
- if (m_ranger->range_on_edge (r, pred_e, name)
- && !r.varying_p ()
- && !r.undefined_p ())
- {
- set_range_info (name, r);
- maybe_set_nonzero_bits (pred_e, name);
- }
- }
+ if (m_ranger->range_on_edge (r, pred_e, name)
+ && !r.varying_p ()
+ && !r.undefined_p ())
+ {
+ set_range_info (name, r);
+ maybe_set_nonzero_bits (pred_e, name);
+ }
+ }
}
/* Record any equivalences created by the incoming edge to BB into
diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 34cfd1a..2411ac7 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "backend.h"
@@ -45,6 +46,8 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-modref.h"
#include "target.h"
#include "tree-ssa-loop-niter.h"
+#include "cfgloop.h"
+#include "tree-data-ref.h"
/* This file implements dead store elimination.
@@ -937,6 +940,10 @@ contains_phi_arg (gphi *phi, tree arg)
return false;
}
+/* Hash map of the memory use in a GIMPLE assignment to its
+ data reference. If NULL data-ref analysis isn't used. */
+static hash_map<gimple *, data_reference_p> *dse_stmt_to_dr_map;
+
/* A helper of dse_optimize_stmt.
Given a GIMPLE_ASSIGN in STMT that writes to REF, classify it
according to downstream uses and defs. Sets *BY_CLOBBER_P to true
@@ -951,6 +958,8 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
gimple *temp;
int cnt = 0;
auto_bitmap visited;
+ std::unique_ptr<data_reference, void(*)(data_reference_p)>
+ dra (nullptr, free_data_ref);
if (by_clobber_p)
*by_clobber_p = true;
@@ -1019,6 +1028,28 @@ dse_classify_store (ao_ref *ref, gimple *stmt,
/* If the statement is a use the store is not dead. */
else if (ref_maybe_used_by_stmt_p (use_stmt, ref))
{
+ if (dse_stmt_to_dr_map
+ && ref->ref
+ && is_gimple_assign (use_stmt))
+ {
+ if (!dra)
+ dra.reset (create_data_ref (NULL, NULL, ref->ref, stmt,
+ false, false));
+ bool existed_p;
+ data_reference_p &drb
+ = dse_stmt_to_dr_map->get_or_insert (use_stmt, &existed_p);
+ if (!existed_p)
+ drb = create_data_ref (NULL, NULL,
+ gimple_assign_rhs1 (use_stmt),
+ use_stmt, false, false);
+ if (!dr_may_alias_p (dra.get (), drb, NULL))
+ {
+ if (gimple_vdef (use_stmt))
+ defs.safe_push (use_stmt);
+ continue;
+ }
+ }
+
/* Handle common cases where we can easily build an ao_ref
structure for USE_STMT and in doing so we find that the
references hit non-live bytes and thus can be ignored.
@@ -1535,14 +1566,21 @@ class pass_dse : public gimple_opt_pass
{
public:
pass_dse (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_dse, ctxt)
+ : gimple_opt_pass (pass_data_dse, ctxt), use_dr_analysis_p (false)
{}
/* opt_pass methods: */
opt_pass * clone () final override { return new pass_dse (m_ctxt); }
+ void set_pass_param (unsigned n, bool param) final override
+ {
+ gcc_assert (n == 0);
+ use_dr_analysis_p = param;
+ }
bool gate (function *) final override { return flag_tree_dse != 0; }
unsigned int execute (function *) final override;
+private:
+ bool use_dr_analysis_p;
}; // class pass_dse
unsigned int
@@ -1554,6 +1592,8 @@ pass_dse::execute (function *fun)
need_eh_cleanup = BITMAP_ALLOC (NULL);
need_ab_cleanup = BITMAP_ALLOC (NULL);
auto_sbitmap live_bytes (param_dse_max_object_size);
+ if (flag_expensive_optimizations && use_dr_analysis_p)
+ dse_stmt_to_dr_map = new hash_map<gimple *, data_reference_p>;
renumber_gimple_stmt_uids (fun);
@@ -1644,6 +1684,15 @@ pass_dse::execute (function *fun)
if (released_def)
free_numbers_of_iterations_estimates (fun);
+ if (flag_expensive_optimizations && use_dr_analysis_p)
+ {
+ for (auto i = dse_stmt_to_dr_map->begin ();
+ i != dse_stmt_to_dr_map->end (); ++i)
+ free_data_ref ((*i).second);
+ delete dse_stmt_to_dr_map;
+ dse_stmt_to_dr_map = NULL;
+ }
+
return todo;
}
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 74b8d8d..2cc2c0e 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -1803,7 +1803,8 @@ struct vn_walk_cb_data
vn_lookup_kind vn_walk_kind_, bool tbaa_p_, tree mask_,
bool redundant_store_removal_p_)
: vr (vr_), last_vuse_ptr (last_vuse_ptr_), last_vuse (NULL_TREE),
- mask (mask_), masked_result (NULL_TREE), vn_walk_kind (vn_walk_kind_),
+ mask (mask_), masked_result (NULL_TREE), same_val (NULL_TREE),
+ vn_walk_kind (vn_walk_kind_),
tbaa_p (tbaa_p_), redundant_store_removal_p (redundant_store_removal_p_),
saved_operands (vNULL), first_set (-2), first_base_set (-2),
known_ranges (NULL)
@@ -1864,6 +1865,7 @@ struct vn_walk_cb_data
tree last_vuse;
tree mask;
tree masked_result;
+ tree same_val;
vn_lookup_kind vn_walk_kind;
bool tbaa_p;
bool redundant_store_removal_p;
@@ -1902,6 +1904,8 @@ vn_walk_cb_data::finish (alias_set_type set, alias_set_type base_set, tree val)
masked_result = val;
return (void *) -1;
}
+ if (same_val && !operand_equal_p (val, same_val))
+ return (void *) -1;
vec<vn_reference_op_s> &operands
= saved_operands.exists () ? saved_operands : vr->operands;
return vn_reference_lookup_or_insert_for_pieces (last_vuse, set, base_set,
@@ -2675,36 +2679,61 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
and return the found value. */
if (is_gimple_reg_type (TREE_TYPE (lhs))
&& types_compatible_p (TREE_TYPE (lhs), vr->type)
- && (ref->ref || data->orig_ref.ref))
- {
- tree *saved_last_vuse_ptr = data->last_vuse_ptr;
- /* Do not update last_vuse_ptr in vn_reference_lookup_2. */
- data->last_vuse_ptr = NULL;
- tree saved_vuse = vr->vuse;
- hashval_t saved_hashcode = vr->hashcode;
- void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), data);
- /* Need to restore vr->vuse and vr->hashcode. */
- vr->vuse = saved_vuse;
- vr->hashcode = saved_hashcode;
- data->last_vuse_ptr = saved_last_vuse_ptr;
- if (res && res != (void *)-1)
+ && (ref->ref || data->orig_ref.ref)
+ && !data->mask
+ && data->partial_defs.is_empty ()
+ && multiple_p (get_object_alignment
+ (ref->ref ? ref->ref : data->orig_ref.ref),
+ ref->size)
+ && multiple_p (get_object_alignment (lhs), ref->size))
+ {
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ /* ??? We may not compare to ahead values which might be from
+ a different loop iteration but only to loop invariants. Use
+ CONSTANT_CLASS_P (unvalueized!) as conservative approximation.
+ The one-hop lookup below doesn't have this issue since there's
+ a virtual PHI before we ever reach a backedge to cross.
+ We can skip multiple defs as long as they are from the same
+ value though. */
+ if (data->same_val
+ && !operand_equal_p (data->same_val, rhs))
+ ;
+ else if (CONSTANT_CLASS_P (rhs))
{
- vn_reference_t vnresult = (vn_reference_t) res;
- tree rhs = gimple_assign_rhs1 (def_stmt);
- if (TREE_CODE (rhs) == SSA_NAME)
- rhs = SSA_VAL (rhs);
- if (vnresult->result
- && operand_equal_p (vnresult->result, rhs, 0)
- /* We have to honor our promise about union type punning
- and also support arbitrary overlaps with
- -fno-strict-aliasing. So simply resort to alignment to
- rule out overlaps. Do this check last because it is
- quite expensive compared to the hash-lookup above. */
- && multiple_p (get_object_alignment
- (ref->ref ? ref->ref : data->orig_ref.ref),
- ref->size)
- && multiple_p (get_object_alignment (lhs), ref->size))
- return res;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "Skipping possible redundant definition ");
+ print_gimple_stmt (dump_file, def_stmt, 0);
+ }
+ /* Delay the actual compare of the values to the end of the walk
+ but do not update last_vuse from here. */
+ data->last_vuse_ptr = NULL;
+ data->same_val = rhs;
+ return NULL;
+ }
+ else
+ {
+ tree *saved_last_vuse_ptr = data->last_vuse_ptr;
+ /* Do not update last_vuse_ptr in vn_reference_lookup_2. */
+ data->last_vuse_ptr = NULL;
+ tree saved_vuse = vr->vuse;
+ hashval_t saved_hashcode = vr->hashcode;
+ void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt),
+ data);
+ /* Need to restore vr->vuse and vr->hashcode. */
+ vr->vuse = saved_vuse;
+ vr->hashcode = saved_hashcode;
+ data->last_vuse_ptr = saved_last_vuse_ptr;
+ if (res && res != (void *)-1)
+ {
+ vn_reference_t vnresult = (vn_reference_t) res;
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = SSA_VAL (rhs);
+ if (vnresult->result
+ && operand_equal_p (vnresult->result, rhs, 0))
+ return res;
+ }
}
}
}
@@ -3798,6 +3827,14 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set,
if (ops_for_ref != shared_lookup_references)
ops_for_ref.release ();
gcc_checking_assert (vr1.operands == shared_lookup_references);
+ if (*vnresult
+ && data.same_val
+ && (!(*vnresult)->result
+ || !operand_equal_p ((*vnresult)->result, data.same_val)))
+ {
+ *vnresult = NULL;
+ return NULL_TREE;
+ }
}
if (*vnresult)
@@ -3913,6 +3950,10 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
if (wvnresult)
{
gcc_assert (mask == NULL_TREE);
+ if (data.same_val
+ && (!wvnresult->result
+ || !operand_equal_p (wvnresult->result, data.same_val)))
+ return NULL_TREE;
if (vnresult)
*vnresult = wvnresult;
return wvnresult->result;
@@ -4460,28 +4501,39 @@ vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
return vn_nary_op_insert_into (vno1, valid_info->nary);
}
+/* Return whether we can track a predicate valid when PRED_E is executed. */
+
+static bool
+can_track_predicate_on_edge (edge pred_e)
+{
+ /* ??? As we are currently recording a basic-block index in
+ vn_pval.valid_dominated_by_p and using dominance for the
+ validity check we cannot track predicates on all edges. */
+ if (single_pred_p (pred_e->dest))
+ return true;
+ /* Never record for backedges. */
+ if (pred_e->flags & EDGE_DFS_BACK)
+ return false;
+ /* When there's more than one predecessor we cannot track
+ predicate validity based on the destination block. The
+ exception is when all other incoming edges are backedges. */
+ edge_iterator ei;
+ edge e;
+ int cnt = 0;
+ FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
+ if (! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
+ cnt++;
+ return cnt == 1;
+}
+
static vn_nary_op_t
vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code,
tree type, tree *ops,
tree result, unsigned int value_id,
edge pred_e)
{
- /* ??? Currently tracking BBs. */
- if (! single_pred_p (pred_e->dest))
- {
- /* Never record for backedges. */
- if (pred_e->flags & EDGE_DFS_BACK)
- return NULL;
- edge_iterator ei;
- edge e;
- int cnt = 0;
- /* Ignore backedges. */
- FOR_EACH_EDGE (e, ei, pred_e->dest->preds)
- if (! dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
- cnt++;
- if (cnt != 1)
- return NULL;
- }
+ if (!can_track_predicate_on_edge (pred_e))
+ return NULL;
if (dump_file && (dump_flags & TDF_DETAILS)
/* ??? Fix dumping, but currently we only get comparisons. */
&& TREE_CODE_CLASS (code) == tcc_comparison)
diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
index 9725f50..2a8cfa3 100644
--- a/gcc/tree-ssa-threadbackward.cc
+++ b/gcc/tree-ssa-threadbackward.cc
@@ -435,28 +435,14 @@ back_threader::find_paths_to_names (basic_block bb, bitmap interesting,
}
/* For other local defs process their uses, amending
imports on the way. */
- else if (gassign *ass = dyn_cast <gassign *> (def_stmt))
+ else
{
tree ssa[3];
- if (range_op_handler (ass))
- {
- ssa[0] = gimple_range_ssa_p (gimple_range_operand1 (ass));
- ssa[1] = gimple_range_ssa_p (gimple_range_operand2 (ass));
- ssa[2] = NULL_TREE;
- }
- else if (gimple_assign_rhs_code (ass) == COND_EXPR)
- {
- ssa[0] = gimple_range_ssa_p (gimple_assign_rhs1 (ass));
- ssa[1] = gimple_range_ssa_p (gimple_assign_rhs2 (ass));
- ssa[2] = gimple_range_ssa_p (gimple_assign_rhs3 (ass));
- }
- else
- continue;
- for (unsigned j = 0; j < 3; ++j)
+ unsigned lim = gimple_range_ssa_names (ssa, 3, def_stmt);
+ for (unsigned j = 0; j < lim; ++j)
{
tree rhs = ssa[j];
if (rhs
- && TREE_CODE (rhs) == SSA_NAME
&& bitmap_set_bit (m_imports,
SSA_NAME_VERSION (rhs)))
{
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 9c434b6..aabdc6f 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -8356,8 +8356,11 @@ vect_create_nonlinear_iv_init (gimple_seq* stmts, tree init_expr,
sel[2 * i + 1] = i + nunits;
}
vec_perm_indices indices (sel, 2, nunits);
+ /* Don't use vect_gen_perm_mask_checked since can_vec_perm_const_p may
+ fail when vec_init is const vector. In that situation vec_perm is not
+ really needed. */
tree perm_mask_even
- = vect_gen_perm_mask_checked (vectype, indices);
+ = vect_gen_perm_mask_any (vectype, indices);
vec_init = gimple_build (stmts, VEC_PERM_EXPR,
vectype,
vec_init, vec_neg,
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index c3030a1..93482e5 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -1069,7 +1069,8 @@ range_fold_binary_expr (value_range *vr,
vr1.set_varying (expr_type);
vr0.normalize_addresses ();
vr1.normalize_addresses ();
- op.fold_range (*vr, expr_type, vr0, vr1);
+ if (!op.fold_range (*vr, expr_type, vr0, vr1))
+ vr->set_varying (expr_type);
}
/* Perform a unary operation on a range. */
@@ -1095,7 +1096,8 @@ range_fold_unary_expr (value_range *vr,
value_range vr0_cst (*vr0);
vr0_cst.normalize_addresses ();
- op.fold_range (*vr, expr_type, vr0_cst, value_range (expr_type));
+ if (!op.fold_range (*vr, expr_type, vr0_cst, value_range (expr_type)))
+ vr->set_varying (expr_type);
}
/* If the range of values taken by OP can be inferred after STMT executes,
diff --git a/gcc/tsan.cc b/gcc/tsan.cc
index 79d4582..2406527 100644
--- a/gcc/tsan.cc
+++ b/gcc/tsan.cc
@@ -620,15 +620,16 @@ instrument_builtin_call (gimple_stmt_iterator *gsi)
maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
if (tsan_atomic_table[i].action == val_cas && lhs)
{
- tree cond;
stmt = gsi_stmt (*gsi);
- g = gimple_build_assign (make_ssa_name (TREE_TYPE (t)), t);
+ tree t2 = make_ssa_name (TREE_TYPE (t));
+ g = gimple_build_assign (t2, t);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
t = make_ssa_name (TREE_TYPE (TREE_TYPE (decl)), stmt);
- cond = build2 (NE_EXPR, boolean_type_node, t,
- build_int_cst (TREE_TYPE (t), 0));
- g = gimple_build_assign (lhs, COND_EXPR, cond, args[1],
- gimple_assign_lhs (g));
+ tree cond = make_ssa_name (boolean_type_node);
+ g = gimple_build_assign (cond, NE_EXPR,
+ t, build_zero_cst (TREE_TYPE (t)));
+ gsi_insert_after (gsi, g, GSI_NEW_STMT);
+ g = gimple_build_assign (lhs, COND_EXPR, cond, args[1], t2);
gimple_call_set_lhs (stmt, t);
update_stmt (stmt);
gsi_insert_after (gsi, g, GSI_NEW_STMT);
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 0bdd670..296784b 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -252,7 +252,8 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
Value_Range r1 (TREE_TYPE (TREE_OPERAND (expr, 1)));
range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
range_of_expr (r1, TREE_OPERAND (expr, 1), stmt);
- op.fold_range (r, type, r0, r1);
+ if (!op.fold_range (r, type, r0, r1))
+ r.set_varying (type);
}
else
r.set_varying (type);
@@ -268,7 +269,8 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
Value_Range r1 (type);
r1.set_varying (type);
range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
- op.fold_range (r, type, r0, r1);
+ if (!op.fold_range (r, type, r0, r1))
+ r.set_varying (type);
}
else
r.set_varying (type);
diff --git a/gcc/value-range-pretty-print.cc b/gcc/value-range-pretty-print.cc
index eb74422..8cbe97b 100644
--- a/gcc/value-range-pretty-print.cc
+++ b/gcc/value-range-pretty-print.cc
@@ -117,6 +117,19 @@ vrange_printer::print_irange_bitmasks (const irange &r) const
pp_string (pp, buf);
}
+void
+vrange_printer::print_real_value (tree type, const REAL_VALUE_TYPE &r) const
+{
+ char s[100];
+ real_to_decimal_for_mode (s, &r, sizeof (s), 0, 1, TYPE_MODE (type));
+ pp_string (pp, s);
+ if (!DECIMAL_FLOAT_TYPE_P (type))
+ {
+ real_to_hexadecimal (s, &r, sizeof (s), 0, 1);
+ pp_printf (pp, " (%s)", s);
+ }
+}
+
// Print an frange.
void
@@ -141,11 +154,9 @@ vrange_printer::visit (const frange &r) const
bool has_endpoints = !r.known_isnan ();
if (has_endpoints)
{
- dump_generic_node (pp,
- build_real (type, r.lower_bound ()), 0, TDF_NONE, false);
+ print_real_value (type, r.lower_bound ());
pp_string (pp, ", ");
- dump_generic_node (pp,
- build_real (type, r.upper_bound ()), 0, TDF_NONE, false);
+ print_real_value (type, r.upper_bound ());
}
pp_character (pp, ']');
print_frange_nan (r);
diff --git a/gcc/value-range-pretty-print.h b/gcc/value-range-pretty-print.h
index 20c2659..a9ae5a7 100644
--- a/gcc/value-range-pretty-print.h
+++ b/gcc/value-range-pretty-print.h
@@ -32,6 +32,7 @@ private:
void print_irange_bound (const wide_int &w, tree type) const;
void print_irange_bitmasks (const irange &) const;
void print_frange_nan (const frange &) const;
+ void print_real_value (tree type, const REAL_VALUE_TYPE &r) const;
pretty_printer *pp;
};
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index a8e3bb3..754379a 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -258,15 +258,6 @@ frange::accept (const vrange_visitor &v) const
v.visit (*this);
}
-// Helper function to compare floats. Returns TRUE if op1 .CODE. op2
-// is nonzero.
-
-static inline bool
-tree_compare (tree_code code, tree op1, tree op2)
-{
- return !integer_zerop (fold_build2 (code, integer_type_node, op1, op2));
-}
-
// Flush denormal endpoints to the appropriate 0.0.
void
@@ -290,7 +281,9 @@ frange::flush_denormals_to_zero ()
// Setter for franges.
void
-frange::set (tree min, tree max, value_range_kind kind)
+frange::set (tree type,
+ const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
+ value_range_kind kind)
{
switch (kind)
{
@@ -299,7 +292,7 @@ frange::set (tree min, tree max, value_range_kind kind)
return;
case VR_VARYING:
case VR_ANTI_RANGE:
- set_varying (TREE_TYPE (min));
+ set_varying (type);
return;
case VR_RANGE:
break;
@@ -308,20 +301,23 @@ frange::set (tree min, tree max, value_range_kind kind)
}
// Handle NANs.
- if (real_isnan (TREE_REAL_CST_PTR (min)) || real_isnan (TREE_REAL_CST_PTR (max)))
+ if (real_isnan (&min) || real_isnan (&max))
{
- gcc_checking_assert (real_identical (TREE_REAL_CST_PTR (min),
- TREE_REAL_CST_PTR (max)));
- tree type = TREE_TYPE (min);
- bool sign = real_isneg (TREE_REAL_CST_PTR (min));
- set_nan (type, sign);
+ gcc_checking_assert (real_identical (&min, &max));
+ if (HONOR_NANS (type))
+ {
+ bool sign = real_isneg (&min);
+ set_nan (type, sign);
+ }
+ else
+ set_undefined ();
return;
}
m_kind = kind;
- m_type = TREE_TYPE (min);
- m_min = *TREE_REAL_CST_PTR (min);
- m_max = *TREE_REAL_CST_PTR (max);
+ m_type = type;
+ m_min = min;
+ m_max = max;
if (HONOR_NANS (m_type))
{
m_pos_nan = true;
@@ -333,8 +329,20 @@ frange::set (tree min, tree max, value_range_kind kind)
m_neg_nan = false;
}
+ // For -ffinite-math-only we can drop ranges outside the
+ // representable numbers to min/max for the type.
+ if (flag_finite_math_only)
+ {
+ REAL_VALUE_TYPE min_repr = frange_val_min (m_type);
+ REAL_VALUE_TYPE max_repr = frange_val_max (m_type);
+ if (real_less (&m_min, &min_repr))
+ m_min = min_repr;
+ if (real_less (&max_repr, &m_max))
+ m_max = max_repr;
+ }
+
// Check for swapped ranges.
- gcc_checking_assert (tree_compare (LE_EXPR, min, max));
+ gcc_checking_assert (real_compare (LE_EXPR, &min, &max));
normalize_kind ();
@@ -344,14 +352,11 @@ frange::set (tree min, tree max, value_range_kind kind)
verify_range ();
}
-// Setter for frange from REAL_VALUE_TYPE endpoints.
-
void
-frange::set (tree type,
- const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
- value_range_kind kind)
+frange::set (tree min, tree max, value_range_kind kind)
{
- set (build_real (type, min), build_real (type, max), kind);
+ set (TREE_TYPE (min),
+ *TREE_REAL_CST_PTR (min), *TREE_REAL_CST_PTR (max), kind);
}
// Normalize range to VARYING or UNDEFINED, or vice versa. Return
@@ -366,8 +371,8 @@ bool
frange::normalize_kind ()
{
if (m_kind == VR_RANGE
- && real_isinf (&m_min, 1)
- && real_isinf (&m_max, 0))
+ && frange_val_is_min (m_min, m_type)
+ && frange_val_is_max (m_max, m_type))
{
if (m_pos_nan && m_neg_nan)
{
@@ -380,8 +385,8 @@ frange::normalize_kind ()
if (!m_pos_nan || !m_neg_nan)
{
m_kind = VR_RANGE;
- m_min = dconstninf;
- m_max = dconstinf;
+ m_min = frange_val_min (m_type);
+ m_max = frange_val_max (m_type);
return true;
}
}
@@ -422,7 +427,7 @@ frange::combine_zeros (const frange &r, bool union_p)
if (maybe_isnan ())
m_kind = VR_NAN;
else
- m_kind = VR_UNDEFINED;
+ set_undefined ();
changed = true;
}
return changed;
@@ -506,7 +511,7 @@ frange::intersect_nans (const frange &r)
if (maybe_isnan ())
m_kind = VR_NAN;
else
- m_kind = VR_UNDEFINED;
+ set_undefined ();
if (flag_checking)
verify_range ();
return true;
@@ -558,7 +563,7 @@ frange::intersect (const vrange &v)
if (maybe_isnan ())
m_kind = VR_NAN;
else
- m_kind = VR_UNDEFINED;
+ set_undefined ();
if (flag_checking)
verify_range ();
return true;
@@ -696,13 +701,13 @@ frange::verify_range ()
switch (m_kind)
{
case VR_UNDEFINED:
- // m_type is ignored.
+ gcc_checking_assert (!m_type);
return;
case VR_VARYING:
gcc_checking_assert (m_type);
gcc_checking_assert (m_pos_nan && m_neg_nan);
- gcc_checking_assert (real_isinf (&m_min, 1));
- gcc_checking_assert (real_isinf (&m_max, 0));
+ gcc_checking_assert (frange_val_is_min (m_min, m_type));
+ gcc_checking_assert (frange_val_is_max (m_max, m_type));
return;
case VR_RANGE:
gcc_checking_assert (m_type);
@@ -727,7 +732,8 @@ frange::verify_range ()
// If all the properties are clear, we better not span the entire
// domain, because that would make us varying.
if (m_pos_nan && m_neg_nan)
- gcc_checking_assert (!real_isinf (&m_min, 1) || !real_isinf (&m_max, 0));
+ gcc_checking_assert (!frange_val_is_min (m_min, m_type)
+ || !frange_val_is_max (m_max, m_type));
}
// We can't do much with nonzeros yet.
@@ -774,7 +780,11 @@ frange::zero_p () const
void
frange::set_nonnegative (tree type)
{
- set (type, dconst0, dconstinf);
+ set (type, dconst0, frange_val_max (type));
+
+ // Set +NAN as the only possibility.
+ if (HONOR_NANS (type))
+ update_nan (/*sign=*/0);
}
// Here we copy between any two irange's. The ranges can be legacy or
@@ -3823,6 +3833,11 @@ range_tests_signed_zeros ()
r1.update_nan ();
r0.intersect (r1);
ASSERT_TRUE (r0.known_isnan ());
+
+ r0.set_nonnegative (float_type_node);
+ ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
+ if (HONOR_NANS (float_type_node))
+ ASSERT_TRUE (r0.maybe_isnan ());
}
static void
@@ -3872,23 +3887,6 @@ range_tests_floats ()
r0.clear_nan ();
ASSERT_FALSE (r0.varying_p ());
- // The endpoints of a VARYING are +-INF.
- r0.set_varying (float_type_node);
- ASSERT_TRUE (real_identical (&r0.lower_bound (), &dconstninf));
- ASSERT_TRUE (real_identical (&r0.upper_bound (), &dconstinf));
-
- // The maximum representable range for a type is still a subset of VARYING.
- REAL_VALUE_TYPE q, r;
- real_min_representable (&q, float_type_node);
- real_max_representable (&r, float_type_node);
- r0 = frange (float_type_node, q, r);
- // r0 is not a varying, because it does not include -INF/+INF.
- ASSERT_FALSE (r0.varying_p ());
- // The upper bound of r0 must be less than +INF.
- ASSERT_TRUE (real_less (&r0.upper_bound (), &dconstinf));
- // The lower bound of r0 must be greater than -INF.
- ASSERT_TRUE (real_less (&dconstninf, &r0.lower_bound ()));
-
// For most architectures, where float and double are different
// sizes, having the same endpoints does not necessarily mean the
// ranges are equal.
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 795b1f0..413e54b 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -312,6 +312,7 @@ public:
const REAL_VALUE_TYPE &lower_bound () const;
const REAL_VALUE_TYPE &upper_bound () const;
void update_nan ();
+ void update_nan (bool sign);
void clear_nan ();
// fpclassify like API
@@ -592,6 +593,8 @@ extern void dump_value_range (FILE *, const vrange *);
extern bool vrp_val_is_min (const_tree);
extern bool vrp_val_is_max (const_tree);
extern bool vrp_operand_equal_p (const_tree, const_tree);
+inline REAL_VALUE_TYPE frange_val_min (const_tree type);
+inline REAL_VALUE_TYPE frange_val_max (const_tree type);
inline value_range_kind
vrange::kind () const
@@ -1008,7 +1011,10 @@ vrp_val_max (const_tree type)
return wide_int_to_tree (const_cast<tree> (type), max);
}
if (frange::supports_p (type))
- return build_real (const_cast <tree> (type), dconstinf);
+ {
+ REAL_VALUE_TYPE r = frange_val_max (type);
+ return build_real (const_cast <tree> (type), r);
+ }
return NULL_TREE;
}
@@ -1022,7 +1028,10 @@ vrp_val_min (const_tree type)
if (POINTER_TYPE_P (type))
return build_zero_cst (const_cast<tree> (type));
if (frange::supports_p (type))
- return build_real (const_cast <tree> (type), dconstninf);
+ {
+ REAL_VALUE_TYPE r = frange_val_min (type);
+ return build_real (const_cast <tree> (type), r);
+ }
return NULL_TREE;
}
@@ -1072,8 +1081,8 @@ frange::set_varying (tree type)
{
m_kind = VR_VARYING;
m_type = type;
- m_min = dconstninf;
- m_max = dconstinf;
+ m_min = frange_val_min (type);
+ m_max = frange_val_max (type);
m_pos_nan = true;
m_neg_nan = true;
}
@@ -1082,6 +1091,10 @@ inline void
frange::set_undefined ()
{
m_kind = VR_UNDEFINED;
+ m_type = NULL;
+ m_pos_nan = false;
+ m_neg_nan = false;
+ // m_min and m_min are unitialized as they are REAL_VALUE_TYPE ??.
if (flag_checking)
verify_range ();
}
@@ -1099,6 +1112,19 @@ frange::update_nan ()
verify_range ();
}
+// Like above, but set the sign of the NAN.
+
+inline void
+frange::update_nan (bool sign)
+{
+ gcc_checking_assert (!undefined_p ());
+ m_pos_nan = !sign;
+ m_neg_nan = sign;
+ normalize_kind ();
+ if (flag_checking)
+ verify_range ();
+}
+
// Clear the NAN bit and adjust the range.
inline void
@@ -1114,23 +1140,66 @@ frange::clear_nan ()
// Set R to maximum representable value for TYPE.
-inline void
-real_max_representable (REAL_VALUE_TYPE *r, tree type)
+inline REAL_VALUE_TYPE
+real_max_representable (const_tree type)
{
+ REAL_VALUE_TYPE r;
char buf[128];
get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
buf, sizeof (buf), false);
- int res = real_from_string (r, buf);
+ int res = real_from_string (&r, buf);
gcc_checking_assert (!res);
+ return r;
}
-// Set R to minimum representable value for TYPE.
+// Return the minimum representable value for TYPE.
-inline void
-real_min_representable (REAL_VALUE_TYPE *r, tree type)
+inline REAL_VALUE_TYPE
+real_min_representable (const_tree type)
{
- real_max_representable (r, type);
- *r = real_value_negate (r);
+ REAL_VALUE_TYPE r = real_max_representable (type);
+ r = real_value_negate (&r);
+ return r;
+}
+
+// Return the minimum value for TYPE.
+
+inline REAL_VALUE_TYPE
+frange_val_min (const_tree type)
+{
+ if (flag_finite_math_only)
+ return real_min_representable (type);
+ else
+ return dconstninf;
+}
+
+// Return the maximum value for TYPE.
+
+inline REAL_VALUE_TYPE
+frange_val_max (const_tree type)
+{
+ if (flag_finite_math_only)
+ return real_max_representable (type);
+ else
+ return dconstinf;
+}
+
+// Return TRUE if R is the minimum value for TYPE.
+
+inline bool
+frange_val_is_min (const REAL_VALUE_TYPE &r, const_tree type)
+{
+ REAL_VALUE_TYPE min = frange_val_min (type);
+ return real_identical (&min, &r);
+}
+
+// Return TRUE if R is the max value for TYPE.
+
+inline bool
+frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
+{
+ REAL_VALUE_TYPE max = frange_val_max (type);
+ return real_identical (&max, &r);
}
// Build a signless NAN of type TYPE.
@@ -1196,6 +1265,8 @@ frange::known_isinf () const
inline bool
frange::maybe_isnan () const
{
+ if (undefined_p ())
+ return false;
return m_pos_nan || m_neg_nan;
}
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 7c434c9..9ebfaa0 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,10 @@
+2022-09-22 Thomas Neumann <tneumann@users.sourceforge.net>
+
+ * unwind-dw2-fde.c: (release_register_frames) Remember
+ when the btree has been destroyed.
+ (__deregister_frame_info_bases) Disable the assert when
+ shutting down.
+
2022-09-18 Thomas Neumann <tneumann@users.sourceforge.net>
* unwind-dw2-fde.c: Replace uintptr_t with typedef
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 919abfe..3c0cc65 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -48,15 +48,17 @@ typedef __UINTPTR_TYPE__ uintptr_type;
#include "unwind-dw2-btree.h"
static struct btree registered_frames;
+static bool in_shutdown;
static void
-release_registered_frames (void) __attribute__ ((destructor (110)));
+release_registered_frames (void) __attribute__ ((destructor));
static void
release_registered_frames (void)
{
/* Release the b-tree and all frames. Frame releases that happen later are
* silently ignored */
btree_destroy (&registered_frames);
+ in_shutdown = true;
}
static void
@@ -65,6 +67,8 @@ static void
init_object (struct object *ob);
#else
+/* Without fast path frame deregistration must always succeed. */
+static const int in_shutdown = 0;
/* The unseen_objects list contains objects that have been registered
but not yet categorized in any way. The seen_objects list has had
@@ -282,7 +286,7 @@ __deregister_frame_info_bases (const void *begin)
__gthread_mutex_unlock (&object_mutex);
#endif
- gcc_assert (ob);
+ gcc_assert (in_shutdown || ob);
return (void *) ob;
}
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index fab472e..864bf6a 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,13 @@
+2022-09-21 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * ieee/ieee_arithmetic.F90 (IEEE_SET_ROUNDING_MODE): Handle
+ RADIX argument better.
+
+2022-09-21 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.map: Add symbols for IEEE_GET_MODES
+ and IEEE_SET_MODES.
+
2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
* ieee/ieee_exceptions.F90: Add IEEE_MODES_TYPE, IEEE_GET_MODES
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index e0e795c..db9b86c 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1759,3 +1759,9 @@ GFORTRAN_12 {
_gfortran_transfer_real128_write;
#endif
} GFORTRAN_10.2;
+
+GFORTRAN_13 {
+ global:
+ __ieee_exceptions_MOD_ieee_get_modes;
+ __ieee_exceptions_MOD_ieee_set_modes;
+} GFORTRAN_12;
diff --git a/libgfortran/ieee/ieee_arithmetic.F90 b/libgfortran/ieee/ieee_arithmetic.F90
index ce30e4a..4c8e3bb 100644
--- a/libgfortran/ieee/ieee_arithmetic.F90
+++ b/libgfortran/ieee/ieee_arithmetic.F90
@@ -816,7 +816,7 @@ REM_MACRO(4,4,4)
IEEE_SUPPORT_ROUNDING_NOARG
end interface
public :: IEEE_SUPPORT_ROUNDING
-
+
! Interface to the FPU-specific function
interface
pure integer function support_rounding_helper(flag) &
@@ -839,7 +839,7 @@ REM_MACRO(4,4,4)
IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG
end interface
public :: IEEE_SUPPORT_UNDERFLOW_CONTROL
-
+
! Interface to the FPU-specific function
interface
pure integer function support_underflow_control_helper(kind) &
@@ -1074,7 +1074,13 @@ contains
integer, value :: val
end subroutine
end interface
-
+
+ ! We do not support RADIX = 10, and such calls should not
+ ! modify the binary rounding mode.
+ if (present(RADIX)) then
+ if (RADIX == 10) return
+ end if
+
call helper(ROUND_VALUE%hidden)
end subroutine
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index 0239149..e786aea 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -132,12 +132,11 @@ func (p *Package) addToFlag(flag string, args []string) {
//
// For example, the following string:
//
-// `a b:"c d" 'e''f' "g\""`
+// `a b:"c d" 'e''f' "g\""`
//
// Would be parsed as:
//
-// []string{"a", "b:c d", "ef", `g"`}
-//
+// []string{"a", "b:c d", "ef", `g"`}
func splitQuoted(s string) (r []string, err error) {
var args []string
arg := make([]rune, len(s))
@@ -1156,13 +1155,19 @@ func (p *Package) mangle(f *File, arg *ast.Expr, addPosition bool) (ast.Expr, bo
// checkIndex checks whether arg has the form &a[i], possibly inside
// type conversions. If so, then in the general case it writes
-// _cgoIndexNN := a
-// _cgoNN := &cgoIndexNN[i] // with type conversions, if any
+//
+// _cgoIndexNN := a
+// _cgoNN := &cgoIndexNN[i] // with type conversions, if any
+//
// to sb, and writes
-// _cgoCheckPointer(_cgoNN, _cgoIndexNN)
+//
+// _cgoCheckPointer(_cgoNN, _cgoIndexNN)
+//
// to sbCheck, and returns true. If a is a simple variable or field reference,
// it writes
-// _cgoIndexNN := &a
+//
+// _cgoIndexNN := &a
+//
// and dereferences the uses of _cgoIndexNN. Taking the address avoids
// making a copy of an array.
//
@@ -1210,10 +1215,14 @@ func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) boo
// checkAddr checks whether arg has the form &x, possibly inside type
// conversions. If so, it writes
-// _cgoBaseNN := &x
-// _cgoNN := _cgoBaseNN // with type conversions, if any
+//
+// _cgoBaseNN := &x
+// _cgoNN := _cgoBaseNN // with type conversions, if any
+//
// to sb, and writes
-// _cgoCheckPointer(_cgoBaseNN, true)
+//
+// _cgoCheckPointer(_cgoBaseNN, true)
+//
// to sbCheck, and returns true. This tells _cgoCheckPointer to check
// just the contents of the pointer being passed, not any other part
// of the memory allocation. This is run after checkIndex, which looks
@@ -2131,8 +2140,8 @@ type typeConv struct {
// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
getTypeIDs map[string]bool
- // badStructs contains C structs that should be marked NotInHeap.
- notInHeapStructs map[string]bool
+ // incompleteStructs contains C structs that should be marked Incomplete.
+ incompleteStructs map[string]bool
// Predeclared types.
bool ast.Expr
@@ -2145,7 +2154,6 @@ type typeConv struct {
string ast.Expr
goVoid ast.Expr // _Ctype_void, denotes C's void
goVoidPtr ast.Expr // unsafe.Pointer or *byte
- goVoidPtrNoHeap ast.Expr // *_Ctype_void_notinheap, like goVoidPtr but marked NotInHeap
ptrSize int64
intSize int64
@@ -2169,7 +2177,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
c.m = make(map[string]*Type)
c.ptrs = make(map[string][]*Type)
c.getTypeIDs = make(map[string]bool)
- c.notInHeapStructs = make(map[string]bool)
+ c.incompleteStructs = make(map[string]bool)
c.bool = c.Ident("bool")
c.byte = c.Ident("byte")
c.int8 = c.Ident("int8")
@@ -2188,7 +2196,6 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
c.void = c.Ident("void")
c.string = c.Ident("string")
c.goVoid = c.Ident("_Ctype_void")
- c.goVoidPtrNoHeap = c.Ident("*_Ctype_void_notinheap")
// Normally cgo translates void* to unsafe.Pointer,
// but for historical reasons -godefs uses *byte instead.
@@ -2531,19 +2538,13 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
// other than try to determine a Go representation.
tt := *t
tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
- tt.Go = c.Ident("struct{}")
- if dt.Kind == "struct" {
- // We don't know what the representation of this struct is, so don't let
- // anyone allocate one on the Go side. As a side effect of this annotation,
- // pointers to this type will not be considered pointers in Go. They won't
- // get writebarrier-ed or adjusted during a stack copy. This should handle
- // all the cases badPointerTypedef used to handle, but hopefully will
- // continue to work going forward without any more need for cgo changes.
- tt.NotInHeap = true
- // TODO: we should probably do the same for unions. Unions can't live
- // on the Go heap, right? It currently doesn't work for unions because
- // they are defined as a type alias for struct{}, not a defined type.
- }
+ // We don't know what the representation of this struct is, so don't let
+ // anyone allocate one on the Go side. As a side effect of this annotation,
+ // pointers to this type will not be considered pointers in Go. They won't
+ // get writebarrier-ed or adjusted during a stack copy. This should handle
+ // all the cases badPointerTypedef used to handle, but hopefully will
+ // continue to work going forward without any more need for cgo changes.
+ tt.Go = c.Ident("_cgopackage.Incomplete")
typedef[name.Name] = &tt
break
}
@@ -2569,7 +2570,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
}
tt.Go = g
- tt.NotInHeap = c.notInHeapStructs[tag]
+ if c.incompleteStructs[tag] {
+ tt.Go = c.Ident("_cgopackage.Incomplete")
+ }
typedef[name.Name] = &tt
}
@@ -2614,9 +2617,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
}
}
if c.badVoidPointerTypedef(dt) {
- // Treat this typedef as a pointer to a NotInHeap void.
+ // Treat this typedef as a pointer to a _cgopackage.Incomplete.
s := *sub
- s.Go = c.goVoidPtrNoHeap
+ s.Go = c.Ident("*_cgopackage.Incomplete")
sub = &s
// Make sure we update any previously computed type.
if oldType := typedef[name.Name]; oldType != nil {
@@ -2624,22 +2627,21 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
}
}
// Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
- // typedefs that should be marked NotInHeap.
+ // typedefs that should be marked Incomplete.
if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
if strct, ok := ptr.Type.(*dwarf.StructType); ok {
if c.badStructPointerTypedef(dt.Name, strct) {
- c.notInHeapStructs[strct.StructName] = true
+ c.incompleteStructs[strct.StructName] = true
// Make sure we update any previously computed type.
name := "_Ctype_struct_" + strct.StructName
if oldType := typedef[name]; oldType != nil {
- oldType.NotInHeap = true
+ oldType.Go = c.Ident("_cgopackage.Incomplete")
}
}
}
}
t.Go = name
t.BadPointer = sub.BadPointer
- t.NotInHeap = sub.NotInHeap
if unionWithPointer[sub.Go] {
unionWithPointer[t.Go] = true
}
@@ -2650,7 +2652,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
tt := *t
tt.Go = sub.Go
tt.BadPointer = sub.BadPointer
- tt.NotInHeap = sub.NotInHeap
typedef[name.Name] = &tt
}
@@ -3174,7 +3175,7 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
// non-pointers in this type.
// TODO: Currently our best solution is to find these manually and list them as
// they come up. A better solution is desired.
-// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file.
+// Note: DEPRECATED. There is now a better solution. Search for _cgopackage.Incomplete in this file.
func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
if c.badCFType(dt) {
return true
@@ -3188,7 +3189,7 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
return false
}
-// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be NotInHeap.
+// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
// Match the Windows HANDLE type (#42018).
if goos != "windows" || dt.Name != "HANDLE" {
diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go
index 58477e4..186aef0 100644
--- a/libgo/go/cmd/cgo/main.go
+++ b/libgo/go/cmd/cgo/main.go
@@ -153,7 +153,6 @@ type Type struct {
EnumValues map[string]int64
Typedef string
BadPointer bool // this pointer type should be represented as a uintptr (deprecated)
- NotInHeap bool // this type should have a go:notinheap annotation
}
// A FuncType collects information about a function type in both the C and Go worlds.
diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go
index 8d1eb5b..9ed88b8 100644
--- a/libgo/go/cmd/cgo/out.go
+++ b/libgo/go/cmd/cgo/out.go
@@ -85,11 +85,14 @@ func (p *Package) writeDefs() {
fmt.Fprintf(fgo2, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName)
fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
- if !*gccgo && *importRuntimeCgo {
- fmt.Fprintf(fgo2, "import _ \"runtime/cgo\"\n\n")
- }
if *importSyscall {
fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
+ }
+ if *importRuntimeCgo {
+ fmt.Fprintf(fgo2, "import _cgopackage \"runtime/cgo\"\n\n")
+ fmt.Fprintf(fgo2, "type _ _cgopackage.Incomplete\n") // prevent import-not-used error
+ }
+ if *importSyscall {
fmt.Fprintf(fgo2, "var _ syscall.Errno\n")
}
fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
@@ -113,9 +116,6 @@ func (p *Package) writeDefs() {
sort.Strings(typedefNames)
for _, name := range typedefNames {
def := typedef[name]
- if def.NotInHeap {
- fmt.Fprintf(fgo2, "//go:notinheap\n")
- }
fmt.Fprintf(fgo2, "type %s ", name)
// We don't have source info for these types, so write them out without source info.
// Otherwise types would look like:
@@ -140,7 +140,6 @@ func (p *Package) writeDefs() {
fmt.Fprintf(fgo2, "%s", buf.Bytes())
fmt.Fprintf(fgo2, "\n\n")
}
- fmt.Fprintf(fgo2, "//go:notinheap\ntype _Ctype_void_notinheap struct{}\n\n")
if *gccgo {
fmt.Fprintf(fgo2, "type _Ctype_void byte\n")
} else {
diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go
index 44bd61c..9c5c0a1 100644
--- a/libgo/go/cmd/go/internal/load/pkg.go
+++ b/libgo/go/cmd/go/internal/load/pkg.go
@@ -1818,7 +1818,7 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
if p.UsesCgo() {
addImport("unsafe", true)
}
- if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
+ if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) {
addImport("runtime/cgo", true)
}
if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
@@ -1828,9 +1828,7 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
// SWIG adds imports of some standard packages.
if p.UsesSwig() {
addImport("unsafe", true)
- if cfg.BuildContext.Compiler != "gccgo" {
- addImport("runtime/cgo", true)
- }
+ addImport("runtime/cgo", true)
addImport("syscall", true)
addImport("sync", true)
@@ -2455,7 +2453,7 @@ func LinkerDeps(p *Package) []string {
deps := []string{"runtime"}
// External linking mode forces an import of runtime/cgo.
- if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
+ if externalLinkingForced(p) {
deps = append(deps, "runtime/cgo")
}
// On ARM with GOARM=5, it forces an import of math, for soft floating point.
diff --git a/libgo/go/runtime/cgo/cgo.go b/libgo/go/runtime/cgo/cgo.go
new file mode 100644
index 0000000..5921435
--- /dev/null
+++ b/libgo/go/runtime/cgo/cgo.go
@@ -0,0 +1,18 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package cgo contains runtime support for code generated
+by the cgo tool. See the documentation for the cgo command
+for details on using cgo.
+*/
+package cgo
+
+// Incomplete is used specifically for the semantics of incomplete C types.
+//
+//go:notinheap
+type Incomplete struct {
+ // _ sys.NotInHeap
+ _ struct{ _ struct{} }
+}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index d3b4758..a5830a4 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2022-09-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/106981
+ * testsuite/libgomp.c-c++-common/pr106981.c: New test.
+
2022-09-14 Julian Brown <julian@codesourcery.com>
* testsuite/libgomp.oacc-c-c++-common/deep-copy-15.c: New test.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr106981.c b/libgomp/testsuite/libgomp.c-c++-common/pr106981.c
new file mode 100644
index 0000000..ed48d27
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr106981.c
@@ -0,0 +1,19 @@
+/* PR c/106981 */
+
+int
+main ()
+{
+ int a[0x101];
+ unsigned int b = 0x100;
+ if ((unsigned char) b || (unsigned short) b != 0x100)
+ return 0;
+ a[0] = 0;
+ a[0x100] = 42;
+ #pragma omp atomic update
+ a[(unsigned char) b] = a[(unsigned short) b] + a[(unsigned char) b];
+ #pragma omp atomic update
+ a[(unsigned char) b] = a[(unsigned char) b] + a[(unsigned short) b];
+ if (a[0] != 84 || a[0x100] != 42)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 736288f..f537372 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,7 @@
+2022-09-22 Jonathan Wakely <jwakely@redhat.com>
+
+ * README: Replace gcc-bugs email address with Bugzilla URL.
+
2022-08-25 Martin Liska <mliska@suse.cz>
* configure: Regenerate.
diff --git a/libiberty/README b/libiberty/README
index 9f1cc97..e7ffb17 100644
--- a/libiberty/README
+++ b/libiberty/README
@@ -15,7 +15,7 @@ The library must be configured from the top source directory. Don't
try to run configure in this directory. Follow the configuration
instructions in ../README.
-Please report bugs to "gcc-bugs@gcc.gnu.org" and send fixes to
+Please report bugs to https://gcc.gnu.org/bugzilla/ and send fixes to
"gcc-patches@gcc.gnu.org". Thank you.
ADDING A NEW FILE
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index a55293e..e6722cf 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,207 @@
+2022-09-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/alloc_traits.h (allocator_traits::is_always_equal):
+ Only instantiate is_empty if needed.
+ * include/bits/ptr_traits.h (__ptr_traits_impl::difference_type)
+ (__ptr_traits_impl::rebind): Use __detected_or.
+ * include/experimental/type_traits (is_same_v): Add a partial
+ specialization instead of instantiating the std::is_same class
+ template.
+ (detected_t): Redefine in terms of detected_or_t.
+ (is_detected, is_detected_v): Redefine in terms of detected_t.
+ * include/std/type_traits [__cpp_concepts] (__detected_or): Add
+ new definition using concepts.
+ (__detector::value_t): Rename to __is_detected.
+ * testsuite/17_intro/names.cc: Check value_t isn't used.
+
+2022-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/is_assignable/requirements/access.cc:
+ New test.
+
+2022-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/91456
+ * include/std/type_traits (__is_nothrow_invocable_lib): Remove.
+ (__is_invocable_impl::__nothrow_type): New member type which
+ checks if the conversion can throw.
+ (__is_nt_invocable_impl): Replace class template with alias
+ template to __is_nt_invocable_impl::__nothrow_type.
+ * testsuite/20_util/is_nothrow_invocable/91456.cc: New test.
+ * testsuite/20_util/is_nothrow_convertible/value.cc: Remove
+ macro used by value_ext.cc test.
+ * testsuite/20_util/is_nothrow_convertible/value_ext.cc: Remove
+ test for non-standard __is_nothrow_invocable_lib trait.
+
+2022-09-23 Marek Polacek <polacek@redhat.com>
+
+ PR c++/106784
+ * include/std/type_traits: Rename __is_nothrow_convertible to
+ __is_nothrow_convertible_lib.
+ * testsuite/20_util/is_nothrow_convertible/value_ext.cc: Likewise.
+
+2022-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/bitset (operator>>): Do not copy for N==0.
+ * testsuite/20_util/bitset/io/input.cc: Add comment.
+
+2022-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/debug/bitset (__debug::bitset): Add constexpr to all
+ member functions.
+ (operator&, operator|, operator^): Add inline and constexpr.
+ (operator>>, operator<<): Add inline.
+ * testsuite/20_util/bitset/access/constexpr.cc: Only check using
+ constexpr std::string for the cxx11 ABI.
+ * testsuite/20_util/bitset/cons/constexpr_c++23.cc: Likewise.
+ * testsuite/20_util/headers/bitset/synopsis.cc: Check constexpr
+ for C++23.
+
+2022-09-23 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/bitset (bitset::_M_copy_to_string): Find set bits
+ instead of iterating over individual bits.
+
+2022-09-22 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/bitset (bitset): Add constexpr for C++23. Guard
+ members using std::string with _GLIBCXX_HOSTED.
+ * include/std/version (__cpp_lib_constexpr_bitset): Define.
+ * testsuite/20_util/bitset/access/constexpr.cc: New test.
+ * testsuite/20_util/bitset/cons/constexpr_c++23.cc: New test.
+ * testsuite/20_util/bitset/count/constexpr.cc: New test.
+ * testsuite/20_util/bitset/ext/constexpr.cc: New test.
+ * testsuite/20_util/bitset/operations/constexpr_c++23.cc: New test.
+ * testsuite/20_util/bitset/version.cc: New test.
+
+2022-09-22 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/23_containers/bitset/18604.cc: Moved to...
+ * testsuite/20_util/bitset/18604.cc: ...here.
+ * testsuite/23_containers/bitset/45713.cc: Moved to...
+ * testsuite/20_util/bitset/45713.cc: ...here.
+ * testsuite/23_containers/bitset/to_string/dr396.cc: Moved to...
+ * testsuite/20_util/bitset/access/dr396.cc: ...here.
+ * testsuite/23_containers/bitset/to_string/1.cc: Moved to...
+ * testsuite/20_util/bitset/access/to_string.cc: ...here.
+ * testsuite/23_containers/bitset/to_ullong/1.cc: Moved to...
+ * testsuite/20_util/bitset/access/to_ullong.cc: ...here.
+ * testsuite/23_containers/bitset/to_ulong/1.cc: Moved to...
+ * testsuite/20_util/bitset/access/to_ulong.cc: ...here.
+ * testsuite/23_containers/bitset/cons/1.cc: Moved to...
+ * testsuite/20_util/bitset/cons/1.cc: ...here.
+ * testsuite/23_containers/bitset/cons/16020.cc: Moved to...
+ * testsuite/20_util/bitset/cons/16020.cc: ...here.
+ * testsuite/23_containers/bitset/cons/2.cc: Moved to...
+ * testsuite/20_util/bitset/cons/2.cc: ...here.
+ * testsuite/23_containers/bitset/cons/3.cc: Moved to...
+ * testsuite/20_util/bitset/cons/3.cc: ...here.
+ * testsuite/23_containers/bitset/cons/38244.cc: Moved to...
+ * testsuite/20_util/bitset/cons/38244.cc: ...here.
+ * testsuite/23_containers/bitset/cons/50268.cc: Moved to...
+ * testsuite/20_util/bitset/cons/50268.cc: ...here.
+ * testsuite/23_containers/bitset/cons/6282.cc: Moved to...
+ * testsuite/20_util/bitset/cons/6282.cc: ...here.
+ * testsuite/23_containers/bitset/cons/constexpr.cc: Moved to...
+ * testsuite/20_util/bitset/cons/constexpr.cc: ...here.
+ * testsuite/23_containers/bitset/cons/dr1325-1.cc: Moved to...
+ * testsuite/20_util/bitset/cons/dr1325-1.cc: ...here.
+ * testsuite/23_containers/bitset/cons/dr1325-2.cc: Moved to...
+ * testsuite/20_util/bitset/cons/dr1325-2.cc: ...here.
+ * testsuite/23_containers/bitset/cons/dr396.cc: Moved to...
+ * testsuite/20_util/bitset/cons/dr396.cc: ...here.
+ * testsuite/23_containers/bitset/debug/invalidation/1.cc: Moved to...
+ * testsuite/20_util/bitset/debug/invalidation/1.cc: ...here.
+ * testsuite/23_containers/bitset/ext/15361.cc: Moved to...
+ * testsuite/20_util/bitset/ext/15361.cc: ...here.
+ * testsuite/23_containers/bitset/hash/1.cc: Moved to...
+ * testsuite/20_util/bitset/hash/1.cc: ...here.
+ * testsuite/23_containers/bitset/input/1.cc: Moved to...
+ * testsuite/20_util/bitset/io/input.cc: ...here.
+ * testsuite/23_containers/bitset/count/6124.cc: Moved to...
+ * testsuite/20_util/bitset/observers/6124.cc: ...here.
+ * testsuite/23_containers/bitset/all/1.cc: Moved to...
+ * testsuite/20_util/bitset/observers/all.cc: ...here.
+ * testsuite/23_containers/bitset/test/1.cc: Moved to...
+ * testsuite/20_util/bitset/observers/test.cc: ...here.
+ * testsuite/23_containers/bitset/operations/1.cc: Moved to...
+ * testsuite/20_util/bitset/operations/1.cc: ...here.
+ * testsuite/23_containers/bitset/operations/13838.cc: Moved to...
+ * testsuite/20_util/bitset/operations/13838.cc: ...here.
+ * testsuite/23_containers/bitset/operations/2.cc: Moved to...
+ * testsuite/20_util/bitset/operations/2.cc: ...here.
+ * testsuite/23_containers/bitset/operations/96303.cc: Moved to...
+ * testsuite/20_util/bitset/operations/96303.cc: ...here.
+ * testsuite/23_containers/bitset/operations/constexpr-2.cc: Moved to...
+ * testsuite/20_util/bitset/operations/constexpr-2.cc: ...here.
+ * testsuite/23_containers/bitset/operations/constexpr.cc: Moved to...
+ * testsuite/20_util/bitset/operations/constexpr.cc: ...here.
+ * testsuite/23_containers/bitset/requirements/constexpr_functions.cc: Moved to...
+ * testsuite/20_util/bitset/requirements/constexpr_functions.cc: ...here.
+ * testsuite/23_containers/bitset/requirements/explicit_instantiation/1.cc: Moved to...
+ * testsuite/20_util/bitset/requirements/explicit_instantiation/1.cc: ...here.
+ * testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc: Moved to...
+ * testsuite/20_util/bitset/requirements/explicit_instantiation/1_c++0x.cc: ...here.
+ * testsuite/23_containers/headers/bitset/synopsis.cc: Moved to...
+ * testsuite/20_util/headers/bitset/synopsis.cc: ...here.
+
+2022-09-22 François Dumont <fdumont@gcc.gnu.org>
+
+ * python/libstdcxx/v6/printers.py: Remove ptinter registration for non-existing
+ types std::__debug::unique_ptr, std::__debug::stack, std::__debug::queue,
+ std::__debug::priority_queue.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/91456
+ * testsuite/20_util/function/91456.cc: Add comment with PR
+ number.
+ * testsuite/20_util/is_invocable/91456.cc: Likewise. Replace
+ std::function checks with std::is_invocable_r checks.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/17_intro/headers/c++1998/all_attributes.cc: Remove
+ unnecessary main function.
+ * testsuite/17_intro/headers/c++2011/all_attributes.cc:
+ Likewise.
+ * testsuite/17_intro/headers/c++2014/all_attributes.cc:
+ Likewise.
+ * testsuite/17_intro/headers/c++2017/all_attributes.cc:
+ Likewise.
+ * testsuite/17_intro/headers/c++2020/all_attributes.cc:
+ Likewise.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/20_util/headers/memory/synopsis.cc: Add declarations
+ from C++11 and later.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/xml/manual/documentation_hacking.xml: Remove trailing
+ whitespace.
+ * doc/xml/manual/policy_data_structures.xml: Likewise.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/c_compatibility/stdlib.h [!_GLIBCXX_HOSTED]: Add
+ using-declaration for _Exit.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/18_support/uncaught_exception/14026.cc: Qualify
+ call to std::abort.
+
+2022-09-21 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/ranges_base.h: Include <initializer_list>.
+
+2022-09-20 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/c_global/cstdlib [!_GLIBCXX_HOSTED] (quick_exit): Fix
+ missing space.
+
2022-09-16 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/106953
diff --git a/libstdc++-v3/doc/xml/manual/documentation_hacking.xml b/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
index 03bf1f1..776d5e8 100644
--- a/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
+++ b/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
@@ -353,7 +353,7 @@
documentation. Here are some of the obvious errors, and ways
to fix some common issues that may appear quite cryptic.
</para>
-
+
<para>
First, if using a rule like <code>make pdf</code>, try to
narrow down the scope of the error to either docbook
@@ -844,7 +844,7 @@ make <literal>XSL_STYLE_DIR="/usr/share/xml/docbook/stylesheet/nwalsh"</literal>
documentation. Here are some of the obvious errors, and ways
to fix some common issues that may appear quite cryptic.
</para>
-
+
<para>
First, if using a rule like <code>make pdf</code>, try to
narrow down the scope of the error to either docbook
diff --git a/libstdc++-v3/doc/xml/manual/policy_data_structures.xml b/libstdc++-v3/doc/xml/manual/policy_data_structures.xml
index 3e59810..305257c 100644
--- a/libstdc++-v3/doc/xml/manual/policy_data_structures.xml
+++ b/libstdc++-v3/doc/xml/manual/policy_data_structures.xml
@@ -3003,7 +3003,7 @@
</textobject>
</mediaobject>
</figure>
-
+
<para>Let U be a domain (e.g., the integers, or the
strings of 3 characters). A hash-table algorithm needs to map
elements of U "uniformly" into the range [0,..., m -
@@ -3179,7 +3179,7 @@
0</subscript><superscript>t - 1</superscript> s<subscript>i</subscript> a<superscript>i</superscript> mod m
</mathphrase>
</equation>
-
+
<para>where a is some non-negative integral value. This is
the standard string-hashing function used in SGI's
@@ -3278,7 +3278,7 @@
</textobject>
</mediaobject>
</figure>
-
+
<para>If <classname>cc_hash_table</classname>'s
hash-functor, <classname>Hash_Fn</classname> is instantiated by <classname>null_type</classname> , then <classname>Comb_Hash_Fn</classname> is taken to be
a ranged-hash function. The graphic below shows an <function>insert</function> sequence
@@ -3298,7 +3298,7 @@
</textobject>
</mediaobject>
</figure>
-
+
</section>
<section xml:id="hash_policies.implementation.probe">
@@ -3917,7 +3917,7 @@
</textobject>
</mediaobject>
</figure>
-
+
<para>Supporting such trees is difficult for a number of
reasons:</para>
@@ -4819,7 +4819,7 @@
assert(p.top() == 3);
</programlisting>
-
+
<para>It should be noted that an alternative design could embed an
associative container in a priority queue. Could, but most
probably should not. To begin with, it should be noted that one
diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 507e8f1..8479bfd 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
using __pocs = typename _Tp::propagate_on_container_swap;
template<typename _Tp>
- using __equal = typename _Tp::is_always_equal;
+ using __equal = __type_identity<typename _Tp::is_always_equal>;
};
template<typename _Alloc, typename _Up>
@@ -209,7 +209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* otherwise @c is_empty<Alloc>::type
*/
using is_always_equal
- = __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
+ = typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
template<typename _Tp>
using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
diff --git a/libstdc++-v3/include/bits/ptr_traits.h b/libstdc++-v3/include/bits/ptr_traits.h
index 8360c3b..ae88107 100644
--- a/libstdc++-v3/include/bits/ptr_traits.h
+++ b/libstdc++-v3/include/bits/ptr_traits.h
@@ -144,29 +144,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __ptr_traits_impl : __ptr_traits_ptr_to<_Ptr, _Elt>
{
private:
- template<typename _Tp, typename = void>
- struct __difference { using type = ptrdiff_t; };
-
template<typename _Tp>
-#if __cpp_concepts
- requires requires { typename _Tp::difference_type; }
- struct __difference<_Tp>
-#else
- struct __difference<_Tp, __void_t<typename _Tp::difference_type>>
-#endif
- { using type = typename _Tp::difference_type; };
-
- template<typename _Tp, typename _Up, typename = void>
- struct __rebind : __replace_first_arg<_Tp, _Up> { };
+ using __diff_t = typename _Tp::difference_type;
template<typename _Tp, typename _Up>
-#if __cpp_concepts
- requires requires { typename _Tp::template rebind<_Up>; }
- struct __rebind<_Tp, _Up>
-#else
- struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
-#endif
- { using type = typename _Tp::template rebind<_Up>; };
+ using __rebind = __type_identity<typename _Tp::template rebind<_Up>>;
public:
/// The pointer type.
@@ -176,11 +158,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using element_type = _Elt;
/// The type used to represent the difference between two pointers.
- using difference_type = typename __difference<_Ptr>::type;
+ using difference_type = __detected_or_t<ptrdiff_t, __diff_t, _Ptr>;
/// A pointer to a different type.
template<typename _Up>
- using rebind = typename __rebind<_Ptr, _Up>::type;
+ using rebind = typename __detected_or_t<__replace_first_arg<_Ptr, _Up>,
+ __rebind, _Ptr, _Up>::type;
};
// _GLIBCXX_RESOLVE_LIB_DEFECTS
diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 866d7c5..805f196 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -33,6 +33,7 @@
#pragma GCC system_header
#if __cplusplus > 201703L
+#include <initializer_list>
#include <bits/iterator_concepts.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>
diff --git a/libstdc++-v3/include/c_compatibility/stdlib.h b/libstdc++-v3/include/c_compatibility/stdlib.h
index 377b910..70fa4c8 100644
--- a/libstdc++-v3/include/c_compatibility/stdlib.h
+++ b/libstdc++-v3/include/c_compatibility/stdlib.h
@@ -45,6 +45,9 @@ using std::exit;
# ifdef _GLIBCXX_HAVE_QUICK_EXIT
using std::quick_exit;
# endif
+# if _GLIBCXX_USE_C99_STDLIB
+ using std::_Exit;
+# endif
#endif
#if _GLIBCXX_HOSTED
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
index 4c0af03..9335fe4 100644
--- a/libstdc++-v3/include/debug/bitset
+++ b/libstdc++-v3/include/debug/bitset
@@ -141,6 +141,7 @@ namespace __debug
: _Base(__val) { }
template<typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX23_CONSTEXPR
explicit
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
@@ -152,6 +153,7 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __str,
typename std::basic_string<_CharT, _Traits, _Alloc>::size_type
__pos,
@@ -160,10 +162,12 @@ namespace __debug
_CharT __zero, _CharT __one = _CharT('1'))
: _Base(__str, __pos, __n, __zero, __one) { }
+ _GLIBCXX23_CONSTEXPR
bitset(const _Base& __x) : _Base(__x) { }
#if __cplusplus >= 201103L
template<typename _CharT>
+ _GLIBCXX23_CONSTEXPR
explicit
bitset(const _CharT* __str,
typename std::basic_string<_CharT>::size_type __n
@@ -173,6 +177,7 @@ namespace __debug
#endif
// 23.3.5.2 bitset operations:
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -180,6 +185,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -187,6 +193,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -194,6 +201,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator<<=(size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -201,6 +209,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator>>=(size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -208,6 +217,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
set() _GLIBCXX_NOEXCEPT
{
@@ -217,6 +227,7 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 186. bitset::set() second parameter should be bool
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
set(size_t __pos, bool __val = true)
{
@@ -224,6 +235,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
reset() _GLIBCXX_NOEXCEPT
{
@@ -231,6 +243,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
reset(size_t __pos)
{
@@ -238,10 +251,12 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator~() const _GLIBCXX_NOEXCEPT
{ return bitset(~_M_base()); }
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
flip() _GLIBCXX_NOEXCEPT
{
@@ -249,6 +264,7 @@ namespace __debug
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
flip(size_t __pos)
{
@@ -259,6 +275,7 @@ namespace __debug
// element access:
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 11. Bitset minor problems
+ _GLIBCXX23_CONSTEXPR
reference
operator[](size_t __pos)
{
@@ -288,6 +305,7 @@ namespace __debug
#endif
template <typename _CharT, typename _Traits, typename _Alloc>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, _Alloc>
to_string() const
{ return _M_base().template to_string<_CharT, _Traits, _Alloc>(); }
@@ -295,6 +313,7 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, _Alloc>
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
@@ -305,6 +324,7 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 434. bitset::to_string() hard to use.
template<typename _CharT, typename _Traits>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string() const
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
@@ -312,12 +332,14 @@ namespace __debug
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 853. to_string needs updating with zero and one.
template<class _CharT, class _Traits>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{ return to_string<_CharT, _Traits,
std::allocator<_CharT> >(__zero, __one); }
template<typename _CharT>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string() const
@@ -327,6 +349,7 @@ namespace __debug
}
template<class _CharT>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
@@ -335,12 +358,14 @@ namespace __debug
std::allocator<_CharT> >(__zero, __one);
}
+ _GLIBCXX23_CONSTEXPR
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string() const
{
return to_string<char,std::char_traits<char>,std::allocator<char> >();
}
+ _GLIBCXX23_CONSTEXPR
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string(char __zero, char __one = '1') const
{
@@ -351,6 +376,7 @@ namespace __debug
using _Base::count;
using _Base::size;
+ _GLIBCXX23_CONSTEXPR
bool
operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
{ return _M_base() == __rhs._M_base(); }
@@ -366,45 +392,52 @@ namespace __debug
using _Base::any;
using _Base::none;
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator<<(size_t __pos) const _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(_M_base() << __pos); }
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator>>(size_t __pos) const _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(_M_base() >> __pos); }
+ _GLIBCXX23_CONSTEXPR
_Base&
_M_base() _GLIBCXX_NOEXCEPT
{ return *this; }
+ _GLIBCXX23_CONSTEXPR
const _Base&
_M_base() const _GLIBCXX_NOEXCEPT
{ return *this; }
};
template<size_t _Nb>
- bitset<_Nb>
+ _GLIBCXX23_CONSTEXPR
+ inline bitset<_Nb>
operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(__x) &= __y; }
template<size_t _Nb>
- bitset<_Nb>
+ _GLIBCXX23_CONSTEXPR
+ inline bitset<_Nb>
operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(__x) |= __y; }
template<size_t _Nb>
- bitset<_Nb>
+ _GLIBCXX23_CONSTEXPR
+ inline bitset<_Nb>
operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(__x) ^= __y; }
template<typename _CharT, typename _Traits, size_t _Nb>
- std::basic_istream<_CharT, _Traits>&
+ inline std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is, bitset<_Nb>& __x)
{ return __is >> __x._M_base(); }
template<typename _CharT, typename _Traits, size_t _Nb>
- std::basic_ostream<_CharT, _Traits>&
+ inline std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const bitset<_Nb>& __x)
{ return __os << __x._M_base(); }
diff --git a/libstdc++-v3/include/experimental/type_traits b/libstdc++-v3/include/experimental/type_traits
index af5970e..fa25a1c 100644
--- a/libstdc++-v3/include/experimental/type_traits
+++ b/libstdc++-v3/include/experimental/type_traits
@@ -223,7 +223,9 @@ template <typename _Tp, unsigned _Idx = 0>
// See C++14 20.10.6, type relations
template <typename _Tp, typename _Up>
- constexpr bool is_same_v = is_same<_Tp, _Up>::value;
+ constexpr bool is_same_v = false;
+template <typename _Tp>
+ constexpr bool is_same_v<_Tp, _Tp> = true;
template <typename _Base, typename _Derived>
constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value;
template <typename _From, typename _To>
@@ -266,23 +268,21 @@ struct nonesuch : private __nonesuchbase
};
#pragma GCC diagnostic pop
-template<template<typename...> class _Op, typename... _Args>
- using is_detected
- = typename std::__detector<nonesuch, void, _Op, _Args...>::value_t;
-
-template<template<typename...> class _Op, typename... _Args>
- constexpr bool is_detected_v = is_detected<_Op, _Args...>::value;
-
-template<template<typename...> class _Op, typename... _Args>
- using detected_t
- = typename std::__detector<nonesuch, void, _Op, _Args...>::type;
-
template<typename _Default, template<typename...> class _Op, typename... _Args>
using detected_or = std::__detected_or<_Default, _Op, _Args...>;
template<typename _Default, template<typename...> class _Op, typename... _Args>
using detected_or_t = typename detected_or<_Default, _Op, _Args...>::type;
+template<template<typename...> class _Op, typename... _Args>
+ using detected_t = detected_or_t<nonesuch, _Op, _Args...>;
+
+template<template<typename...> class _Op, typename... _Args>
+ using is_detected = typename detected_or<void, _Op, _Args...>::__is_detected;
+
+template<template<typename...> class _Op, typename... _Args>
+ constexpr bool is_detected_v = is_detected<_Op, _Args...>::value;
+
template<typename _Expected, template<typename...> class _Op, typename... _Args>
using is_detected_exact = is_same<_Expected, detected_t<_Op, _Args...>>;
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 438c2f7..1a551cf 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -44,14 +44,15 @@
#pragma GCC system_header
-#include <string>
#include <bits/functexcept.h> // For invalid_argument, out_of_range,
// overflow_error
-#include <iosfwd>
-#include <bits/cxxabi_forced.h>
-
-#if __cplusplus >= 201103L
-# include <bits/functional_hash.h>
+#if _GLIBCXX_HOSTED
+# include <string>
+# include <iosfwd>
+# include <bits/cxxabi_forced.h>
+# if __cplusplus >= 201103L
+# include <bits/functional_hash.h>
+# endif
#endif
#define _GLIBCXX_BITSET_BITS_PER_WORD (__CHAR_BIT__ * __SIZEOF_LONG__)
@@ -65,6 +66,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
+#if __cplusplus > 202002L && _GLIBCXX_HOSTED
+# define __cpp_lib_constexpr_bitset 202202L
+#endif
+
/**
* Base class, general case. It is a class invariant that _Nw will be
* nonnegative.
@@ -111,7 +116,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT
{ return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
- _WordT&
+ _GLIBCXX14_CONSTEXPR _WordT&
_M_getword(size_t __pos) _GLIBCXX_NOEXCEPT
{ return _M_w[_S_whichword(__pos)]; }
@@ -120,12 +125,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_w[_S_whichword(__pos)]; }
#if __cplusplus >= 201103L
- const _WordT*
+ constexpr const _WordT*
_M_getdata() const noexcept
{ return _M_w; }
#endif
- _WordT&
+ _GLIBCXX23_CONSTEXPR _WordT&
_M_hiword() _GLIBCXX_NOEXCEPT
{ return _M_w[_Nw - 1]; }
@@ -133,52 +138,62 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_hiword() const _GLIBCXX_NOEXCEPT
{ return _M_w[_Nw - 1]; }
- void
+ _GLIBCXX23_CONSTEXPR void
_M_do_and(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
_M_w[__i] &= __x._M_w[__i];
}
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_or(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
_M_w[__i] |= __x._M_w[__i];
}
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_xor(const _Base_bitset<_Nw>& __x) _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
_M_w[__i] ^= __x._M_w[__i];
}
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT;
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT;
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_flip() _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
_M_w[__i] = ~_M_w[__i];
}
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_set() _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
_M_w[__i] = ~static_cast<_WordT>(0);
}
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_reset() _GLIBCXX_NOEXCEPT
- { __builtin_memset(_M_w, 0, _Nw * sizeof(_WordT)); }
+ {
+#if __cplusplus >= 201402L
+ if (__builtin_is_constant_evaluated())
+ {
+ for (_WordT& __w : _M_w)
+ __w = 0;
+ return;
+ }
+#endif
+ __builtin_memset(_M_w, 0, _Nw * sizeof(_WordT));
+ }
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_is_equal(const _Base_bitset<_Nw>& __x) const _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; ++__i)
@@ -188,7 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<size_t _Nb>
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_are_all() const _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw - 1; __i++)
@@ -199,7 +214,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
- _Nb));
}
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_is_any() const _GLIBCXX_NOEXCEPT
{
for (size_t __i = 0; __i < _Nw; __i++)
@@ -208,7 +223,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return false;
}
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_count() const _GLIBCXX_NOEXCEPT
{
size_t __result = 0;
@@ -217,26 +232,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return __result;
}
- unsigned long
+ _GLIBCXX14_CONSTEXPR unsigned long
_M_do_to_ulong() const;
#if __cplusplus >= 201103L
- unsigned long long
+ _GLIBCXX14_CONSTEXPR unsigned long long
_M_do_to_ullong() const;
#endif
// find first "on" bit
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT;
// find the next "on" bit that follows "prev"
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT;
};
// Definitions of non-inline functions from _Base_bitset.
template<size_t _Nw>
- void
+ _GLIBCXX14_CONSTEXPR void
_Base_bitset<_Nw>::_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT
{
if (__builtin_expect(__shift != 0, 1))
@@ -262,7 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<size_t _Nw>
- void
+ _GLIBCXX14_CONSTEXPR void
_Base_bitset<_Nw>::_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT
{
if (__builtin_expect(__shift != 0, 1))
@@ -289,7 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<size_t _Nw>
- unsigned long
+ _GLIBCXX14_CONSTEXPR unsigned long
_Base_bitset<_Nw>::_M_do_to_ulong() const
{
for (size_t __i = 1; __i < _Nw; ++__i)
@@ -300,7 +315,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#if __cplusplus >= 201103L
template<size_t _Nw>
- unsigned long long
+ _GLIBCXX14_CONSTEXPR unsigned long long
_Base_bitset<_Nw>::_M_do_to_ullong() const
{
const bool __dw = sizeof(unsigned long long) > sizeof(unsigned long);
@@ -316,7 +331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
#endif
template<size_t _Nw>
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_Base_bitset<_Nw>::
_M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT
{
@@ -332,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<size_t _Nw>
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_Base_bitset<_Nw>::
_M_do_find_next(size_t __prev, size_t __not_found) const _GLIBCXX_NOEXCEPT
{
@@ -406,7 +421,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_S_maskbit(size_t __pos) _GLIBCXX_NOEXCEPT
{ return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
- _WordT&
+ _GLIBCXX14_CONSTEXPR _WordT&
_M_getword(size_t) _GLIBCXX_NOEXCEPT
{ return _M_w; }
@@ -415,12 +430,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return _M_w; }
#if __cplusplus >= 201103L
- const _WordT*
+ constexpr const _WordT*
_M_getdata() const noexcept
{ return &_M_w; }
#endif
- _WordT&
+ _GLIBCXX14_CONSTEXPR _WordT&
_M_hiword() _GLIBCXX_NOEXCEPT
{ return _M_w; }
@@ -428,67 +443,67 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_hiword() const _GLIBCXX_NOEXCEPT
{ return _M_w; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_and(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT
{ _M_w &= __x._M_w; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_or(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT
{ _M_w |= __x._M_w; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_xor(const _Base_bitset<1>& __x) _GLIBCXX_NOEXCEPT
{ _M_w ^= __x._M_w; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_left_shift(size_t __shift) _GLIBCXX_NOEXCEPT
{ _M_w <<= __shift; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_right_shift(size_t __shift) _GLIBCXX_NOEXCEPT
{ _M_w >>= __shift; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_flip() _GLIBCXX_NOEXCEPT
{ _M_w = ~_M_w; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_set() _GLIBCXX_NOEXCEPT
{ _M_w = ~static_cast<_WordT>(0); }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_reset() _GLIBCXX_NOEXCEPT
{ _M_w = 0; }
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_is_equal(const _Base_bitset<1>& __x) const _GLIBCXX_NOEXCEPT
{ return _M_w == __x._M_w; }
template<size_t _Nb>
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_are_all() const _GLIBCXX_NOEXCEPT
{ return _M_w == (~static_cast<_WordT>(0)
>> (_GLIBCXX_BITSET_BITS_PER_WORD - _Nb)); }
- bool
+ _GLIBCXX14_CONSTEXPR bool
_M_is_any() const _GLIBCXX_NOEXCEPT
{ return _M_w != 0; }
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_count() const _GLIBCXX_NOEXCEPT
{ return __builtin_popcountl(_M_w); }
- unsigned long
+ _GLIBCXX14_CONSTEXPR unsigned long
_M_do_to_ulong() const _GLIBCXX_NOEXCEPT
{ return _M_w; }
#if __cplusplus >= 201103L
- unsigned long long
+ constexpr unsigned long long
_M_do_to_ullong() const noexcept
{ return _M_w; }
#endif
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_find_first(size_t __not_found) const _GLIBCXX_NOEXCEPT
{
if (_M_w != 0)
@@ -498,7 +513,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
// find the next "on" bit that follows "prev"
- size_t
+ _GLIBCXX14_CONSTEXPR size_t
_M_do_find_next(size_t __prev, size_t __not_found) const
_GLIBCXX_NOEXCEPT
{
@@ -552,17 +567,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// This would normally give access to the data. The bounds-checking
// in the bitset class will prevent the user from getting this far,
- // but (1) it must still return an lvalue to compile, and (2) the
- // user might call _Unchecked_set directly, in which case this /needs/
- // to fail. Let's not penalize zero-length users unless they actually
+ // but this must fail if the user calls _Unchecked_set directly.
+ // Let's not penalize zero-length users unless they actually
// make an unchecked call; all the memory ugliness is therefore
// localized to this single should-never-get-this-far function.
+ __attribute__((__noreturn__))
_WordT&
_M_getword(size_t) _GLIBCXX_NOEXCEPT
- {
- __throw_out_of_range(__N("_Base_bitset::_M_getword"));
- return *new _WordT;
- }
+ { __throw_out_of_range(__N("_Base_bitset::_M_getword")); }
_GLIBCXX_CONSTEXPR _WordT
_M_getword(size_t) const _GLIBCXX_NOEXCEPT
@@ -572,75 +584,75 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_hiword() const _GLIBCXX_NOEXCEPT
{ return 0; }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_and(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_or(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_xor(const _Base_bitset<0>&) _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_left_shift(size_t) _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_right_shift(size_t) _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_flip() _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_set() _GLIBCXX_NOEXCEPT
{ }
- void
+ _GLIBCXX14_CONSTEXPR void
_M_do_reset() _GLIBCXX_NOEXCEPT
{ }
// Are all empty bitsets equal to each other? Are they equal to
// themselves? How to compare a thing which has no state? What is
// the sound of one zero-length bitset clapping?
- bool
+ _GLIBCXX_CONSTEXPR bool
_M_is_equal(const _Base_bitset<0>&) const _GLIBCXX_NOEXCEPT
{ return true; }
template<size_t _Nb>
- bool
+ _GLIBCXX_CONSTEXPR bool
_M_are_all() const _GLIBCXX_NOEXCEPT
{ return true; }
- bool
+ _GLIBCXX_CONSTEXPR bool
_M_is_any() const _GLIBCXX_NOEXCEPT
{ return false; }
- size_t
+ _GLIBCXX_CONSTEXPR size_t
_M_do_count() const _GLIBCXX_NOEXCEPT
{ return 0; }
- unsigned long
+ _GLIBCXX_CONSTEXPR unsigned long
_M_do_to_ulong() const _GLIBCXX_NOEXCEPT
{ return 0; }
#if __cplusplus >= 201103L
- unsigned long long
+ constexpr unsigned long long
_M_do_to_ullong() const noexcept
{ return 0; }
#endif
// Normally "not found" is the size, but that could also be
// misinterpreted as an index in this corner case. Oh well.
- size_t
+ _GLIBCXX_CONSTEXPR size_t
_M_do_find_first(size_t) const _GLIBCXX_NOEXCEPT
{ return 0; }
- size_t
+ _GLIBCXX_CONSTEXPR size_t
_M_do_find_next(size_t, size_t) const _GLIBCXX_NOEXCEPT
{ return 0; }
};
@@ -652,7 +664,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
typedef unsigned long _WordT;
- static void
+ static _GLIBCXX14_CONSTEXPR void
_S_do_sanitize(_WordT& __val) _GLIBCXX_NOEXCEPT
{ __val &= ~((~static_cast<_WordT>(0)) << _Extrabits); }
};
@@ -662,7 +674,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{
typedef unsigned long _WordT;
- static void
+ static _GLIBCXX14_CONSTEXPR void
_S_do_sanitize(_WordT) _GLIBCXX_NOEXCEPT { }
};
@@ -755,7 +767,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base;
typedef unsigned long _WordT;
+#if _GLIBCXX_HOSTED
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
_M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
size_t __position) const
@@ -766,7 +780,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
"(which is %zu)"),
__position, __s.size());
}
+#endif // HOSTED
+ _GLIBCXX23_CONSTEXPR
void _M_check(size_t __position, const char *__s) const
{
if (__position >= _Nb)
@@ -775,6 +791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__s, __position, _Nb);
}
+ _GLIBCXX23_CONSTEXPR
void
_M_do_sanitize() _GLIBCXX_NOEXCEPT
{
@@ -810,6 +827,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
reference();
public:
+ _GLIBCXX23_CONSTEXPR
reference(bitset& __b, size_t __pos) _GLIBCXX_NOEXCEPT
{
_M_wp = &__b._M_getword(__pos);
@@ -820,10 +838,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
reference(const reference&) = default;
#endif
+#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
+ constexpr
+#endif
~reference() _GLIBCXX_NOEXCEPT
{ }
// For b[i] = __x;
+ _GLIBCXX23_CONSTEXPR
reference&
operator=(bool __x) _GLIBCXX_NOEXCEPT
{
@@ -835,6 +857,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
// For b[i] = b[__j];
+ _GLIBCXX23_CONSTEXPR
reference&
operator=(const reference& __j) _GLIBCXX_NOEXCEPT
{
@@ -846,15 +869,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
// Flips the bit
+ _GLIBCXX23_CONSTEXPR
bool
operator~() const _GLIBCXX_NOEXCEPT
{ return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) == 0; }
// For __x = b[i];
+ _GLIBCXX23_CONSTEXPR
operator bool() const _GLIBCXX_NOEXCEPT
{ return (*(_M_wp) & _Base::_S_maskbit(_M_bpos)) != 0; }
// For b[i].flip();
+ _GLIBCXX23_CONSTEXPR
reference&
flip() _GLIBCXX_NOEXCEPT
{
@@ -879,6 +905,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ _M_do_sanitize(); }
#endif
+#if _GLIBCXX_HOSTED
/**
* Use a subset of a string.
* @param __s A string of @a 0 and @a 1 characters.
@@ -889,6 +916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* which is neither @a 0 nor @a 1.
*/
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
explicit
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
size_t __position = 0)
@@ -911,6 +939,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* which is neither @a 0 nor @a 1.
*/
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
size_t __position, size_t __n)
: _Base()
@@ -922,6 +951,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
bitset(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
size_t __position, size_t __n,
_CharT __zero, _CharT __one = _CharT('1'))
@@ -942,6 +972,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* which is neither @a __zero nor @a __one.
*/
template<typename _CharT>
+ [[__gnu__::__nonnull__]]
+ _GLIBCXX23_CONSTEXPR
explicit
bitset(const _CharT* __str,
typename std::basic_string<_CharT>::size_type __n
@@ -958,7 +990,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__n, __zero,
__one);
}
-#endif
+#endif // C++11
+#endif // HOSTED
// 23.3.5.2 bitset operations:
///@{
@@ -968,6 +1001,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* These should be self-explanatory.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator&=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -975,6 +1009,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator|=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -982,6 +1017,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator^=(const bitset<_Nb>& __rhs) _GLIBCXX_NOEXCEPT
{
@@ -997,6 +1033,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* These should be self-explanatory.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator<<=(size_t __position) _GLIBCXX_NOEXCEPT
{
@@ -1010,6 +1047,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
operator>>=(size_t __position) _GLIBCXX_NOEXCEPT
{
@@ -1030,6 +1068,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* extensions from the SGI version. They do no range checking.
* @ingroup SGIextensions
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
_Unchecked_set(size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -1037,6 +1076,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
_Unchecked_set(size_t __pos, int __val) _GLIBCXX_NOEXCEPT
{
@@ -1047,6 +1087,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
_Unchecked_reset(size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -1054,6 +1095,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return *this;
}
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
_Unchecked_flip(size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -1071,6 +1113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief Sets every bit to true.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
set() _GLIBCXX_NOEXCEPT
{
@@ -1085,6 +1128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @param __val Either true or false, defaults to true.
* @throw std::out_of_range If @a pos is bigger the size of the %set.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
set(size_t __position, bool __val = true)
{
@@ -1095,6 +1139,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief Sets every bit to false.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
reset() _GLIBCXX_NOEXCEPT
{
@@ -1109,6 +1154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*
* Same as writing @c set(pos,false).
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
reset(size_t __position)
{
@@ -1119,6 +1165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
/**
* @brief Toggles every bit to its opposite value.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
flip() _GLIBCXX_NOEXCEPT
{
@@ -1132,6 +1179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @param __position The index of the bit.
* @throw std::out_of_range If @a pos is bigger the size of the %set.
*/
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>&
flip(size_t __position)
{
@@ -1140,6 +1188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
/// See the no-argument flip().
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator~() const _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(*this).flip(); }
@@ -1159,6 +1208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* The DR has since been changed: range-checking is a precondition
* (users' responsibility), and these functions must not throw. -pme
*/
+ _GLIBCXX23_CONSTEXPR
reference
operator[](size_t __position)
{ return reference(*this, __position); }
@@ -1174,16 +1224,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @throw std::overflow_error If there are too many bits to be
* represented in an @c unsigned @c long.
*/
+ _GLIBCXX23_CONSTEXPR
unsigned long
to_ulong() const
{ return this->_M_do_to_ulong(); }
#if __cplusplus >= 201103L
+ _GLIBCXX23_CONSTEXPR
unsigned long long
to_ullong() const
{ return this->_M_do_to_ullong(); }
#endif
+#if _GLIBCXX_HOSTED
/**
* @brief Returns a character interpretation of the %bitset.
* @return The string equivalent of the bits.
@@ -1193,6 +1246,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* an example).
*/
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, _Alloc>
to_string() const
{
@@ -1204,6 +1258,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 396. what are characters zero and one.
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, _Alloc>
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{
@@ -1215,6 +1270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 434. bitset::to_string() hard to use.
template<class _CharT, class _Traits>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string() const
{ return to_string<_CharT, _Traits, std::allocator<_CharT> >(); }
@@ -1222,12 +1278,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 853. to_string needs updating with zero and one.
template<class _CharT, class _Traits>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, _Traits, std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
{ return to_string<_CharT, _Traits,
std::allocator<_CharT> >(__zero, __one); }
template<class _CharT>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string() const
@@ -1237,6 +1295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<class _CharT>
+ _GLIBCXX23_CONSTEXPR
std::basic_string<_CharT, std::char_traits<_CharT>,
std::allocator<_CharT> >
to_string(_CharT __zero, _CharT __one = _CharT('1')) const
@@ -1245,6 +1304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::allocator<_CharT> >(__zero, __one);
}
+ _GLIBCXX23_CONSTEXPR
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string() const
{
@@ -1252,6 +1312,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::allocator<char> >();
}
+ _GLIBCXX23_CONSTEXPR
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
to_string(char __zero, char __one = '1') const
{
@@ -1261,11 +1322,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Helper functions for string operations.
template<class _CharT, class _Traits>
+ _GLIBCXX23_CONSTEXPR
void
_M_copy_from_ptr(const _CharT*, size_t, size_t, size_t,
_CharT, _CharT);
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
_M_copy_from_string(const std::basic_string<_CharT,
_Traits, _Alloc>& __s, size_t __pos, size_t __n,
@@ -1274,23 +1337,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__zero, __one); }
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>&,
_CharT, _CharT) const;
// NB: Backward compat.
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
_M_copy_from_string(const std::basic_string<_CharT,
_Traits, _Alloc>& __s, size_t __pos, size_t __n)
{ _M_copy_from_string(__s, __pos, __n, _CharT('0'), _CharT('1')); }
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
_M_copy_to_string(std::basic_string<_CharT, _Traits,_Alloc>& __s) const
{ _M_copy_to_string(__s, _CharT('0'), _CharT('1')); }
+#endif // HOSTED
/// Returns the number of bits which are set.
+ _GLIBCXX23_CONSTEXPR
size_t
count() const _GLIBCXX_NOEXCEPT
{ return this->_M_do_count(); }
@@ -1302,11 +1370,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
///@{
/// These comparisons for equality/inequality are, well, @e bitwise.
+ _GLIBCXX23_CONSTEXPR
bool
operator==(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
{ return this->_M_is_equal(__rhs); }
#if __cpp_impl_three_way_comparison < 201907L
+ _GLIBCXX23_CONSTEXPR
bool
operator!=(const bitset<_Nb>& __rhs) const _GLIBCXX_NOEXCEPT
{ return !this->_M_is_equal(__rhs); }
@@ -1319,6 +1389,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @return The value at @a pos.
* @throw std::out_of_range If @a pos is bigger the size of the %set.
*/
+ _GLIBCXX23_CONSTEXPR
bool
test(size_t __position) const
{
@@ -1332,6 +1403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Tests whether all the bits are on.
* @return True if all the bits are set.
*/
+ _GLIBCXX23_CONSTEXPR
bool
all() const _GLIBCXX_NOEXCEPT
{ return this->template _M_are_all<_Nb>(); }
@@ -1340,6 +1412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Tests whether any of the bits are on.
* @return True if at least one bit is set.
*/
+ _GLIBCXX23_CONSTEXPR
bool
any() const _GLIBCXX_NOEXCEPT
{ return this->_M_is_any(); }
@@ -1348,16 +1421,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @brief Tests whether any of the bits are on.
* @return True if none of the bits are set.
*/
+ _GLIBCXX23_CONSTEXPR
bool
none() const _GLIBCXX_NOEXCEPT
{ return !this->_M_is_any(); }
///@{
/// Self-explanatory.
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator<<(size_t __position) const _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(*this) <<= __position; }
+ _GLIBCXX23_CONSTEXPR
bitset<_Nb>
operator>>(size_t __position) const _GLIBCXX_NOEXCEPT
{ return bitset<_Nb>(*this) >>= __position; }
@@ -1369,6 +1445,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @ingroup SGIextensions
* @sa _Find_next
*/
+ _GLIBCXX23_CONSTEXPR
size_t
_Find_first() const _GLIBCXX_NOEXCEPT
{ return this->_M_do_find_first(_Nb); }
@@ -1380,14 +1457,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* @ingroup SGIextensions
* @sa _Find_first
*/
+ _GLIBCXX23_CONSTEXPR
size_t
_Find_next(size_t __prev) const _GLIBCXX_NOEXCEPT
{ return this->_M_do_find_next(__prev, _Nb); }
};
+#if _GLIBCXX_HOSTED
// Definitions of non-inline member functions.
template<size_t _Nb>
template<class _CharT, class _Traits>
+ _GLIBCXX23_CONSTEXPR
void
bitset<_Nb>::
_M_copy_from_ptr(const _CharT* __s, size_t __len,
@@ -1409,16 +1489,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<size_t _Nb>
template<class _CharT, class _Traits, class _Alloc>
+ _GLIBCXX23_CONSTEXPR
void
bitset<_Nb>::
_M_copy_to_string(std::basic_string<_CharT, _Traits, _Alloc>& __s,
_CharT __zero, _CharT __one) const
{
__s.assign(_Nb, __zero);
- for (size_t __i = _Nb; __i > 0; --__i)
- if (_Unchecked_test(__i - 1))
- _Traits::assign(__s[_Nb - __i], __one);
+ size_t __n = this->_Find_first();
+ while (__n < _Nb)
+ {
+ __s[_Nb - __n - 1] = __one;
+ __n = _Find_next(__n);
+ }
}
+#endif // HOSTED
// 23.3.5.3 bitset operations:
///@{
@@ -1431,6 +1516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* These should be self-explanatory.
*/
template<size_t _Nb>
+ _GLIBCXX23_CONSTEXPR
inline bitset<_Nb>
operator&(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{
@@ -1440,6 +1526,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<size_t _Nb>
+ _GLIBCXX23_CONSTEXPR
inline bitset<_Nb>
operator|(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{
@@ -1449,6 +1536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template <size_t _Nb>
+ _GLIBCXX23_CONSTEXPR
inline bitset<_Nb>
operator^(const bitset<_Nb>& __x, const bitset<_Nb>& __y) _GLIBCXX_NOEXCEPT
{
@@ -1458,6 +1546,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
///@}
+#if _GLIBCXX_HOSTED
///@{
/**
* @brief Global I/O operators for bitsets.
@@ -1527,7 +1616,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
if (__tmp.empty() && _Nb)
__state |= __ios_base::failbit;
- else
+ else if _GLIBCXX17_CONSTEXPR (_Nb)
__x._M_copy_from_string(__tmp, static_cast<size_t>(0), _Nb,
__zero, __one);
if (__state)
@@ -1549,6 +1638,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return __os << __tmp;
}
///@}
+#endif // HOSTED
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
@@ -1557,7 +1647,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
#undef _GLIBCXX_BITSET_BITS_PER_WORD
#undef _GLIBCXX_BITSET_BITS_PER_ULL
-#if __cplusplus >= 201103L
+#if __cplusplus >= 201103L && _GLIBCXX_HOSTED
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -1591,7 +1681,7 @@ _GLIBCXX_END_NAMESPACE_VERSION
#endif // C++11
-#ifdef _GLIBCXX_DEBUG
+#if defined _GLIBCXX_DEBUG && _GLIBCXX_HOSTED
# include <debug/bitset>
#endif
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 94e73ea..c5853fc 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1451,12 +1451,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
#pragma GCC diagnostic pop
- // is_nothrow_convertible for C++11
- template<typename _From, typename _To>
- struct __is_nothrow_convertible
- : public __is_nt_convertible_helper<_From, _To>::type
- { };
-
#if __cplusplus > 201703L
#define __cpp_lib_is_nothrow_convertible 201806L
/// is_nothrow_convertible
@@ -2557,13 +2551,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
+ // Detection idiom.
+ // Detect whether _Op<_Args...> is a valid type, use default _Def if not.
+
+#if __cpp_concepts
+ // Implementation of the detection idiom (negative case).
+ template<typename _Def, template<typename...> class _Op, typename... _Args>
+ struct __detected_or
+ {
+ using type = _Def;
+ using __is_detected = false_type;
+ };
+
+ // Implementation of the detection idiom (positive case).
+ template<typename _Def, template<typename...> class _Op, typename... _Args>
+ requires requires { typename _Op<_Args...>; }
+ struct __detected_or<_Def, _Op, _Args...>
+ {
+ using type = _Op<_Args...>;
+ using __is_detected = true_type;
+ };
+#else
/// Implementation of the detection idiom (negative case).
template<typename _Default, typename _AlwaysVoid,
template<typename...> class _Op, typename... _Args>
struct __detector
{
- using value_t = false_type;
using type = _Default;
+ using __is_detected = false_type;
};
/// Implementation of the detection idiom (positive case).
@@ -2571,14 +2586,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename... _Args>
struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...>
{
- using value_t = true_type;
using type = _Op<_Args...>;
+ using __is_detected = true_type;
};
- // Detect whether _Op<_Args...> is a valid type, use _Default if not.
template<typename _Default, template<typename...> class _Op,
typename... _Args>
using __detected_or = __detector<_Default, void, _Op, _Args...>;
+#endif // __cpp_concepts
// _Op<_Args...> if that is a valid type, otherwise _Default.
template<typename _Default, template<typename...> class _Op,
@@ -2825,7 +2840,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// The primary template is used for invalid INVOKE expressions.
template<typename _Result, typename _Ret,
bool = is_void<_Ret>::value, typename = void>
- struct __is_invocable_impl : false_type { };
+ struct __is_invocable_impl
+ : false_type
+ {
+ using __nothrow_type = false_type; // For is_nothrow_invocable_r
+ };
// Used for valid INVOKE and INVOKE<void> expressions.
template<typename _Result, typename _Ret>
@@ -2833,7 +2852,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/* is_void<_Ret> = */ true,
__void_t<typename _Result::type>>
: true_type
- { };
+ {
+ using __nothrow_type = true_type; // For is_nothrow_invocable_r
+ };
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
@@ -2845,23 +2866,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
private:
// The type of the INVOKE expression.
- // Unlike declval, this doesn't add_rvalue_reference.
- static typename _Result::type _S_get();
+ // Unlike declval, this doesn't add_rvalue_reference, so it respects
+ // guaranteed copy elision.
+ static typename _Result::type _S_get() noexcept;
template<typename _Tp>
- static void _S_conv(_Tp);
+ static void _S_conv(_Tp) noexcept;
// This overload is viable if INVOKE(f, args...) can convert to _Tp.
- template<typename _Tp, typename = decltype(_S_conv<_Tp>(_S_get()))>
- static true_type
+ template<typename _Tp, bool _Check_Noex = false,
+ typename = decltype(_S_conv<_Tp>(_S_get())),
+ bool _Noex = noexcept(_S_conv<_Tp>(_S_get()))>
+ static __bool_constant<_Check_Noex ? _Noex : true>
_S_test(int);
- template<typename _Tp>
+ template<typename _Tp, bool = false>
static false_type
_S_test(...);
public:
+ // For is_invocable_r
using type = decltype(_S_test<_Ret>(1));
+
+ // For is_nothrow_invocable_r
+ using __nothrow_type = decltype(_S_test<_Ret, true>(1));
};
#pragma GCC diagnostic pop
@@ -2992,15 +3020,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
/// @cond undocumented
- template<typename _Result, typename _Ret, typename = void>
- struct __is_nt_invocable_impl : false_type { };
-
template<typename _Result, typename _Ret>
- struct __is_nt_invocable_impl<_Result, _Ret,
- __void_t<typename _Result::type>>
- : __or_<is_void<_Ret>,
- __is_nothrow_convertible<typename _Result::type, _Ret>>::type
- { };
+ using __is_nt_invocable_impl
+ = typename __is_invocable_impl<_Result, _Ret>::__nothrow_type;
/// @endcond
/// std::is_nothrow_invocable_r
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 6b61879..3fd5182 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -309,6 +309,7 @@
#if _GLIBCXX_HOSTED
#define __cpp_lib_adaptor_iterator_pair_constructor 202106L
#if __cpp_constexpr_dynamic_alloc
+# define __cpp_lib_constexpr_bitset 202202L
# undef __cpp_lib_constexpr_memory
# define __cpp_lib_constexpr_memory 202202L
#endif
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index bd4289c..5a3dcbd 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2246,12 +2246,7 @@ def build_libstdcxx_dictionary ():
libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
- libstdcxx_printer.add('std::__debug::priority_queue',
- StdStackOrQueuePrinter)
- libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
- libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
- libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
# These are the TR1 and C++11 printers.
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
index 20cda77..b8b3747 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++1998/all_attributes.cc
@@ -38,8 +38,3 @@
#include <bits/extc++.h>
#include <cxxabi.h>
-
-int
-main()
-{
-}
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
index c2b4c23..222ab78 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/all_attributes.cc
@@ -38,8 +38,3 @@
#include <bits/extc++.h>
#include <cxxabi.h>
-
-int
-main()
-{
-}
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
index f6c4251..b31d13f 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2014/all_attributes.cc
@@ -38,8 +38,3 @@
#include <bits/extc++.h>
#include <cxxabi.h>
-
-int
-main()
-{
-}
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
index 170ebef..fd4d7d4 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2017/all_attributes.cc
@@ -37,8 +37,3 @@
#include <bits/extc++.h>
#include <cxxabi.h>
-
-int
-main()
-{
-}
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
index 1d573a2..f700bad 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2020/all_attributes.cc
@@ -36,8 +36,3 @@
#include <bits/extc++.h>
#include <cxxabi.h>
-
-int
-main()
-{
-}
diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc
index 82e201c..6490cd6 100644
--- a/libstdc++-v3/testsuite/17_intro/names.cc
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
@@ -112,6 +112,7 @@
#define tmp (
#define sz (
#define token (
+#define value_t (
#if __cplusplus < 201103L
#define uses_allocator (
diff --git a/libstdc++-v3/testsuite/18_support/uncaught_exception/14026.cc b/libstdc++-v3/testsuite/18_support/uncaught_exception/14026.cc
index 22d4a90..bd281b9 100644
--- a/libstdc++-v3/testsuite/18_support/uncaught_exception/14026.cc
+++ b/libstdc++-v3/testsuite/18_support/uncaught_exception/14026.cc
@@ -28,7 +28,7 @@ static void
no_uncaught ()
{
if (std::uncaught_exception())
- abort();
+ std::abort();
}
int
diff --git a/libstdc++-v3/testsuite/20_util/bitset/107037.cc b/libstdc++-v3/testsuite/20_util/bitset/107037.cc
new file mode 100644
index 0000000..b4560dd
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/107037.cc
@@ -0,0 +1,7 @@
+// { dg-options "-std=c++03" }
+// { dg-do compile }
+// PR libstdc++/107037 bitset::_M_do_reset fails for strict -std=c++03 mode
+#include <bitset>
+template class std::bitset<0>;
+template class std::bitset<1>;
+template class std::bitset<100>;
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/18604.cc b/libstdc++-v3/testsuite/20_util/bitset/18604.cc
index f91cdfa..f91cdfa 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/18604.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/18604.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/45713.cc b/libstdc++-v3/testsuite/20_util/bitset/45713.cc
index 5cec1b5..5cec1b5 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/45713.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/45713.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/access/constexpr.cc b/libstdc++-v3/testsuite/20_util/bitset/access/constexpr.cc
new file mode 100644
index 0000000..53bb07f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/access/constexpr.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include <bitset>
+#include <string>
+#include <testsuite_hooks.h>
+
+constexpr bool
+test_indexing()
+{
+ std::bitset<100> b("10010110");
+ VERIFY( b[0] == 0 );
+ VERIFY( b[1] == 1 );
+ const auto& cb = b;
+ VERIFY( cb[0] == 0 );
+ VERIFY( cb[1] == 1 );
+ b[1].flip();
+ VERIFY( cb[1] == 0 );
+ VERIFY( b[1] == 0 );
+ VERIFY( ~b[1] == 1 );
+ b[3] = true;
+ bool b3 = b[3];
+ VERIFY( b3 );
+ b[4] = b[3];
+ return true;
+}
+
+static_assert( test_indexing() );
+
+#if _GLIBCXX_USE_CXX11_ABI
+constexpr bool
+test_to_string()
+{
+ std::string str = "01101001";
+ return std::bitset<8>(str).to_string() == str;
+}
+
+static_assert( test_to_string() );
+#endif
+
+constexpr bool
+test_to_ulong()
+{
+ unsigned long val = 0xcabba123;
+ return std::bitset<100>(val).to_ulong() == val;
+}
+
+static_assert( test_to_ulong() );
+
+constexpr bool
+test_to_ullong()
+{
+ unsigned long long val = 0x0123abcd0123abcd;
+ return std::bitset<100>(val).to_ullong() == val;
+}
+
+static_assert( test_to_ullong() );
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/to_string/dr396.cc b/libstdc++-v3/testsuite/20_util/bitset/access/dr396.cc
index dfba27e..dfba27e 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/to_string/dr396.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/access/dr396.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc b/libstdc++-v3/testsuite/20_util/bitset/access/to_string.cc
index 8384eb9..8384eb9 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/to_string/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/access/to_string.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/to_ullong/1.cc b/libstdc++-v3/testsuite/20_util/bitset/access/to_ullong.cc
index 18fc077..18fc077 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/to_ullong/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/access/to_ullong.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/to_ulong/1.cc b/libstdc++-v3/testsuite/20_util/bitset/access/to_ulong.cc
index 8163701..8163701 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/to_ulong/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/access/to_ulong.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/1.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc
index c2a54c3..c2a54c3 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/16020.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/16020.cc
index ffccdd2..ffccdd2 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/16020.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/16020.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/2.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/2.cc
index 947124e..947124e 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/2.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/2.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/3.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/3.cc
index 6308e4e..6308e4e 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/3.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/3.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/38244.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/38244.cc
index 610197c..610197c 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/38244.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/38244.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/50268.cc
index 6d4b946..6d4b946 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/50268.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/50268.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/6282.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc
index 5409336..5409336 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/6282.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/6282.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/constexpr.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr.cc
index bf16b19..bf16b19 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/constexpr.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc
new file mode 100644
index 0000000..532fc9d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc
@@ -0,0 +1,55 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include <bitset>
+
+#ifndef __cpp_lib_constexpr_bitset
+# error "Feature-test macro for constexpr bitset missing in <bitset>"
+#elif __cpp_lib_constexpr_bitset != 202202L
+# error "Feature-test macro for constexpr bitset has wrong value in <bitset>"
+#endif
+
+#include <testsuite_hooks.h>
+
+constexpr bool test_ntbs()
+{
+ VERIFY( std::bitset<0>("000").all() );
+ VERIFY( std::bitset<0>("000", 2).all() );
+ VERIFY( std::bitset<1>("100", 2).all() );
+ VERIFY( std::bitset<1>("z00", 2, 'z').none() );
+ VERIFY( std::bitset<2>("ab0", 3, 'a', 'b').count() == 1 );
+
+ return true;
+}
+
+static_assert( test_ntbs() );
+
+#if _GLIBCXX_USE_CXX11_ABI
+constexpr bool test_string()
+{
+ using S = std::string;
+ VERIFY( std::bitset<0>(S("000")).all() );
+ VERIFY( std::bitset<1>(S("010"), 1, 2).all() );
+ VERIFY( std::bitset<2>(S("0110"), 1, 2).all() );
+ VERIFY( std::bitset<2>(S("1z110"), 1, 3, 'z').count() == 1 );
+ VERIFY( std::bitset<3>(S("0abab0"), 2, 3, 'a', 'b').count() == 2 );
+
+ return true;
+}
+
+static_assert( test_string() );
+
+constexpr bool test_wstring()
+{
+ using S = std::wstring;
+ VERIFY( std::bitset<0>(S(L"000")).all() );
+ VERIFY( std::bitset<1>(S(L"010"), 1, 2).all() );
+ VERIFY( std::bitset<2>(S(L"0110"), 1, 2).all() );
+ VERIFY( std::bitset<2>(S(L"1z110"), 1, 3, L'z').count() == 1 );
+ VERIFY( std::bitset<3>(S(L"0abab0"), 2, 3, L'a', L'b').count() == 2 );
+
+ return true;
+}
+
+static_assert( test_wstring() );
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-1.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-1.cc
index aa50804..aa50804 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-2.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-2.cc
index 2371bef..2371bef 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr1325-2.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/dr1325-2.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr396.cc b/libstdc++-v3/testsuite/20_util/bitset/cons/dr396.cc
index f1f9d87..f1f9d87 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/cons/dr396.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/cons/dr396.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/count/constexpr.cc b/libstdc++-v3/testsuite/20_util/bitset/count/constexpr.cc
new file mode 100644
index 0000000..98f8e22
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/count/constexpr.cc
@@ -0,0 +1,93 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include <bitset>
+#include <testsuite_hooks.h>
+
+constexpr bool
+test_counting()
+{
+ auto check = []<std::size_t N>(const std::bitset<N>& bs) {
+ VERIFY( bs.size() == N );
+ unsigned count = 0;
+ for (unsigned n = 0; n < N; ++n)
+ if (bs.test(n))
+ ++count;
+ VERIFY( count == bs.count() );
+ VERIFY( bs.all() == (bs.count() == bs.size()) );
+ VERIFY( bs.any() == (bs.count() != 0) );
+ VERIFY( bs.none() == (bs.count() == 0) );
+ return true;
+ };
+
+ std::bitset<0> z0;
+ VERIFY( z0.count() == 0 );
+ VERIFY( check(z0) );
+ z0.set();
+ VERIFY( z0.count() == 0 );
+ VERIFY( check(z0) );
+
+ std::bitset<7> z7;
+ VERIFY( z7.count() == 0 );
+ VERIFY( check(z7) );
+ z7.set();
+ VERIFY( z7.count() == 7 );
+ VERIFY( check(z7) );
+ z7.flip(1);
+ VERIFY( z7.count() == 6 );
+ VERIFY( check(z7) );
+
+ std::bitset<31> z31;
+ VERIFY( z31.count() == 0 );
+ VERIFY( check(z31) );
+ z31.set();
+ VERIFY( z31.count() == 31 );
+ VERIFY( check(z31) );
+ z31.flip(1);
+ VERIFY( z31.count() == 30 );
+ VERIFY( check(z31) );
+
+ std::bitset<32> z32;
+ VERIFY( z32.count() == 0 );
+ VERIFY( check(z32) );
+ z32.set();
+ VERIFY( z32.count() == 32 );
+ VERIFY( check(z32) );
+ z32.flip(1);
+ VERIFY( z32.count() == 31 );
+ VERIFY( check(z32) );
+
+ std::bitset<63> z63;
+ VERIFY( z63.count() == 0 );
+ VERIFY( check(z63) );
+ z63.set();
+ VERIFY( z63.count() == 63 );
+ VERIFY( check(z63) );
+ z63.flip(1);
+ VERIFY( z63.count() == 62 );
+ VERIFY( check(z63) );
+
+ std::bitset<64> z64;
+ VERIFY( z64.count() == 0 );
+ VERIFY( check(z64) );
+ z64.set();
+ VERIFY( z64.count() == 64 );
+ VERIFY( check(z64) );
+ z64.flip(1);
+ VERIFY( z64.count() == 63 );
+ VERIFY( check(z64) );
+
+ std::bitset<1000> z1k;
+ VERIFY( z1k.count() == 0 );
+ VERIFY( check(z1k) );
+ z1k.set();
+ VERIFY( z1k.count() == 1000 );
+ VERIFY( check(z1k) );
+ z1k.flip(1);
+ VERIFY( z1k.count() == 999 );
+ VERIFY( check(z1k) );
+
+ return true;
+}
+
+static_assert( test_counting() );
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/debug/invalidation/1.cc b/libstdc++-v3/testsuite/20_util/bitset/debug/invalidation/1.cc
index 5d0e3c15..5d0e3c15 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/debug/invalidation/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/debug/invalidation/1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc b/libstdc++-v3/testsuite/20_util/bitset/ext/15361.cc
index 3924700..3924700 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/ext/15361.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/ext/15361.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/ext/constexpr.cc b/libstdc++-v3/testsuite/20_util/bitset/ext/constexpr.cc
new file mode 100644
index 0000000..f82e7aa
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/ext/constexpr.cc
@@ -0,0 +1,32 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include <bitset>
+#include <testsuite_hooks.h>
+
+constexpr bool
+test_find()
+{
+ VERIFY( std::bitset<0>()._Find_first() == 0 );
+ VERIFY( std::bitset<1>()._Find_first() == 1 );
+ VERIFY( std::bitset<55>("001000")._Find_first() == 3 );
+ VERIFY( std::bitset<66>("101000")._Find_next(3) == 5 );
+ return true;
+}
+
+static_assert( test_find() );
+
+constexpr bool
+test_unchecked()
+{
+ VERIFY( std::bitset<1>()._Unchecked_set(0).count() == 1 );
+ VERIFY( std::bitset<44>()._Unchecked_set(3).count() == 1 );
+ VERIFY( std::bitset<55>()._Unchecked_set(3, 0).count() == 0 );
+ VERIFY( std::bitset<66>()._Unchecked_set(3, 1).count() == 1 );
+ VERIFY( std::bitset<77>("111")._Unchecked_reset(1).count() == 2 );
+ VERIFY( std::bitset<88>("101")._Unchecked_flip(1).count() == 3 );
+ VERIFY( std::bitset<99>("010")._Unchecked_test(1) );
+ return true;
+}
+
+static_assert( test_unchecked() );
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/hash/1.cc b/libstdc++-v3/testsuite/20_util/bitset/hash/1.cc
index aba6b72..aba6b72 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/hash/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/hash/1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/input/1.cc b/libstdc++-v3/testsuite/20_util/bitset/io/input.cc
index 939861b..0f22cef 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/input/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/io/input.cc
@@ -39,7 +39,7 @@ void test01()
ss.clear();
ss.str("*");
ss >> b0;
- VERIFY( ss.rdstate() == ios_base::goodbit );
+ VERIFY( ss.rdstate() == ios_base::goodbit ); // LWG 3199
}
int main()
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/count/6124.cc b/libstdc++-v3/testsuite/20_util/bitset/observers/6124.cc
index d08211c..d08211c 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/count/6124.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/observers/6124.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/all/1.cc b/libstdc++-v3/testsuite/20_util/bitset/observers/all.cc
index 9840f25..9840f25 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/all/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/observers/all.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/test/1.cc b/libstdc++-v3/testsuite/20_util/bitset/observers/test.cc
index 2444499..2444499 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/test/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/observers/test.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/1.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/1.cc
index 5894210..5894210 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/13838.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/13838.cc
index c38ccc3..c38ccc3 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/13838.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/13838.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/2.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/2.cc
index a909e38..a909e38 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/2.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/2.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/96303.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/96303.cc
index b1f729d..b1f729d 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/96303.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/96303.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr-2.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr-2.cc
index 91098d9..91098d9 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr-2.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr-2.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr.cc
index 3f77003..3f77003 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/operations/constexpr.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr_c++23.cc b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr_c++23.cc
new file mode 100644
index 0000000..c594dd6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/operations/constexpr_c++23.cc
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do compile { target c++23 } }
+
+#include <bitset>
+#include <testsuite_hooks.h>
+
+constexpr bool
+test()
+{
+ std::bitset<16> b0;
+ std::bitset<16> b1 = ~b0;
+ VERIFY( b1.all() );
+ b0 &= b1;
+ VERIFY( b0.none() );
+ b0 |= b1;
+ VERIFY( b0.all() );
+ b0 ^= b1;
+ VERIFY( b0.none() );
+ b0 = b1 << 8;
+ VERIFY( !b0.all() && !b0.none() );
+ VERIFY( ((b1 << 8) | (b1 >> 8)).all() );
+ b1 <<= 8;
+ b1 >>= 8;
+ b1 >>= 8;
+ VERIFY( b1.none() );
+ VERIFY( (~b1).all() );
+ VERIFY( b1.flip().all() );
+ return true;
+}
+
+static_assert( test() );
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/requirements/constexpr_functions.cc b/libstdc++-v3/testsuite/20_util/bitset/requirements/constexpr_functions.cc
index a3c9047..a3c9047 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/requirements/constexpr_functions.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/requirements/constexpr_functions.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1.cc
index d1d8f57..d1d8f57 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1.cc
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc b/libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1_c++0x.cc
index 9a1c147..9a1c147 100644
--- a/libstdc++-v3/testsuite/23_containers/bitset/requirements/explicit_instantiation/1_c++0x.cc
+++ b/libstdc++-v3/testsuite/20_util/bitset/requirements/explicit_instantiation/1_c++0x.cc
diff --git a/libstdc++-v3/testsuite/20_util/bitset/version.cc b/libstdc++-v3/testsuite/20_util/bitset/version.cc
new file mode 100644
index 0000000..7197b1e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/version.cc
@@ -0,0 +1,10 @@
+// { dg-options "-std=gnu++23" }
+// { dg-do preprocess { target c++23 } }
+
+#include <version>
+
+#ifndef __cpp_lib_constexpr_bitset
+# error "Feature-test macro for constexpr bitset missing in <version>"
+#elif __cpp_lib_constexpr_bitset != 202202L
+# error "Feature-test macro for constexpr bitset has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/function/91456.cc b/libstdc++-v3/testsuite/20_util/function/91456.cc
index 6b6631c..081bf20 100644
--- a/libstdc++-v3/testsuite/20_util/function/91456.cc
+++ b/libstdc++-v3/testsuite/20_util/function/91456.cc
@@ -17,6 +17,9 @@
// { dg-do compile { target c++17 } }
+// PR 91456
+// std::function and std::is_invocable_r do not understand guaranteed elision
+
#include <functional>
struct Immovable {
diff --git a/libstdc++-v3/testsuite/23_containers/headers/bitset/synopsis.cc b/libstdc++-v3/testsuite/20_util/headers/bitset/synopsis.cc
index e7ea4f8..ed5604b 100644
--- a/libstdc++-v3/testsuite/23_containers/headers/bitset/synopsis.cc
+++ b/libstdc++-v3/testsuite/20_util/headers/bitset/synopsis.cc
@@ -27,17 +27,26 @@
# define NOTHROW
#endif
+#if __cplusplus > 202002L
+# define CONSTEXPR constexpr
+#else
+# define CONSTEXPR
+#endif
+
namespace std {
template <size_t N> class bitset;
// 23.3.5.3 bitset operations:
template <size_t N>
+ CONSTEXPR
bitset<N> operator&(const bitset<N>&, const bitset<N>&) NOTHROW;
template <size_t N>
+ CONSTEXPR
bitset<N> operator|(const bitset<N>&, const bitset<N>&) NOTHROW;
template <size_t N>
+ CONSTEXPR
bitset<N> operator^(const bitset<N>&, const bitset<N>&) NOTHROW;
template <class charT, class traits, size_t N>
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/synopsis.cc b/libstdc++-v3/testsuite/20_util/headers/memory/synopsis.cc
index 03e3f80d..15437c7 100644
--- a/libstdc++-v3/testsuite/20_util/headers/memory/synopsis.cc
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/synopsis.cc
@@ -26,20 +26,35 @@
# define NOTHROW
#endif
-namespace std {
+namespace std
+{
+#if __cplusplus >= 201103L
+ template<class Ptr> struct pointer_traits;
+ template<class T> struct pointer_traits<T*>;
+
+ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
+
+ struct allocator_arg_t;
+ extern const allocator_arg_t allocator_arg;
+
+ template<class T, class Alloc> struct uses_allocator;
+
+ template<class Alloc> struct allocator_traits;
+#endif // C++11
+
+#if __STDC_HOSTED__
// lib.default.allocator, the default allocator:
template <class T> class allocator;
+#if __cplusplus >= 202002L
+ template <class T, class U>
+ constexpr bool operator==(const allocator<T>&, const allocator<U>&) throw();
+#else
template <> class allocator<void>;
template <class T, class U>
-#if __cplusplus > 201703L
- constexpr
-#endif
bool operator==(const allocator<T>&, const allocator<U>&) throw();
template <class T, class U>
-#if __cplusplus > 201703L
- constexpr
-#endif
bool operator!=(const allocator<T>&, const allocator<U>&) throw();
+#endif
// lib.storage.iterator, raw storage iterator:
template <class OutputIterator, class T> class raw_storage_iterator;
@@ -49,18 +64,55 @@ namespace std {
pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) NOTHROW;
template <class T>
void return_temporary_buffer(T* p);
+#endif // HOSTED
// lib.specialized.algorithms, specialized algorithms:
+#if __cplusplus >= 201703L
+ template <class T> constexpr T* addressof(T&) noexcept;
+#elif __cplusplus >= 201402L
+ template <class T> T* addressof(T&) noexcept;
+#endif
template <class InputIterator, class ForwardIterator>
ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result);
+#if __cplusplus >= 201103L
+ template <class InputIterator, class Size, class ForwardIterator>
+ ForwardIterator
+ uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
+#endif
template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x);
template <class ForwardIterator, class Size, class T>
void uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
+#if __cplusplus >= 201103L
+ template<class T> class default_delete;
+ template<class T> class default_delete<T[]>;
+ template<class T, class D> class unique_ptr;
+ template<class T, class D> class unique_ptr<T[], D>;
+ template<class T, class D>
+ void swap(unique_ptr<T, D>&, unique_ptr<T, D>&) noexcept;
+#if __cplusplus >= 201402L
+ template<class T, class... Args> unique_ptr<T> make_unique(Args&&...);
+#endif
+
+ class bad_weak_ptr;
+ template<class T> class shared_ptr;
+ template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
+ template<class T, class A, class... Args>
+ shared_ptr<T> allocate_shared(const A& a, Args&&... args);
+ template<class T> void swap(shared_ptr<T>&, shared_ptr<T>&) noexcept;
+ template<class T> class weak_ptr;
+ template<class T> void swap(weak_ptr<T>&, weak_ptr<T>&) noexcept;
+ template<class T> class owner_less;
+ template<class T> class enable_shared_from_this;
+
+ template<class T, class D> struct hash<unique_ptr<T, D>>;
+ template<class T> struct hash<shared_ptr<T>>;
+#endif
+
// lib.auto.ptr, pointers:
template<class X> class auto_ptr;
}
diff --git a/libstdc++-v3/testsuite/20_util/is_assignable/requirements/access.cc b/libstdc++-v3/testsuite/20_util/is_assignable/requirements/access.cc
new file mode 100644
index 0000000..a96fba6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_assignable/requirements/access.cc
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+class S {
+ operator int();
+ friend void g(); // #1
+};
+
+void
+g()
+{
+ int i = 0;
+ S s;
+ i = s; // this works, because we're inside a friend.
+
+ // But the traits are evaluated in "a context unrelated to either type".
+ static_assert( ! std::is_assignable<int&, S>::value, "unfriendly");
+#if __cplusplus >= 201703L
+ static_assert( ! std::is_assignable_v<int&, S>, "unfriendly");
+#endif
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc b/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc
index a946db1..976d257 100644
--- a/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc
@@ -17,6 +17,9 @@
// { dg-do compile { target c++17 } }
+// PR 91456
+// std::function and std::is_invocable_r do not understand guaranteed elision
+
#include <type_traits>
#include <functional>
@@ -27,7 +30,6 @@ struct Immovable {
Immovable& operator=(const Immovable&) = delete;
};
-Immovable get() { return {}; }
-const Immovable i = get(); // OK
-std::function<const Immovable()> f{&get}; // fails
-const Immovable i2 = f();
+static_assert(std::is_invocable_r_v<Immovable, Immovable(*)()>);
+static_assert(std::is_invocable_r_v<const Immovable, Immovable(*)()>);
+static_assert(std::is_invocable_r_v<Immovable, const Immovable(*)()>);
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value.cc
index e9aded7..a268628 100644
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value.cc
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value.cc
@@ -21,9 +21,7 @@
#include <type_traits>
#include <testsuite_tr1.h>
-#ifndef IS_NT_CONVERTIBLE_DEFINED
using std::is_nothrow_convertible;
-#endif
void test01()
{
diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value_ext.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/91456.cc
index 0f89642..abbbd1a 100644
--- a/libstdc++-v3/testsuite/20_util/is_nothrow_convertible/value_ext.cc
+++ b/libstdc++-v3/testsuite/20_util/is_nothrow_invocable/91456.cc
@@ -15,14 +15,21 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-do compile { target c++11 } }
+// { dg-do compile { target c++17 } }
+
+// PR 91456
+// std::function and std::is_invocable_r do not understand guaranteed elision
#include <type_traits>
-// Test the non-standard __is_nothrow_convertible trait
+#include <functional>
-template<typename From, typename To>
- using is_nothrow_convertible = std::__is_nothrow_convertible<From, To>;
+struct Immovable {
+ Immovable() = default;
+ Immovable(const Immovable&) = delete;
+ Immovable& operator=(const Immovable&) = delete;
+};
-#define IS_NT_CONVERTIBLE_DEFINED
-#include "value.cc"
+static_assert(std::is_nothrow_invocable_r_v<Immovable, Immovable(*)() noexcept>);
+static_assert(std::is_nothrow_invocable_r_v<const Immovable, Immovable(*)() noexcept>);
+static_assert(std::is_nothrow_invocable_r_v<Immovable, const Immovable(*)() noexcept>);